Baca tentang apa itu dan apa yang berhasil kami lakukan selama mengerjakan proyek di artikel ini.

Kami, Denis Tarasov dan Denis Filippov, sudah menjadi mahasiswa tahun kedua di bidang Matematika dan Informatika Terapan di St. Petersburg HSE. Kami mengerjakan proyek bersama dengan Yan Freidkin dan Ivan Chunarev. Kami belajar dengan mereka di sekolah yang sama: GFML St. Petersburg No. 30.
Di kelas 11, Yan dan Ivan memiliki proyek robotika γΌ "Smart T-shirt" (ada di foto pertama). Idenya begini: T-shirt diambil, berbagai sensor dipasang padanya (akselerometer, giroskop, dan lainnya). Beberapa indikator dapat ditentukan dari data yang dibaca, misalnya postur tubuh yang benar. Orang-orang tersebut berhasil mengikuti beberapa konferensi dan akan terus mengerjakan proyek setelah lulus, tetapi menyadari bahwa mereka membutuhkan programmer.
Kaos Jan dan Ivan dapat membaca EKG dan melacak postur yang benar. Untuk ini, Arduino UNO digunakan, platform pengembangan dengan mikrokontroler AVR yang sudah ketinggalan zaman. Tak lama kemudian, mereka kehabisan memori kode. Pada tahap baru pengerjaan proyek, kami menyadari bahwa perlu untuk memberlakukan persyaratan yang lebih ketat pada mikrokontroler:
- untuk menghubungkan lebih banyak sensor, diperlukan prosesor dengan frekuensi yang lebih tinggi, lebih banyak periferal, dan periferal yang lebih cepat;
- lebih banyak memori flash, RAM;
- biaya rendah;
- stabilitas mikrokontroler.
Kami memutuskan bahwa kami perlu mengganti mikrokontroler. Kami memiliki dua opsi: gunakan mikrokontroler seri AVR yang lebih kuat (dalam kasus kami Arduino) atau beralih ke seri mikrokontroler lain, yaitu ARM (dalam kasus kami STM32). Meskipun komunitas Arduino besar dan kemudahan penggunaan mikrokontroler ini, kami memutuskan untuk meningkatkan ke STM32 karena memiliki kinerja yang lebih baik dan lebih banyak memori. Kami saat ini menggunakan mikrokontroler STM32f4 *.

Dalam semester terakhir, kami menetapkan tujuan untuk mendapatkan informasi tentang postur tubuh seseorang dan memprosesnya. Skema proyek ini adalah sebagai berikut: kami memiliki T-shirt dengan akselerometer dan giroskop yang terpasang padanya, dengan bantuan yang kami dapatkan sudut pelintirannya. Data yang diterima dari sensor dikirim ke mikrokontroler. Di sana mereka diproses dan, jika perlu, tegangan diterapkan ke motor getaran, yang menstimulasi orang tersebut untuk menegakkan tubuh. Menggunakan aplikasi Android, pemrosesan postur diaktifkan dan dinonaktifkan, dan T-shirt ditautkan ke pengguna. Tetapi secara umum, T-shirt dapat berfungsi tanpa akses ke smartphone: Anda dapat mengaktifkan pemrosesan postur dalam aplikasi, meninggalkan ponsel di rumah dan berjalan-jalan dengan T-shirt. Dalam hal ini, data akan diolah pada mikrokontroler dan motor getaran akan menyala jika posisinya salah.

Langkah pertama. LED menyala
Kami tidak memiliki pengalaman dalam memprogram mikrokontroler, dan kami membaca bahwa menginisialisasi dan mendeklarasikan sensor dan pin pada STM itu panjang dan sulit. Oleh karena itu, kami menggunakan abstraksi tingkat tinggi menggunakan pustaka HAL dan STM32CubeMX . STM32CubeMX adalah alat yang mengkonfigurasi port mikrokontroler menggunakan antarmuka grafis dan menghasilkan kode yang sesuai menggunakan pustaka HAL. Pertama, kami memutuskan untuk melakukan hal paling dasar dalam pemrograman mikrokontroler (pada level "Hello world") - menyalakan LED.

Antarmuka STM32CubeMX
Setelah lama mencari IDE yang akan lintas platform, gratis dan mudah dikembangkan, kami menetap di STM32CubeIDE .

Tugas menyalakan LED ternyata bukan yang termudah, karena ada cukup banyak informasi tentang pemrograman STM32 di Internet (terutama dibandingkan dengan Arduino). Ke depan, faktor ini turut mempersulit pengerjaan proyek.
Firmware mikrokontroler
Setelah kami mempelajari cara menyalakan LED dan memahami cara memprogram mikrokontroler secara umum, kami mulai menulis dasar dari firmware mikrokontroler, yang menjadi dasar berbagai fungsi dapat ditambahkan di masa mendatang. Pertama, perlu dipelajari cara menginisialisasi sensor dan menerima informasi darinya. Dari sensor, kami hanya berhasil sampai ke sensor IMU: giroskop dan akselerometer. Kami memiliki sensor MPU-6050.

