# 基隆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)