14 июля

Умная перчатка для велосипедистов

Машинное обучениеРазработка под ArduinoDIY или Сделай самТранспорт
Автор оригинала: Matlek


Перевод с сайта instructables.com, автор проекта: Matlek

В данной статье я подробно расскажу процесс изготовления «умной перчатки» и её светодиодной панели, предназначенных для повышения безопасности велосипедистов и других людей, путешествующих по дорогам. Сначала можно посмотреть небольшую демонстрацию работы:


Как это работает


В перчатке находится плата Arduino, собирающая данные с гироскопа и акселерометра. Код использует модель «крохотного машинного обучения» tinyML и распознаёт жесты: каждое движение руки анализируется и превращается в сигнал (рука наклоняется влево, вправо, вперёд, назад, и т.п.). Сигнал отправляется по Bluetooth (BLE) на другой микроконтроллер, к которому подсоединена светодиодная матрица (которую, например, можно закрепить на рюкзак). Сообразно полученному сигналу матрица выводит определённые последовательности символов – так, чтобы другие водители и велосипедисты могли понимать, что собирается сделать велосипедист (к примеру, это могут быть стрелки влево, вправо, или текст).









Происхождение проекта


Во-первых, я езжу на велосипеде на работу, и провожу в седле более часа в день (проезжая порядка 22 км). Это всегда интересно, однако я живу в одном из самых густонаселённых городов Франции, где часто происходят происшествия с участием автомобилей и велосипедистов. Также Марсель – худший во Франции город для велосипедистов — там отчаянно не хватает велодорожек. Поэтому данный проект посвящён как увеличению безопасности велосипедистов, так и попыткам обратить внимание городских властей на эту проблему.

Во-вторых, этот проект поможет всем участникам движения пообщаться и лучше понимать друг друга. С моей точки зрения большая часть неприятностей, происходящих на дороге, связана с тем, что некоторые участники движения неправильно поняли других, что в результате привело к испугу, а потом к агрессии. Мне хочется, чтобы такое устройство помогло участникам движения лучше понимать друг друга. Стрелки показывают направление, а ещё можно выводить текст по буквам (однако я целиком и полностью выступаю за вежливые и конструктивные надписи, во избежание конфликтов).

Почему «умная перчатка»?


Я начал работу над проектом зимой, и холодная погода мотивировала меня на то, чтобы закрепить устройство на перчатке. Но я быстро понял, что идея была не очень хорошей, потому что в нашей местности летом довольно жарко. Поэтому я решил, что лучше всего будет поместить устройство в коробку и закрепить на руке. Но поскольку я не знал, как назвать его по-другому, я решил оставить слово «перчатка» в названии.

«Умная» происходит от техники машинного обучения, которую я использовал в данном проекте.

Вдохновение


Проект в основном является смесью двух других проектов. Я не начинал работу с нуля, а пользовался их наработками, которые потом развивал далее. Вот, чем я вдохновлялся при разработке:

  • распознавание жестов при помощи Arduino Nano 33 BLE SENSE.
  • не какой-то конкретный проект, а концепция использования светодиодных матриц для велосипедистов. Таких проектов полно – некоторые используют рюкзаки с интегрированными панелями, другие просто предлагают готовую матрицу, которую можно поместить куда угодно. В любом случае, эти светодиодные матрицы управляются при помощи пульта дистанционного управления, а не распознавания жестов.

Комплектующие


Для 3D-печати – 3D-принтер или доступ к таковому.

Электроника


  • Arduino Nano 33 BLE SENSE;
  • Ещё один МИ с BLE (Arduino Nano 33 BLE, Arduino 33 BLE SENSE, Arduino nano 33 IOT, ESP32, и т.д.). Я решил использовать плату на ESP32.
  • Светодиодная полоска (WS2812B). Я использовал 160 светодиодов, чтобы получить матрицу 20×8;
  • Четырёхуровневый буфер с 3 В до 5 В: 74AHCT125.
  • Конденсатор на 1000 мкФ.
  • Переключатели SPST, 3 шт.
  • Макетная плата.
  • Провода.
  • Батарейка 9 В.
  • Внешний аккумулятор.

