---
# System prepended metadata

title: 基隆xAUV ROS 教學
tags: [基隆, ROS]

---

# 基隆xAUV ROS 教學

###### tags: `基隆` `ROS`

![](https://i.imgur.com/ScFzWun.png)


[TOC]

## ROS(Robot Operating System)
ROS 是在 Linux 中的，專門設計來控制機器人與自動化裝置的軟體架構。

#### 基本結構
##### Workspace 工作空間
如果沒有工作空間，那就不能使用 ROS，就假設這是個虛擬平台，連結著所有的節點(node)。
##### Node 節點
節點，就是執行檔。通常會含有發佈者(publisher)和訂閱者(subscriber)
##### Topic 主題
發佈者(publisher)可以發佈訊息(message)到主題，而訂閱者(subscriber)可以訂閱主題以接收訊息(message)，用這種方式節點(node)跟節點之間便可以溝通。
##### Package 包裹
包裹中可以存放所需的節點(node)。通常一個包裹代表一個特定的任務，節點則是任務的拆解子任務。
##### Launch file
通常包裹中都會有一個 Launch 資料夾，裡面存放不同的 launch 文件，只要執行一個 launch 文件，便會一次啟動所有需要的節點。

- [ROS自學筆記](https://charlyhuangrostutorial.wordpress.com/ros-%E8%87%AA%E5%AD%B8%E7%AD%86%E8%A8%98/)
![](https://i.imgur.com/p5nDCgf.png)

---

## 啟動 ROS
開啟終端機(ctrl+alt+t)並輸入
```
roscore
```
確認是否有出現類似畫面

![](https://i.imgur.com/xTxRQ5k.png)

:::success
**因為接下來要執行的工作都要確保ROS是啟動狀態
所以要開啟新的終端機(ctrl+alt+t)來執行工作**
:::
 
---

## 範例 (Python)
### 發佈者(publisher)
```python=
#!/usr/bin/env python3
import rospy
from std_msgs.msg import String

def talker():
    rospy.init_node('talker', anonymous=True)
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rate = rospy.Rate(10) # 10hz

    while not rospy.is_shutdown():
        hello_str = "hello world"
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass
```
#### 引用(import): 為了使用已經寫好的library
```python=
import rospy
from std_msgs.msg import String
```
#### 節點(node)初始化
```python=
rospy.init_node('talker', anonymous=True)
```
- 'talker': 為節點(node)名稱
- anonymous=True: 確保此節點名稱是唯一的，不會跟其他節點名稱重複

#### 設置發佈者(publisher)參數:
```python=
pub = rospy.Publisher('chatter', String, queue_size=10)
```
- 'chatter': 發佈的主題(topic)名稱 
- String: 訊息(message)的資料型態(data type)
- queue_size: 最多暫存資料數

#### 執行迴圈速度
```python=
rate = rospy.Rate(10) # 10hz
```
- 以每秒發佈幾次訊息為單位

#### 發佈訊息(message)
```python=
while not rospy.is_shutdown():
    hello_str = "hello world"
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()
```
- rospy.is_shutdown(): 為停止發佈訊息(message)的中止條件(ctrl+c)
- rospy.loginfo(hello_str): 其中之一的功能是將發佈訊息(message)顯示到終端機上
- pub.publish(hello_str): 發佈訊息(message)到主題上(topic)
- rate.sleep(): 為了配合執行速度

#### 執行結果
![](https://i.imgur.com/74UNmIA.png)



### 訂閱者(subscriber)
``` python=
#!/usr/bin/env python3
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo("I heard %s", data.data)
     
def listener():
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('chatter', String, callback)
    rospy.spin()

if __name__ == '__main__':
    listener()
```

#### 節點(node)初始化
```python=
rospy.init_node('listener', anonymous=True)
```
- 'listener': 為節點(node)名稱
- anonymous=True: 確保此節點名稱是唯一的，不會跟其他節點名稱重複

#### 設置訂閱者(subscriber)參數:
```python=
rospy.Subscriber('chatter', String, callback)
```
- 'chatter': 訂閱的主題(topic)名稱 
- String: 訂閱訊息(message)的資料型態(data type)
- callback: 訂閱到訊息後要執行的工作(handle function)

#### handle function:
- 此處為固定形式
```python=
def callback(data): 
    ...
```    

#### 重複訂閱
```python
rospy.spin()
```

#### 執行結果
![](https://i.imgur.com/4cdEygo.png)

## 指令
- ```rostopic list```: 列出所有在ROS上存在的所有主題(topic)
- ```rostopic echo /topic-name```: 把發佈(publish)到指定主題(topic)的訊息(message)顯示在終端機上
- ```rosrun package_name node_name```: 執行指定的node(需要開啟roscore)
- ```roslaunch package_name file_name.launch```: 執行指定的launch檔(會自動開啟roscore)

## 連線 ROS Master(開啟roscore的裝置)
1. 連上與master相同的網域
2. 開啟終端機
3. 在終端機輸入 ``ifconfig`` 確認自己裝置的IP
4. 在終端機輸入 ``vim ~/.bashrc``
5. 並在最底下加上
    ``export ROS_MASTER_URI=http://<ros master的                 ip>:11311``
    ``export ROS_IP=自己裝置的IP``
   後儲存後跳出
6. 在終端機輸入 ``source ~/.bashrc``
7. 這樣自己的裝置就能和ROS_Master共用ROS環境

---

## RVIZ
ROS 應用程式的 3D 視覺化工具，它也可以顯示來自於攝影機等資料。

先在終端機輸入```rviz```確認是否有安裝

### 安裝rviz
開啟終端機並輸入
``` 
rosdep update
rosdep install rviz
rosmake rviz
```

### 啟動rviz
- 開啟樹梅派的終端機並輸入(開啟鏡頭)
```
roslaunch usb_cam usb_cam-test.launch 
```

- 將自己的裝置和樹梅派連線後開啟終端機並輸入
```
rviz
```

### 啟動後的畫面
- 終端機(自己)

![](https://i.imgur.com/QoTlcD8.png)

- 終端機(樹梅派)

![](https://i.imgur.com/izLLeF9.png)

- 跳出的視窗(自己)

![](https://i.imgur.com/Ld5vDhh.png)


### 新增攝影機畫面

1. 按下 ***Add***

![](https://i.imgur.com/fPJKfDU.png)

2. 按下 ***By topic***

![](https://i.imgur.com/KFppEDE.png)

3. 按下 ***Image*** 後按 ***OK***

![](https://i.imgur.com/TZpFVIu.png)

接下來就可以看到畫面囉~

---

## Advanced
### 安裝 ROS
[官網安裝說明](http://wiki.ros.org/melodic/Installation/Ubuntu)
Ver: ros-melodic-desktop-full

```bash=
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt update
sudo apt install ros-melodic-desktop-full
apt search ros-melodic
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
sudo apt install python-rosdep
sudo rosdep init
rosdep update
```

### 創建 ROS workspace
``` = bash
$ cd
$ mkdir -p catkin_ws/src
$ cd catkin_ws
$ catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
```
#### 接下來就可以下載或創建package到/catkin_ws/src底下

:::warning
在安裝或創建任何的ROS套件後一定要執行
``catkin_make``
:::

### 建立 ROS Package
```
$ catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
```

```
$ cd ~/catkin_ws/src
$ catkin_create_pkg test
```

### Troubleshooting
#### 找不到ROS套件
##### 在終端機輸入以下指令後重開終端機
`source ~/.bashrc`
`source ~/catkin_ws/devel/setup.bash`
#### rosrun 找不到 node
利用 ```chmod +x node_name``` 將node的檔案改為可執行檔
#### can't find 'rospkg'
`$ pip3 install rospkg`
#### can't find 'catkin_pkg'
`$ pip3 install catkin_pkg`
#### can't find 'em'
`$ pip3 install empy`
#### can't find 'yaml'
`$ pip3 install pyyaml`

## Reference
[ROS自學筆記](https://charlyhuangrostutorial.wordpress.com/ros-%E8%87%AA%E5%AD%B8%E7%AD%86%E8%A8%98/)
[ROS Wiki rostopic](http://wiki.ros.org/rostopic)
[ROS Wiki publisher_and_subscriber](http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28python%29#rospy_tutorials.2FTutorials.2FWritingPublisherSubscriber.CA-c82832e0d612370fe9886563f0b7f5433f6caee1_1)
[aws amazon](https://docs.aws.amazon.com/zh_tw/robomaker/latest/dg/simulation-tools-rviz.html)
