본문 바로가기

작업 일기

rosserial 통신으로 LED 제어하기 (간단한 LED STATUS)

- 개발 환경 : Raspberry Pi 4B (Ubuntu 18.04 / ROS melodic)

- 사용품 : Arduino Uno, LED, RGB LED        

- 참고 : https://pinkwink.kr/1149

 

 

 

Step1. Linux용 아두이노 IDE 설치

- 아래의 링크에서 Linux용 아두이노 IDE를 설치하고 압축해제합니다.

https://www.arduino.cc/en/software

 

Software

Open-source electronic prototyping platform enabling users to create interactive electronic objects.

www.arduino.cc

 

- 아래 명령어를 통해 압축을 푼 폴더로 이동한 후 설치를 진행합니다. (버전은 다를 수 있음)

$ cd arduino-1.8.13
$ sudo ./install.sh

 

- 한글폰트를 설치

$ sudo apt install fonts-nanum-coding
$ sudo apt-get update
//입력 후 아두이노 재실행

 

- 아두이노 보드와 ROS를 인터페이싱한다는 것은 일반 ROS 노드처럼 발행/구독이 가능한 ROS 노드를 아두이노에서 실행하는 것을 의미합니다. PC (Raspberry Pi / Ubuntu 18.04 / ROS melodic)와 아두이노의 주요 통신은 UART를 통해 이루어지는데, ROS Serial이라는 전용 프로토콜이 있으며, ROS Serial message를 인코딩 및 디코딩 할 수 있는 ROS 메타패키지로서 구현됩니다. 즉, ROS Serial 프로토콜을 이용하여 UART를 통해 ROS 노드처럼 Arduino를 발행 및 구독할 수 있습니다. 흔히 말해 ROS Serial 통신을 하는 것 입니다.

 

- 먼저, PC (Raspberry Pi / Ubuntu 18.04 / ROS melodic)에서 rosserial 메타패키지/클라이언트 패키지를 설치합니다.

$ sudo apt-get install ros-melodic-rosserial
$ sudo apt-get install ros-melodic-rosserial-arduino

 

 

- 아두이노 IDE를 실행시켜 File - Preference에 들어가서 Sketchbook location을 설정해줍니다.

Arduino board preference

 

- sketchbook location으로 가서 libraries 폴더가 없다면 생성해줍니다. 모든 Arduino 라이브러리를 보관하는 곳입니다.

 

- 터미널 창을 열어 libraries 폴더로 들어가 Arduino용 ros_lib 라이브러리를 생성합니다.

$ cd libraries
$ rosrun rosserial_arduino make_libraries.py .

 

 

- 아두이노 IDE에서 File - Examples 에 보면 ros_lib을 확인하실 수 있습니다.

 

- 툴 - 라이브러리 관리 클릭하여 Adafruit NeoPixel 라이브러리를 설치해줍니다.

 

 

 

 

 

STEP2. 아두이노 및 부품 설정

- 아래의 사진과 같이 아두이노 및 부품의 배선도를 끼워줍니다.

아두이노 배선도

 

실제 모습

 

STEP3. 아두이노 코드 작성

- 전체 아두이노 코드

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

String LED;

ros::NodeHandle nh;

std_msgs::String led_pos;
ros::Publisher LED_status("LED_status", &led_pos);

void action_LED( const std_msgs::String& msg){
  LED = msg.data;
  LED_status.publish(&msg);

  if (LED=="red") {
    digitalWrite(7, HIGH-digitalRead(7));
  }

  if (LED=="yellow") {
    digitalWrite(5, HIGH-digitalRead(5));
  }

  if (LED=="green") {
    digitalWrite(3, HIGH-digitalRead(3));
  }

}

ros::Subscriber<std_msgs::String> sub("toggle_led", &action_LED);

void setup()
{
  pinMode(7, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(3, OUTPUT);

  nh.initNode();
  nh.advertise(LED_status);
  nh.subscribe(sub);
}


void loop()
{
  nh.spinOnce();
  delay(10);
}

 

 

세부 설명

 

- 먼저 필요한 ros.h와 std_msgs/String.h를 include

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

String LED;

ros::NodeHandle nh;

 

- 아두이노에서 LED_status라는 이름의 Publisher를 설정.

std_msgs::String led_pos;
ros::Publisher LED_status("LED_status", &led_pos);

 

- PC(라즈베리파이)에서 명령을 주면 받아서 처리할 Subscriber를 준비. 콜백 함수를 만들어 줌.

void action_LED( const std_msgs::String& msg){
  LED = msg.data;
  LED_status.publish(&msg);

  if (LED=="red") {
    digitalWrite(7, HIGH-digitalRead(7));
  }

  if (LED=="yellow") {
    digitalWrite(5, HIGH-digitalRead(5));
  }

  if (LED=="green") {
    digitalWrite(3, HIGH-digitalRead(3));
  }

}

ros::Subscriber<std_msgs::String> sub("toggle_led", &action_LED);

 

- 초기 설정. publish는 advertise, subscribe에는 subscribe를 사용

void setup()
{
  pinMode(7, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(3, OUTPUT);

  nh.initNode();
  nh.advertise(LED_status);
  nh.subscribe(sub);
}

 

- 루프에서는 spin 실행하기

void loop()
{
  nh.spinOnce();
  delay(10);
}

 

STEP4. 실행

- 터미널에 해당 실행코드를 타이핑

$ roscore

$ rosrun rosserial_python serial_node.py __name:=arduino _port:/dev/ttyACM0 _baud:=57600

$ rostopic pub /toggle_led std_msgs/String "data: "red"" --once
$ rostopic pub /toggle_led std_msgs/String "data: "yellow"" --once
$ rostopic pub /toggle_led std_msgs/String "data: "green"" --once

rqt_graph