LoginSignup
12
2

More than 1 year has passed since last update.

ROS コマンドラインツール シェル芸

Last updated at Posted at 2021-12-07

ROS のコマンドラインツールでシェル芸をしました。

ROS のコマンドラインツールをシェル芸で使う

みなさん ROS のコマンドラインツールは毎日使ってると思います。
rostopic, rosnode, rosparam, rosbag, rosservice... どれも便利です。
しかし、コマンドラインツールなんだからシェル芸で使っても良さそうなのに、
あんまりそういう使い方はされてない感じがしますね。
出力を grep するくらいでしょうか。
今回は ROS のコマンドラインツールを使ってシェル芸をやってみました。

やりたいこと

$ rostopic echo|なんかコマンド|rostopic pub

という感じで、pub されているメッセージを標準出力に持ってきて、それを何か加工して、
rostopic pub に入力して pub/sub の世界に戻してやる、
みたいなことができたら面白そうなのでやってみます。

できるの?

rostopic echo された文字列を加工するところまでは普通にできそうですが、
rostopic pub にデータをパイプで渡して pub することってできるんでしょうか?
試してみましょう。
ターミナルを3つ立てて

term1
$ rostopic pub hoge std_msgs/String "data: 'fuga'"
term2
$ rostopic echo hoge|rostopic pub piyo std_msgs/String
term3
$ rostopic echo piyo

すると、term3 でdata: "fuga"が受信できます。
つまり、term2 では、rostopic echo で pub/sub の空間の hoge トピックからメッセージを受信して、
標準入出力の空間に持ってきて、それを rostopic pub で
pub/sub の空間に戻して piyo トピックに流し込むことができているわけです。
こうなるともうやりたいことはできそうな感じですね。

sed で加工

term2 のコマンドを止めて、受信したメッセージをそのまま戻すのではなく、
ちょっと加工して戻してみましょう。

term2a
$ rostopic echo hoge|sed 's/g/n/g'|rostopic pub piyo std_msgs/String

sed で g を n に置換してみました。
これで term3 で data: "funa" が受信できるはずですね。
ところが term3 では何も受信されません。
term2 で rostopic pub に渡さずに

term2b
$ rostopic echo hoge|sed 's/g/n/g'

とすると、data: "funa" が繰り返し出力されるのに、不思議ですね。
これは sed がパイプラインへの出力をバッファするからです。

term2c
rostopic echo hoge|sed -u 's/g/n/g'|rostopic pub piyo std_msgs/String

として、バッファせずに頻繁に出力するようにすると、
term3 で data: "funa" が受信できました。

亀を動かす

文字列をいじってるだけでは ROS らしくないので、亀でも動かしましょう。
何かセンサーの入力があって、それを処理して、亀が動くというのが ROS らしくてよさそうです。
ウェブカメラの Image メッセージを echo して、それをシェル芸で処理して、
Twist メッセージを作って、亀の目標速度として pub しましょう。

term4
$ rosrun usb_cam usb_cam_node
term5
$ rosrun turtlesim turtlesim_node

して、ウェブカメラの Image メッセージを pub、亀の目標速度の Twist メッセージを sub します。
そして、この間をつなぐシェル芸が

term6
$ rostopic echo /usb_cam/image_raw|tr -d '[,]'|awk 'BEGIN{c=0}$1=="width:"{width=$2}$1=="height:"{height=$2}$1=="step:"{step=$2}$1=="data:"{if(c%3==0){a=0;b=0;for(i=2;i<=NF;i=i+30){if((i-2)%step<step/2){a+=$i}else{b+=$i}}{printf "linear:\n  x: 0.1\n  y: 0.0\n  z: 0.0\nangular:\n  x: 0.0\n  y: 0.0\n  z: "(a>b?"0.1":"-0.1")"\n---\n";fflush()}}c++}'|rostopic pub /turtle1/cmd_vel geometry_msgs/Twist

のようになります。rostopic echoから````rostopic pub```まで
パイプラインで繋がったワンライナーになっています。
動かすと

こんな感じになります。 これで、やりたかったことができました。

経緯

なんでこういうことをやったかというと、以前から

ということを考えていたんですが、これに対して[@ryuichiueda](https://twitter.com/ryuichiueda)先生から という反応があり「えっできるの?」と思ってやってみたらできました。
12
2
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
12
2