Другое


  • Винты и гайки М3.
  • Застёжка-липучка.

Шаг 1: подготовка (МИ, код)






Прочитав статью про Arduino и машинное обучение, я решил тоже попробовать. Поскольку в последнее время появилось несколько новых плат Arduino Nano, я сделал сравнительную табличку, чтобы сделать наилучший выбор перед покупкой.



Все платы интересные, однако для распознавания жестов я мог использовать только одну — Arduino Nano 33 BLE SENSE. Лишь у неё есть нужные датчики и поддержка Tensorflow Lite. Ещё один интересный момент – на платах Arduino Nano 33 IOT, BLE и BLE SENSE есть собственный Bluetooth, поэтому любую из них можно использовать на светодиодной матрице для приёма BLE сигналов.

Загруженный в плату код основан на множестве различных программ для Arduino, найденных мною при разработке. Поэтому перед началом работы я решил проверить их с найденными мною примерами.

Поиграемся с BLE


В данном проекте связь по Bluetooth имеет решающее значение, поскольку именно так сигнал отправляется с датчиков на светодиодную матрицу. До этого я никогда не связывал две платы Arduino по BLE. Поэтому я практиковался со следующими примерами из библиотеки ArduinoBLE:

  • Скетч LedControl, используемый с платой Arduino Nano 33 BLE Sense и кнопкой с притягивающим резистором, подсоединённым к контакту 2. Пример опрашивает BLE-периферию, пока не найдёт сервис с UUID 19b10000-e8f2-537e-4f6c-d104768a1214. После его обнаружения и установления соединения он будет удалённо управлять периферийным светодиодом BLE по нажатию кнопки.
  • Скетч для светодиода и Arduino Nano 33 IoT.

К сожалению, со скетчем для светодиода у меня возникло множество проблем – 3 платы «сломались» при его загрузке. Понятия не имею, в чём там была проблема, но я решил заменить плату Arduino на другой МИ с BLE – плату ESP32. С новой платой я использовал следующее:

  • Скетч BLE_write из библиотеки BLE ESP32 ARDUINO. Я добавил несколько изменений, чтобы она работала с платой Arduino Nano 33 BLE SENSE. На шаге 10 вы сможете сравнить скетч BLE_write и скетч Smartglove_BLE_LED-matrix, который я написал и загрузил.

Поиграемся со встроенными RGB светодиодами


Вы знали, что у платы Arduino Nano 33 BLE SENSE есть встроенные RGB светодиоды? В данном проекте они пригодятся для проверки правильной работы распознавания жестов. Мы должны проверять, что сигнал был отправлен на светодиодную матрицу – однако поскольку панель, скорее всего, находится на спине велосипедиста, ему будет трудно понять, что распознавание жестов сработало и сигнал был отправлен.

Тут не было ничего сложного, я просто немного подправил пример Blink. Из кода видно, что красный светодиод находится на контакте 22, зелёный – на контакте 23, синий – на контакте 24. Входной сигнал LOW включает светодиод, HIGH – выключает.

const int LED_BUILTIN_RED = 22;
const int LED_BUILTIN_GREEN = 23;
const int LED_BUILTIN_BLUE = 24;

// функция setup запускается один раз после включения или перезагрузки платы
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN_RED, OUTPUT);
  pinMode(LED_BUILTIN_GREEN, OUTPUT);
  pinMode(LED_BUILTIN_BLUE, OUTPUT);
}

// функция loop повторяется вечно
void loop() {
  digitalWrite(LED_BUILTIN_RED, LOW);   // включить LED (HIGH – уровень напряжения)
  delay(1000);                       // подождать секунду
  digitalWrite(LED_BUILTIN_RED, HIGH);    // выключить LED, понизив напряжение до LOW
  delay(1000);                       // подождать секунду 

digitalWrite(LED_BUILTIN_GREEN, LOW);   // включить LED (HIGH – уровень напряжения)
  delay(1000);                       // подождать секунду
  digitalWrite(LED_BUILTIN_GREEN, HIGH);    // выключить LED, понизив напряжение до LOW
  delay(1000);   // подождать секунду
  
  digitalWrite(LED_BUILTIN_BLUE, LOW);   // включить LED (HIGH – уровень напряжения)
  delay(1000);                       // подождать секунду
  digitalWrite(LED_BUILTIN_BLUE, HIGH);    // выключить LED, понизив напряжение до LOW
  delay(1000);                       // подождать секунду
}

