【ROS2関係トップページへ】
【ROS2レクチャー:初級 -ROS1 style-】
【前:ROS2における時間管理・Rate系とTimer系】
【次:ROS2独自メッセージの作成】
publisherプログラムを作成する.
メッセージ受信者はここで作成したsubscriberプログラムを使用する.
更新:2020/07/15
Foxy Fitzroy用に更新.主に以下の点について加筆・修正.
- std_msgsの廃止に伴うexample_interfacesの利用
- create_subscriptionの引数の変更への対応
準備
$ cd ~/ros2_studies_ws/
$ ros2 pkg create minimal_publisher_ros1_like --dependencies rclcpp example_interfaces
ROS風publisher
作成物:
- 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 format="3">
<depend>rclcpp</depend>
<depend>example_interfaces</depend>
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はここで作成したものを使用.
ビルド
$ cd ~/ros2_studies_ws/
$ colcon build --symlink-install --packages-up-to minimal_publisher_ros1_like
$ . install/local_setup.bash
実行
publisher用のterminalとsubscriber用のterminalを起動.
$ cd ~/ros2_studies_ws/
$ . install/local_setup.bash
$ ros2 run minimal_publisher_ros1_like ros1_like_publisher_test
$ cd ~/ros2_studies_ws/
$ . install/local_setup.bash
$ ros2 run minimal_subscriber_ros1_like callback_subscriber_test