Управление коптером с Arduino === Для взаимодействия с ROS-топиками и сервисами на Raspberry Pi можно использовать библиотеку [rosserial_arduino](http://wiki.ros.org/rosserial_arduino). Основной туториал по rosserial: http://wiki.ros.org/rosserial_arduino/Tutorials Arudino необходимо установить на Клевер и подключить по USB-порту. Настройка Arduino IDE --- Необходимо скачать и скопировать [библиотеку ROS-сообщений Клевера](https://github.com/CopterExpress/clever_bundle/blob/master/deploy/clever_arudino.tar.gz?raw=true) (`ros_lib`) в `<папку скетчей>/libraries`. Настройка Raspberry Pi --- Чтобы единоразово запустить программу на Arduino, можно воспользоваться командой: ``` roslaunch clever arduino.launch ``` Чтобы запускать связку с Arduino при старте системы автоматически, необходимо установить аргумент `arudino` в launch-файле Клевера (`~/catkin_ws/src/clever/clever/launch/clever.launch`): ```xml ``` При изменении launch-файла необходимо перезапустить пакет `clever`: ```bash sudo systemctl restart clever ``` Работа с Клевером --- Набор сервисов и топиков аналогичен обычному набору в [simple_offboard](/docs/simple_offboard.md) и [mavros](/docs/mavros.md). Пример программы, контролирующей коптер по позиции, с использованием сервисов `navigate` и `set_mode`: ```cpp // Подключение библиотек для работы с rosseral #include // Подключение заголовочных файлов сообщений пакета Clever и MAVROS #include #include using namespace clever; using namespace mavros_msgs; ros::NodeHandle nh; // Объявление сервисов ros::ServiceClient navigate("/navigate"); ros::ServiceClient setMode("/mavros/set_mode"); void setup() { // Инициализация rosserial nh.initNode(); // Инициализация сервисов nh.serviceClient(navigate); nh.serviceClient(setMode); // Ожидание подключение к Raspberry Pi while(!nh.connected()) nh.spinOnce(); nh.loginfo("Startup complete"); // Пользовательская настройка // <...> // Тестовая программа Navigate::Request nav_req; Navigate::Response nav_res; SetMode::Request sm_req; SetMode::Response sm_res; // Взлет на 2 метра: nh.loginfo("Take off"); nav_req.auto_arm = false; nav_req.x = 0; nav_req.y = 0; nav_req.z = 2; nav_req.frame_id = "fcu_horiz"; nav_req.speed = 0.5; navigate.call(nav_req, nav_res); // Ждем 5 секунд delay(5000); nav_req.auto_arm = false; // Пролет вперед на 3 метра: nh.loginfo("Fly forward"); nav_req.auto_arm = true; nav_req.x = 3; nav_req.y = 0; nav_req.z = 0; nav_req.frame_id = "fcu_horiz"; nav_req.speed = 0.8; navigate.call(nav_req, nav_res); // Ждем 5 секунд delay(5000); // Полет в точку 1:0:2 по маркерному полю nh.loginfo("Fly on point"); nav_req.auto_arm = false; nav_req.x = 1; nav_req.y = 0; nav_req.z = 2; nav_req.frame_id = "aruco_map"; nav_req.update_frame = true; nav_req.speed = 0.8; navigate.call(nav_req, nav_res); // Ждем 5 секунд delay(5000); // Посадка nh.loginfo("Land"); sm_req.custom_mode = "AUTO.LAND"; setMode.call(sm_req, sm_res); } void loop() { } ``` При использовании Arudino Nano может не хватать оперативной памяти (RAM). В таком случае в Aruino IDE будут появляться сообщения, типа: ``` Глобальные переменные используют 1837 байт (89%) динамической памяти, оставляя 211 байт для локальных переменных. Максимум: 2048 байт. Недостаточно памяти, программа может работать нестабильно. ``` Можно сократить использование оперативной памяти уменьшив размер выделяемых буферов для передачи и приема сообщений. Для этого **в самое начало** программы следует поместить строку: ```cpp #define __AVR_ATmega168__ 1 ```