Komunikasi dengan mikrokontroler dilakukan melalui bus I2C. Berkat perpustakaan HAL, transfer data menjadi mudah: Anda perlu memanggil suatu fungsi untuk membaca / menulis. Contoh membaca data dari akselerometer dari kode:
HAL_I2C_Mem_Read(i2c_handle, addres, ACCEL_XOUT_H_REG, 1, buffer, 6, 1000)
Fungsi tersebut menerima handler bus yang diinginkan, alamat sensor di atasnya, register yang darinya perlu dibaca (register ditulis dalam dokumentasi untuk sensor), ukuran register, buffer untuk menulis, ukuran buffer dan batas waktu (waktu yang dihabiskan untuk menunggu respons) dalam milidetik. Fungsi perekaman memiliki tanda tangan yang serupa. Contoh pengaturan rentang pengukuran giroskop:
HAL_I2C_Mem_Write(i2c_handle, addres, GYRO_CONFIG_RE G, 1, &Data, 1, 1000)
Kami juga memiliki modul Bluetooth (HC-05 dan HC-06), tetapi tidak memerlukan manipulasi khusus untuk bekerja. Setelah menghubungkannya, Anda cukup mengirim data melalui universal asynchronous transceiver (UART) - perangkat khusus di dalam mikrokontroler yang memungkinkan Anda untuk berkomunikasi dengan perangkat lain. Untuk itu, HAL menyediakan fungsi yang mirip dengan I2C. Kami baru saja menulis pembungkus kecil di atasnya untuk membuatnya lebih mudah menampilkan pesan saat debugging.

HC-06
Selanjutnya, kami membuat kelas Controller yang menginisialisasi sensor, memulai loop program utama dan memproses permintaan yang datang dari aplikasi. Permintaan disimpan dalam antrian, diterima melalui Bluetooth, dan diterima menggunakan mekanisme interupsi. Interupsi adalah sinyal dari perangkat lunak atau perangkat keras yang menginformasikan prosesor tentang terjadinya suatu peristiwa yang memerlukan perhatian segera. Mekanisme interupsi juga diperlukan untuk respon cepat sistem terhadap peristiwa penting.
Controller juga menyimpan daftar fungsi T-shirt menggunakan base class BaseFunc. Saat ini, kami hanya memiliki pemrosesan postur, tetapi di masa mendatang, saat menambahkan fungsionalitas baru, cukup membuat kelas turunan dan menambahkannya ke daftar fungsi. Pengontrolnya terlihat seperti ini:
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(); //
};
Selain itu, untuk mendapatkan sudut putar dari sensor IMU, kami harus menambahkan filter khusus, yang menurut data dari akselerometer dan giroskop, memberikan sudut defleksi yang benar. Kami memutuskan untuk menggunakan filter pelengkap karena cukup efisien dan mudah diterapkan. Saat menerapkan filter ini, kami menulis matematika untuk quaternions. Itu mungkin dilakukan dengan vektor, tetapi angka empat diperlukan di filter lain yang kami uji, jadi sekarang kami menggunakan angka empat.
Apa yang ada di prototipe
Setelah kami mengetahui pemrograman mikrokontroler dan menulis dasar-dasar firmware, kami memerlukan prototipe kaos, yang dengannya kami dapat mulai melakukan pemrosesan postur. Dan kemudian virus Corona ikut campur ...
Karena pandemi, kami tidak bisa lagi bertemu dan mengerjakan T-shirt bersama kami berempat, dan kami sebenarnya tidak memiliki kesempatan untuk pergi ke Jan dan Ivan sehingga jika ada masalah dengan prototipe, kami dapat segera menyelesaikannya. Jan dan Ivan mengembangkan prototipe kaos di mana sensor dapat ditempatkan dengan menarik kabel sehingga tidak mempengaruhi pembacaan dengan berat dan ketegangannya. Orang-orang mengirimi Denis dan saya salinan T-shirt, juga pita listrik, kabel, dll., Sehingga kami sendiri dapat menghilangkan kemungkinan kerusakan.
Aplikasi Android
Kami menetapkan sendiri tujuan membuat aplikasi Android dengan kemampuan untuk berkomunikasi melalui Bluetooth dengan mikrokontroler. Seperti dalam kasus pemrograman mikrokontroler, kami tidak memiliki pengalaman dalam menulis aplikasi untuk Android, tetapi menemukan informasi tentang Android ternyata jauh lebih mudah daripada tentang STM32. Kami mempelajari dasar-dasarnya menggunakan kursus di Stepik.org (kursus ini sangat bagus), di mana Anda pertama kali menganalisis dasar-dasar bahasa Kotlin, dan kemudian berbicara tentang pemrograman untuk Android.
Versi pertama dari aplikasi memungkinkan koneksi ke mikrokontroler melalui Bluetooth dan mengirim pesan ke sana. Versi terbaru tidak jauh berbeda dari yang pertama (menulis aplikasi bukanlah prioritas kami): sekarang memiliki widget untuk memulai kalibrasi dan mengaktifkan / menonaktifkan fungsi pelacakan postur yang benar.
Butuh waktu sekitar 6 jam untuk menulis versi kerja pertama dari aplikasi - kami menghabiskan lebih banyak waktu untuk mempelajari teori. Kode untuk aplikasi sederhana tersebut membutuhkan sekitar 400 baris, yang merupakan kejutan yang menyenangkan. Apalagi yang pasti bisa ditulis lebih kompak.
Menu navigasi
Tab untuk koneksi Bluetooth
Tab untuk pertukaran data
Perawatan postur tubuh
Kami menemukan dua cara berbeda untuk menangani postur tubuh: dengan dan tanpa metode analisis data.
Perawatan Postur Dengan Teknik Analisis Data
Pada versi sebelumnya, T-shirt hanya memiliki satu sensor, menurut data yang diambil tentang postur tubuh yang benar: itu tergantung pada sudut rotasi sensor. Tentunya, pendekatan ini tidak bisa memberikan akurasi yang tinggi, karena kami tidak memiliki data posisi sebagian besar bek. Versi kami memiliki 4 sensor. Cukup sulit untuk mengetahui bagaimana menafsirkan bacaan mereka, jadi kami memutuskan untuk menggunakan metode analisis data. Karena masalah dengan prototipe, banyak yang tidak dilakukan sebelum tenggat waktu.
Pertama, kami mengambil data dari diri kami sendiri: sudut putar dan pembacaan akselerometer dari masing-masing sensor. Kami mendapat sekitar 2000 pengukuran: sekitar 1000 positif dan 1000 negatif. Konfigurasi sensornya adalah sebagai berikut (dua sensor terletak di tulang belikat dan dua di tulang belakang):

