Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Автономный танк

Добавление гораздо более дешевой альтернативы образцу Картера и Кая с использованием набора Lego EV3.

В этом проекте я задокументирую строительство гусеничной машины, сделанной из деталей и двигателей Lego Technic, усовершенствованной с помощью LiDAR и управляемой платой Jetson Nano с последней версией Isaac SDK. Перейти к части 8 или 10 для полной демонстрации автономной навигации.

Проект состоит из следующих компонентов:

Почему Isaac SDK, а не ROS?

Почему именно детали Lego?

Выбор этого пути вызывает некоторые проблемы:

ЧАСТЬ 1. Начало работы

1. SDK Isaac

2. Распознавание голоса (необязательно)

3. Изображение Ev3dev

Загрузите и запишите последний образ для EV3 (ev3dev-stretch) на карту microSD или microSDHC. Формат MicroSDXC не поддерживается модулем EV3.

4. Кросс-компилятор ARM для ev3dev

  $ sudo apt-get install gcc-arm-linux-gnueabi g ++ - arm-linux-gnueabi  

Эту часть было особенно сложно правильно настроить. Ubuntu 18.04 (хост-компьютер и Jetson Nano) использует GLIBC_2.28, а ev3dev использует Debian stretch и GLIBC_2.24. Все, что скомпилировано с конфигурацией компилятора arm-linux-gnueabi-g ++ по умолчанию, зависело от GLIBC_2.28 и не запускалось на EV3. Статическое связывание не работало, поскольку что-то более сложное, чем hello world, приводило к сбою в работе. Решение, которое я нашел, заключалось в том, чтобы динамически связать все, кроме математической библиотеки. Дополнительную информацию можно найти в файле jetson-ev3 / toolchain / CROSSTOOL. Другое решение - использовать образ Docker Debian 9.

5. Рабочее пространство Jetson + EV3

  $ git clone https://github.com/andrei-ace/jetson-ev3.git  
  local_repository (
name ="com_nvidia_isaac",
path ="/ home / andrei / ml / isaac"
)
  • Отредактируйте jetson-ev3 / toolchain / CROSSTOOL и укажите путь к каталогу, в котором находится этот файл.
  # отредактируйте, указав свой путь к цепочке инструментов 
linker_flag:"-L / home / andrei / ml / jetson-ev3 / toolchain"

6. Подключите Jetson Nano к EV3

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

  [email protected]:~ / ml / jetson-ev3 $ # это запущено на моем компьютере 
[email protected]:~ $ #this on Jetson Nano
[адрес электронной почты защищен]:~ $ $ # это на EV3

IP-адреса моего Jetson Nano - 192.168.0.173 (Ethernet) и 192.168.0.218 (WiFi), поэтому всякий раз, когда вы видите команду, использующую эти значения, замените их своими.

Я использовал кабель USB A-mini для подключения платы Jetson к модулю EV3, выполнив следующие действия.

Попробуйте использовать ssh с платы Jetson:

  [защита электронной почты]:~ $ ssh [защита электронной почты]  

Пароль по умолчанию - maker.

7. Учебник по настольному теннису

У Исаака есть руководство, объясняющее очень простой Codelet. Я предлагаю сначала изучить этот урок. Он познакомит вас с концепциями, необходимыми для создания любого приложения, работающего на Isaac.

Теперь перейдите в каталог jetson-ev3 / apps / ev3 / ping_pong /. Это модифицированная версия предыдущего урока, с одной изюминкой:мы отправим пинг на блок EV3.

Большинство файлов знакомо по предыдущему руководству. Мы будем использовать Cap’n Proto RPC для звонков между Jetson и EV3. Cap’n Proto широко используется для связи между различными компонентами Isaac, поэтому имеет смысл использовать его здесь. Для этого нам понадобятся новые файлы:

  • jetson-ev3 / apps / ev3 / ping_pong / ping.capnp - определяет интерфейс между клиентом, который будет работать на Isaac Robot Engine, и сервером, который будет работать на EV3.
  • jetson-ev3 / apps / ev3 / ping_pong / PongEv3Server.cpp это сервер, который работает на модуле EV3.
  • jetson-ev3 / apps / ev3 / ping_pong / Pong.cpp это было изменено для вызова сервера Pong, работающего на EV3.

Скомпилируйте сервер ev3_pong:

  [защита электронной почты]:~ / ml / jetson-ev3 $ bazel build --config =ev3dev // apps / ev3 / ping_pong:ev3_pong  

