# 4장 ROS 하드웨어 제어

### 1. 아두이노란?

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl--EzgcdjAUG/1b38789f099206ae87bad444278b6135191efed76e26f776a9bc048beac343096751810a55e4d5c9ef088904fc9792a936bb3f6c70ac4957b8ed86d8be60b7851bf5545b69fbd7a8aa03dd94c4c6a9e7b9279e37bf6fd0f4623f0a29ea28c27f120f4f13)

마이크로프로세서나 컴퓨터 인터페이스와 같은 전문적인 지식없이도 사용할 수 있게 된 제어기를 말해요. 특히 회로도나 소스코드가 공개 되어서 누구나  '쉽게 공부하면서' 사용할 수 있고, 더 나아가 수정해서 사용할 수 있다는 장점이 있죠. 그 중 가장 대표적인 오픈소스 제어기가 아두이노예요.여담으로 'Arduino'라는 명칭의  상표권 문제로 공식적으로는 미국에서만 Arduino라고 하고, 그 외 국가에서는 Genuino라고 해요. 한국에서도 대부분의 메이커들이 Arduino라고 하죠. 참고로 둘은 같은 상품이라고 보면 돼요.\


### 2. 아두이노의 종류

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-cx3Pia7NYi/1d33177aea13172ada218d44259708fd1bfa088c623f7e0653ab6f7a221cb8e3c45d7d9cd0ade730c5938020a7e07121ca591f9e4837ce01bbb1757af49216e31f20bb6f8fc62c085adcc84a723b51ae3828e91ee9edf87a29ae490591f512964a378d09)

대표적인 아두이노는 아두이노 UNO예요. 교육용으로 주로 사용되죠. 그 외에는 좀더 사양이 좋은 아두이노 MEGA도 있고, 수십\~수백가지의 보드가 존재합니다. 또한 보드에  WiFi, Bluetooth와 같은 기능을 연장하기 위한 아두이노 쉴드(Arduino Shield)라는 것도 사용을 할 수가 있어요.\


### 3. 아두이노 IDE 사용하기

앞에서 아두이노 제어기에 대해서 알아 보았는데요. 이러한 아두이노를 코딩하기 위해서는 아두이노 IDE를 설치해야해요. Windows, MAC, Linux를 포함한 운영체제에서 실행할 수 있어요.\


