Использование GPIO в Raspberry Pi из ROS

Добрый день, уважаемые читатели Хабра!
Недавно изучая книги по практическому использованию ROS я узнал об интересной возможности использования портов GPIO, доступных на Raspberry Pi из ROS. В этой статье я хочу рассказать о том, каким образом это возможно осуществить. Для доступа к портам GPIO на плате Raspberry Pi мы будем использовать библиотеку Wiring Pi. Кого заинтересовала эта тема, прошу под кат.

Установка Wiring Pi


Для начала установим библиотеку Wiring Pi на Raspberry Pi:

git clone git://git.drogon.net/wiringPi
cd wiringPi
./build


Схему назначения портов GPIO на Raspberry Pi можно посмотреть в статье.

Пример Blink LED


Мы сделаем простой пример мигания светодиодом с помощью команд, которые будем публиковать в топик ROS. Мы подключим светодиод к пинам на Raspberry Pi таким образом: короткую ножку (катод) к порту GND, длинную ножку (анод) к порту GPIO18 (пин номер 12 на схеме).
У нас получится такое подключение:

image

Создадим пакет ROS:

catkin_create_pkg ros_wiring_example


Создайте файл C++ со следующим кодом:

#include "ros/ros.h"
#include "std_msgs/Bool.h"
#include 

//Wiring Pi header
#include "wiringPi.h"
//Wiring PI first pin
#define LED 1
//Callback to blink the LED according to the topic value
void blink_callback(const std_msgs::Bool::ConstPtr& msg)
{
if(msg->data == 1){
digitalWrite (LED, HIGH) ;
ROS_INFO("LED ON");
}
if(msg->data == 0){
digitalWrite (LED, LOW) ;
ROS_INFO("LED OFF");
}
}
int main(int argc, char** argv)
{
ros::init(argc, argv,"blink_led");
ROS_INFO("Started RPi Blink Node");
//Setting WiringPi
wiringPiSetup ();
//Setting LED pin as output
pinMode(LED, OUTPUT);
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("led_blink",10,blink_callback);
ros::spin();
}


Здесь мы включаем библиотечный файл wiringPi.h и добавляем инициализацию вызовом метода wiringPiSetup (). Методы pinMode () и digitalWrite () выполняют то же самое, что одноименные методы, используемые для Arduino.
Создадим файл CMakeLists.txt с таким содержанием:

cmake_minimum_required(VERSION 2.8.3)
project(ros_wiring_examples)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)
find_package(Boost REQUIRED COMPONENTS system)
//Include directory of wiring Pi
set(wiringPi_include "/usr/local/include")
include_directories(
${catkin_INCLUDE_DIRS}
${wiringPi_include}

)
//Link directory of wiring Pi
LINK_DIRECTORIES("/usr/local/lib")
add_executable(blink_led src/blink.cpp)

target_link_libraries(blink_led
${catkin_LIBRARIES} wiringPi
)


У нас будет простая логика. Создаем подписчика на топик led_blink типа Boolean. Если приходит значение 1, то зажигаем светодиод. Если приходит 0, то гасим светодиод.
Далее компилируем пакет:

cd ~/
catkin_make
source devel/setup.bash


И наконец запускаем узел:

roscore


Мы должны залогиниться из-под пользователя root для запуска узла:

sudo -s
cd /home/pi/
rosrun ros_wiring_example blink_led


Отправим команду для включения светодиода:

rostopic pub /blink_led std_msgs/Bool 1


Отправим команду для выключения светодиода:

rostopic pub /blink_led std_msgs/Bool 0


Все очень просто. Мы просто указываем топик blink_led, тип сообщения std_msgs/Bool и значение: 0 или 1.
Теперь можно использовать всю силу портов GPIO на Raspberry Pi в своих проктах. Мы можем подключать ультразвуковые сенсоры дистанции, сервомоторы и тд. и управлять ими или получать данные с них в узлах ROS без необходимости подключать дополнительные платы типа Arduino.
Желаю удачи в ваших робототехнических проектах с Raspberry Pi и до новых встреч!

© Geektimes