launchファイルを指定時間sleep後に起動する "timed_roslaunch"

# はじめに

プロジェクトが完成に近づくと，1発`launch`ファイルを起動すれば必要なノードをすべて自動で起動できるように設定したくなるのが人情というものです．

ですが，それだとまれに問題が起きる時があります．例えばこんな理由．

- 実機のインターフェースが完了してから起動しないとうまく機能しない`node`がある
- `Gazebo`センサプラグインの初期化が完了してから起動しないと機能しない`node`がある

こういう仕様は，手で一つ一つ立ち上げていたときには気が付かないものです．`launch`でまとめて起動しようとしたときに初めて気がつく場合があります．

もちろん，複数の`launch`ファイルに分割して`<iclude>`すれば，確実にシーケンシャルに実行してくれるようなのですが，初期化処理中に次の`launch`が起動されてしまってやっぱりうまくいかない，なんてことがあります．

もちろん，そういう`node`の仕様自体に問題があるのですが，人様のパッケージを使わせていただいている場合だってよくあるわけですし，かつそれを腰を据えて修正する時間もね～！今は取り敢えず動くもの作らないと間に合わねー！みたいな時だってあるわけです．

そこで，`launch`ファイルを指定時間遅らせて起動してくれる`timed_roslaunch`というスクリプトがあったので，備忘録として残すこととします．

# 参考
- [ROS Answers - Can I run a bash script using roslaunch?](http://answers.ros.org/question/51474/can-i-run-a-bash-script-using-roslaunch/)

# 使い方
`timed_roslaunch`のパッケージが見当たらなかったので，私がとりあえずパッケージ化したものをcatkinのワークスペースに入れるのが楽かもしれません．

- [github.com/MoriKen254/timed_roslaunch](https://github.com/MoriKen254/timed_roslaunch)

そしてこんな風に使います．

```xml
<launch>
  <arg name="arg_user_input" default="hoge_default" />
  <node pkg="timed_roslaunch" type="timed_roslaunch.sh" 
    args="2 package_name launch_file_name.launch arg1:=hoge arg2:=$(arg user_input)" 
    name="timed_roslaunch_hoge" output="screen">
  </node>
</launch>
```


要は，

```bash
args="2 package_name launch_file_name.launch arg1:=hoge arg2:=$(arg user_input)" 
```

が単にコマンドラインの入力になっているだけです．最初の2という数字の部分に，遅れさせたい時間[sec]を入れれば良いです．

[参考サイト](http://answers.ros.org/question/51474/can-i-run-a-bash-script-using-roslaunch/)に掲載されたスクリプトをそのまま使っています．

内部的には，`roslaunch`の前にコマンドラインで`sleep`をしているシンプルなものです．

```bash
#!/bin/bash          
#
# Script to delay the launch of a roslaunch file
# 
# Koen Lekkerkerker
# Thu 24 Apr 2014 
#
# Use: ./timed_roslaunch.sh [number of seconds to delay] [rospkg] [roslaunch file]
#

function showHelp(){
    echo 
    echo "This script can delay the launch of a roslaunch file"
    echo "Place it in the 'scripts' folder of your catkin package"
    echo "and make sure that the file is executable (chmod +x timed_roslaunch.sh)"
    echo 
    echo "Run it from command line:"
    echo 
    echo "Use: ./timed_roslaunch.sh [number of seconds to delay] [rospkg] [roslaunch file] [arguments (optional)]"
    echo "Or: rosrun [yourpackage] time_roslaunch.sh [number of seconds to delay] [rospkg] [roslaunch file] [arguments (optional)]"
    echo "Example: ./timed_roslaunch.sh 2 turtlebot_navigation amcl_demo.launch initial_pose_x:=17.0 initial_pose_y:=17.0"
    echo 
    echo "Or run it from another roslaunch file:"
    echo 
    echo '<launch>'
    echo '  <arg name="initial_pose_y" default="17.0" />'
    echo '  <node pkg="semantic_turtle_test" type="timed_roslaunch.sh"'
    echo '    args="2 turtlebot_navigation amcl_demo.launch initial_pose_x:=17.0 initial_pose_y:=$(arg initial_pose_y)"'
    echo '    name="timed_roslaunch" output="screen">'
    echo '  </node>'
    echo '</launch>'
}

if [ "$1" = "-h" ]; then
    showHelp
else 
    echo "start wait for $1 seconds"
    sleep $1
    echo "end wait for $1 seconds"
    shift
        echo "now running 'roslaunch $@'"
    roslaunch $@
fi
```

こんな感じです．

# おわりに
`timed_roslaunch`を使うことで，とりあえず冒頭で述べた問題は解決しました．

本質的には，`node`側で解決すべき問題であることは忘れてはいけません．

あくまで，本番前で時間ねー！原因わかんないけどまずは動かさないと行けないんだー！的な場合の対処療法だと認識して使う分には，十分だと思います^^