衣服很聪明,但我们更聪明:我们如何制作带姿势控制的T恤

你好!在第二学期,圣彼得堡HSE应用数学和信息学计划的所有一年级学生都使用C ++进行团队项目我们一直在开发智能T恤。



在本文中,了解它是什么以及我们在该项目的工作中设法完成的工作。





我们Denis Tarasov和Denis Filippov已经是圣彼得堡HSE应用数学和信息学的二年级本科生。我们与Yan Freidkin和Ivan Chunarev一起进行了该项目。我们在同一所学校和他们一起学习:圣彼得堡GFML第30号。



在11年级时,Yan和Ivan有一个机器人项目ー“ Smart T-shirt”(在第一张照片中)。这个想法是这样的:一件T恤衫,各种传感器(加速度计,陀螺仪和其他传感器)连接到它。可以从读取的数据中确定一些指标,例如正确的姿势。他们设法参加了几次会议,毕业后将继续从事该项目,但意识到他们需要程序员。其实,我们来了。



Jan和Ivan的T恤可以读取ECG并跟踪正确的姿势。为此,使用了Arduino UNO,这是带有过时的AVR微控制器的开发平台。很快,它们用完了代码内存。在该项目的新工作阶段,我们意识到有必要对微控制器施加更严格的要求: 



  • 为了连接更多的传感器,需要具有更高频率,更多外围设备和更快外围设备的处理器;
  • 更多的闪存,RAM;
  • 更低的花费;
  • 微控制器的稳定性。


我们决定需要更换微控制器。我们有两个选择:使用功能更强大的AVR系列微控制器(在我们的情况下为Arduino)或切换到另一系列微控制器,即ARM(在我们的情况下为STM32)。尽管存在着庞大的Arduino社区并且易于使用该微控制器,但我们还是决定升级到STM32,因为它具有更好的性能和更多的内存。我们目前正在使用STM32f4 *微控制器。





在过去的一个学期中,我们为自己设定了实现接收有关人的姿势及其处理信息的目标。该项目的方案如下:我们有一件T恤,加速度计和陀螺仪固定在它上面,借助它我们可以得到扭曲的角度。从传感器接收的数据被发送到微控制器。在那里进行处理,并在必要时将电压施加到振动马达上,从而刺激人站直。使用Android应用程序,可以打开和关闭姿势处理,并将T恤链接到用户。但总的来说,T恤可以在不使用智能手机的情况下工作:您可以在应用程序中打开姿势处理,将手机留在家里然后穿T恤散步。在这种情况下,如果位置不正确,数据将在微控制器上处理,并且振动电机将打开。





第一步。LED灯亮



我们没有对微控制器进行编程的经验,并且我们读到,在STM上初始化和声明传感器和引脚很长而且很困难。因此,我们使用了HAL库和STM32CubeMX进行了高级抽象STM32CubeMX是一款使用图形界面配置微控制器端口并使用HAL库生成适当代码工具。首先,我们决定做微控制器编程中最基本的事情(在“ Hello world”级别),然后点亮LED。





STM32CubeMX接口



经过长期寻找可以跨平台,免费且易于开发的IDE,我们选择了STM32CubeIDE。 







事实证明,打开LED的任务并不是最容易的,因为Internet上有很多有关STM32编程的信息(尤其是与Arduino相比)。后来,这个因素也使该项目的工作复杂化。



微控制器固件



在学习了如何点亮LED并了解了如何对微控制器进行总体编程之后,我们开始编写微控制器固件的基础,并在此基础上将来添加各种功能。首先,有必要学习如何初始化传感器并从中接收信息。从传感器,我们设法仅到达IMU传感器:陀螺仪和加速度计。我们有MPU-6050传感器。 





通过I2C总线与微控制器进行通信。借助HAL库,数据传输变得容易:您需要调用一个函数来进行读取/写入。从代码中读取加速度计数据的示例:



HAL_I2C_Mem_Read(i2c_handle, addres, ACCEL_XOUT_H_REG, 1, buffer, 6, 1000)


该函数接收所需总线的处理程序,其上传感器的地址,必须从中读取的寄存器(寄存器写在传感器的文档中),寄存器的大小,用于写入的缓冲区,缓冲区的大小以及超时(等待响应所花费的时间)(以毫秒为单位)。记录功能具有相似的签名。设置陀螺仪测量范围的示例:



HAL_I2C_Mem_Write(i2c_handle, addres, GYRO_CONFIG_RE	G, 1, &Data, 1, 1000)