|                 |                                                                                  |
| --------------- | -------------------------------------------------------------------------------- |
| Column 1        | Column 2                                                                         |
| 아두이노 공식 홈       | [http://www.arduino.cc](http://www.arduino.cc/)                                  |
| 아두이노 보드 정보      | [http://www.arduino.cc/en/main/boards](http://www.arduino.cc/en/main/boards)     |
| 아두이노 소프트웨어 다운로드 | [http://www.arduino.cc/en/main/software](http://www.arduino.cc/en/main/software) |

#### 아두이노 IDE 설치하기

아두이노 IDE는 [https://www.arduino.cc/en/main/software](https://www.arduino.cc/en/main/software) 링크에서 다운받을 수 있어요. 여기서 IDE는 한국말로 통합 개발 환경( Integrated Development Environment)을 의미하는데요. 프로그램 개발 관련된 작업을 하는 작업환경이라고 보면돼요. 문서작업을 위해서 워드나, 한글 같은 작업용 프로그램이라고 볼 수 있어요.\


OpenCR 보드의 경우에 아래와 같이 실행하면, 포트 엑세스 문제를 해결 할 수 있다.

```
wget https://raw.githubusercontent.com/ROBOTIS-GIT/OpenCR/master/99-opencr-cdc.rules
sudo cp ./99-opencr-cdc.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
```



아두이노 보드의 경우에 아래 같은 명령어로 포트 엑세스 문제를 해결 할 수 있다.\


```
sudo chmod a+rw /dev/ttyACM0
```

### 4. Rosserial

로봇은 PC와 임베디드 시스템으로 구성되어 있는데 그 중 대부분은 임베디드 시스템이 차지하고 있다.\
하지만 보통의 임베디드에는 ROS설치가 불가능하기 때문에, 실시간 확보와 하드웨어 제어를 위해 “Rosserial” 패키지 이용한다.

\
위의 그림을 보면 ROS가 설치 되어있는 PC가 있고 PC와 연결되어 있는 Embedded가 있으며 그 Embedded에는 Sensor와 Motor가 연결 되어있다.  PC에서 Rosserial을 이용해 Embedded와 연결되어 있는 센서값을 읽어오거나 모터를 제어할 수 있다.\
Rosserial의 제약• 메모리 =>퍼블리셔, 서브스크라이버 개수 및 송신, 수신 버퍼의 크기를 미리 정의해야 함\
• Float64 =>마이크로컨트롤러는 64비트 실수연산을 지원하지 않아 32비트형으로 변경함\
• Strings =>문자열 데이터를 String 메시지 안에 저장하지 않고 외부에서 정의한 문자열 데이터의 포인터 값만 메시지에 저장함\
• Arrays =>메모리 제약사항으로 배열의 크기를 지정해서 사용\
• 통신 속도 =>UART 같은 경우 115200bps와 같은 속도로는 메시지의 개수가 많아지면 응답 및 처리속도가 느려 짐\


|   |   |
| - | - |
|   |   |

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-AtY8QLJYa2/962b4d8dd9f15ee49508a15310f49ae8bcc994a6f16c76b6a61af4bf6480ad39f16722477f068f3d803269581bc10be79f7631ffd8e3fffc4e0bf5da36316962d7d65d59e19c6d6710052dca53931abad07d05b037940242dd9ef5cb5618e2dd64bad309)

### 4.1 OpenCR이란?

ROS를 지원하는 보드이며 터틀봇3의 메인 제어기로 쓰인다. 오픈소스 하드웨어, 소프트웨어이므로 누구나 만들 수 있다. 소스는 [https://github.com/ROBOTIS-GIT/OpenCR-Hardware](https://github.com/ROBOTIS-GIT/OpenCR-Hardware)에 공개되어 있다.\


|          |                       |                                                                                                  |
| -------- | --------------------- | ------------------------------------------------------------------------------------------------ |
| Column 1 | Column 2              | Column 3                                                                                         |
|          | Arduino Uno           | OpenCR                                                                                           |
| 마이크로컨트롤러 | Atmega328 /8-bit      | STM32F746ZGT6 / 32-bit ARM Cortex®-M7 with FPU                                                   |
| 플래시 메모리  | 32KB                  | 1MB                                                                                              |
| SRAM     | 2KB                   | 320KB                                                                                            |
| 아날로그 입력  | 6개                    | ADC Channels (Max 12bit) x6                                                                      |
|  디지털 I/O |  14개 (6개의 PWM출력핀 포함 ) | 32 pins (L 14, R 18) \*Arduino connectivity 5Pin OLLO x 4 GPIO x 18 pins PWM x 6 I2C x 1 SPI x 1 |

\


![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-uzxD9N2nZL/f281955b7c7e9f6b9e6e2fb17d96fe5762c5da5b407b999f53c503c298b8e7f77ca144322ef7bada397708d45eab21fcf4eebb78b344398ceb2d8bf6f57ccac5153fc266eb377b18947aa4b098d188e94921c4f120954e4f4a414836cc64a764576754e7)

Rosserial의 제약을 극복하려고 많이 노력함\
•32-bit ARM Cortex-M7 with FPU (216MHz, 462DMIPS)•1MB 플래시메모리•320KB SRAM•Float64 지원•UART가아닌USB 패킷전송사용더 자세한 정보는 [http://emanual.robotis.com/docs/en/parts/controller/opencr10/](http://emanual.robotis.com/docs/en/parts/controller/opencr10/) 에서 볼 수 있다.\
\


### 4.2 Rosserial 따라하기

Rosserial 설치

```
sudo apt-get install ros-kinetic-rosserial-arduino
```

```
sudo apt-get install ros-kinetic-rosserial
```



### 4.2.1 OpenCr&#x20;

ros\_lib 설치 (아두이노용 rosserial 라이브러리)

```
 cd <arduino IDE path>/libraries
```

여기서 \<arduino IDE path>는 아두이노 IDE가 설치된 경로를 말한다.\
ex) cd Arduino/libraries (Arduino 파일이 home에 설치되어 있는 경우)

```
 rm -rf ros_lib
```

혹시나 libraries에 미리 설치된 ros\_lib이 존재한다면 제거한다.

```
 rosrun rosserial_arduino make_libraries.py .
```

libraries.py 한 칸 뒤에 있는 점까지 적어주어야 한다. 오타가 아니다.

```
ls
```

\
&#x20;ls 명령어를 입력하면 libraries파일 안에 ros\_lib이 설치되어있는 것을 확인 할 수 있다. 그러면 이제 Rosserial의 간단한 예제를 살펴보자



### 4.2.2 Library Manager

![](https://917233451-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LcW4PzQzrJVLjrT8lUh%2F-LnYK7u0E45WslUOLApp%2F-LnYKyvaSpPITHHYu3Kn%2FScreenshot%20from%202019-08-31%2001-20-37.png?alt=media\&token=2b08d27b-198c-4eb2-86af-18e56efe9ed8)

### 4.3 Rosserial publisher, Rosserial subscriber

준비물: Arduino Uno, 아두이노와 연결할 수 있는 usb 케이블\
우선 아두이노를 실행한다.

```
Arduino
```

아두이노 상단의 메뉴에서 File→Examples→ros\_lib→HelloWorld를 선택한다.\
그리고 다시 상단의 메뉴에서 Tools→Board→ Arduino Uno를 선택해주고 같은 메뉴에서 Port를 설정해준다.

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-uG4q5UDCoB/ad6f6f1b6715b64005e0cf3ceeef202dd843ceff1bc9721a2b31f0304133323f658b46e51abdbd2a3a27de59dda88b066ced827d8735ab0fc66e58350334907abdf745b2bac38da52a63c83b0fec91988717454b16651bb61afacce0ad7f4177f57acf0b)

\
그리고 업로드 버튼을 누른 뒤에 에러 없이 정상적으로 업로드 되었으면 다음을 진행한다. 터미널 창을 열고\


![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-9825fwePsg/b4b33c9a194e1854ff118debf0591df463d0440696c02cd1ef69bfed2b87ec2126fc0df0d750f70811b3b9296e27b777068ed4e7682469c2797b8be16d691a6e2611bee90fb93f74e89b6d20fef1b3cad9bbffa7b4ebdf1c32b6b9ff28b123fbe990fcea)

```
roscore
```

를 실행해준뒤 새로 터미널 창을 하나 더 열어서

```
rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=57600
```

\
를 실행한다 이는 Rosserial을 USB0포트에서 보 레이트 속도를 57600으로 설정하여 통신을 하겠다는 말이다.만약 아두이노가 다른 USB포트에 연결되어 있으면 ttyUSB0 대신에 연결되어 있는 포트로 수정해서 실행한다.\


![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-gQsIvgqVDk/109bd37737797160aa806216a8205deae35bb00b7b639cfb782cda47bdd3cbe22c37cabbae9cf778da9a9d4cee6a0fd985f82355f3cd4fbd28dad05f77dc9454b03979f30fb0ac5d1ea32ccf26e51a2ea255c8ba3d527f0e98dccece065d161d2d87de53)

이와 같이 나오면 성공이다.또 다시 새로운 터미널 창 하나를 더 열어서

```
$rostopic echo /chatter
```

명령어를 실행해보자 그러면 ‘ Hello world! ‘라는 글자가 1초마다 반복 되는 것을 알 수 있다.이는 Arduino Uno가 Publisher가 되어서 PC로 "Hello World!" 라는 문자를 보내주는 것이다. 이번에는 아두이노 IDE에 작성된 소스코드를 살펴보자

```
#include <ros.h>                                     // 아두이노에서 ros를 사용할 수 있게 해주는 헤더파일
#include <std_msgs/String.h>                   //메세지를 위한 헤더파일
ros::NodeHandle nh;                            //노드핸들을 ‘nh’라는 이름으로 선언
std_msgs::String str_msg;                 // ‘str_msg’이라는 이름의 메세지를 String형태로 설정
ros::Publisher chatter("chatter", &str_msg);              // 토픽 이름을 “chatter”로 정하고 메세지를 str_msg의 형태로 설정하는 chatter 객체 생성 
char hello[13] = "hello world!";       //보낼 메세지를 문자열로 저장

void setup()                                             //처음에 한 번만 실행
{

nh.initNode();                                      //노드핸들 초기화
nh.advertise(chatter);                      // chatter 토픽을 Publish 한다.
}

void loop()                                              // 계속 반복
{

      str_msg.data = hello;                      //’hello’ 배열에 저장된 값을 메세지에 저장
      chatter.publish( &str_msg );        // “chatter” 토픽으로 str_msg를 Publish 해준다.
      nh.spinOnce();                                   //콜백함수 호출을 위한 함수로써, 메시지가 수신되기를 대기
      delay(1000);                                       // 1000ms = 1s 동안 딜레이
}
```

이로써 Rosserial의 Publisher 예제를 살펴보았다.&#x20;



이번에는 Subscriber 예제를 실행 해보자.아두이노 상단의 메뉴에서 File→Examples→ros\_lib→Blink를 선택한다.

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-3kakqbLpA3/f7e621371403cbba57e562b174d4a3bdee6c3084b04ed9b625453fc1ead92c5d267ee367e3d19b8ee799224297b63fabb8f5507f4e749cff28afebba4e9a278daa86b9386ba97e74e6513ba245f3116a464c4b51a0c93a8245b2b7689df11479500279cc)

\
그리고 아까와 똑같이 상단의 메뉴에서 Tools→Board→ Arduino Uno를 선택해주고 같은 메뉴에서 Port 설정해주고 업로드를 한다.\


![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-ZBYAy0_8Td/6e927d482646e63676415a8c9dbb9fe38fb9db5f800124d5b18e321f84471d161dd35e452f72d9bdd0fc8c4e5375e74ea703651665d9905a6bb1502e742f92354c21200e270a40d3f8e57e9f9786f6a97404f5d1113586d74d99e2dec1fef96fc7dd2eeb)

```
roscore
```

\
를 실행해주고 아까와 같이 새로 터미널 창을 하나 더 열어서\


```
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=57600
```

\
을 실행한  뒤 또 다시 새로운 터미널 창을 열자 그리고 다음의 명령어를 입력해보자\


```
rostopic pub toggle_led std_msgs/Empty --once
```

\
명령어를 입력할 때마다 13번 핀과 연결되어있는 LED가 켜지고 꺼지는 것을 알 수 있다.

이는 Arduino Uno가 Subscriber가 되어서 PC에서 내리는 명령을 받는 역할을 한다.\
아두이노 IDE에 작성된 소스코드를 살펴보자\


```
#include <ros.h>
#include <std_msgs/Empty.h>
ros::NodeHandle nh;

void messageCb( const std_msgs::Empty& toggle_msg){
digitalWrite(13, HIGH-digitalRead(13));              //메세지를 받을 때마다 LED가 깜빡임
}

ros::Subscriber<std_msgs::Empty> sub("toggle_led", &messageCb );   // 이름이 "toggle_led"인 토픽과   std_msgs::Empty 인스턴스화

void setup()
{

pinMode(13, OUTPUT);                          //13번 PIN을 OUTPUT으로 설정한다.
nh.initNode();
nh.subscribe(sub);

}

void loop()
{

nh.spinOnce();
delay(1);

}
```

이로써 Rosserial의 Subscriber 예제를 살펴보았다.\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\


#### &#x20;
