# Robot Operating System :::info 整理者:黃智彬 ::: # Abstract 機器人作業系統Robot Operating System,簡稱ROS,是由 # Install of the Ubuntu ### 1. Windows subsystem for Linux(WSL) 1. 確認電腦Windows版本需要在Win10 21H2或Win11以上。 2. 在PowerShell中打入: ``` command wsl --install -d Ubuntu-20.04(版本號) ``` #### <font color="bull">PowerShell重要指令</font> 系統更新:```wsl --update``` 列出可安裝版本:```wsl --list --online``` 列出狀態:```wsl --list --verbose ``` 簡寫 ```wsl -l -v``` 關機:```wsl --terminate 系統名稱``` 或 ```wsl --shutdown``` 刪除,真的實體刪除:```wsl --unregister 系統名稱``` #### <font color="bull">第一次啟動Ubuntu </font> 在Windows的開始視窗中找到Ubuntu,即可開啟,進入後第一次輸入自己的名稱與密碼。 #### <font color="bull">系統實體位置</font> 整個虛擬系統的實體位置: C:\Users\你的帳號名稱\AppData\Local\Packages\CanonicalGroupLimited……… #### <font color="bull">系統移植</font> **將系統關機:**```wsl --terminate ubuntu-20.04``` **將實體檔案複製到其他地方:**```wsl --export ubuntu-20.04 d:\ubuntu-20.04.tar``` **刪除原有系統檔案:**```wsl --unregister ubuntu-20.04``` **利用檔案總管,在後續需要的地方建立資料夾,例如d:\wsl\ubuntu-20.04** **匯入實體檔案:**```wsl --import ubuntu-20.04 d:\wsl\ubuntu-20.04\ d:\ubuntu-20.04.tar``` **刪除備份資料:**```del d:\ubuntu-20.04.tar``` ### 2. VM Virtual Box ### 3. Docker # ROS安裝 ## STEP **正規安裝(版本:Ubuntu18.04/ROS melodic)** 1. 開啟setting,進入Sofeware & Updates,把Source code打勾。 2. 執行以下命令,使電腦允許接收packages.ros.org的軟體 ``` command sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' ``` 3. 設置金鑰 ``` sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - ``` 4. 確保系統套件是最新的 ``` sudo apt update ``` 5. 安裝ROS 桌面完整安裝,包含ROS, rqt, rviz, robot通用函式庫,2D/3D模擬器(約10GB)。 ``` sudo apt install ros-melodic-desktop-full ``` 桌面安裝:包含ROS, rqt, rviz, robot通用函式庫。 ``` sudo apt install ros-melodic-desktop ``` ROS輕量板:只有ROS包,通訊庫。 ``` sudo apt install ros-melodic-ros-base ``` 安裝特定套件: ``` sudo apt install ros-melodic-PACKAGE ``` 安裝完後確認目前的可用套件: ``` apt search ros-melodic ``` 6. 將ROS的環境變數添加至bash文件中 ``` echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc ``` 7. 用於生成ROS包的依賴項 ``` sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential ``` 8. 初始化rosdep ``` sudo apt install python-rosdep sudo rosdep init rosdep update ``` * catkin build安裝 ``` sudo apt-get install python3-catkin-tools ``` **快速安裝** 1. 安裝Git工具 ``` command sudo apt update ``` ``` command sudo apt install -y git curl ``` 2. 安裝ROS工具包 ``` command sh -c "$(curl -fsSL https://raw.githubusercontent.com/Adlink-ROS/ros_menu/master/scripts/setup.sh)" ``` 3. 測試ROS的功能(Turtle) Terminal-1 ``` command roscore ``` Terminal-2 ``` command rosrun turtlesim turtlesim_node ``` Terminal-3 ``` command rosrun turtlesim turtle_teleop_key ``` # ROS概述 ![](https://i.imgur.com/BfYvVvF.png) # ROS的重要觀念 ## ROS Architecture ![reference link](https://i.imgur.com/Ck2DFjJ.png) * 3 Layer: OS->middleware->APP * APPs(Nodes)use ROS library * Master controls communication ## 檔案架構層 * **ROS中,會有兩個資料夾可以使用** ![](https://i.imgur.com/ZEtAm7p.png) 最常使用的為右邊的workspace資料夾,catkin可以在創建此資料夾時任意更改,這個資料夾主要是用來放置開發用的各種ROS包、標頭檔與Code等檔案。 * **workspace的文件配置** ![](https://i.imgur.com/X3xOSNa.png) 在workspace的資料夾底下,一定會區分成三個區域,分別是:build, devel, src,其中會動到的資料夾只有src。 * **src** ![](https://i.imgur.com/7C18qaP.png) 在ROS中,Node是可執行的文件檔案中最小的單位,Node可以使用C/C++、Python等ROS能支援的語言Coding,並透過ROS特殊的通訊機制將Node組合起來,使其成為一個具有單一功能的Package。( 就算是利用不同語言撰寫的Node也可以在ROS的通訊中傳遞資料) * **Package資料夾的檔案配置** 上述所言,雖然Package是由一大堆的Node組合而成的,但將所有的Node全部扔在Package中未免也太雜亂了。 所以ROS定義了一套Package的標準資料夾結構, ![](https://i.imgur.com/GkXzO0I.png) 以下說明各資料夾: | File Name | Definition | -------------- | ---------- | action | 存放自定義的action文件檔案 | config | 存放自定義的動態配置文件檔案 | include | 存放Package會使用的標頭檔案(C)或模組(Python) | launch | 存放launch文件檔案 | msg | 存放自定義Message文件檔案 | scripts | 存放可直接執行的Python程式碼檔案,或是執行演算法的程式碼檔案 | src | 存放需要進行編譯的C/C++程式檔案,或是直接操作硬體相關的Code | srv | 存放自定義srv文件檔案 | CmakeLists.txt | 使用catkin_make編譯功能時,所需要的編譯規則 | package.xml | 存放會使用其他package的清單 ## 計算圖層 Node在ROS網路中是透過==P2P網路(Peer-to-peer對等式網路)== 與[Point-to-Point Proctocol(PPP)](https://reurl.cc/DXzbYN)的通訊機制進行溝通。 ROS計算圖層的概念包含Node、Topic、Message、Master、Parameter server、Service與bag。 * Node: Node是一個Process,多個Node是使用ROS API進行數據交流。 * Master: 在網路中扮演接線生的角色,Master擁有ROS網路中各個Node的所有資料。將某個Node與其他Node的詳細資料交換來建立起之間的連線,資料交換後,兩個Node就可以開始通訊。 * Parameter Server: ROS把所有Node所使用的變數都放置在Parameter Server,並且可以為每個變數設置隱私權,即訪問權限,以方便篩選需要使用的Node訪問。 * Message: 定義ROS網路中的通訊協定。 * Bag: Bag是ROS中用於紀錄與重播Topic的公用程式。在很多時候我們都得在沒有硬體的強況下操作Robot,透過rosbag,我們得以紀錄感測器的資料,還可以把bag檔copy到另一台電腦來重播,藉以檢查資料的正確性。 ## ROS Message ROS有三種的通訊方法:Topic, Service, Action,以下是它們的概念圖。 ![](https://i.imgur.com/opOp5e6.jpg) --- ### <font color="purple">**Topic**</font> ROS中最常用的通訊方式,為多對多單向且[異步(Asynchronous)](https://baike.baidu.com/item/%E5%BC%82%E6%AD%A5/3441874)的通訊方式,在Topic的通訊機制,具體是透過Node之間傳遞message進行訊息傳輸,適合狀態監控類的任務。 * Publisher(發佈者): 1. 生成訊息,發佈message到對應的Topic上。 2. 通常用於處理原始的Sensor data,如相機、Encoder。 * Subscriber(訂閱者): 1. 接收訊息,訂閱所需的Topic上的message下來使用。 2. 可用於監測系統狀態,如當手臂關節到極限位置時觸發運動中斷。 可以理解成,有一個人將message publish到一個佈告欄(Topic)上,那有需要的人可以subscribe這個佈告欄上的message下來使用,因此為單向的通訊方式。 Subscriber在收到訊息時會先進行處理,稱之為Callback(回調),Callback即為提前定義好一個處理函式(在Process中),當有消息來就會觸發這個處理函式,類似Arduino的中斷(Interrupt)。 ``` python rospy.Subscriber("Topic名稱", message類型, callback_function) ``` message是Node之間傳遞訊息的數據格式,ROS支持[標準數據格式](http://wiki.ros.org/msg)(int8, float16, string),也可以自定義message的類型,當然ROS本身也定義了一套用於Robot的數據格式,包括控制動作的**actionlib_msgs** 、導航用**nav_msgs**、感測器用的**sensor_msgs**,會建議能使用原先提供的message type就先使用,並且遵照其定義的訊息意義使用。 #### Topic通訊特點 1. 多對多的異步通信方式: Publusher調用publish()發佈消息,發佈完立即返回,不用等待反饋;Subscriber通過Callback的方式來處理message。 對於同一Topic,系統中可以同時存在多個Publisher與Subsciber。 另外,Publisher並不知道哪個Node會接收消息,而Subscriber也不知道接收的消息來自哪裡,Node之間式鬆耦合的,這是ROS最關鍵的設計之一。 2. 對於實時性、週期性的消息,使用Topic傳輸是最佳解。 3. Topic通信方式充分體現出分散式系統通信的好處:擴展性好、軟體複用性高。 #### Topic communcate step ![](https://i.imgur.com/dOloP9M.png) 1. Publisher和Subcriber利用[RPC](https://reurl.cc/OEZ6W7)向Master註冊自己的訊息(Node地址等...)。 2. Master確定需要通信的Node後就會對Node的訊息進行匹配。 3. Subscriber向Publisher發送自身的[TCP/IP protocol](https://zh.wikipedia.org/wiki/TCP/IP%E5%8D%8F%E8%AE%AE%E6%97%8F)以及連接請求。 4. Publisher確定連接請求,然後將自身的TCP/IP address發送給Subscriber。 5. 兩個Node正式建立連接,並以TCPIP protocol進行數據傳輸。 #### msg自定義格式 Topic有很嚴格的訊息格式,ROS中message遵照著固定的型態格式。 bool, int8, int16, int32, int64, uint, float32, float64, string, time, duration, header, array, vector(可變長度的array) msg的範例: ``` std_msg/Header header uint32 seq time stamp string frame_id uint 32 height uint32 width string encoding uint8 is_bigendian uint32 step uint8[] data ``` MSG相關操作命令 |rosmsg指令 |作用 |----------------------| ---- |rosmsg list |列出系統上所有的msg |rosmsg show "msg_name"|顯示某個msg的內容 #### command window操作命令 |命令 |作用 |:-------------------------------|:---------- |```rostopic list``` |列出當前所有topic |```rostopic info "topic_name"```|顯示topic的屬性信息 |```rostopic echo "topic_name"```|顯示topic的內容 |```rostopic pub "topic_name"``` |向topic發佈內容 |```rostopic bw "topic_name"``` |查看topic的頻寬 |```rostopic hz "topic_name"``` |查看topic的頻率 |```rostopic find "topic_type"```|查找某個類型的topic |```rostopic type "topic_name"```|查看topic的類型 --- ### <font color="purple">**Service**</font> 為了解決某些Node只是臨時而非週期性的需要某些數據,使用Topic通訊則會消耗大量不必要的系統資源,導致整體系統的低效率高功耗;在這種情況下,Service就是因應此需求而開發的。 Service是透過Request&Response來溝通,屬於單對單的雙向同步通訊方式,它不但可以發送訊息,同時也會得到反饋,並且回應及時。 Service包括兩部分,一部分為**應答方/服務提供方(Server)**,另一部分為**請求方(Client)**。 ![](https://i.imgur.com/hiLInFp.png) #### 過程 Client發佈Request後會在原地等待Response,直到Server處理完Request後並且回傳Response,Client才會繼續動作。 Client等待過程中,是處於阻塞的狀態。這種的通信模型沒有頻繁的訊息傳遞,沒有衝突與高系統資源的占用,只有接收Request才執行Service。 #### SRV SRV是Service的一種訊息格是,跟message很像,其附檔名為.srv,SRV文件包含Request跟Response的格式。 以OpenNI的人體檢測ROS包中的為例: msgs_demo/srv/DetectHuman.srv ``` bool start_detect --- my_pkg/HumanPose[] pose_data ``` msgs_demo/msg/HumanPose.msg ``` std_msgs/Header header string uuid int32 number_of_joints my_pkg/JointPose[] joint_data ``` msgs_demo/msg/JointPose.msg ``` string joint_name geometry_msgs/Pose pose float32 confidence ``` 這個.srv檔用來查詢當前深度鏡頭中的人體姿態和關節數。 .srv檔的格式很固定,第一行為Request的格式,第三行為Response的格式,中間用---隔開。 本例中,Requset為是否開始檢測,Response為一陣列,陣列中的每個元素為某人的姿態(HumanPose)。 而對於人的姿態,其實為一msg,因此srv可以嵌入msg在其中,但相反就不行。 SRV相關操作命令 |rossrv指令 |作用 |----------------|----- |rossrv show |顯示service描述 |rossrv list |列出所有service |rossrv md5 |顯示服務md5sum |rossrv package |列出package中的service |rossrv packages |列出包含service的package #### command window操作命令 |命令 |作用 |:---------------------|:--------------- |```rosservice list ```|顯示Service列表 |```rosservice info ```|印出Service訊息 |```rosservice type ```|印出Service類型 |```rosservice uri ```|印出服務ROSRPC uri |```rosservice find ```|依Service類型查找Service |```rosservice call ```|使用所提供的args調用Service |```rosservice args ```|印出Service參數 --- ### <font color="purple">**Action**</font> 當機器人執行一個長時間的任務時,如果利用Service,那麼Client會很長時間接收不到Response,此時我們有多工的需求時,Servic會導致通信受阻。 Action就是在這一個背景下開發的,它類似Service的通訊機制,但Action比較適合長時間的通信過程,在Action通信的過程可以隨時查看過程進度,也可以終止過程,這種特性,使得它在一些特別的機制擁有很高的效率。 Action也包括兩部分: * Action server:向ROS系統廣播指定action的Node,其他Node也可向該Node發出action目標請求。 * Action client:發出action目標請求的Node。 通訊原理示意圖:Action的工作原理是client-server模式,為雙向的通訊。 ![](https://i.imgur.com/UJpT5Tj.png) 通信雙方在ROS Action Protocal下進行通信,如下圖。 ![](https://i.imgur.com/PHD4nsu.png) 可以看到,Client(客戶端)會向Server發送目標指令和取消動作的指令,而Server則可以向Client回報實時的Status, result, feedback等訊息,這些都是Service無法完成的。 #### Action 規範 利用Actionlib請求動作時,該動作的內容必須包含三個部分goal, feedback, result。 * Goal(目標) 機器人執行一個動作,應該要有明確的移動目標信息,包括參數的設定、方向、角度、速度等等。從而使機器人完成動作任務。 * Feedback(反饋) 在動作進行的過程中,應有實時的狀態訊息反饋給Client,告訴Client動作完成的狀態,可以使Client作出準確的判斷去修正命令。 * Result(結果) 當動作完成時,Server把動作的結果發送給Client,使Client得到本次動作的全部訊息,如:機器人的運動時長、最終位姿等。 #### Action文件格式 * 文件名稱:<custion_message_type>.action * 文件副檔名:.action * 文件位置:<ros_package_name>/action文件夾中 * 內容格式: ``` command # Define the goal uint32 dishwasher_id #Specify which dishwasher we want to use --- # Define tje result uint32 total_dishes_cleaned --- # Define a feedback message float32 percent_complete --- ``` #### Action相關資料 https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/chapter4/4.4.html https://tr-ros-tutorial.readthedocs.io/zh_CN/latest/_source/basics/1.6_ROS_Action.html #### 自定義msg, srv, actiion修改部分文件 在添加完自己定義的msg, srv, action檔後,需要修改CMakeLists.txt,使其生效。 ``` find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs geometry_msgs #add new line message_generation #add new line actionlib #add for action actionlib_msgs #add for action ) ## Generate messages in the 'msg' folder add_message_files( FILES RobotState.msg ## 自定義的msg檔 ) ## Generate services in the 'srv' folder add_service_files( FILES RobotStateService.srv ## 自定義的srv檔 ) ## Generate actions in the 'action' folder add_action_files( FILES AutoDocking.action ## 自定義的action檔 ) ## Generate added messages and services with any dependencies listed here generate_messages( DEPENDENCIES std_msgs geometry_msgs actionlib_msgs ) ``` 若有其中的檔案有引用的原本ROS的訊息格式(如:geometry_msgs等...),除了需要在CMakeLists.txt文件中添加訊息的依賴,同時也需要在package.xml中添加該訊息的依賴,如下: ``` xml <build_depend>geometry_msgs</build_depend> <build_depend>message_generation</build_depend> <build_depend>actionlib</build_depend> <build_export_depend>geometry_msgs</build_export_depend> <build_export_depend>actionlib</build_export_depend> <exec_depend>geometry_msgs</exec_depend> <exec_depend>message_runtime</exec_depend> <exec_depend>actionlib</exec_depend> ``` 修改完後,在運行以下指令編譯即可: ``` cmd cd ~/"workspace" catkin_make ``` 編譯完後,可透過rosmsg/rossrv show查看定義。 ``` cmd cd ~/"workspace" source devel/setup.bash rosmsg show tutorial/RobotState rossrv show tutorial/RobotStateService ``` ### 三種通訊方式的差別 |Type |Featurs |Featurs |Description |--------|--------------|--------- |-------------- |Topic |Asynchronous |Unidirectional |Used when exchanging data continuosly |Service |Synchronous |Bi-directional |Used when request processing requests and responds current states |Action |Asyschronous |Bi-directional |Used when it's difficult to use the service due to long response times after the request or when an intermediate feedback value is needed # 常用工具 ## Rviz ## Gazebo # 參考文獻 https://www.twblogs.net/a/5bf6f36fbd9eee18ceccf906 https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/chapter1/