Поиграемся с распознаванием жестов и tinyML


Наконец, я изучил руководство по использованию машинного обучения на Arduino, и попрактиковался с примером распознавания жестов. Пример делится на три основные части:

  • Распознавание данных с программой IMU_Capture (и Arduino Nano 33 BLE sense);
  • Обучение модели на записанных данных на google colab (на компьютере);
  • Использование обученной модели на Arduino с IMU_Classifier для распознавания образов (опять на плате Arduino).

Шаг 2: перчатка 1/6 (электроника)












С шагов 2 по 7 я привожу одну и ту же схему, обозначая на ней шаги с тем, чтобы вам проще было понять процесс изготовления перчатки.

Схема электроники для перчатки очень простая:

  • Плата Arduino.
  • Батарейка на 9 В (я использую аккумулятор).
  • Переключатель SPST.

Шаг 3: перчатка 2/6 – корпус






















Корпус простой, и состоит всего из двух частей, распечатанных на 3D-принтере:

  • В жёлтой части находится плата Arduino, аккумулятор и переключатель. Отверстия в корпусе позволяют перезаряжать батарею и перепрограммировать плату Arduino без необходимости разбирать корпус.
  • Чёрная часть – это крышка, защищающая аккумулятор и плату.

На руку я креплю её полоской липучки.

Также я нарисовал логотип, который потом приклеил на крышку. Он обозначает велосипедиста, на которого смотрят сверху, и в нём есть три стрелочки – прямо, налево и направо. Четвёртая стрелочка отстоит от трёх остальных, потому что велосипеды не ездят назад.

Файлы


content.instructables.com/ORIG/FS2/L3M3/K9N93ZYW/FS2L3M3K9N93ZYW.stl

content.instructables.com/ORIG/F72/21NG/K9N93ZZG/F7221NGK9N93ZZG.stl

content.instructables.com/ORIG/FD3/NVS8/K9N93ZZI/FD3NVS8K9N93ZZI.stl

Шаг 4: перчатка 3/6: запись данных
















После сборки устройства приходит время записи данных. Цель – записать каждый жест многократно. Я установил порог для гироскопа, и когда он выходит за это значение, Arduino начинает выводить записанные данные на монитор.

Я записал следующие жесты:

  • Рука указывает влево (стандартный жест велосипедистов, обозначающий поворот налево).
  • Торможение (жест пальцами, тянущимися к рычагу тормоза).
  • Рука наклоняется назад.
  • Рука наклоняется вперёд.
  • Рука наклоняется влево.
  • Рука наклоняется вправо.

Естественно, вы можете записывать свои жесты.

Для записи данных я написал программку, переключающую на светодиоде цвета после каждых 20 движений. Это помогало мне понимать, когда нужно переходить к другому жесту. Я подсоединил Arduino к компьютеру, открыл программу для отслеживания порта и положил ноутбук в рюкзак.

Записав все жесты, я перешёл к последнему этапу – скопировал данные, выведенные в программу, и сохранил их в формате csv.

content.instructables.com/ORIG/FC7/B0JT/K9UEA78V/FC7B0JTK9UEA78V.ino

Шаг 5: перчатка 4/6: обучение








Для обучения я использовал следующий пример, исправив в нём всего несколько строк. Перед обучением стоит проверить, что для каждого жеста у вас есть свой csv-файл, и данные в каждом файле относятся именно к этому жесту.

На сайте Google Colab по ссылке в разделе «Upload data» загрузите свои данные.

В разделе «Graph Data (optional)» добавьте имя одного из файлов.

filename = «Arm_left.csv»

