0
Help us understand the problem. What are the problem?

posted at

updated at

ROS2の最小構成publisher:初級 -ROS1 style-

ROS2関係トップページへ
ROS2レクチャー:初級 -ROS1 style-

【前:ROS2における時間管理・Rate系とTimer系
【次:ROS2独自メッセージの作成

publisherプログラムを作成する.
メッセージ受信者はここで作成したsubscriberプログラムを使用する.

更新:2020/07/15

Foxy Fitzroy用に更新.主に以下の点について加筆・修正.

  • std_msgsの廃止に伴うexample_interfacesの利用
  • create_subscriptionの引数の変更への対応

準備

terminal
$ cd ~/ros2_studies_ws/
$ ros2 pkg create minimal_publisher_ros1_like --dependencies rclcpp example_interfaces

ROS風publisher

作成物:

  • src/ros1_like_main.cpp

プログラム

src/ros1_like_main.cpp
#include <rclcpp/rclcpp.hpp>
#include <rclcpp/qos.hpp>
#include <example_interfaces/msg/string.hpp>
#include <chrono>

int main(int argc, char * argv[]){
  using namespace std::chrono_literals;

  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("minimal_publisher");
  auto publisher = node->create_publisher<example_interfaces::msg::String>("topic_test",rclcpp::QoS(10));
  auto message = std::make_shared<example_interfaces::msg::String>();
  auto pub_counter=0;

  rclcpp::WallRate loop_rate(1s);

  while(rclcpp::ok()){
    message->data = "hello " + std::to_string(pub_counter++);
    RCLCPP_INFO(node->get_logger(),"Pub:%s",message->data.c_str());
    publisher->publish(*message);
    loop_rate.sleep();
  }
  rclcpp::shutdown();
  return 0;
}

概要

publisherはメッセージ発信者である.代表的な使用シーンは「定期的にセンサ値を取得して処理をする他のnodeに発信」などである.そのため,例としてRate系を使用した定期的なメッセージ発信を行う.ここでは単なる文字列の発信を行っている.Timer系でも同様の実装は可.
spin系関数を用いていないが,publish関数は即時メッセージを発信するもので,callback関数によって実行されるものではない.よってspin系関数は不必要.詳しくはこちら

説明

11,12行目でnodeを作成し,そのnodeがpublisherとして動くように設定.メッセージを発信先の識別名・トピック名を12行目の引数で指定(topic_test).第二引数はメッセージキューの数.何個までメッセージ数を保持しておくか.
13,14行目で発信するメッセージの変数を宣言.メッセージはROSのStringクラスなので,make_sharedでsharedポインタとして実体化している.

今回はTimer系ではなくRate系を使用していてsleep関数で制御しているため,18行目から始まるwhileで定期的にメッセージ発信を行っている.ただ,ROS2のコーディングとしては非推奨(定期実行をROSではなくC++が制御しているので).

19行目で発信するメッセージに値を代入しており,21行目で発信している.

細かい話として19行目のstd::to_string関数がある.message->dataはString型で,+演算子で文字列の結合をしようとしている.ここでpub_counterは整数値なので文字列に変換するためにstd::to_string関数を使っている.

package.xmlとCMakeLists

以下は重要な部分のみを抜粋.

package.xml

package.xml
<package format="3">
  <depend>rclcpp</depend>
  <depend>example_interfaces</depend>

CMakeLists.txt

CmakeLists.txt
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)

add_executable(ros1_like_publisher_test
  src/ros1_like_main.cpp
)
ament_target_dependencies(ros1_like_publisher_test
  rclcpp
  example_interfaces
)

install(TARGETS
  ros1_like_publisher_test
  DESTINATION lib/${PROJECT_NAME}
)

ビルド・実行

publisherはここで作成したもの,subscriberはここで作成したものを使用.

ビルド

terminal
$ cd ~/ros2_studies_ws/
$ colcon build --symlink-install --packages-up-to minimal_publisher_ros1_like
$ . install/local_setup.bash

実行

publisher用のterminalとsubscriber用のterminalを起動.

terminal1
$ cd ~/ros2_studies_ws/
$ . install/local_setup.bash
$ ros2 run minimal_publisher_ros1_like ros1_like_publisher_test
terminal1
$ cd ~/ros2_studies_ws/
$ . install/local_setup.bash
$ ros2 run minimal_subscriber_ros1_like callback_subscriber_test


バグ?(2019/4/23現在:dashing)ros1_like_publisherを実行するとわかるが,最初の一回目のメッセージ発信(publish)が行われない.仕様?バグ?

【前:ROS2における時間管理・Rate系とTimer系
【次:ROS2独自メッセージの作成

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?