La ropa es inteligente, pero nosotros somos más inteligentes: cómo hicimos una camiseta con control de postura

¡Hola! En el segundo semestre, todos los estudiantes de primer año del programa de Informática y Matemáticas Aplicadas en St. Petersburg HSE realizan proyectos en equipo en C ++ . Hemos estado desarrollando una camiseta inteligente.



Lea sobre qué es y qué logramos hacer durante el trabajo en el proyecto en este artículo.





Nosotros, Denis Tarasov y Denis Filippov, ya somos estudiantes de segundo año de pregrado en Matemáticas Aplicadas e Informática en el HSE de San Petersburgo. Trabajamos en el proyecto junto con Yan Freidkin e Ivan Chunarev. Estudiamos con ellos en la misma escuela: St. Petersburg GFML No. 30.



En el 11º grado, Yan e Ivan tenían un proyecto de robótica ー "Camiseta inteligente" (está en la primera foto). La idea es la siguiente: se toma una camiseta, se le colocan varios sensores (acelerómetro, giroscopio y otros). Algunos indicadores se pueden determinar a partir de los datos leídos, por ejemplo, la postura correcta. Los chicos lograron participar en varias conferencias e iban a seguir trabajando en el proyecto después de graduarse, pero se dieron cuenta de que necesitaban programadores. De hecho, aquí estamos.



La camiseta de Jan e Ivan podía leer el ECG y seguir la postura correcta. Para ello se utilizó el Arduino UNO, una plataforma de desarrollo con microcontroladores AVR obsoletos. Muy pronto, se quedaron sin memoria de código. En una nueva etapa de trabajo en el proyecto, nos dimos cuenta de que era necesario imponer requisitos más estrictos al microcontrolador: 



  • para conectar más sensores, se necesitaba un procesador con una frecuencia más alta, más periféricos y periféricos más rápidos;
  • más memoria flash, RAM;
  • costo más bajo;
  • estabilidad del microcontrolador.


Decidimos que necesitábamos cambiar el microcontrolador. Teníamos dos opciones: usar un microcontrolador de la serie AVR más potente (en nuestro caso Arduino) o cambiar a otra serie de microcontroladores, a saber, ARM (en nuestro caso STM32). A pesar de la gran comunidad de Arduino y la facilidad de uso de este microcontrolador, decidimos actualizar a STM32 porque tiene un mejor rendimiento y más memoria. Actualmente estamos usando un microcontrolador STM32f4 *.





En el último semestre, nos propusimos el objetivo de darnos cuenta de la recepción de información sobre la postura de una persona y su procesamiento. El esquema del proyecto es el siguiente: tenemos una camiseta, se le adjuntan acelerómetros y giroscopios, con la ayuda de los cuales obtenemos los ángulos de torsión. Los datos recibidos de los sensores se envían al microcontrolador. Allí se procesan y, si es necesario, se aplica voltaje al motor de vibración, lo que estimula a la persona a enderezarse. Con la aplicación de Android, el procesamiento de la postura se enciende y apaga, y la camiseta se vincula al usuario. Pero, en general, una camiseta puede funcionar sin acceso a un teléfono inteligente: puede activar el procesamiento de postura en la aplicación, dejar su teléfono en casa e ir a caminar con una camiseta. En este caso, los datos se procesarán en el microcontrolador y el motor de vibración se encenderá si la posición es incorrecta.





Los primeros pasos. LED encendido



No teníamos experiencia en la programación de microcontroladores y leímos que inicializar y declarar sensores y pines en un STM es largo y difícil. Por lo tanto, utilizamos un alto nivel de abstracción utilizando la biblioteca HAL y STM32CubeMX . STM32CubeMX es una herramienta que configura los puertos del microcontrolador usando una interfaz gráfica y genera el código apropiado usando la biblioteca HAL. Primero, decidimos hacer lo más básico en la programación de microcontroladores (en el nivel “Hola mundo”) encender el LED.





Interfaz STM32CubeMX



Después de una larga búsqueda de un IDE que fuera multiplataforma, gratuito y fácil de desarrollar, nos decidimos por STM32CubeIDE







La tarea de encender el LED resultó no ser la más fácil, ya que hay bastante información sobre la programación STM32 en Internet (especialmente en comparación con Arduino). Posteriormente, este factor también complicó el trabajo en el proyecto.