Sayangnya pada kedua prototipe tersebut terdapat masalah pada salah satu dari keempat sensor tersebut, sehingga sensor nomor 3 tidak digunakan. Kami menempatkannya secara intuitif: kami ingin melacak posisi tulang belikat dan tulang belakang di dekat leher.


Proyeksi data ke dalam ruang dua dimensi.
Di sini, area dengan postur yang benar disorot dengan warna hijau, dan area dengan postur yang salah disorot dengan warna merah. Ketika diproyeksikan ke dalam ruang tiga dimensi, dapat dilihat bahwa posisi yang benar dan yang salah dapat dengan mudah dipisahkan satu sama lain.

Selanjutnya, perlu memilih model untuk prediksi. Kami memutuskan untuk mencoba regresi linier, atau lebih tepatnya modifikasi Ridge-nya, mendukung mesin vektor (SVM) dengan kernel linier, dan pohon keputusan. Pilihannya adalah karena kesederhanaan mentransfer model ke mikrokontroler: dua yang pertama dijelaskan oleh sejumlah koefisien, dan yang terakhir adalah sekumpulan kondisi if-else. Model diambil dari pustaka scikit-learn. Contoh carryover regresi linier:
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;
nilai a ??, g ??, bias diambil dari model yang dilatih.
Akurasi model dengan konfigurasi berbeda pada sampel uji dapat dilihat pada tabel:

Ukuran sampel uji adalah 33% dari semua data. Tarif tinggi seperti itu kemungkinan besar karena jumlah data yang sedikit, karena prediksi yang terlalu bagus.
Dalam kehidupan nyata, model yang kami uji (pohon keputusan dan beberapa konfigurasi regresi linier) tidak berfungsi dengan baik, sehingga harus sedikit disesuaikan agar berperilaku lebih tepat. Punggung terbaik adalah yang terlatih dalam sudut putar.

Contoh pohon keputusan.
Dalam pandemi dan hanya dengan dua prototipe, kami tidak dapat mengumpulkan sejumlah besar data dari orang yang berbeda, yang berdampak buruk pada model. Selain itu, solusi saat ini hanya menggunakan satu pengukuran untuk menentukan postur yang benar, yang tentu saja tidak cukup. Seseorang dapat dengan mudah membungkuk di atas benda tersebut, dan kaus itu akan bergetar. Untuk mengatasi masalah seperti itu, Anda harus mencoba model yang membuat prediksi dari urutan data masukan, tetapi model seperti itu akan lebih sulit untuk ditransfer ke mikrokontroler dengan cara yang ada di solusi saat ini.
Postur terbalik tanpa metode analisis data
Untuk menangani postur tubuh tanpa ML, banyak artikel kedokteran tentang postur yang harus dipelajari terlebih dahulu. Saya benar-benar ingin mencari informasi tentang karakteristik kuantitatif yang dapat diukur dan dibandingkan dengan norma: yaitu mengetahui rentang nilai yang "normal".
Kami mempelajari banyak artikel, tetapi kebanyakan dari mereka tidak memiliki karakteristik kuantitatif, atau karakteristik tersebut tidak dapat diukur dengan sarana yang kami miliki. Hanya satu artikel yang ternyata bermanfaat bagi kami (ngomong-ngomong, banyak penelitian lain yang terkait dengan postur manusia merujuknya). Ini menggambarkan berbagai sudut, yang nilainya dapat digunakan untuk menentukan postur tubuh yang benar.

