外部からパラメータの値を受け取れるようなROSノードの書き方について説明します.
前のページで作成したpublisherにパラメータを受け取る記述を追加して,送信する文字列をパラメータで指定可能なようにしましょう.
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char **argv)
{
ros::init(argc, argv, "my_simple_publisher");
ros::NodeHandle nh;
// added
ros::NodeHandle pnh("~");
std::string pub_string = "hello world";
pnh.getParam("pub_string", pub_string);
ros::Publisher simple_pub = nh.advertise<std_msgs::String>("my_topic", 1);
ros::Rate loop_rate(10);
while (ros::ok())
{
std_msgs::String msg;
msg.data = pub_string;
ROS_INFO("publish: %s", msg.data.c_str());
simple_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
各行の意味
ros::NodeHandle pnh("~");
std::string pub_string = "hello world";
pnh.getParam("pub_string", pub_string);
- パラメータを受け取るための新たなノードハンドルの作成
- パラメータで受け取る値を格納する変数の定義.デフォルト値を与えておくとよい.
- getParamで""で囲まれた名前のパラメータを受け取り,第二引数に渡した変数に格納する.
- このコードの場合,もし"pub_string"というパラメータが外部から与えられなければ,pub_string変数に値の代入は行われない.よってデフォルト値を入れていないと何が起こるかわからないためデフォルト値を入れている.
- getParamは値を受け取れた場合true,受け取れなかった場合falseを返すので,その結果を用いて例外処理を挟むことも可能.(参考)
catkin build
roscore
したうえで別ターミナルで
rosrun my_ros_tutorial my_simple_publisher _pub_string:="hoge"
すると出力が以下のようになるはず
decwest@DESKTOP-PRFDO60:~/catkin_ws$ rosrun my_ros_tutorial my_simple_publisher _pub_string:="hoge"
[ INFO] [1632634919.572324700]: publish: hoge
[ INFO] [1632634919.672427100]: publish: hoge
[ INFO] [1632634919.772410900]: publish: hoge
[ INFO] [1632634919.872397500]: publish: hoge
[ INFO] [1632634919.972398900]: publish: hoge
上記のpublisherのループ周波数をパラメータで変更できるようにしよう
ROSはパラメータをパラメータサーバというもので管理しています.パラメータの値と名前が保存されていて,適宜パラメータの名前と値をサーバーに登録したり,読み出したりします. 興味のある方はこのROS Wikiを見てください.
パラメータの登録にはコマンドラインツール,rosrunのオプション(今回扱ったやつ),launchファイルでの指定(次のページで扱う)等があります.
ROSのパラメータは基本的には静的で,一度登録したら値の書き換えができません.しかし,dynamic reconfigureというものを用いれば途中で値の変更が可能な動的なパラメータを作成することができます. こちらがわかりやすいです.
興味のある方はこのROS Wikiを見てください.
今回,以下のようにしてノードにパラメータを渡したと思います.
rosrun my_ros_tutorial my_simple_publisher _pub_string:="hoge"
ここで,_の数によって何の名前に関するものを設定するのかが変わります.
-
__(2個)
ノード名に関する変更になります.
__name:=(変更後のnodeの名前)
とします. -
_(1個)
パラメータに関する変更になります.
_(値を変更したいパラメータ名):=(パラメータの値)
とします. なお,パラメータ名は勝手にプライベートな名前空間になるので,ノード側は"~"で初期化したノードハンドルで受け取れます. -
(0個)
トピック名に関する変更になります.
(元のトピック名):=(変更後のトピック名)
とします.