第 6 章 啟動檔案 
利用啟動檔案一次性配置和執行多個節點 。 
roslaunch :這是一個自適應工具,如果啟動多節點時沒有節點管理器執行,它會自動啟動節點管理器;如果已經有一個節點 管理器在執行,則會使用已有的。    
利用啟動檔案一次性配置和執行多個節點。任何包含兩個或兩個以上節點的系統都可以利 用啟動檔案來指定和配置需要使用的節點。本章將對啟動檔案和執行啟動檔案的 roslaunch 工具進行介紹。
6.1 使用啟動檔案  
    (1)執行啟動檔案 想要執行一個啟動檔案,可以像下面這樣使用 roslaunch命令 : roslaunch package-name launch-file-name 
launch-file-name正常情況下創建於一個package中。
注意:使用roslaunch命令之前需要先:source devel/setup.bash
    (2)ROS 也允許使用不歸屬於任何功能包的啟 動檔案,此時需要向 roslaunch 提供啟動檔案的路徑:roslaunch ~/ros/src/agitr/example.launch 

    終止啟動過程可以使用 Ctrl-C 來終止一個活躍的 roslaunch。
6.2 建立啟動檔案 
    (1)啟動檔案的儲存位置 :
        每一個啟動檔案都應該和一個特定的功能包關聯起來。
        example.launch具體位置:

    (2)啟動檔案是 XML 檔案。
        插入根元素 :
            
    (3)啟動節點:
        節點元素的形式為: 
            
        ——》斜槓“/”是很容易忘記的,但是它很重要。它表明不必再等待結束標籤(“</node>”),並且該節點元素是完整的。
    每個節點元素有如下三個必需的屬性:
    ——》pkg 和 type 屬性定義了 ROS 應該執行哪個程式來啟動這個節點。即給出功能包名和可執行檔案的名稱。 
        pkg=”package-name”
        type=”executable-name”  
        name=”node-name” 
    ——》name 屬性給節點指派了名稱,它將覆蓋任何通過呼叫 ros::int 來賦予節點的名稱。
為節點保留獨立的終端:Launch-prefix=“command-prefix” 。
        檢視節點日誌檔案:從啟動檔案啟動節點的標準輸出被重定向到一個日誌檔案中,該日誌檔案的名稱是: 
            ~/.ros/log/run_id/node_name-number-stout.log 
    
在控制檯中輸出資訊對於某個單獨的節點,只需在節點元素中配置 output 屬性就可以達到該目的: 
            output=”screen”——》配置了該屬性的節點會將標準輸出顯示在螢幕上而不是記錄到之前討論的日誌文件。
使用--screen 命令列選項來令 roslaunch 在控制檯中顯示所有節點的輸出: 
            roslaunch –screen package-name launch-file-name 
請求復位:對於每個節點,我們可以設定 respawn 屬性為真,這樣當節點停止的時候, roslaunch 會重新啟動該節點。 
            respawn=”true” 
必要節點(requiring node) :
    將一個節 點宣告為必要節點:
        required=”true” 
  當一個必要節點終止的時候,roslaunch 會終止所有其他活躍節點並退出。
為節點維護獨立的視窗 :
        ——》使用 roslaunch 的一個缺點是所有的節點共享一個終端。
    roslaunch 提供了一個 對某個節點提供所需要依賴控制檯輸入的終端 的簡潔方法—— 對節點元素使用啟動字首(launch-prefix)屬性: 
            launch-prefix=“command-prefix” 
        
        launch-prefix=“xterm -e” 
它與下列命令等價:
     xterm -e rosrun turtlesim turtle_teleop_key 
xterm 命令將開啟一個簡單終端視窗。引數-e 告訴 xterm 在新開啟的終端中執行該命令列的剩餘部分(這裡是 rosrun turtle_teleop_key)。
    
6.3 在名稱空間內啟動節點 
    對一個節點設定預設名稱空間的通常方法是使用 一個啟動檔案,並對其節點元素配置名稱空間(ns)屬性: (ns = namespace)
            
6.4 名稱重對映(REMAPPING NAMES) 
    當啟動一個節點的時候,有兩種方法來建立重對映。:
    (1)當使用命令列啟動節點時,分別給出原始名稱和新名稱,中間由一個:=分開,如下所示: 
            original-name := new-name 
        e.g:rosrun turtlesim turtlesim_node turtle1/pose:=tim 
    (2)通過啟動檔案的方式,只需在啟動檔案內使用重對映(remap) 元素即可:
        <remap from=”original-name”to ”new-name”/> 