Skor postur tubuh pada orang dengan gangguan depresi mayor sebelum (A) dan setelah (B) pengobatan dari J. Canales et al (2010)
Yang tersisa hanyalah mengukur sudut-sudut ini. Untuk mengukur, Anda kira-kira dapat menggambarkan posisi normal tulang belakang menggunakan beberapa fungsi, lalu mengambil titik yang diperlukan pada grafik dan mencari nilai dari berbagai sudut darinya.


Konfigurasi sensor
Sensor terletak di sepanjang tulang belakang. Pada titik-titik di mana mereka berada, Anda bisa mendapatkan sudut kemiringan garis singgung, dan oleh karena itu temukan nilai turunannya (yang sama dengan garis singgung sudut kemiringan garis singgung). Saat tulang punggung menekuk, koordinat titik berubah sepanjang waktu. Karena itu, tidak mungkin untuk menerapkan, misalnya, interpolasi Hermite. Dalam kasus ini, jarak antara titik-titik di sepanjang kurva diketahui: mereka dapat diukur secara fisik. Awalnya, dengan menggunakan data ini, kami ingin mencoba menemukan fungsi yang mulus, misalnya, beberapa polinomial. Tapi, pertama, ini membutuhkan lebih banyak poin di mana turunannya diketahui, dan kedua, masalahnya tidak cukup sederhana dari sudut pandang matematika dan komputasi. Oleh karena itu, pada tahap perkembangan ini, diputuskan untuk mendekati tulang belakang menggunakan fungsi linier sepotong-sepotong.

Hasilnya, dari dua sudut yang kami coba ukur (sudut 3 dan 4 pada gambar dari artikel), yang satu diukur dengan benar, dan yang lainnya tidak. Nilai sudut 3 bertepatan dengan nilai normal yang ditunjukkan dalam artikel. Sudut 4 tidak diukur dengan baik karena fitur desain. Kemungkinan besar, masalahnya terletak pada fakta bahwa T-shirt tidak pas dengan badan di beberapa tempat, itulah sebabnya sudut kemiringan garis singgung tidak dihitung dengan benar.
Video demo
Berikut adalah video demo kerja kaos dan aplikasi:
Pemrosesan postur dimulai terlebih dahulu, kemudian kalibrasi dimulai, dan kemudian pesan tentang postur yang benar mulai berdatangan.
Kesimpulan
Alhasil, kami berhasil mengolah postur tersebut dengan dua cara yaitu menangani pemograman untuk Android, membuat aplikasi untuk Android, dan sekaligus memahami sedikit tentang pemograman mikrokontroler STM32.
Tentu saja baju kami belum bisa dibilang sudah jadi - tapi sejauh ini kami sudah mengerjakannya selama satu semester di tahun pertama. Masih banyak yang harus dilakukan, dan tahun depan kami berencana untuk melanjutkan!
Sekarang sedikit tentang rencana kita untuk masa depan. Kami ingin:
- Persempit perkiraan tulang belakang dengan fungsi untuk mengukur sudut yang terkait dengan tulang belakang dengan lebih akurat.
- Kumpulkan lebih banyak data untuk pemrosesan postur. Saat ini, data hanya diambil dari kami berdua dan prototipe kami sedikit berbeda.
- Perluas fungsionalitas. Misalnya menambahkan rekaman elektrokardiogram sehingga dapat digunakan untuk mengidentifikasi berbagai penyakit, kelainan, dll.
- Tingkatkan aplikasi: perluas fungsinya. Misalnya, menghitung statistik, menganalisisnya, menggambar grafik.
- Buat prototipe kaos yang akan memiliki tampilan lebih laku. Pada tahap saat ini, prototipe ditujukan hanya untuk menguji fungsionalitas. Saya ingin mengumpulkan T-shirt, siap digunakan sepenuhnya.
Tautan ke github proyek:
github.com/DT6A/Mithril firmware mikrokontroler,
github.com/DT6A/MithrilAppγΌ aplikasi android,
github.com/DT6A/MithrilDataγΌ bekerja dengan data.