Salut, les amateurs de Habr! Par une heureuse coïncidence, en août 2018, j'ai eu la chance de commencer à travailler avec mon camarade (
kirillskiy ) sur un projet qui était incroyable dans son intérêt. Et donc, pendant la journée, nous étions des programmeurs ordinaires, et la nuit, nous étions à nouveau des programmeurs qui ont du mal à reconnaître les mouvements des personnes ayant une fonctionnalité limitée de leurs membres, des personnes naturellement en bonne santé pourraient également utiliser cela en utilisant une technologie similaire de diverses manières.
Dans
cet article , Cyril parle en termes généraux du projet, mais je vais en parler plus en détail et toucher le sujet d'Android.
Tout d'abord, je vais vous parler de l'ensemble du projet, de ce que nous avons proposé et de la manière dont nous voulions le mettre en œuvre:
1) L'
EMG (électromyographie - enregistrement de l'activité électrique des muscles) a été choisi comme moyen d'obtenir des données (oh, oui, il y aura beaucoup de données). Pour la première fois cette méthode a été appliquée en 1907, nous avons donc marché le long des sentiers battus.
2) Nous avons trouvé un capteur EMG à 8 canaux qui fonctionne sur Bluetooth (même avec sa propre API, qui s'est finalement avérée absolument inutile, car j'ai dû me connecter en tant qu'appareil BT moi-même. Merci au moins, nous avons écrit une spécification)
3) Nous avons décidé que tout fonctionnerait comme ceci:
- mode d'entraînement. Nous habillons le capteur sur l'avant-bras, sélectionnons le type de mouvement que nous allons entraîner. Par exemple ... "plier la brosse". et commencez l'entraînement (répétez le mouvement 12 fois). Nous allons enregistrer les données reçues à ce moment puis les envoyer au serveur, où nous formerons le réseau neuronal (calmement, je vais vous en parler aussi)
- Mode de reconnaissance de mouvement direct. Les données prises lors du mouvement sont comparées au modèle obtenu grâce à l'entraînement du réseau neuronal. Sur la base des résultats, nous obtiendrons déjà une «BROSSE PLIANTE», par exemple.
- mode de conduite. Selon un certain type de mouvement, il faut faire bouger quelque chose. Par exemple, un manipulateur assemblé dans la cuisine par un designer (PPC, combien coûte) d'un célèbre fabricant danois.
4) Élément Android. Je suis développeur Android - et c'était un péché de ne pas l'utiliser. Android fait ici avec nous:
- trouve tous les appareils BT disponibles
- se connecte au capteur
- dessine un graphique basé sur des données provenant de capteurs (8 canaux, fréquence 200 Hz). 8 belles courbes colorées.
- met en œuvre le mode d'entraînement (sélection du type de mouvement entraîné, bouton de démarrage d'entraînement, bouton d'envoi de données)
- implémente l'interaction client-serveur. Il est nécessaire d'envoyer des données au serveur pour que le réseau de neurones soit formé
- implémente la connexion et l'interaction avec le Raspberry PI 3B, auquel les moteurs sont soudés, ce qui déplace le manipulateur en mouvement.
5) Raspberry PI 3B. c'est à la framboise que nous avons mis Android Things, puis nous avons soulevé le serveur BT, qui reçoit des messages d'un appareil Android et déplace les moteurs correspondants, ce qui a déclenché une super-griffe de LEGO.
6) Serveur. Il est déployé par Docker localement sur un ordinateur. Il reçoit les données envoyées par votre appareil, enseigne un réseau de neurones et renvoie un modèle.
Numéro de pièce 1. Android. Cette fois, nous considérerons le capot du projet concernant Android jusqu'à ce que les données soient envoyées au serveur.Il s'appelle NUKLEOS (https://github.com/cyber-punk-me/nukleos)
Pile:
- Kotlin
- MVP
- Dague2
- Retrofit2
- RxKotlin, RxAndroid
pour la framboise:
-Android Things
Au travail, ils ne me laissent pas jouer avec l'architecture, mais finalement j'ai eu l'occasion de jouer avec un vieux jouet appelé MVP.
L'application se compose d'un style d'activité de navigation inférieure et de 4 fragments:
Le premier est
«Liste de tous les appareils BT disponibles»Nous avons choisi un capteur BT à 8 canaux, qui avait sa propre API pour travailler avec BT. Malheureusement, l'API s'est avérée absolument inutile, car elle a immédiatement suggéré de définir l'un des 6 types (similaires) de mouvement, mais la précision de reconnaissance était de 80% - et ce n'était pas bon. Eh bien, nous avions besoin de données réelles. La valeur des changements dans les potentiels bioélectriques qui se produisent dans les muscles humains lors de l'excitation d'une fibre musculaire. Et pour cela, il fallait travailler directement avec ce capteur. Les créateurs ont laissé une description du protocole pour travailler avec, donc ils ont dû fouiller un peu plus longtemps. Je peux décrire un exemple de travail avec des appareils BT nus dans un article séparé, si c'est intéressant, mais en un mot, cela ressemble à ceci:
class BluetoothConnector(val context: Context) { private val mBTLowEnergyScanner by lazy { (context.getSystemService(Activity.BLUETOOTH_SERVICE) as BluetoothManager) .adapter.bluetoothLeScanner } private var mBluetoothScanCallback: BluetoothScanCallback? = null
Enveloppez soigneusement le service BT standard dans RX et obtenez moins de douleur.
Ensuite, lancez l'analyse, et grâce à rx sur l'abonnement, nous créons une liste de tous les appareils en les fourrant dans RecyclerView:
mFindSubscription = mFindFlowable ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe({ if (it !in mBluetoothStuffManager.foundBTDevicesList) { addSensorToList(SensorStuff(it.name, it.address)) mBluetoothStuffManager.foundBTDevicesList.add(it) } }, { hideFindLoader() showFindError() if (mBluetoothStuffManager.foundBTDevicesList.isEmpty()) { showEmptyListText() } }, { hideFindLoader() showFindSuccess() if (mBluetoothStuffManager.foundBTDevicesList.isEmpty()) { showEmptyListText() } })
Sélectionnez l'un des appareils, sélectionnez-le et passez à l'écran suivant:
«Paramètres du capteur»Nous nous y connectons et commençons à diffuser les données du capteur à l'aide des commandes que nous avons préparées à l'avance. Heureusement, le protocole de travail avec cet appareil par les créateurs du capteur est décrit:
object CommandList {
Travailler avec l'appareil est également soigneusement emballé dans du rx pour travailler sans douleur.
Les capteurs ont renvoyé des tableaux d'octets naturellement, et il a fallu couper le convertisseur, la fréquence des capteurs était de 200 Hz ... si c'est intéressant, je peux le décrire en détail (enfin, ou regardez le code), mais au final on travaille avec une quantité de données suffisamment importante de cette façon:
1 - Nous devons dessiner les courbes de chacun des capteurs. Bien sûr, il est inutile de rendre ABSOLUMENT toutes les données, car sur l'appareil mobile, il n'est pas logique que l'œil examine 200 changements par seconde sur chaque capteur. Par conséquent, nous ne prendrons pas tout.
2 - Nous devons travailler avec toute la quantité de données, s'il s'agit d'un processus d'apprentissage ou de reconnaissance.
pour ces besoins, le RX est parfaitement adapté à tous ses filtres.
Il fallait faire des graphiques. Peu importe - regardez PowerfullChartsView dans le dossier des vues.
Et maintenant quelques vidéos:
Dans la vidéo, vous verrez comment Cyril fonctionne avec le système dans son ensemble. La vidéo fonctionne avec le modèle. Mais le modèle est sur le serveur. À l'avenir, ce sera bien sûr sur l'appareil, ce qui accélérera considérablement la réponse)
Écrivez quels aspects sont intéressants, lesquels raconter plus en détail. Naturellement, nous travaillons sur un projet et sommes ouverts à vos suggestions.
L'ensemble du projet github est ici