ROS の Parameter Server を python で永続的に使う


目的

Parameter Server に蓄えた情報は roscore がシャットダウンされると全て消えてしまう。
電源を入れ直した時にも永続的に蓄えた情報を使うにはシャットダウンの直前にそれをsaveしておいて次に roscore を起動した直後にloadすれば良い。

コマンドライン

コマンドラインでのsave/loadは次のコマンドで実行できる。保存するファイル名をtest.yamlとする。

$ rosparam dump test.yaml
$ rosparam load test.yaml

python

同じことをpythonプログラムから行いたい。
上記コマンドラインでsaveしたファイルを見てみると余計な情報(run_id等)まで入っている。
従って、必要なパラメーターだけをファイルにsave/loadしたい。
pythonのROSモジュールであるrosparamを使えば実現できるのだが、ちょいと面倒なデータ構造になっているのでそれを関数にまとめてみた。

#!/usr/bin/env python

import rospy
import rosparam

#---------------------------------------------------------------------------
# save/load param
#---------------------------------------------------------------------------
def save_param(filename, paramname):
    rosparam.dump_params(filename, paramname)

def load_param(filename, paramname):
    (param, ns) = rosparam.load_file(filename)[0]
    rospy.set_param(paramname, param)

使い方はこんな感じで

if __name__ == '__main__':
    rospy.init_node('params_test')
    try:
        print 'try to load test.yaml'
        load_param('test.yaml', '/global_params/test')
    except:
        print 'make param and save it'
        rospy.set_param('/global_params/test', {'init':{'px':0, 'py':0, 'dir':0}, 'p1':{'px':0, 'py':1, 'dir':20}})
        save_param('test.yaml', '/global_params/test')
    # load /global_params/test and print it
    test = rospy.get_param('/global_params/test')
    print test

備考

  • load_param関数で指定したファイルが存在しない時は例外が発生するので使う時に処理を書いておくのが良い。
  • rosparamモジュールにもset_paramやget_paramがある。
  • しかし、情報が辞書の場合にエラーとなってしまうようだ。
  • 従って、set_param や get_param は rospy モジュールで使うようにするのが良いだろう。