LoginSignup
7
7

More than 5 years have passed since last update.

[ROS自動起動] robot_upstart vs 自分で書く

Posted at

はじめに

ロボット制御ROSを自動起動する必要があり、ROSパッケージのrobot_upstart
ROSを自動起動するを参考に自分で書く、2パターンでトライしてみましたのでそのメモです。
結論としては、使うデバイスやLaunchファイルの数が少ないシンプルな構成の時はrobot_upstart、デバイスやPermissionが複雑な構成の時は自分で書いた方が幸せになれるように思います。

環境

  • Ubuntu 18.04 (JetPack 4.1.1 Developer Preview)
  • ROS Melodic Morenia
  • Jetson AGX Xavier

比較

どちらも、実施していることはサービスの作成です。なので、robot_upstart特有のトレードオフというよりは「ツールを使うか自作するか」という種の問題に一般的な長所短所があります。

長所 短所
robot_upstart - 導入と使用方法が簡便
- Linux特有の知識はほぼ不要
- 自動化されすぎててデバッグが面倒
自分で書く - 柔軟性が高い
- デバッグが容易
- Linux (Ubuntu)の知識がある程度必要

robot_upstartを使ってみた

robot_upstartの導入は簡単です。わずか一行。

sudo apt-get install ros-<distro>-robot-upstart

次に、自動で起動させたいlaunch fileを登録します。これも簡単。

rosrun robot_upstart install <your_package_name>/launch/<your_launch_file>.launch

これだけで、次回起動時には登録したlaunchファイルが起動するようになります。

robot_upstartのつまづきポイント

ログの出力先がドキュメントと異なる。

たぶんドキュメントが更新されてないだけだと思いますが、私の環境ではドキュメントに書いてある/var/log/upstartではなく/var/log/syslogに出力されていました。

環境変数の設定

setuidgidで直接roslaunchを叩いているためか.bash_profile.bashrcが読み込まれないので、必要な環境変数が無かったり意図しない値になってたりすることがあります。
こちらにあるように、必要な設定を書いた.robotrcなどの適当なファイルを作って/opt/ros/<distro>/setup.bash<your_catkin_ws>/devel/setup.bashからsource path/to/your/fileしてあげるのが良いようです。

【参考】
ログインシェルとインタラクティブシェルと~/.bashrc達の関係
How to reference environmental variables inside an upstart installed launch file

CUDAがエラーになる(未解決)

CPUオンリーのノード群は問題なく上記の設定で動いたのですが、私の環境ではCUDAを使っているノードがエラーでコケてしまい立ち上がりませんでした。
おそらく何かのPermissionが適切に設定されてないためだと思うのですが、未解決です。

自分で書いてみた

一見とっつきづらいですが、ROSを自動起動するを参考に書いていくと意外と簡単に書けました。
非常にわかりやすい記事を書いてくださった@strv様に感謝です。

robot_upstartで直面したCUDAエラーもこちらでは発生しなかったので、私は現在こちらを使用しています。

自分で書いた場合のつまづきポイント

デバイスをsystemdで利用可能にする

systemdで利用可能なデバイス名については、
systemctl --t device -a --full
で確認することが出来ます。

とありますが、デバイスによってはデフォルトのままだとこのリストに出てこないことがあります。
そういう時は、該当するデバイスのudevルールにTAG+="systemd"を追加してあげましょう。
既存のルールが無い場合は自分で作成しても大丈夫です。私の場合は下記のようなudevルールを用意しました。

SUBSYSTEM=="hidraw", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", TAG+="systemd", SYMLINK+="sensor_device%n", MODE="0666"

【参考】
Raspberry Pi 2 + systemd + udevで、USBデバイス挿入時にサービスを起動するLinux でデバイスを接続している時だけ動くサービスを作る

roscoreの検出

元記事だとExecStartPre=/bin/bash -l -c 'rostopic list'でroscoreの検出を行っていますが、このやり方だとrostopic listが失敗した時点でサービス自体が落ちるので、後ろに書いてあるRestart=alwaysとの合わせ技で成立しています。

ExecStartPre=/bin/bash -l -c 'rostopic list'
<中略>
Restart=always

元々の方針としてRestart=alwaysであるlaunchファイルならこのやり方が良いと思いますが、私の場合は多数のデバイスが絡むlaunchファイルになっていて頻繁に再起動するような仕様にしたくなかったのでRestart=noにしています。
この場合rostopic listでのroscore検出が出来ないので、元記事のコメントにあるようにroslaunch --waitオプションで待ってあげる必要があります。

ExecStart=/usr/bin/screen -S mavros -ADm bash -l -c 'roslaunch --wait mavros px4.launch'
7
7
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
7
7