Firmware del microcontrolador



Después de que aprendimos a encender el LED y entendimos cómo programar el microcontrolador en general, comenzamos a escribir la base del firmware del microcontrolador, sobre la base de la cual se podrían agregar varias funciones en el futuro. Para empezar, era necesario aprender a inicializar los sensores y recibir información de ellos. Desde los sensores, logramos llegar solo a los sensores IMU: el giroscopio y el acelerómetro. Teníamos sensores MPU-6050. 





La comunicación con el microcontrolador se realiza a través del bus I2C. Gracias a la biblioteca HAL, la transferencia de datos es fácil: necesita llamar a una función para leer / escribir. Un ejemplo de lectura de datos de un acelerómetro a partir del código:



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


La función recibe el manejador del bus deseado, la dirección del sensor en él, el registro desde el cual es necesario leer (los registros están escritos en la documentación del sensor), el tamaño del registro, el búfer para escribir, el tamaño del búfer y el tiempo de espera (el tiempo de espera de una respuesta) en milisegundos. La función de grabación tiene una firma similar. Ejemplo de configuración del rango de medición de un giroscopio:



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


También teníamos un módulo Bluetooth (HC-05 y HC-06), pero no requirió ninguna manipulación especial para funcionar. Después de conectarlo, simplemente puede enviar datos a través del transceptor asíncrono universal (UART), un dispositivo especial dentro del microcontrolador que le permite comunicarse con otros dispositivos. Para ello, el HAL proporciona funciones similares a las del I2C. Acabamos de escribir un pequeño contenedor sobre ellos para facilitar la visualización de mensajes durante la depuración.





HC-06



A continuación, creamos una clase de controlador que inicializa los sensores, inicia el ciclo principal del programa y procesa las solicitudes provenientes de la aplicación. Las solicitudes se almacenan en una cola, se reciben a través de Bluetooth y se reciben mediante un mecanismo de interrupción. Una interrupción es una señal de software o hardware que informa al procesador sobre la ocurrencia de un evento que requiere atención inmediata. El mecanismo de interrupción es necesario, entre otras cosas, para la rápida respuesta del sistema a eventos importantes. 



El controlador también mantiene una lista de funciones de la camiseta utilizando la clase base BaseFunc. Por el momento, solo tenemos procesamiento de posturas, pero en el futuro, al agregar nueva funcionalidad, será suficiente solo con crear una clase descendiente y agregarla a la lista de funciones. El controlador se parece a esto:



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(); //   
};


Además, para obtener los ángulos de giro de los sensores IMU, tuvimos que agregar un filtro especial, que, según los datos del acelerómetro y el giroscopio, da los ángulos de deflexión correctos. Decidimos utilizar un filtro complementario porque es lo suficientemente eficiente y fácil de implementar. Al implementar este filtro, escribimos las matemáticas para los cuaterniones. Era posible arreglárselas con vectores, pero se necesitaban cuaterniones en otro filtro que probamos, por lo que ahora estamos usando cuaterniones.



Que hay en el prototipo



Después de que descubrimos la programación del microcontrolador y escribimos los conceptos básicos de su firmware, necesitábamos un prototipo de camiseta, con el que pudiéramos comenzar a hacer el procesamiento de la postura. Y luego intervino el coronavirus ... 



Debido a la pandemia, ya no pudimos reunirnos y trabajar en una camiseta con los cuatro, y en realidad no tuvimos la oportunidad de ir con Jan e Ivan para que en caso de problemas con los prototipos, pudiéramos resolverlos rápidamente. Jan e Ivan desarrollaron un prototipo de camiseta en la que se podían colocar los sensores tirando de los cables para que no afectaran las lecturas con su peso y tensión. Los chicos nos enviaron a Denis ya mí una copia de una camiseta, además de cinta aislante, cables, etc., para que nosotros mismos pudiéramos eliminar posibles averías. 



aplicación Android



Nos marcamos el objetivo de crear una aplicación para Android con la capacidad de comunicarse vía Bluetooth con un microcontrolador. Como en el caso de la programación de microcontroladores, no teníamos experiencia en escribir aplicaciones para Android, pero encontrar información sobre Android resultó ser mucho más fácil que sobre STM32. Aprendimos los conceptos básicos usando el  curso en Stepik.org (el curso es realmente bueno), donde primero analizas los conceptos básicos del lenguaje Kotlin y luego hablas sobre programación para Android. 



