嗨,哈伯恋人! 碰巧的是,在2018年8月,我很幸运地开始与我的同志(
kirillskiy )合作进行一个项目,该项目的兴趣令人赞叹。 因此,在白天,我们是普通的程序员,而在晚上,我们又是程序员,他们都在为肢体功能受限的人识别动作而苦苦挣扎,自然健康的人也可以通过各种方式使用类似的技术来使用它。
在
本文中 ,Cyril笼统地谈论了该项目,但我将更详细地讲述该项目,并涉及其中的android主题。
首先,我将向您介绍整个项目,我们想出了什么以及我们如何实现这一目标:
1)选择了
EMG (电泳法-记录肌肉的电活动)作为获取数据的方式(哦,是的,会有很多数据)。 这种方法在1907年首次应用,因此我们沿着人迹罕至的地方走了。
2)我们发现了一个可以在蓝牙上工作的8通道EMG传感器(即使具有自己的API,最终也被证明是绝对没有用的,因为我必须自己作为BT设备进行连接。至少感谢我们编写了规范)
3)我们决定一切都会像这样工作:
- 训练模式。 我们将传感器穿在前臂上,选择要训练的运动类型。 例如...“弯曲画笔”。 并开始训练(重复运动12次)。 我们将保存此时接收到的数据,然后将其发送到服务器,在此我们将训练神经网络(当然,我也会告诉您)
- 直接动作识别模式。 将运动过程中获取的数据与通过训练神经网络而获得的模型进行比较。 根据结果,例如,我们将获得“弯曲刷”。
- 驾驶模式。 根据某种运动类型,必须做出一些运动。 例如,由丹麦著名制造商的设计师(PPC,价格昂贵)在厨房组装的机械手。
4)Android项目。 我是一名Android开发人员-不使用它是一个罪过。 Android在这里与我们合作:
- 查找所有可用的BT设备
- 连接到传感器
- 根据从传感器(8个通道,频率200Hz)获取的数据绘制图形。 8条美丽多彩的曲线。
- 实现训练模式(选择训练的动作类型,训练开始按钮,数据发送按钮)
- 实现客户端-服务器交互。 有必要将数据发送到服务器,以便训练神经网络
- 与Raspberry PI 3B进行连接和交互,将Raspberry PI 3B焊接到电动机上,从而使机械臂运动。
5)Raspberry PI 3B。 是在树莓派上安装了Android Things,然后在其上举起了BT服务器,该服务器从Android设备接收消息并移动相应的电机,从而使乐高的超级爪子动起来。
6)服务器。 它由Docker本地部署在计算机上。 它接收您设备发送的数据,教一个神经网络,并返回一个模型。
部件号1. Android。 这次,我们将考虑有关Android的项目,直到将数据发送到服务器为止。它被称为NUKLEOS(https://github.com/cyber-punk-me/nukleos)
堆栈:
-科特林
-MVP
-匕首2
-改造2
-RxKotlin,RxAndroid
对于覆盆子:
-Android事物
在工作中,他们不允许我玩建筑,但最后我有机会玩一个叫做MVP的旧玩具。
该应用程序由一种活动的“底部导航”样式和4个片段组成:
第一个是
“所有可用BT设备的列表”我们选择了8通道BT传感器,该传感器具有用于BT的自己的API。 不幸的是,该api绝对是无用的,因为它立即建议定义6种(类似)运动类型之一,但是识别精度为80%,这并不好。 好吧,我们需要实际数据。 激发肌肉纤维后在人类肌肉中发生的生物电势变化的价值。 为此,必须直接使用此传感器。 创建者留下了使用该协议的说明,因此他们不得不花很长时间进行挖掘。 如果有趣,我可以在另一篇文章中描述使用裸露BT设备的示例,但简而言之,它看起来像这样:
class BluetoothConnector(val context: Context) { private val mBTLowEnergyScanner by lazy { (context.getSystemService(Activity.BLUETOOTH_SERVICE) as BluetoothManager) .adapter.bluetoothLeScanner } private var mBluetoothScanCallback: BluetoothScanCallback? = null
小心地将标准BT服务包装在RX中,以减轻痛苦。
接下来,运行扫描,并感谢订阅上的rx,我们将所有设备填充到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() } })
选择一个设备,选择它,然后转到下一个屏幕:
“传感器设置”我们连接到它,并使用预先准备的命令开始流式传输传感器数据。 幸运的是,描述了传感器创建者使用此设备的协议:
object CommandList {
小心地将设备包装在rx中,可以轻松工作。
传感器自然返回字节数组,因此有必要切断转换器,传感器的频率为200 Hz ...如果有意思,我可以详细描述它(或者看一下代码),但是最后我们以这种方式处理了足够多的数据:
1-我们需要绘制每个传感器的曲线。 当然,绝对渲染所有数据是没有意义的,因为在移动设备上,眼睛每秒检查每个传感器200次变化是没有意义的。 因此,我们不会采取一切措施。
2-如果是学习或识别过程,我们需要处理全部数据。
针对这些需求,RX非常适合与其所有滤波器一起使用。
必须绘制图表。 谁在乎-在views文件夹中查看PowerfullChartsView。
现在看一些视频:
在视频中,您将看到Cyril如何与整个系统配合使用。 该视频正在使用模型。 但是模型在服务器上。 将来,它当然会在设备上,这将显着加快响应速度)
写出哪些方面很有趣,哪些方面可以更详细地说明。 自然,我们正在研究一个项目,欢迎您提出建议。
整个github项目在这里