Скопируйте его в EV3, используя scp сначала в Jetson, а затем в EV3.

Создайте и разверните пример пинг-понга в Jetson:

  [электронная почта защищена]:~ / ml / jetson-ev3 $  /engine/build/deploy.sh --remote_user <ВАШ-ПОЛЬЗОВАТЕЛЬ -JETSON> -p // apps / ev3 / ping_pong:ping_pong-pkg -d jetpack43 -h <ВАШ-JETSON-IP>  

Дополнительная информация о том, как развертывать и запускать ваши приложения на Jetson, находится здесь.

Запустите оба приложения:

  [защита электронной почты]:~ $ ./ev3_pong ev3dev.local:9999 
[защита электронной почты]:~ / deploy / andrei / ping_pong-pkg $. / apps / ev3 / ping_pong

Если все работает, вы должны услышать сообщения, отправленные компонентом Ping в динамик EV3.

8.Управление мотором от Исаака

Те же принципы, только немного посложнее. Я использовал другое руководство Isaac для взаимодействия с двигателем EV3:

В учебнике используется база Segway RMP. Поскольку у меня нет ни одного валяния или 10000 долларов на его покупку, я создал драйвер, который вместо этого будет управлять двигателями EV3. Код здесь.

Сервер, работающий на EV3, находится здесь, и его можно собрать и запустить с помощью следующей команды:

  [email protected]:~ / ml / jetson-ev3 $ bazel build --config =ev3dev // packages / ev3 / ev3dev:ev3_control_server 
[электронная почта protected]:~ $ ./ev3_control_server ev3dev.local:9000

Я использовал виртуальный джойстик от Sight, как описано здесь.

9.DifferentialBase для EV3

Сервер Ev3ControlServer ответит на 2 вызова:

  • команда (cmd:Control) - принимает в качестве параметров линейную и угловую скорости и управляет обоими двигателями для достижения требуемых скоростей.
  • состояние () -> (состояние:Динамика); - возвращает реальные линейные и угловые скорости робота.

Более подробно кинематика объясняется здесь и здесь.

Я использовал приложение-пример ratio_control_cpp, чтобы проехать 1 м для робота и сообщить данные одометрии EV3 (линейные и угловые скорости) в импульсах вращения (отсчетах тахометра) в секунду. Используя вычисленное расстояние перемещения (по Исааку) и измеряя реальное расстояние, я придумал константу, чтобы скорректировать сообщаемые значения, чтобы они соответствовали реальным результатам. Это сработало хорошо, и результаты можно было воспроизводить много раз, и не только по прямым линиям. Вы также можете вычислить эти значения, используя радиус колеса (или гусеницы в нашем случае).

Часть 2:Создание робота

База очень похожа на Lego EV3 Track3r, одну из официальных моделей комплекта EV3:https://www.lego.com/biassets/bi/6124045.pdf

Чехол для Jetson Nano находится здесь:https://github.com/3D-printable-lego-technic/PELA-blocks

Часть 3. Приложения Isaac

Приложение Isaac состоит из трех основных частей:

  • граф - узлы:эта часть определяет все компоненты, из которых состоит приложение. Узел также может быть другим графом, определенным в другом файле. Узел voice_detection из примера является подграфом.
  • граф - ребра:эта часть определяет поток сообщений между узлами. У края есть источник и цель. Например, обнаруженная команда от узла (подграфа) voice_detection будет отправлена ​​компоненту, который генерирует цели.
  • конфигурация - эта часть настраивает узлы графа

