Урок 9

Введение: Данная задача, является первой из серии задач в которой мы будем интегрировать ROS и Arduino. На нашем роботе Arduino демонстрирует подход в современной робототехнике, при котором простые функции общения с периферийным железом на низком уровне делегированы специальному микроконтроллеру, имеющему связь с основным компьютером робота. Таким образом простые функции контроля периферии отданы на отдельный контроллер, а вверх на уровень ROS поднимаются уже обработанные сигналы от железа, в виде привычных для ROS - сообщений.

Мы предполагаем, что учащиеся знакомы с основными принципами программирования Arduino, и на деталях языка C для Ардуино мы не будем останавливаться в нашем занятии. Если учащиеся не знакомы с Arduino, то рекомендуем пройти какие-нибудь курсы, например, тут.

Подготовка:

Перед компиляцией Arduino-скетча необходимо подключить в Arduino библиотеку ros_lib содержащую все файлы ROS нужные для сборки скетчей. Обратите внимание, что если вы делаете какие-то свои пакеты под ROS и впоследствии хотите использовать собственные типы сообщения в Arduino, вам необходимо пересобрать библиотеку ros_lib на роботе, на котором собран ваш пакет и затем переподключить ее к вашему Arduino IDE. Процесс подключения библиотеки описан в инструкции к роботу.

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

Подготовить скетч к загрузке

  1. В Arduino IDE выбрать МК Arduino/Genuino Mega or Mega 2560
  2. Скомпилировать программу (кнопка Проверить)
  3. В меню выбрать Скетч→Экспорт Бинарного файла
  4. В директории где находиться файл скетча, будут созданы два файла с бинарными данными вида (sketch_mar24a.ino.mega.hex sketch_mar24a.ino.with_bootloader.mega.hex)
  5. Мы должны использовать файл sketch_mar24a.ino.mega.hex

Загрузить бинарный файл на Arduino:

  1. Скопировать файлы .hex на робота, например командой linux scp
    1. scp sketch_mar24a.ino.mega.hex pi@ip_робота:/home/pi/sketch_mar24a.ino.mega.hex
  2. На роботе выполнить команду "прошивки" платы Arduino
avrdude -v -v -p atmega2560 -c wiring -P /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -b 115200 -D -U flash:w:sketch_mar24a.ino.mega.hex:i

Где sketch_mar24a.ino.mega.hex имя файла с прошивкой.

3. Проверить, что все сделано правильно можно залив для теста программу Blink мигающую светодиодом и убедиться по внешней камере полигона, что светодиод на роботе мигает.

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

Задача: После загрузки прошивки, при нажатии на кнопку D23 Adruino робота должно посылать в топик "button_topic", сообщение типа String - "button pressed"

Общий алгоритм решения:

1. Настраиваем связь Arduino и ROS, в соответствии с инструкцией к роботу

2. В основном цикле читаем 23-ю кнопку командой digitalRead()

3. Если значение возвращаемое командой digitalRead() равно 1, оправляем сообщение "button pressed" в топик "button_topic"

4. Если значение равно 0, то ждем 10 микросекунд и повторяем цикл.

Решение: Для начала импортируем все библиотеки и структуры данных, которые нам понадобятся.

#include <ros.h>
#include <std_msgs/String.h>

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

class NewHardware : public ArduinoHardware
{
  public:
  NewHardware():ArduinoHardware(&Serial1, 115200){};
};
ros::NodeHandle_<NewHardware>  nh;

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

str_msg - это строковая структура данных РОС, которую мы будем публиковать

chatter - наш Издатель, именно его метод Publish мы будем использовать для публикации

but_msg - массив символов, который мы будем публиковать

inPin - номер пина кнопки, которую надо будет нажать, чтобы сообщение опубликовалось

val - значение 0 или 1 нажатия на кнопку, его мы будем читать в основном цикле

std_msgs::String str_msg;
ros::Publisher chatter("button_topic", &str_msg);

char but_msg[14] = "button pressed";
int inPin = 23;                   
int val = 0;

Напишем секцию setup, здесь мы инициализируем ноду, зарегистрируем в ROS нашего Издателя и установим пин 23 в режим Ввода.

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
  pinMode(inPin, INPUT);
}

Теперь основной цикл. Читаем 23й пин при помощи команды digitalRead() и возвращаемый результат записываем в переменную val. Далее проверяем значение val, и если оно равно 1, т.е. кнопка нажата, то мы присваиваем полю data, структуры str_msg значение нашего массива butmsg - "button pressed", вызываем функцию publish у созданного ранее Издателя и передаем ей ссылку на заполненную структуру str_msg. После чего вызываем функцию spinOnce(), нашей ноды для того чтобы произошел один цикл публикации Издателя.

void loop()
{
  val = digitalRead(inPin);
  if (val == 1)
  {
    str_msg.data = but_msg;
    chatter.publish( &str_msg );
    nh.spinOnce();
  }
  else{
    delay(10);
  }
}

В случае же если значение val не равно 1, мы делаем паузу на 10 микросекунд и перезапускаем основной цикле по-новой.

Итого весь скетч, должен выглядеть следующим образом:

#include <ros.h>
#include <std_msgs/String.h>

class NewHardware : public ArduinoHardware
{
  public:
  NewHardware():ArduinoHardware(&Serial1, 115200){};
};
ros::NodeHandle_<NewHardware>  nh;

std_msgs::String str_msg;
ros::Publisher chatter("button_topic", &str_msg);

char but_msg[14] = "button pressed";
int inPin = 23;                   
int val = 0; 

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
  pinMode(inPin, INPUT);
}

void loop()
{
  val = digitalRead(inPin);
  if (val == 1)
  {
    str_msg.data = but_msg;
    chatter.publish( &str_msg );
    nh.spinOnce();
  }
  else{
    delay(10);
  }
}

Проверка решения:

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

Это занятие является вводным в серию занятий по Arduino + ROS и его правильное выполнение обязательно для дальнейшего успеха в освоении данной темы.

results matching ""

    No results matching ""