Затем исправьте эту строчку, чтобы выводить только данные с гироскопа:

#index = range(1, len(df['aX']) + 1)
index = range(1, len(df['gX']) + 1)

Закомментируйте следующие строки – данные акселерометра мы не используем:

#plt.plot(index, df['aX'], 'g.', label='x', linestyle='solid', marker=',')
#plt.plot(index, df['aY'], 'b.', label='y', linestyle='solid', marker=',')
#plt.plot(index, df['aZ'], 'r.', label='z', linestyle='solid', marker=',')
#plt.title("Acceleration")
#plt.xlabel("Sample #")
#plt.ylabel("Acceleration (G)")
#plt.legend()
#plt.show()

В разделе «Parse and prepare the data» добавьте все названия файлов:

#GESTURES = ["punch", "flex",]
GESTURES = ["Arm_left", "Brake", "Hand_back-tilt", "Hand_front-tilt", "Hand_left-tilt", "Hand_right-tilt"]

Измените количество образцов на один жест, если меняли их в коде для Arduino:

#SAMPLES_PER_GESTURE = 119
SAMPLES_PER_GESTURE = 64

Осталось только закомментировать ускорение:

# normalize the input data, between 0 to 1:
# - acceleration is between: -4 to +4
# - gyroscope is between: -2000 to +2000
      tensor += [
          #(df['aX'][index] + 4) / 8,
          #(df['aY'][index] + 4) / 8,
          #(df['aZ'][index] + 4) / 8,
          (df['gX'][index] + 2000) / 4000,
          (df['gY'][index] + 2000) / 4000,
          (df['gZ'][index] + 2000) / 4000
      ]

После прохода всей программы вы сможете скачать обученную модель.

Файлы


content.instructables.com/ORIG/F7A/GLEK/K9UEA8Z5/F7AGLEKK9UEA8Z5.csv

content.instructables.com/ORIG/FV1/853G/K9UEA8Z6/FV1853GK9UEA8Z6.csv

content.instructables.com/ORIG/FQH/OAZD/K9UEA8Z7/FQHOAZDK9UEA8Z7.csv

content.instructables.com/ORIG/F7N/P7AG/K9UEA8Z9/F7NP7AGK9UEA8Z9.csv

content.instructables.com/ORIG/FD4/WZRM/K9UEA8ZA/FD4WZRMK9UEA8ZA.csv

content.instructables.com/ORIG/F6W/7SO2/K9UEA8ZB/F6W7SO2K9UEA8ZB.csv

Шаг 6: перчатка 5/6: код для Arduino



Итоговый мой код для умной перчатки – это смесь следующих программ:

  • пример «LED» из библиотеки «ArduinoBLE» (Peripheral>LED).
  • «IMU_Classifier» отсюда.

Подробно тут я распространяться о них не буду, просто рекомендую прочитать оригинальные программы, чтобы лучше понимать происходящее.

Добавьте свою модель в код, и её можно будет испытывать!

Файлы


content.instructables.com/ORIG/F9N/4SBK/K9UEA98M/F9N4SBKK9UEA98M.h

content.instructables.com/ORIG/FKZ/ODO9/KB52VXZK/FKZODO9KB52VXZK.ino

Шаг 7: перчатка 6/6: испытания










Как видно из видеоролика, светодиод загорается по-разному в зависимости от распознанного жеста:


Шаг 8: светодиодная матрица 1/4: электроника












Как я уже упоминал, при закачке скетча из библиотеки ArduinoBLE для светодиода на Arduino Nano 33 BLE SENSE я столкнулся с некоторыми проблемами. Поэтому я решил вместо этой платы использовать ESP32. Поэтому на приведённых фотографиях вы можете увидеть обе платы.

Поскольку обе платы, Arduino Nano 33 BLE SENSE и ESP32, работают с логикой на 3,3 В, я добавил четырёхуровневый буфер с 3 В до 5 В (74AHCT125), как рекомендуется в инструкции от Adafruit.

Также я добавил конденсатор на 100 мкФ для защиты светодиода от резких перепадов напряжения.

