こんにちは
自律移動ロボットの研究をしているHUTONです.
ROS Navigation_stackを使っているとき,
「あ!mapを切り替えたい!!」って思うときありますよね?
(階層の違う地図を使ったりとか)
背景
筆者がつくばチャレンジに参加した際に以下のような問題がありました.
・一枚の地図を一気に作ろうとすると歪み,破綻することがある.
これを解消するためにはひじょ〜〜〜に辛いチューニング作業という地図職人が必要に...
・大きなmapでは読み込みにどえらい時間がかかることがある.
つまり
→分割した地図を乗り換えていけば良いのでは??
ということからmapを動的に切り替える方法を考えます.
※ROS noeticを対象にします.
実装
実装としてmap_serverをkillして立て直す方法がかんがえられますが,
自律移動中に立て直すのはフェールセーフの面から考えて危険に感じますよね(主観です)
それではどうするか???
そこで調査するとこんなものが
Added change_map service to map_server #461
現在map_serverには/change_mapというserviceが追加されているようです.
(ROS wikiに書いてないのはいかがなものか)
このserviceは,nav_msgs::LoadMapという型で引数(map_url)を持っています.
この引数へ,mapのパスを記載するとなんと!
mapを切り替えをすることができます!!!!!
実際の例を以下に示します.
初めにmap_servarを起動します.
rosrun map_server map_server {mapのパス}.yaml
別のターミナルで
rosservice call /change_map map_url:={切り替えるmapのパス}.yaml
次にmove_base, amclを含めたnavigationを起動した後に切り替えるノードを作ります.
施策したパッケージはこちらです.
github
具体的には
前述の/change_mapへmapを渡します
#include <nav_msgs/LoadMap.h>
複数のmapのpassをコードに直書きしても良いのですが,
美しくない&いちいちビルドしなくちゃいけないという弊害があるため
yamlにまとめましょ〜〜
configの中のmap_list.yamlは個人的な用途以下のように書きます
map_list:
-map
id: 人間の識別用の番号
map_name: mapのpassを記載
pose_x: 切り替え後の初期pose x
pose_y: 切り替え後の初期pose y
ori_z: 切り替え後の初期ori z
ori_w: 切り替え後の初期ori w
あとは何かしらのサービスでmapの番号を投げてあげれば切り替わるはず...
それではよいROS人生を!!!
気が向いたら切り替えの様子を追記します