如果該屬性在頂層,即作為 launch 元素的子元素出現,重映 射將會應用到所有的後續節點。
        這些重對映元素也可以作為 一個節點元素的子元素,如: 
        <node node-attributes> 
            <remap from=”original-name”to ”new-name”/> 
        </node> ——》在這種情況下,給出的重對映只應用於其所在的節點。
    有一點需要牢記:在 ROS 應用任何重對映之前,所有的名稱都要先解析為全域性名稱,包括重對映中的原始名稱和新名稱。

6.5 啟動檔案的其他元素 
    (1)如果想在啟動檔案中包含其他啟動檔案的內容:<include file=”path-to-launch-file”> 
        ——》此處 file 屬性的值應該是我們想包含的檔案的完整路徑。
        由於直接輸入路徑資訊很繁瑣且容易出錯,大多數包含元素都使用 查詢(find)命令搜尋功能包的位置來替代直接輸入路徑: 
            <include file=”$(find package-name)/launch-file-name”>
    當roslaunch 命令列工具在搜尋一個功能包中的 啟動檔案時,會搜尋功能包內的所有子目錄。
        包含元素同樣支援名稱空間屬性,可以將內容壓入一個指定 的名稱空間中去: 
        <include file=”…” ns=”namespace”/> 
    (2)為了使啟動檔案便於配置,roslaunch還支援啟動引數,有時 也簡稱為引數甚至args。
        宣告引數: 為了宣告一個引數,可以使用 arg 元素:
        <arg name=”agr-name”> 
        引數賦值: 啟動檔案中的每一個引數都要進行賦值,三種方法:
            A:roslaunch package-name launch-file-name arg-name:=arg-value 
            B:<arg name=”arg-name” default=”arg-value”/> 
                <arg name=”arg-name” value=”arg-value”/>
        A和B的區別在於命令列引數可以覆蓋預設值 default,但 是不能覆蓋引數值 value。 value 設定的引數值是不能更改的。
        獲取引數值 :$(arg arg-name) 
        向包括的啟動檔案中傳送引數值 :
        

    建立組:組(group)元素,它提供了一種在大型啟動檔案內管理節點的便捷方式 。
    ——》組元素可以完成如下兩種任務:
        (1)組可以把若干個節點放入同一個名稱空間內。 
            <group ns=”namespace”/> 
            … 
            </group>  
        (2)組可以有條件地使能或禁用一個節點。
            
 
6.6 展望 
    本章節介紹如何建立通過訊息傳遞來進行通訊的節點,如何在(可能有的)複雜配置下一次性啟動多個節點。

第 7 章 引數
    介紹引數伺服器,向大家展現提供節點部分配置資訊的集中式方法。通過調整引數配置節點。
 
7.1 通過命令列獲取引數 
    檢視引數列表:rosparam list 
        

    所有的引數都 屬於引數伺服器而不是任何特定的節點。這意味著引數— —即使是由節點建立的——在節點終止時仍將繼續存在。 
    查詢引數: 向引數伺服器查詢某個引數的值,可以使用 rosparam get 命令:
         rosparam get parameter_name 
    設定引數: 如下命令用於設定引數的值: 
        rosparam set parameter_name parameter_value 
    為了以YAML 件的形式儲存名稱空間中的所有引數,可以使用 rosparam dump 命令: rosparam dump filename namespace 
    與dump 相反的命令是 load,它從一個檔案中讀取引數,並將它們新增到引數伺服器: rosparam load filename namespace 
7.2 例:turtlesim中的引數
     從引數伺服器讀取這些引數的值,呼叫這個服務可以使用以下命令: rosservice call /clear 

7.3 使用 C++獲取引數 
使用ROS引數的C++介面是相當簡單的: 
void ros::param::set(parameter_name, input_value); 
bool ros::param::get(parameter_name, output_value); 

7.4 在啟動檔案中設定引數
    另外一種常用的引數設定方法是在啟動檔案中設定。 
    設定引數: 可以使用param元素請求roslaunch設定引數值: 
        <param name="param-name" value="param-value" /> 
    在檔案中讀取引數:
    ——》可以一次性從檔案中載入多個引數 :<rosparam command="load" file="path-to-param-file" /> 
第 8 章 服務
將討論 ROS 的最後一種通訊機制——即服務,它實現了一對一的雙向資訊流。討論如何呼叫服務並對服務請求進行響應。
訊息傳遞機制儘管是 ROS 系統中節點通訊的主要方法,但確實受 到了一定的限制。本章引入另一種用於通訊的方法,稱之為服務 呼叫( service calls)。服務呼叫與訊息的區別主要體現在兩個方面:
(1)服務呼叫是雙向的,一個節點給另一個節點發送資訊並等待 響應,因此資訊流是雙向的。而訊息是單向的。
(2)服務呼叫實現的是一對一通訊。每一個服務由一個節點發起, 對這個服務的響應返回同一個節點。