La primera versión de la aplicación permitía conectarse al microcontrolador a través de Bluetooth y enviarle mensajes. La última versión no difiere mucho de la primera (escribir una aplicación no era una prioridad para nosotros): ahora tiene widgets para iniciar la calibración y activar / desactivar la función de seguimiento de la postura correcta. 



Tomó alrededor de 6 horas escribir la primera versión funcional de la aplicación; dedicamos más tiempo a estudiar la teoría. El código para una aplicación tan simple tomó alrededor de 400 líneas, lo que fue una agradable sorpresa. Además, seguro que se puede escribir de forma más compacta. 





Menú de navegación





 Pestaña para conexión Bluetooth





Pestaña para intercambio de datos



Tratamiento postural



Se nos ocurrieron dos formas diferentes de manejar la postura: con y sin métodos de análisis de datos.



Tratamiento de la postura mediante técnicas de análisis de datos



En la versión anterior, solo había un sensor en la camiseta, según los datos a partir de los cuales se tomó una decisión sobre la postura correcta de una persona: dependía del ángulo de rotación del sensor. Obviamente, este enfoque no puede proporcionar una alta precisión, porque no tenemos datos sobre la posición de la mayor parte de la espalda. Nuestra versión tiene 4 sensores. Fue bastante difícil averiguar cómo interpretar sus lecturas, por lo que decidimos recurrir a métodos de análisis de datos. Debido a problemas con los prototipos, no se hizo mucho antes de la fecha límite. 



Primero, tomamos los datos de nosotros mismos: ángulos de giro y lecturas del acelerómetro de cada uno de los sensores. Obtuvimos alrededor de 2000 mediciones: alrededor de 1000 positivas y 1000 negativas. La configuración del sensor fue la siguiente (dos sensores están ubicados en los omóplatos y dos en la columna):





 

Desafortunadamente, en ambos prototipos, hubo problemas con uno de los cuatro sensores, por lo que no se utilizó el sensor número 3. Los colocamos intuitivamente: queríamos rastrear la posición de los omóplatos y la columna cerca del cuello.







Proyección de datos en un espacio bidimensional.



Aquí, las áreas de postura correcta se resaltan en verde y las áreas de postura incorrecta se resaltan en rojo. En proyección sobre un espacio tridimensional, se ve que las posiciones correctas y las incorrectas son fáciles de separar entre sí. 





A continuación, fue necesario seleccionar modelos para la predicción. Decidimos probar la regresión lineal, o más bien su modificación de Ridge, máquina de vectores de soporte (SVM) con un kernel lineal y un árbol de decisión. La elección se debe a la simplicidad de transferir los modelos al microcontrolador: los dos primeros se describen mediante un cierto número de coeficientes y el último es un conjunto de condiciones if-else. Los modelos se tomaron de la biblioteca scikit-learn. Ejemplo de arrastre de regresión lineal:



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;


los valores a ??, g ??, sesgo se toman del modelo entrenado.



La precisión de los modelos con diferentes configuraciones en la muestra de prueba se puede ver en la tabla:





El tamaño de la muestra de prueba fue el 33% de todos los datos. Es muy probable que tasas tan altas se deban a la pequeña cantidad de datos, porque las predicciones son demasiado buenas.



En la vida real, los modelos que probamos (árboles de decisión y algunas configuraciones de regresión lineal) no funcionaron tan bien, por lo que tuvieron que ajustarse ligeramente para que se comportaran de manera más apropiada. El mejor Ridge es el que está entrenado en ángulos de giro.





Un ejemplo de árbol de decisiones.



En una pandemia y con solo dos prototipos, no pudimos recopilar una gran cantidad de datos de diferentes personas, lo que es malo para los modelos. Además, la solución actual utiliza solo una medida para determinar la postura correcta, lo que, por supuesto, no es suficiente. Una persona puede simplemente inclinarse sobre el objeto y la camiseta comenzará a vibrar. Para resolver tales problemas, debe probar modelos que hagan predicciones a partir de la secuencia de datos de entrada, pero dichos modelos serán más difíciles de transferir al microcontrolador de la forma en que estaba en la solución actual.



