Open garaemon opened 9 years ago
どこに定義するのか?
robot-interface.lに一票です。 この関数を定義するとしたら、のもっともupstream寄りなところはどこかと考えると、robot-interface.lな気がします。 (apt-getでインストールした環境で、robot-initのどれか一つ(端的にはpr2)が動く最小構成をかんがえると、pr2eusがはいればよい、という意味)
本当にファイルを書き下さなくてはいけないのか
難しいですね。 これで良い気はしますが、なにか案ありますか? 同じパッケージのものは
((member lower-name (list "samplerobot" "jaxon" "hrp2jsk" ....) :test #'equal)
(format nil "package://hrpsys_ros_bridge_tutorials/euslisp/~A-interface.l" lower-name))
((member lower-name (list "nao" "papper" "baxter" ....) :test #'equal)
(format nil "package://~Aeus/euslisp/~A-interface.l" lower-name lower-name))
でまとめておく、というのもなきにしもあらずなきがします。
難しいですね。 これで良い気はしますが、なにか案ありますか? 同じパッケージのものは
nodeletは各パッケージ(子供パッケージ)のpackage.xmlに
<export>
<nodelet plugin="${prefix}/jsk_pcl_nodelets.xml"/>
</export>
とかくと、親パッケージ(=nodelet)からその一覧を取得しています。 この作戦が利用できる気がしてきています。
$ rospack plugins --attrib=plugin nodelet
laser_proc /opt/ros/hydro/share/laser_proc/nodelets.xml
velodyne_driver /opt/ros/hydro/share/velodyne_driver/nodelet_velodyne.xml
yocs_velocity_smoother /opt/ros/hydro/share/yocs_velocity_smoother/plugins/nodelets.xml
jsk_perception /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_recognition/jsk_perception/jsk_perception_nodelets.xml
image_rotate /home/lueda/ros/hydro/src/image_pipeline/image_rotate/nodelet_plugins.xml
stereo_image_proc /home/lueda/ros/hydro/src/image_pipeline/stereo_image_proc/nodelet_plugins.xml
depth_image_proc /home/lueda/ros/hydro/src/image_pipeline/depth_image_proc/nodelet_plugins.xml
kobuki_bumper2pc /opt/ros/hydro/share/kobuki_bumper2pc/plugins/nodelet_plugins.xml
kobuki_safety_controller /opt/ros/hydro/share/kobuki_safety_controller/plugins/nodelet_plugins.xml
naoqi_sensors /home/lueda/ros/hydro/src/ros_naoqi/naoqi_bridge/naoqi_sensors/naoqicamera_nodelet.xml
velodyne_pointcloud /opt/ros/hydro/share/velodyne_pointcloud/nodelets.xml
pointcloud_to_laserscan /home/lueda/ros/hydro/src/perception_pcl/pointcloud_to_laserscan/nodelets.xml
openni2_camera /opt/ros/hydro/share/openni2_camera/openni2_nodelets.xml
resized_image_transport /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_recognition/resized_image_transport/nodelet.xml
image_proc /home/lueda/ros/hydro/src/image_pipeline/image_proc/nodelet_plugins.xml
uvc_camera /opt/ros/hydro/share/uvc_camera/nodelet_uvc_camera.xml
openni_camera /opt/ros/hydro/share/openni_camera/openni_nodelets.xml
yocs_cmd_vel_mux /opt/ros/hydro/share/yocs_cmd_vel_mux/plugins/nodelets.xml
pcl_ros /home/lueda/ros/hydro/src/perception_pcl/pcl_ros/pcl_nodelets.xml
prosilica_camera /home/lueda/ros/hydro/src/prosilica_driver/prosilica_camera/plugins/nodelet_plugins.xml
jsk_topic_tools /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_common/jsk_topic_tools/jsk_topic_tools_nodelet.xml
jsk_pcl_ros /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_recognition/jsk_pcl_ros/jsk_pcl_nodelets.xml
image_view /home/lueda/ros/hydro/src/image_pipeline/image_view/nodelet_plugins.xml
nodelet_tutorial_math /opt/ros/hydro/share/nodelet_tutorial_math/nodelet_math.xml
imagesift /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_recognition/imagesift/nodelet.xml
ためしに、pr2eus/package.xmlに以下のような内容を記述
<export>
<roseus name="pr2" file="${prefix}/pr2-interface.l" />
</export>
ついでにpeppereusにも追記。
<export>
<roseus name="pepper" file="${prefix}/pepper-interface.l" />
</export>
rospack pluginsで取得してみる
$ rospack plugins --attrib=name roseus
peppereus pepper
pr2eus pr2
$ rospack plugins --attrib=file roseus
peppereus /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_robot/jsk_pepper_robot/peppereus/pepper-interface.l
pr2eus /home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_pr2eus/pr2eus/pr2-interface.l
つまり作戦としては、
robot-init
の中でrospack plugins
を読んで実行時に対応関係を知る(fileとnameで二回呼ばないといけないのがちょっとダサイ)というのでどうでしょうか。
rospack pluginsは使ったことないのですが、 hrpsys_ros_bridge_tutorialsみたいに複数ロボットが同じパッケージにいる場合は並べてかくだけでOK?
書かなくてはいけないコードは減ってなくて、かつ覚えなければいけないことが増えてるようなきがちょっとだけします。
rospack pluginsは使ったことないのですが、 hrpsys_ros_bridge_tutorialsみたいに複数ロボットが同じパッケージにいる場合は並べてかくだけでOK?
はい、並べて書くだけでOKです。
書かなくてはいけないコードは減ってなくて、かつ覚えなければいけないことが増えてるようなきがちょっとだけします。
考えられる作戦は
の2つしかないと思っていて、2を採用した場合はrospack plugins
を使わないとしても、何かしら似たようなことをしなくてはいけないと思います。
覚えなければいけないこと対策としては、robot-initのエラーで丁寧に"package.xmlにこれこれかかれていないんじゃない?"ということを出すというので対応できないですかね。
- 何かしらかの方法だ対応付けをどこかにそれぞれ書き下す
でrospack pluginsを使うとすると、
- すべてを書き下しておく
で書き下す方式から書いてあるファイルが変わるだけで、 書く分量は減らず、(これ関係で)管理するファイルが増えるだけではないかな? 例えばrospack pluginsでしかできないようなメリットがあるといいんだけど。。。
- 何かしらかの方法だ対応付けをどこかにそれぞれ書き下す
でしかできないメリットをかんがえてみたところ、 どうしてもrobot-initの中にかくことができないものがある場合は、 rospack pluginsなどでやる必要がありそう。
例えば、クローズドなロボットを使っていてrobot-initの中にかくPRが送れないとなったときに、 クローズドなロボットのpackage.xmlにかいてさえいれば robot-initを前提にした全てのプログラムをそのまま使える、 というのはメリットになりそう。
と考えると
- 何かしらかの方法だ対応付けをどこかにそれぞれ書き下す
にした方が良いですね。
で書き下す方式から書いてあるファイルが変わるだけで、 書く分量は減らず、(これ関係で)管理するファイルが増えるだけではないかな?
それはそうですね。 良い点としては、
rospack plugins
系の作戦のなかではrospackのAPIを使えるので実装は楽(http://docs.ros.org/jade/api/rospack/html/classrospack_1_1Rosstackage.html#a93f3aef56fc3f97a9a9ee422ad7f84c9)rospack pluginsでパッケージを明示的に師弟するだけにして、_load-path_とかを駆使したら rospack pluginsの呼び出しが1回+同じパッケージでロボットが増えてももうpackage.xmlをいじらなくすむ、 になったりして。
rospack pluginsでパッケージを明示的に師弟するだけにして、load-pathとかを駆使したら rospack pluginsの呼び出しが1回+同じパッケージでロボットが増えてももうpackage.xmlをいじらなくすむ、
rospack pluginsの呼び出し回数はそこまできにしなくて良いと思います。
また、暗黙的なルールを導入すると書く分量はへって玄人的には使いやすくなると思うのですが、例えばxx-interface.lというファイルが必ずpackage/euslispの下にあるとか、それよりは明示的に書いたほうが良いかなと個人的には思います。(この例だとファイルシステムをスキャンするので重そう)
また、暗黙的なルールを導入すると書く分量はへって玄人的には使いやすくなると思うのですが、例えばxx-interface.lというファイルが必ずpackage/euslispの下にあるとか、それよりは明示的に書いたほうが良いかなと個人的には思います。(この例だとファイルシステムをスキャンするので重そう)
確かにそうですね。
https://github.com/jsk-ros-pkg/jsk_roseus/pull/369/commits を使って、
1.irteusgl$ (pprint (ros::rospack-plugins "pr2eus" "robot-name"))
(("hrpsys_ros_bridge_tutorials" . "hrp2jsk")
("hrpsys_ros_bridge_tutorials" . "hrp2jsknt")
("hrpsys_ros_bridge_tutorials" . "hrp2jsknts")
("hrpsys_ros_bridge_tutorials" . "jaxon")
("hrpsys_ros_bridge_tutorials" . "jaxon_red")
("pr2eus" . "pr2"))
nil
2.irteusgl$ (pprint (ros::rospack-plugins "pr2eus" "interface-file"))
(("hrpsys_ros_bridge_tutorials"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsk-interface.l")
("hrpsys_ros_bridge_tutorials"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsknt-interface.l")
("hrpsys_ros_bridge_tutorials"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsknts-interface.l")
("hrpsys_ros_bridge_tutorials"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/jaxon-interface.l")
("hrpsys_ros_bridge_tutorials"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/jaxon_red-interface.l")
("pr2eus"
. "/home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_pr2eus/pr2eus/pr2-interface.l"))
nil
追加したのは pr2eus/package.xml
+ <export>
+ <pr2eus robot-name="pr2" interface-file="${prefix}/pr2-interface.l" />
+ </export>
hrpsys_ros_bridge_tutorials/package.xml
<export>
+ <pr2eus robot-name="hrp2jsk" interface-file="${prefix}/euslisp/hrp2jsk-interface.l" />
+ <pr2eus robot-name="hrp2jsknt" interface-file="${prefix}/euslisp/hrp2jsknt-interface.l" />
+ <pr2eus robot-name="hrp2jsknts" interface-file="${prefix}/euslisp/hrp2jsknts-interface.l" />
+ <pr2eus robot-name="jaxon" interface-file="${prefix}/euslisp/jaxon-interface.l" />
+ <pr2eus robot-name="jaxon_red" interface-file="${prefix}/euslisp/jaxon_red-interface.l" />
</export>
(defun robot-name-interface-file ()
(mapcar #'(lambda (robot-name robot-file)
(cons (cdr robot-name) (cdr robot-file)))
(ros::rospack-plugins "pr2eus" "robot-name")
(ros::rospack-plugins "pr2eus" "interface-file"))
)
(pprint (robot-name-interface-file))
(("hrp2jsk"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsk-interface.l")
("hrp2jsknt"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsknt-interface.l")
("hrp2jsknts"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/hrp2jsknts-interface.l")
("jaxon"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/jaxon-interface.l")
("jaxon_red"
. "/home/lueda/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/euslisp/jaxon_red-interface.l")
("pr2"
. "/home/lueda/ros/hydro/src/jsk-ros-pkg/jsk_pr2eus/pr2eus/pr2-interface.l"))
よさそうですね。
I'll create PR for this.
これの現状を整理すると、 #222 によって、
解決したい問題は
1. 複数のロボットで動くプログラムを書くときに、`pr2-init`や`hrp2jsk-init`のような関数を書くのが面倒 2. さらっとプログラムを書くときに`(load "package://hrpsys_ros_bridge_tutorials/euslisp/hrp2jsk-interface.l)"`と書くのが結構面倒 3. パラメータを変えるだけで対象ロボットが変わるプログラムを書きたい
のうち、3は解決されてそうな感じです。
1は3と同じような意味だと思っていますが、もし各ロボット用のinit関数をなくすことを目指していたとすると、#222 でも結局、pr2-interface.l
などの各interfaceファイルにpr2-init
などのinit関数が書かれていないといけないので、1はあまり解決してなさそうです。
(load "package://pr2eus/robot-interface.l)
が必要なので、2は改善されたが完全解決はなされずといったところでしょうか。https://github.com/jsk-ros-pkg/jsk_pr2eus/pull/222#issuecomment-214929078 のように、 #222 が使われないんじゃないかという懸念があり、 #224 は一旦 #222 をrevertするものでした。 しかし、#222 がmergeされてから二年以上が経過し、 #222 にはテストコードも入っています。
また、問題3を解決する便利な方法だと思うので、今はキツいですが、僕も使っていきたいです。 今使われていないとしても、少しずつ広めていくしかないと思います。
すみません、robotのインスタンスが、*pr2*
とか*baxter*
のように、ロボット固有の名前になっているのを忘れていました。
robot-init
を本格的に運用するには、全てのinit関数で
(setq *robot* *pr2*)
のように、*robot*
も定義してあげるとよいのかもしれません。
robot-init関数を導入したい。
解決したい問題は
pr2-init
やhrp2jsk-init
のような関数を書くのが面倒(load "package://hrpsys_ros_bridge_tutorials/euslisp/hrp2jsk-interface.l)"
と書くのが結構面倒解決する方法は
robot-init (robot-name)
という関数を導入する. ロボットの定義がどのファイルに書いてあるかは仕方ないので手書きしておく(robot-interface-file
)。移行について
2段階で移行する。
hogehoge-init
をrobot-init
を利用するように書き換えて、warningを出すhogehoge-init
を消すhogehoge-init
:arrow_right:robot-init
の変換のためのsedスクリプトみたいなものは用意したい。手順
[ ] rospack pluginsをroseusでサポートする
https://github.com/jsk-ros-pkg/jsk_roseus/pull/369
議論ポイント
[x] どこに定義するのか?
robot-interface.lが良いきがする。ちょっと依存関係はおかしいかも.
:arrow_right: robot-interface.l
[x] 本当にファイルを書き下さなくてはいけないのか
package.xmlにうまいことexportタグで書くという技がある気がしてきた
:arrow_right:
rospack plugins
作戦