Всю схему я собрал на макетной плате.

Видно, что я задействовал оба разъёма внешнего источника питания, поскольку испугался, что светодиодной матрице потребуется слишком большой ток. Поэтому матрица и МИ питаются от разных разъёмов внешнего источника питания.

Шаг 9: светодиодная матрица 2/4: корпус




























Мне нужен был сборный корпус для светодиодной матрицы. Поэтому он состоит из нескольких частей (а ещё потому, что мой 3D-принтер очень крохотный), и я предусмотрел в них отверстия для болтов.

Для подсоединения панели я снова воспользовался липучкой.

Файлы


content.instructables.com/ORIG/FH6/TB4H/K9N93ZZJ/FH6TB4HK9N93ZZJ.stl

content.instructables.com/ORIG/FK3/BZPC/K9N93ZZK/FK3BZPCK9N93ZZK.stl

content.instructables.com/ORIG/FMU/ZRTY/K9N93ZZL/FMUZRTYK9N93ZZL.stl

content.instructables.com/ORIG/F38/BF1P/K9N93ZZM/F38BF1PK9N93ZZM.stl

content.instructables.com/ORIG/FJC/DQMY/K9N93ZZN/FJCDQMYK9N93ZZN.stl

content.instructables.com/ORIG/F43/ELQV/K9N93ZZQ/F43ELQVK9N93ZZQ.stl

content.instructables.com/ORIG/FJE/C5FG/K9N93ZZR/FJEC5FGK9N93ZZR.stl

content.instructables.com/ORIG/F55/1X43/K9N93ZZS/F551X43K9N93ZZS.stl

Шаг 10: светодиодная матрица 3/4: код для Arduino














Итоговый код – смесь следующих кодов (и их модификация):
  • Пример BLE_Write из библиотеки BLE ESP32 ARDUINO.
  • Пример MatrixGFXDemo64 из библиотеки FastLED NeoMatrix.


Подробно тут я распространяться о них не буду, просто рекомендую прочитать оригинальные программы, чтобы лучше понимать происходящее.

content.instructables.com/ORIG/FIR/RETZ/KB52VXP4/FIRRETZKB52VXP4.ino

Шаг 11: светодиодная матрица 4/4: испытания






Настало время всё проверить! После распознавания каждого жеста на светодиодную матрицу отправляется сигнал, и она показывает определённый узор. Видно, что на перчатке светодиоды зажигаются соответственно распознанному жесту.



Шаг 12: итоговые испытания и заключение






Вот как это выглядит вживую:



Я очень доволен получившимся устройством. Благодаря проекту я гораздо увереннее чувствую себя с tinyML и BLE. С тех пор я купил ещё Arduino Nano 33 IOT, и сейчас занимаюсь весьма интересным проектом, о котором напишу позже. Что бы я изменил во второй версии описанного мною устройства:

  • Крышка для «перчатки». Сейчас она держится на корпусе только за счёт того, что туго надевается. Однако как-то во время поездки я задел что-то рукой, крышка соскочила и разбилась. В следующей версии прикручу её винтами.
  • Корпус для светодиодной матрицы. Я почти сразу понял, что в моём корпусе отсутствует быстрый доступ к USB МИ. А мне хотелось бы иметь доступ, чтобы отлаживать код или менять его. Также без раскручивания корпуса нельзя зарядить внешний источник питания.
  • Больше данных для обучения. Иногда некоторые из жестов не распознаются, а иногда распознаются ошибочно. Думаю, не хватает данных (всего 20 движений для каждого жеста). Больше движений – лучше модель, меньше ошибок.

На завершение проекта и написание этого текста у меня ушло несколько месяцев. Если что-то неясно, или какого-то файла не хватает, пишите в комментариях к оригинальной статье.

См. также:

Теги:велосипедперчаткауказатели поворотабезопасностьдорожное движениеpython
Хабы: Машинное обучение Разработка под Arduino DIY или Сделай сам Транспорт
+19
5,4k 49
Комментарии 48
Лучшие публикации за сутки

Партнерские материалы

Разместить