環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 20.04 |
ROS | Noetic |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
#概要
ROSノード間ではROSメッセージに基づいた型で通信が行われます。様々なROSメッセージ型がデフォルトで用意されていますが、自分でオリジナルのROSメッセージを作りたくなることがあります。自分で定義したROSメッセージ自体の作成、そのROSメッセージを使ったROSノードの作成を解説していきます。
流れ
- カスタムROSメッセージの定義:ROSパッケージを作りmsgファイルの定義とビルドの設定を追加する。
- カスタムROSメッセージ使用:msgファイルをincludeして使います。
カスタムmsgを定義するROSパッケージと使うROSパッケージは別々の物にすることが推奨されてます。カスタムROSメッセージを定義するROSパッケージは***_msgs
という名前にすることが推奨されています。
カスタムROSメッセージの定義
ここではros_lecture_msgs
というROSパッケージを作成します。
msgファイル
パッケージ直下のmsg
ディレクトリの中にカスタムROSメッセージを定義するファイルを置きます。例えば以下のようなものになります。この時に要素として使えるのは基本型(以下のstringやint32)とROSメッセージの型(例えばgeometry_msgs/Pose等)のみです。
今回は以下のような型を定義します。カスタムROSメッセージの名前はCustomRosMsgのようにパスカルケースで書くのが一般的です。
ここで書けるのはこの記事の下に書いた基本型か他のROSメッセージ型になります(例えばgeometry_msgs/Twist型を持ちたいならgeometry_msgs/Twist target_twist
の様に書きます)。
string word
int32 number
CMakeListの設定
まずfind packageにメッセージをビルドするためのmessage_generationとmsgファイルで依存するROSパッケージを記述します。(厳密にはCostom.msgはstd_msgsには依存しませんが説明のために書いておきます。)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs # msgファイルが依存するpkgを追加
message_generation #この行を追加
)
またcatkin_packageに必要なパッケージを加えます。#
でコメントアウトしているものの#
を外して、以下のようにmessage_runtime
を追加します。
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES ros_lecture
# CATKIN_DEPENDS roscpp rospy std_msgs
# DEPENDS system_lib
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES ros_lecture
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
後のほうの## Generate messages in the 'msg' folder
とある下のブロックを#
のコメントウアウトを外して、以下のようにFILES
と自分で作ったmsgファイルを書きます
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
add_message_files(
FILES
Custom.msg
)
generate_messageのブロックのコメントアウトを解除します。また上記のカスタムmsgの定義の時に使ったROSの型が所属するROSパッケージ(今回の例ではstd_msgs)をここに追加します。今回はstd_msgs以外の内容の追加は必要ありません。
# generate_messages(
# DEPENDENCIES
# std_msgs
# )
generate_messages(
DEPENDENCIES
std_msgs
)
package.xmlの設定
message_generationへの依存を追加します。
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
コメントアウトを外して上の記述を復活させます。
昔は<run_depend>
だったみたいですが今は<exec_depend>
を使いましょう。
(package.xmlのver1、ver2の違いです)
ビルド
cd ~/catkin_ws
catkin build
カスタムROSメッセージの確認
カスタムROSメッセージを確認するにはrosmsg
コマンドを使用します。
rosmsg show ros_lecture_msgs/Custom
以下のように.msgファイルの中身が表示されます。
string word
int32 number
カスタムROSメッセージの使用
カスタムROSメッセージを定義したros_lecture_msgs
とは別のbasic_lecture
の中のノードで使用していきます。
カスタムROSメッセージを使用するROSノード
#include <ros/ros.h>
#include <ros_lecture_msgs/Custom.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "basic_cmsg_talker");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<ros_lecture_msgs::Custom>("chatter", 10);
ros::Rate loop_rate(1);
while (ros::ok())
{
ros_lecture_msgs::Custom data;
data.word = "hello";
data.number = 10;
pub.publish(data);
ros::spinOnce();
loop_rate.sleep();
}
}
カスタムメッセージは#include <ROSパッケージ名/カスタムメッセージ名.h>
のようにincludeします。
CmakeListの設定
まずfind_package
の中でカスタムROSメッセージの定義を行ったROSパッケージ(今回の例ではros_lecture_msgs
)をここに追加します。
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
ros_lecture_msgs #この行を追加
)
次にROSノードのビルドの設定です。いつもと違うのは3行目のadd_dependencies()
です。上記でincludeしているROSメッセージのヘッダファイルはビルド時に生成されます。この行はそのビルド生成物を利用するための依存の記述です。今回のように同時にビルドする時に必要となります。
add_executable(basic_cmsg_talker src/basic_cmsg_talker.cpp)
add_dependencies(basic_cmsg_talker ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(basic_cmsg_talker
${catkin_LIBRARIES}
)
package.xmlの設定
カスタムROSメッセージが含まれるROSパッケージへの依存をpackage.xmlへの記述します。
<build_depend>ros_lecture_msgs</build_depend>
ビルド
cd ~/catkin_ws
catkin build
実行
各ターミナルごとに実行前にsource ~/catkin_ws/devel/setup.bash
を実行する必要があります。
roscore
rosrun basic_lecture basic_cmsg_talker
rostopic echo /chatter
このように実行すると3つ目のターミナルから以下のような表示が出てきて、カスタムメッセージがpublishされていることがわかります。
word: "hello"
number: 10
---
word: "hello"
number: 10
---
word: "hello"
number: 10
---
(参考)ROSの基本型
rosのmsgファイルで記述できる型は以下の基本型か他のrosmsgになります。つまりROSの型は必ず以下の型かその組み合わせになります。
ROSの基本型 | C++対応 | python対応 |
---|---|---|
bool | uint8_t | bool |
int8 | int8_t | int |
uint8 | uint8_t | int |
int16 | int16_t | int |
uint16 | uint16_t | int |
int32 | int32_t | int |
uint32 | uint32_t | int |
int64 | int64_t | int(long) |
uint64 | uint64_t | int(long) |
float32 | float | float |
float64 | double | float |
string | std::string | byte(str) |
time | ros::Time | rospy.Time |
duration | ros::Duration | rospy.Duraiton |
#参照
ROSwiki: msgを作る
カスタムmsgを定義する
カスタムmsgの依存