Пример приложения:

  {
"name":"voice_control",
"modules":[
"// apps / ev3 / voice_control:voice_control_goal_generator ",
" @ com_nvidia_isaac // пакеты / навигация ",
" @ com_nvidia_isaac // пакеты / планировщик "
],
" config_files ":[
" apps / ev3 / voice_control / model / isaac_vcd_model.metadata.json "
],
" config ":{
" 2d_ev3.ev3_hardware.ev3 ":{
" isaac.Ev3Driver ":{
" адрес ":" ev3dev.local ",
" порт ":9000
}
},
" navigation.imu_odometry.odometry ":{
"DifferentialBaseWheelImuOdometry":{
"use_imu":false
}
},
"commander.robot_remote":{
"isaac.navigation.RobotRemoteControl ":{
" angular_speed_max ":0,6,
" linear_speed_max ":0,3
}
},
" websight ":{
" WebsightServer ":{
"webroot":"external / com_nvidia_isaac / packages / Sight / webroot",
"ui_config":{
"windows":{
"Обнаружение голосовых команд":{
"средство визуализации":"сюжет" ,
"тускнеет":{
"ширина":400,
"высота":200
},
"каналы":[
{
"name":"voice_control / voice_detection.voice_command_detector / isaac.audio.VoiceCommandConstruction / voice_command_id",
"active":true
}
]
}
}
}
}
},
"navigation.shared_robot_model":{
"SphericalRobotShapeComponent":{
"круги":[
{"center":[0.0, 0.0], "radius":0.075},
{"center":[0.02, 0.03464], "radius":0.055},
{"center":[0,02, -0,03464], «радиус»:0,055},
{«центр»:[-0,04, 0,0], «радиус»:0,055},
{«центр»:[0,0525, 0,09093 ], «радиус»:0,035},
{«центр»:[0,0525, -0,09093], «радиус»:0,035},
{«центр»:[-0,105, 0,0], «радиус ":0.035}
]
}
},
" navigation.control.lqr ":{
" isaac.planner.DifferentialBaseLqrPlanner ":{
"manual_mode_channel":"commander.robot_remote / isaac.navigation.RobotRemoteControl / manual_mode"
}
},
"navigation.control.control":{
"isaac.planner.DifferentialBaseControl":{
"manual_mode_channel":"commander.robot_remote / isaac.navigation.RobotRemoteControl / manual_mode"
}
}
},
«график»:{
«узлы»:[
{
«имя»:«voice_control_components»,
"компоненты":[
{
"имя":"message_ledger",
"тип":"isaac ::alice ::MessageLedger"
},
{
"name":"goal_generator",
"type":"isaac ::VoiceControlGoalGenerator"
}
]
},
{
"name":"voice_detection",
"subgraph":"apps / ev3 / voice_control / voice_command_detection.subgraph.json"
},
{
"name":"2d_ev3",
"подграф":"apps / ev3 / 2d_ev3.subgraph.json"
},

{
"name":"навигация",
"подграф":"@ com_nvidia_isaac // пакеты / навигация / приложения / diff_base_navigation.subgraph.json"
},
{
"имя":"командир",
"подграф":"@ com_nvidia_isaac // пакеты / навигация / apps / Difference_base_commander.subgraph.json "
}
],
" edge ":[
{
" source ":" voice_detection.subgraph / interface /hibited_command » ,
"target":"voice_control_components / goal_generator / detect_command"
},
{
"source":"voice_control_components / goal_generator / goal",
"target" :"navigation.subgraph / interface / goal"
},
{
"source":"2d_ev3.subgraph / interface / base_state",
"target":"navigation. подграф / интерфейс / состояние "
},
{
" источник ":" navigation.subgraph / interface / command ",
" target ":" commander.subgraph / interface / control "
},
{
" source ":" commander.subgraph / interface / command ",
" target ":" 2d_ev3.subgraph / interface / base_command "
},
{
"source":"2d_ev3.subgraph / interface / flatscan",
"target":"navigation.subgraph / interface / flatscan_for_localization"
},
{
"источник":"2d_ev3.subgraph / interface / flatscan",
"цель":"навигация. подграф / интерфейс / flatscan_for_obstacles "
}
]
}
}

Пример подграфа:

  {
"modules":[
"@ com_nvidia_isaac // пакеты / аудио",
"@ com_nvidia_isaac // пакеты / ml:tensorflow "
],
" граф ":{
" узлы ":[
{
" имя ":" подграф ",
" компоненты ":[
{
" name ":" message_ledger ",
" type ":" isaac ::alice ::MessageLedger "
},
{
"name":"interface",
"type":"isaac ::alice ::Subgraph"
}
]
},
{
"name":"audio_capture",
"components":[
{
"name":"ml",
"type»:"isaac ::alice ::MessageLedger "
},
{
" name ":" isaac.audio.AudioCapture ",
" type ":" isaac ::audio ::AudioCapture "
}
]
},
{
"name":"voice_command_detector",
"components":[
{
" name ":" ml ",
" type ":" isaac ::alice ::MessageLedger "
},
{
" name ":" isaac.audio.VoiceCommandFeatureExtraction " ,
"тип":"isaac ::audio ::VoiceCommandFeatureExtraction"
},
{
" name ":" isaac.ml.TensorflowInference ",
" type ":" isaac ::ml ::TensorflowInference "
},
{
" name ":" isaac. audio.VoiceCommandConstruction ",
" type ":" isaac ::audio ::VoiceCommandConstruction "
}
]
}
],
" края " :[
{
«источник»:«audio_capture / isaac.audio.AudioCapture / audio_capture»,
«target»:«voice_command_detector / isaac.audio.VoiceCommandFeatureExtraction / audio_packets»
},
{
"источник":"voice_command_detector / isaac.audio.VoiceCommandFeatureExtraction / feature_tensors",
"target":"voice_command_detector / isaac.ml.TensorflowInference / input_tensors"
},
{
"источник":"voice_command_detector / isaac.ml.TensorflowInference / output_tensors",
"target":"voice_command_detector / isaac.audio.VoiceCommandConstruction / keyword_probabilities"
},
{
"источник":"voice_command_detector / isaac.audio.VoiceCommandConstruction / detect_command",
"target":"подграф / интерфейс / обнаружен _command "
}
]
},
" config ":{
" audio_capture ":{
" isaac.audio.AudioCapture ":{
"sample_rate":16000,
"num_channels":1,
"audio_frame_in_milliseconds":100,
"ticks_per_frame":5
}
},
"voice_command_detector":{
"isaac.audio.VoiceCommandFeatureExtraction":{
"audio_channel_index":0,
"minimum_time_between_inferences":0,1
},
"isaac.ml.TensorflowInference":{
"путь_файла_модели":"apps / ev3 / voice_control / model / isaac_vcd_model.pb",
"путь_к_файлу_конфигурации":"apps / ev3 / voice_control / model / isaac_vcd_config. pb "
},
" isaac.audio.VoiceCommandConstruction ":{
" command_list ":[
" jetson ",
" jetson left ",
"jetson right"
],
"command_ids":[0, 1, 2],
"max_frames_allowed_after_keyword_detected":14
}
}
}
}

Подграф можно повторно использовать во многих приложениях. Фактически стек навигации isaac используется как подграф.

Часть 4. Запуск приложений Isaac на EV3

Драйвер (jetson-ev3 / packages / ev3 / BUILD) реагирует на те же команды, что и базовый драйвер Segway RMP. Это означает, что он будет работать со многими приложениями, работающими на Kaya или Carter, что делает его третьим вариантом и намного дешевле!

Я адаптировал некоторые приложения, созданные для демонстрации ботов Carter и Kaya:

  • Приложение-джойстик - управляет роботом DifferentialBase с помощью джойстика. В нем есть LiDAR для создания местных карт.
  • распределенная карта gmapping:ev3 и хост от робота Kaya - это позволяет создать GMap с помощью робота EV3 и YDLIDAR X4.
  • полная навигация - я добавил подграфы для аппаратной и 2D-навигации для робота EV3, чтобы их можно было использовать в других приложениях так же просто, как с помощью Carter или Kaya.

Часть 5. Одометрия

Для бега в автономном режиме важно иметь хорошую одометрию. Это используется для оценки положения робота с течением времени. Давайте настроим его с помощью приложения ev3:

  [электронная почта защищена]:~ / ml / jetson-ev3 $ ./engine/build/deploy.sh --remote_user andrei -p // apps / ev3:ev3 -pkg -d jetpack43 -h 192.168.0.173 

[защита электронной почты]:~ $ brickrun ./ev3_control_server ev3dev.local:9000

[защита электронной почты]:~ / deploy / andrei / ev3-pkg $ ./apps/ev3/ev3 --graph ./apps/assets/maps/map.graph.json --config ./apps/assets/maps/map.config.json

Нам нужно оценить две вещи:

  • линейная скорость
  • угловая скорость

Формулы для линейной и угловой скоростей:

Определить угловую скорость несложно:это разница между правым и левым моторами, деленная на базовую длину.

Найти линейную скорость немного сложнее. У нас есть 3 кейса:

  • когда обе скорости двигателя равны - линейная скорость равна правой скорости (и левой скорости).
  • если скорость левого мотора противоположна скорости правого мотора, линейная скорость равна 0, бак будет вращаться на месте.
  • когда скорость левого двигателя равна 0 (случай, описанный справа). Линейная скорость составляет половину правильной скорости (центр робота движется по меньшей дуге).

Эксперимент с угловой скоростью

Мы будем использовать ручное управление, чтобы повернуть робота на 360 градусов на месте. Это достигается перемещением левого и правого двигателей с противоположными скоростями. Зная скорости обоих двигателей, мы можем вычислить угловую скорость.

Давай попробуем:

Эксперимент с угловой и линейной скоростями .

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

Часть 6. Собираем все вместе

Итак, мы дошли до того, чтобы иметь дорогой радиоуправляемый танк? Нет, теперь мы можем использовать все разные части Исаака. Например, отдавая голосовые команды и заставляя робота двигаться автономно. См. Пример этого в voice_control.

Он использует жемчужины аудио и машинного обучения от Исаака. Что такое драгоценный камень? Как сказано в руководстве:«GEM:набор алгоритмов робототехники от планирования до восприятия, большинство из них с ускорением на GPU».

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

Я научил свой распознавать 3 слова:«джетсон», «левый» и «правый». Здесь вы можете найти сохраненную модель. Из этих трех слов мы можем составить 2 команды:«jetson left» и «jetson right».

Часть обнаружения описана здесь в отдельном подграфе, готовом к использованию и повторному использованию.

По сути, он слушает микрофон, и если одна из команд выбрана, он выводит voice_command_id. Для этого используется предварительно обученная RNN.

Мы можем взять эту команду detect_command и передать ее нашему собственному Codelet:

  {
"source":"voice_detection.subgraph / interface /hibited_command",
"target":"voice_control_components / goal_generator / detect_command"
}

из Кодлета мы можем создать цель и опубликовать ее:

  auto proto =rx_detected_command (). getProto (); 
int id =proto.getCommandId ();
auto goal_proto =tx_goal (). initProto ();
target_proto.setStopRobot (true);
goal_proto.setTolerance (0.1);
goal_proto.setGoalFrame ("робот");
ToProto (Pose2d ::Rotation ( 90), goal_proto.initGoal ());
tx_goal (). Publish ();

Это ставит цель повернуть робота влево на 90 градусов. Мы можем ставить разные цели в разных рамках. Это мог быть переход к координате в «мировом» фрейме, например, к координатам кухни. Это могло быть установка Pose2 ::Translate (1.0, 0) в кадре робота, чтобы продвинуть робота на 1 метр.

И оттуда мы передаем цель Глобальному планировщику.

  {
"source":"voice_control_components / goal_generator / goal",
"target":"navigation.subgraph / interface / goal"
}

Где происходит все волшебство:

К сожалению, он будет работать только в режиме 10 Вт, а не 5 Вт, что для моей батареи многовато. В режиме 5W вывод занимает слишком много времени:

Я пробовал использовать меньшие RNN и увеличить количество ядер процессора с 2 (nvpmodel -m 1) до 3, но это не помогло. Это уменьшило время вывода до 30 мс, что все еще слишком долго для точных результатов.

Часть 7. Сопоставление

Чтобы создать карту, нам нужно запустить один экземпляр Isaac на Jetson и один на главном компьютере. Составление карты требует много ресурсов, с которыми Jetson Nano не может справиться.

  [электронная почта защищена]:~ / ml / jetson-ev3 $ ./engine/build/deploy.sh --remote_user andrei -p // apps / ev3:gmapping_distributed_ev3 -pkg -d jetpack43 -h 192.168.0.218 

[электронная почта защищена]:~ / deploy / andrei / gmapping_distributed_ev3-pkg $ ./apps/ev3/gmapping_distributed_ev3

[электронная почта protected]:~ / ml / jetson-ev3 $ bazel run apps / ev3:gmapping_distributed_host

Не забудьте заменить файл apps / ev3 / gmapping_distributed_host.app.json своим IP-адресом Jetson:

  "tcp_subscriber":{
"isaac.alice.TcpSubscriber":{
"port":5000,
"host" :"192.168.0.218"
}
}

Источник:Автономный танк


Производственный процесс

  1. ИИ для автономного вождения для сборщика мусора в машинах-ослах
  2. Резервуар, день 23:дальность и пеленг
  3. Четвероногий автономный робот JQR
  4. Подготовка к автономному будущему
  5. Модель боевого танка с ЧПУ
  6. Автономный робот открывает двери
  7. Автономные сборщики
  8. Что такое резервный резервуар?
  9. Советы по безопасности при сварке топливного бака
  10. Как устранить утечку газа в машине?