8.1 服務的專用術語
(1)服務呼叫的基本資訊流:

請求和響應資料攜帶的特定內容由服務資料型別(service data type)來決定。
8.2 從命令列檢視和呼叫服務
列出所有服務 :rosservice list;輸出的每一行都表示一個當前可以呼叫的服務名。服務名是計算圖源名稱,同其他資源名稱一樣,可以劃分為全域性的、相對的或者 私有的名稱 命令的輸出是所有服務的全域性名稱。 


ROS服務總的來講可以劃分為兩個基本型別: 
    ——》一些服務,例如上表中 get_loggers 和 set_logger_level 服務, 是用來從特定的節點獲取或者向其傳遞資訊的。這類服務通 常將節點名用作名稱空間來防止命名衝突,並且允許節點通 過 私有名稱來提供服務,例如~get_loggers 。
    ——》其他服務表示更一般的不針對某些特定節點的服務。
檢視某個節點提供了哪些服務型別:rosnode info /turtlesim
查詢提供服務的節點 :rosservice node /turtle1/set_pen
查詢服務的資料型別 :rosservice info service-name 

同消 息型別類似,服務資料型別有兩個部分,其一宣告擁有此資料型別的包,其二宣告型別本身: 

檢視服務資料型別 :當服務的資料型別已知時,我們可以使用 rossrv 指令來獲得此服務資料型別的詳情: rossrv show service-data-type-name
服務資料型別中的請求或響應欄位可以為空,甚至兩個欄位可以同時為空。
用命令列呼叫服務 : rosservice call service-name request-content 

8.3 客戶端程式
   (1)宣告請求和響應的型別 就像訊息型別一樣(參照 3.3.1 節),每一種服務資料型別都對應一個我們必須包含的相關 C++標頭檔案: 
        #include <package_name/type_name.h>
(2)建立客戶端物件 

8.4 伺服器程式 
(1)和訂閱話題的程式碼非常相似。除了名稱上的區別,必須建立一個 ros::ServiceServer 來代替 ros::Subscriber,
        唯一的區別在於伺服器端可以通過一個響應物件和一個表明成功與否的布林變數給客戶端回傳資料。 
編寫服務的回撥函式 :
        
8.5 展望 

第 9 章 訊息錄製與回放
通過 rosbag,我們能夠將釋出在一個或者多個話 題上的訊息錄製到一個包檔案中,然後可以回放這些訊息,重現相似的執行過程。
9.1 錄製與回放包檔案
(1)術語包檔案(bag files)是指用於儲存帶時間戳的 ROS 訊息的 特殊格式檔案。rosbag 命令列工具可以用來錄製和回放包檔案。
錄製包檔案 : rosbag record -O filename.bag topic-names 
記錄當前釋出的所有話題的訊息 : rosbag record -a 
當完成包檔案錄製時,使用 Ctrl-C 停止 rosbag
回放包檔案 : rosbag play filename.bag
檢查檔案包 : rosbag info filename.bag 
明服務呼叫並沒有被錄製到包檔案裡面。
9.2 示例:正方形運動軌跡的包檔案 
(1)
9.3 啟動檔案裡面的包檔案
(1)rosrun rosbag record -O filename.bag topic-names
       rosrun rosbag play filename.bag 
通過這兩個可執行檔案可以很容易地將包檔案 作為啟動檔案的一部分,方法是包含適當的節點元素。
9.4 展望 
    對如何在 C ++程式使用包檔案沒有做任何討論。事實上,確實存在一個用於讀取和寫入包檔案的 API,只有一些非常特殊的應用程式才需要這個 API。
第 10 章 總結
    為了在某網路中的多臺計算機上執行ROS,需要在網路層和 ROS層分別進行配置。其中,網路層的配置是確保計算機之間能夠互相通訊。而ROS層的配置是確保所有節點都能與節點管理器通訊。
rviz:非常強大的圖形介面工具。可以通過訂閱使用者選擇的話題來顯示機器人內部的各種資訊,便於機器人的開發和除錯。
tf:使用 tf 工具來管理多個座標系。很多訊息型別均 包含一個 frame_id域來標識訊息中資料所在的座標系。
tftf:是幫助節點來完成座標轉換 。某個座標從一個座標系到另一個座標系的變換矩陣。
使用Gazebo模擬:它是一個高保真的機器人模擬器 ,Gazebo中用模擬機器人測試後的程式碼可以無縫移植到實體機器人。