我们也有一个蓝牙模块(HC-05和HC-06),但是不需要任何特殊的操作。连接后,您可以简单地通过通用异步收发器(UART)发送数据,通用异步收发器(UART)是微控制器内部的一种特殊设备,可让您与其他设备进行通信。为此,HAL提供了类似于I2C的功能。我们只是在它们上面写了一个小包装,以使调试时更容易显示消息。





HC-06



接下来,我们创建了一个Controller类,该类初始化传感器,启动主程序循环并处理来自应用程序的请求。请求存储在队列中,通过蓝牙接收,并使用中断机制接收。中断是来自软件或硬件的信号,它通知处理器有关事件的发生,需要立即引起注意。除其他外,还需要中断机制,以使系统对重要事件做出快速响应。 



控制器还使用基类BaseFunc维护T恤功能列表。目前,我们仅进行状态处理,但是在将来,添加新功能时,仅创建一个后代类并将其添加到功能列表就足够了。控制器看起来像这样:



class Controller {
std::vector<std::unique_ptr<IMU>> IMUSensors;  //  
std::queue<Request> reqQueue; //  
std::vector<std::pair<std::unique_ptr<BaseFunc>, bool>> mithrilFuncs; //   
//< ,   >
Controller();
void Run(); //   
};


同样,为了从IMU传感器获得扭转角,我们必须添加一个特殊的滤波器,该滤波器根据来自加速度计和陀螺仪的数据给出正确的偏转角。我们决定使用互补滤波器,因为它足够高效且易于实现。实施此过滤器时,我们为四元数编写了数学公式。向量是可以实现的,但是在我们测试的另一个过滤器中需要四元数,因此现在我们使用四元数。



原型上有什么



在弄清了微控制器的编程并编写了其固件的基础之后,我们需要一个T恤的原型,通过它我们可以开始进行姿势处理。然后冠状病毒介入... 



由于大流行,我们再也无法与我们四个人见面并穿着T恤工作了,我们实际上没有机会去拜访Jan和Ivan,以便在遇到原型问题时可以迅速解决它们。Jan和Ivan开发了T恤衫的原型,可以通过拉动电线将传感器放置在T恤上,这样它们就不会因其重量和张力而影响读数。伙计们给了丹尼斯和我一份T恤,电工胶带,电线等的副本,以便我们自己消除可能的故障。 



Android应用程式



我们设定的目标是创建一个能够通过蓝牙与微控制器通信的Android应用程序。与对微控制器进行编程一样,我们没有编写用于Android的应用程序的经验,但是事实证明,与STM32相比,查找有关Android的信息要容易得多。我们使用Stepik.org上的课程学习了基础知识  (该课程非常好),您首先在其中分析Kotlin语言的基础知识,然后再讨论Android编程。 



该应用程序的第一个版本允许通过蓝牙连接到微控制器并向其发送消息。最新版本与第一个版本没有什么不同(对我们而言,编写应用程序不是我们的优先事项):现在,它具有用于启动校准和打开/关闭跟踪正确姿势功能的小部件。 



编写该应用程序的第一个工作版本花了大约6个小时-我们花了更多时间研究该理论。如此简单的应用程序的代码大约需要400行,这真是令人惊讶。而且,可以肯定的是它可以写​​得更紧凑。 





导航菜单





 用于蓝牙连接的





标签用于数据交换的标签



姿势治疗



我们提出了两种不同的姿势处理方法:使用和不使用数据分析方法。



使用数据分析技术的姿势治疗



在以前的版本中,T恤仅具有一个传感器,根据该数据,可以根据一个人的正确姿势做出决定:它取决于传感器的旋转角度。显然,这种方法不能提供很高的准确性,因为我们没有关于大多数背部位置的数据。我们的版本有4个传感器。弄清楚如何解释他们的读数非常困难,因此我们决定采用数据分析方法。由于原型存在问题,截止日期前还没有做很多事情。 



首先,我们从我们自己那里获取数据:每个传感器的扭转角和加速度计读数。我们得到约2000个测量值:约1000个正值和1000个负值。传感器配置如下(两个传感器位于肩blade骨上,两个传感器位于脊椎上):





 

不幸的是,在两个原型上,四个传感器之一都有问题,因此没有使用3号传感器。我们直观地放置它们:我们想跟踪肩the骨和颈部附近脊柱的位置。







数据投影到二维空间中。



在此,正确姿势的区域以绿色突出显示,而错误姿势的区域以红色突出显示。在投影到三维空间时,可以看到正确的位置和不正确的位置容易彼此分离。 





接下来,有必要选择用于预测的模型。我们决定尝试线性回归,或更确切地说是它的Ridge修改,带有线性核和决策树的支持向量机(SVM)。选择是因为将模型转移到微控制器很简单:前两个由多个系数描述,后一个是一组if-else条件。这些模型取自scikit-learn库。线性回归结转示例:



