32
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ROS講座09 ROSメッセージ(とarray型の使い方)

Last updated at Posted at 2018-05-15

環境

この記事は以下の環境で動いています。

項目
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」で説明した例を見てみましょう。

baic_lecture/basic_simple_talker.cpp(再掲)
#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

basic_lecture/src/basic_array_talker.cpp
#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

basic_lecture/src/basic_array_listener.cpp
#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つを付け加えます。

basic_lecture/CMakeLists.txt
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

basic_lecture/launch/pubsub_array.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している様子がわかります。

launchの結果
[ 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++のソースファイルの初めにインクルードをする必要があります。

xxx.cppの一部
#include <geometry_msgs/Twist.h>

CmakeList

以下のようにfind_packageに使うmsgの属するROS packageを追加します。

CMakeList.txtの一部
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  geometry_msgs #この行を追加
)

packge.xml

以下のように使うmsgの属するROS packageを追加します。これは追加しなくてもビルド&実行はできてしまいますが、作法として必要です。

package.xmlの一部
<build_depend>std_msgs</build_depend>
<exec_depend>std_msgs</exec_depend>

#rosmsgコマンド
メッセージの中身を調べることができます。05 ROStoolsを参照

#参考
型対応表:http://wiki.ros.org/msg

目次ページへのリンク

ROS講座の目次へのリンク

32
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?