1. 程式人生 > >ROS入門_1.13 建立ROS訊息和ROS服務

ROS入門_1.13 建立ROS訊息和ROS服務

1. 訊息(msg)和服務(srv)介紹

  • 訊息(msg): msg檔案就是一個描述ROS中所使用訊息型別的簡單文字。它們會被用來生成不同語言的原始碼。

  • 服務(srv): 一個srv檔案描述一項服務。它包含兩個部分:請求和響應。

msg檔案存放在package的msg目錄下,srv檔案則存放在srv目錄下。

msg檔案實際上就是每行宣告一個數據型別和變數名。可以使用的資料型別如下:

  • int8, int16, int32, int64 (plus uint*)
  • float32, float64
  • string
  • time, duration
  • other msg files
  • variable-length array[] and fixed-length array[C]

在ROS中有一個特殊的資料型別:Header,它含有時間戳和座標系資訊。在msg檔案的第一行經常可以看到Header header的宣告.

下面是一個msg檔案的樣例,它使用了Header,string,和其他另外兩個訊息型別。

  Header header
  string child_frame_id
  geometry_msgs/PoseWithCovariance pose
  geometry_msgs/TwistWithCovariance twist

srv檔案分為請求和響應兩部分,由'---'分隔。下面是srv的一個樣例:

int64 A
int64 B
---
int64 Sum

其中 A 和 B 是請求, 而Sum 是響應。

2. 使用 msg

2.1 建立一個 msg

下面,我們將在之前建立的package裡定義新的訊息。

$ cd ~/catkin_ws/src/beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg

上面是最簡單的例子——在.msg檔案中只有一行資料。當然,你可以仿造上面的形式多增加幾行以得到更為複雜的訊息:

string first_name
string last_name
uint8 age
uint32 score

接下來,還有關鍵的一步:我們要確保msg檔案被轉換成為C++,Python和其他語言的原始碼:

檢視package.xml, 確保它包含一下兩條語句:

  <build_depend>message_generation</build_depend>
  <run_depend>message_runtime</run_depend>

如果沒有,新增進去。 注意,在構建的時候,我們只需要"message_generation"。然而,在執行的時候,我們只需要"message_runtime"。

在你最喜愛的編輯器中開啟CMakeLists.txt檔案(可以參考前邊的教程rosed).

在 CMakeLists.txt檔案中,利用find_packag函式,增加對message_generation的依賴,這樣就可以生成訊息了。 你可以直接在COMPONENTS的列表裡增加message_generation,就像這樣:

# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)

有時候你會發現,即使你沒有呼叫find_package,你也可以編譯通過。這是因為catkin把你所有的package都整合在一起,因此,如果其他的package呼叫了find_package,你的package的依賴就會是同樣的配置。但是,在你單獨編譯時,忘記呼叫find_package會很容易出錯。

同樣,你需要確保你設定了執行依賴:

catkin_package(
  ...
  CATKIN_DEPENDS message_runtime ...
  ...)

找到如下程式碼塊:

# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

去掉註釋符號#,用你的.msg檔案替代Message*.msg,就像下邊這樣:

add_message_files(
  FILES
  Num.msg
)

手動新增.msg檔案後,我們要確保CMake知道在什麼時候重新配置我們的project。 確保添加了如下程式碼:

generate_messages()

現在,你可以生成自己的訊息原始碼了。如果你想立即實現,那麼就跳過以下部分,到Common step for msg and srv.

2.2 使用 rosmsg

以上就是你建立訊息的所有步驟。下面通過rosmsg show命令,檢查ROS是否能夠識訊息。

使用方法:

$ rosmsg show [message type]

樣例:

$ rosmsg show beginner_tutorials/Num

你將會看到:

  • int64 num

在上邊的樣例中,訊息型別包含兩部分:

  • beginner_tutorials -- 訊息所在的package

  • Num -- 訊息名Num.

如果你忘記了訊息所在的package,你也可以省略掉package名。輸入:

$ rosmsg show Num

你將會看到:

  • [beginner_tutorials/Num]:
    int64 num

=======================================問題解決================================================

進行到此處,一般會提示出現此問題:

Unable to load msg [beginner_tutorials/Num]:Cannot locate message [Num]: unknown package[beginner_tutorials] on search path [{'rosconsole':['/opt/ros/hydro/share/rosconsole/msg'],'catkin':['/opt/ros/hydro/share/catkin/msg'],

仔細觀察錯誤提示可以知道,錯誤為:無法定位訊息,在搜尋路徑上是未知的功能包,根據提示的搜尋路徑可以發現,系統搜尋的均為opt/ros 下的路徑,這是預設路徑,當前的工作空間不符,聯想第一節的環境配置:

1.6 環境設定

如果每次開啟一個新的終端時ROS環境變數都能夠自動配置好(即新增到bash會話中),那將會方便得多:

echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
source ~/.bashrc

如果你安裝有多個ROS版本, ~/.bashrc 必須只能 source 你當前使用版本所對應的 setup.bash

如果你只想改變當前終端下的環境變數,你可以執行命令:

source /opt/ros/indigo/setup.bash

而當前我們是在catkin_ws工作空間下,因此僅需source一下當前工作空間的環境變數即可,執行命令: source ~catkin_ws/devel/setup.bash 即可解決該問題。 另外,修改完CMake檔案後想知道有沒有錯誤,提前編譯一下即可: cd ~/catkin_ws catkin_make =====================================================================================================

3. 使用 srv

3.1 建立一個srv

在剛剛那個package中建立一個服務:

$ roscd beginner_tutorials
$ mkdir srv

這次我們不再手動建立服務,而是從其他的package中複製一個服務。 roscp是一個很實用的命令列工具,它實現了將檔案從一個package複製到另外一個package的功能。

使用方法:

$ roscp [package_name] [file_to_copy_path] [copy_path]

現在我們可以從rospy_tutorials package中複製一個服務檔案了:

$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv

還有很關鍵的一步:我們要確保srv檔案被轉換成C++,Python和其他語言的原始碼。

現在認為,你已經如前邊所介紹的,在CMakeLists.txt檔案中增加了對message_generation的依賴。:

# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)

(對的, message_generation 對msgsrv都起作用)

同樣,跟msg檔案類似,你也需要在package.xml檔案中做一些修改。檢視上邊的說明,增加額外的依賴項。

刪掉#,去除對下邊語句的註釋:

# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

用你自己的srv檔名替換掉那些Service*.srv檔案:

add_service_files(
  FILES
  AddTwoInts.srv
)

現在,你可以生成自己的服務原始碼了。如果你想立即實現,那麼就跳過以下部分,到Common step for msg and srv.

3.2 使用 rossrv

以上就是建立一個服務所需的所有步驟。下面通過rosmsg show命令,檢查ROS是否能夠識該服務。

使用方法:

$ rossrv show <service type>

例子:

$ rossrv show beginner_tutorials/AddTwoInts

你將會看到:

  • int64 a
    int64 b
    ---
    int64 sum

rosmsg類似, 你也可以不指定具體的package名來查詢服務檔案:

$ rossrv show AddTwoInts
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

4 msg和srv都需要的步驟

接下來,在CMakeLists.txt中找到如下部分:

# generate_messages(
#   DEPENDENCIES
# #  std_msgs  # Or other packages containing msgs
# )

去掉註釋並附加上所有你訊息檔案所依賴的那些含有.msg檔案的package(這個例子是依賴std_msgs,不要新增roscpp,rospy),結果如下:

generate_messages(
  DEPENDENCIES
  std_msgs
)

由於增加了新的訊息,所以我們需要重新編譯我們的package:

# In your catkin workspace
$ cd ../..
$ catkin_make
$ cd -

所有在msg路徑下的.msg檔案都將轉換為ROS所支援語言的原始碼。生成的C++標頭檔案將會放置在~/catkin_ws/devel/include/beginner_tutorials/。 Python指令碼語言會在 ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg 目錄下建立。 lisp檔案會出現在 ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/ 路徑下.

5. 獲得幫助

我們已經接觸到不少的ROS工具了。有時候很難記住他們所需要的引數。還好大多數ROS工具都提供了幫助。

輸入:

$ rosmsg -h
  • 你可以看到一系列的rosmsg子命令.

    Commands:
      rosmsg show Show message description
      rosmsg users  Find files that use message
      rosmsg md5  Display message md5sum
      rosmsg package  List messages in a package
      rosmsg packages List packages that contain messages

同樣你也可以獲得子命令的幫助:

$ rosmsg show -h
  • 這會現實rosmsg show 所需的引數:
  • Usage: rosmsg show [options] <message type>
    
    Options:
      -h, --help  show this help message and exit
      -r, --raw   show raw message text, including comments

6. 回顧

總結一下到目前為止我們接觸過的一些命令:

  • rospack = ros+pack(age) : provides information related to ROS packages
  • rosstack = ros+stack : provides information related to ROS stacks
  • roscd = ros+cd : changes directory to a ROS package or stack

  • rosls = ros+ls : lists files in a ROS package

  • roscp = ros+cp : copies files from/to a ROS package

  • rosmsg = ros+msg : provides information related to ROS message definitions
  • rossrv = ros+srv : provides information related to ROS service definitions
  • rosmake = ros+make : makes (compiles) a ROS package