bool isPostureCorrect =
           (a11 * deviceAngles1[0] + a12 * deviceAngles1[1] + a13 * deviceAngles1[2] +
           g11 * deviceGravity1[0] + g12 * deviceGravity1[1] + g13 * deviceGravity1[2] +
           a21 * deviceAngles2[0] + a22 * deviceAngles2[1] + a23 * deviceAngles2[2] +
           g21 * deviceGravity2[0] + g22 * deviceGravity2[1] + g23 * deviceGravity2[2] +
           a41 * deviceAngles3[0] + a42 * deviceAngles3[1] + a43 * deviceAngles3[2] +
           g41 * deviceGravity3[0] + g42 * deviceGravity3[1] + g43 * deviceGravity3[2]) > bias;


从训练模型中得出a,g,偏差值。



下表中显示了测试样本上具有不同配置的模型的准确性:





测试样本量为所有数据的33%。如此高的比率很可能是由于数据量太少,因为预测结果太好了。



在现实生活中,我们测试的模型(决策树和一些线性回归配置)效果不佳,因此必须对其进行一些微调以使其表现得更加适当。最好的山脊是经过扭角训练的山脊。





决策树的示例。



在大流行中,只有两个原型,我们无法从不同的人那里收集大量数据,这对模型不利。而且,当前解决方案仅使用一种测量来确定正确的姿势,这当然是不够的。一个人可以简单地弯腰,然后T恤就会开始振动。为了解决这些问题,您应该尝试根据一系列输入数据进行预测的模型,但是以当前解决方案中的方式将这些模型转移到微控制器将更加困难。



反向姿势,无需数据分析方法



为了在不使用ML的情况下处理姿势,必须首先研究许多关于姿势的医学文章。我真的很想找到有关可以量化并与规范进行比较的定量特征的信息:也就是说,要知道值的“正常”范围。



我们研究了许多文章,但是其中大多数要么缺乏定量特征,要么无法使用我们掌握的手段来测量特征。只有一篇文章对我们有用(顺便说一下,许多其他有关人体姿势的研究都参考了这篇文章)。它描述了各种角度,其值可用于确定正确的姿势。





J. Canales等人(2010)治疗前(A)和治疗后(B)的重度抑郁症患者的姿势评分



,剩下的就是测量这些角度。要进行测量,您可以使用某些功能大致描绘出脊柱的正常位置,然后在图形上选取必要的点并从中搜索各种角度的值。 







传感器配置



传感器沿脊柱放置。在它们所在的点上,可以获得切线的倾斜角度,因此可以找到导数的值(该值等于切线的倾斜角度的切线)。当脊柱弯曲时,这些点的坐标始终在变化。因此,无法应用例如Hermite插值法。在这种情况下,沿曲线的点之间的距离是已知的:可以物理测量它们。最初,我们希望使用这些数据来查找平滑函数,例如一些多项式。但是,首先,这需要知道导数的更多点,其次,从数学和计算的角度来看,问题不是很简单。因此,在开发的这个阶段,决定使用分段线性函数来近似脊柱。





结果,在我们尝试测量的两个角度(文章图像中的角度3和4)中,一个被正确测量,而另一个未被测量。角度3的值与文章中指示的正常值一致。由于设计特征,角度4的测量不佳。问题很可能是因为T恤在某些地方不能紧贴身体,这就是为什么切线的倾斜角度计算不正确的原因。



示范影片



这是T恤和应用程序工作的演示视频:





首先开始姿势处理,然后开始校准,然后开始出现有关正确姿势的消息。



结论



结果,我们设法通过两种方式处理姿势,处理针对Android的编程,编写针对Android的应用程序,同时对STM32微控制器的编程有所了解。



当然,我们的衬衫不能算是成品-但到目前为止,我们已经在第一年的一个学期中着手研究它。还有很多事情要做,明年我们计划继续!



现在介绍一下我们的未来计划。我们想要:



  • 使用更精确地测量与脊柱关联的角度的功能来细化脊柱的近似值。
  • 收集更多数据以进行姿势处理。目前,数据仅来自我们两个人,我们的原型略有不同。 
  • 扩展功能。例如,添加心电图记录,以便可以将其用于识别各种疾病,异常情况等。
  • 改善应用程序:扩展其功能。例如,计算统计数据,对其进行分析,绘制图表。
  • 创建T恤的原型,使其外观更具市场价值。在当前阶段,原型仅用于测试功能。我想整理一件T恤,准备好充分使用。


链接到项目的github:



github.com/DT6A/Mithril微控制器固件,

github.com/DT6A/MithrilAppーandroid应用程序,

github.com/DT6A/MithrilDataー处理数据。



All Articles