環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
ROSのpub sub通信ではROSで定義されている型で通信を行います。Float32やInt32などの基本的な型が標準で組み込まれています。これらの使い方について説明します。
基本的な使い方
「ROS講座03 Pub & Sub」で説明した例を見てみましょう。
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "basic_simple_talker");
ros::NodeHandle nh;
ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 10);
ros::Rate loop_rate(10);
while (ros::ok())
{
std_msgs::String msg;
msg.data = "hello world!";
ROS_INFO("publish: %s", msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
msgが絡むのは2行目と8行目です。2行目の#include <std_msgs/String.h>
でmsg型をインクルードしています。intやstringという基本型でもすべてincludeが必要です。8行目でもpublisherの設定でincludeした型を使っています。型名はstd_msgs::String
のように(パッケージ名)::(型名)というヘッダファイルを指定します。すべてのROSmsgは何らかのパッケージに属しています。
またstd_msgs::String msg;
と宣言したときにmsg
自体は文字列のデータではなく。その中の要素msg.data
が文字列のデータになります。
配列型の使い方
例えばfloatの配列を送るにはstd_msgs/Float32MultiArray
という型を使用します。リストを含む型の使い方を見てみます。
ソースコード
publish
#include <ros/ros.h>
#include <std_msgs/Float32MultiArray.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "basic_array_talker");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<std_msgs::Float32MultiArray>("array", 10);
ros::Rate loop_rate(1);
while (ros::ok())
{
std_msgs::Float32MultiArray array;
array.data.resize(4);
array.data[0] = 0.0;
array.data[1] = 1.0;
array.data[2] = 2.0;
array.data[3] = 3.0;
pub.publish(array);
ROS_INFO("I published array!");
ros::spinOnce();
loop_rate.sleep();
}
}
#include "std_msgs/Float32MultiArray.h"
でインクルード。Float32以外でもほぼすべての型で*****MultiArray
という型が定義されています。配列はstd::vectorとして扱えます。初期化時にはarray.data
は空の(=sizeが0の)std::vector
です。そのためにまず配列のサイズをarray.data.resize(4)
で決定します。後はarray.data[0]
のようにインデックスでアクセスします。
Subscribe
#include <ros/ros.h>
#include <std_msgs/Float32MultiArray.h>
void chatterCallback(const std_msgs::Float32MultiArray& msg)
{
int num = msg.data.size();
ROS_INFO("I susclibed [%i]", num);
for (int i = 0; i < num; i++)
{
ROS_INFO("[%i]:%f", i, msg.data[i]);
}
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "basic_array_listener");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("array", 1000, chatterCallback);
ros::spin();
return 0;
}
msg.data.size()
で配列のサイズを取得できます。
CmakeList
以下の4つを付け加えます。
add_executable(basic_array_talker src/basic_array_talker.cpp)
add_executable(basic_array_listener src/basic_array_listener.cpp)
target_link_libraries(basic_array_talker
${catkin_LIBRARIES}
)
target_link_libraries(basic_array_listener
${catkin_LIBRARIES}
)
launch
<launch>
<node name="talker" pkg="basic_lecture" type="basic_array_talker" output="screen"/>
<node name="listener" pkg="basic_lecture" type="basic_array_listener" output="screen"/>
</launch>
ビルド
cd catkin_ws
catkin build
実行
roslaunch basic_lecture pubsub_array.launch
実行すると以下のような表示が流れてサイズが4の配列をpublish、subscribeしている様子がわかります。
[ INFO] [1534072121.442238388]: I susclibed [4]
[ INFO] [1534072121.442407677]: [0]:0.000000
[ INFO] [1534072121.442449432]: [1]:1.000000
[ INFO] [1534072121.442472959]: [2]:2.000000
[ INFO] [1534072121.442494261]: [3]:3.000000
[ INFO] [1534072122.440483018]: I published array!
[ INFO] [1534072122.441309532]: I susclibed [4]
[ INFO] [1534072122.441474609]: [0]:0.000000
[ INFO] [1534072122.441571959]: [1]:1.000000
[ INFO] [1534072122.441607914]: [2]:2.000000
[ INFO] [1534072122.441794112]: [3]:3.000000
別のパッケージの型を使用
上記の例ではstd_msgs::String
を使いました。std_msgs
はリンクされているので、上記のincludeだけで使えるのですが、ほかのパッケージのmsgを使おうとすると、そのパッケージをリンクする作業が必要です。例えばgeometry_msgs/Twist
という型を使う場合は3つのファイルで記述が必要です。
ソースファイル
以下のようにc++のソースファイルの初めにインクルードをする必要があります。
#include <geometry_msgs/Twist.h>
CmakeList
以下のようにfind_package
に使うmsgの属するROS packageを追加します。
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
geometry_msgs #この行を追加
)
packge.xml
以下のように使うmsgの属するROS packageを追加します。これは追加しなくてもビルド&実行はできてしまいますが、作法として必要です。
<build_depend>std_msgs</build_depend>
<exec_depend>std_msgs</exec_depend>
#rosmsgコマンド
メッセージの中身を調べることができます。05 ROStoolsを参照
#参考
型対応表:http://wiki.ros.org/msg