Postura inversa sin métodos de análisis de datos



Para manejar la postura sin ML, primero se tuvieron que estudiar muchos artículos médicos sobre la postura. Tenía muchas ganas de encontrar información sobre características cuantitativas que pudieran medirse y compararse con la norma: es decir, conocer el rango de valores "normal".



Estudiamos muchos artículos, pero la mayoría de ellos o carecían de características cuantitativas o las características no se podían medir con los medios a nuestra disposición. Solo un artículo nos resultó útil (por cierto, muchos otros estudios relacionados con la postura humana se refieren a él). Describió varios ángulos, cuyos valores se pueden utilizar para determinar la postura correcta.





Puntuaciones de postura en personas con trastorno depresivo mayor antes (A) y después (B) del tratamiento de J. Canales et al (2010).



Todo lo que queda es medir estos ángulos. Para medir, puede representar aproximadamente la posición normal de la columna usando alguna función, y luego tomar los puntos necesarios en el gráfico y buscar los valores de varios ángulos a partir de ellos. 







Configuración del sensor



Los sensores están ubicados a lo largo de la columna. En los puntos donde se ubican, se pueden obtener los ángulos de inclinación de las tangentes, y por tanto hallar el valor de la derivada (que es igual a la tangente del ángulo de inclinación de las tangentes). A medida que la columna se dobla, las coordenadas de los puntos cambian todo el tiempo. Debido a esto, es imposible aplicar, por ejemplo, la interpolación de Hermite. En este caso, se conocen las distancias entre puntos a lo largo de la curva: se pueden medir físicamente. Inicialmente, usando estos datos, queríamos intentar encontrar una función suave, por ejemplo, algún polinomio. Pero, en primer lugar, esto requiere más puntos en los que se conocen las derivadas y, en segundo lugar, el problema no es tan simple desde el punto de vista matemático y computacional. Por lo tanto, en esta etapa de desarrollo, se decidió aproximar la columna usando una función lineal por partes.





Como resultado, de los dos ángulos que intentamos medir (ángulos 3 y 4 en la imagen del artículo), uno se midió correctamente y el otro no. Los valores del ángulo 3 coincidieron con los valores normales indicados en el artículo. El ángulo 4 se midió mal debido a las características del diseño. Lo más probable es que el problema radique en el hecho de que la camiseta no se ajusta bien al cuerpo en algunos lugares, por lo que el ángulo de inclinación de las tangentes se calcula incorrectamente.



Video de demostración



Aquí hay un video de demostración del funcionamiento de la camiseta y la aplicación:





El procesamiento de la postura comienza primero, luego comienza la calibración y luego comienzan a llegar los mensajes sobre la postura correcta.



Conclusión



Como resultado, logramos procesar la postura de dos maneras, lidiar con la programación para Android, escribir una aplicación para Android y, al mismo tiempo, entender un poco sobre la programación del microcontrolador STM32.



Por supuesto, nuestra camiseta no puede considerarse terminada, pero hasta ahora hemos estado trabajando en ella durante un semestre del primer año. ¡Aún queda mucho por hacer y el año que viene planeamos continuar!



Ahora un poco sobre nuestros planes para el futuro. Queremos:



  • Refina las aproximaciones de la columna con una función para medir con mayor precisión los ángulos asociados con la columna.
  • Recopile más datos para el procesamiento de la postura. Por el momento, los datos se han tomado solo de nosotros dos y nuestros prototipos son ligeramente diferentes. 
  • Amplíe la funcionalidad. Por ejemplo, agregue un registro de electrocardiograma para que pueda usarse para identificar diversas enfermedades, anomalías, etc.
  • Mejora la aplicación: amplía su funcionalidad. Por ejemplo, calcular estadísticas, analizarlas, dibujar gráficos.
  • Cree un prototipo de camiseta que tendrá una apariencia más comercial. En la etapa actual, los prototipos están destinados únicamente a probar la funcionalidad. Quiero armar una camiseta, lista para su uso completo.


Enlaces al github del proyecto:



github.com/DT6A/Mithril microcontroller firmware,

github.com/DT6A/MithrilAppー aplicación para Android,

github.com/DT6A/MithrilDataー trabaja con datos.



All Articles