rospyのsubscribeでspin()から抜ける方法

4,255 views
Skip to first unread message

Shinsuke Nakashima

unread,
Jul 21, 2013, 2:43:44 AM7/21/13
to rtm-ros-...@googlegroups.com
エージェントシステム受講者の中島です。


現在、課題5でkeyboard_teleop.pyを
ps3-joypad仕様に書き換えたいと考えています。
具体的には、
run(self)ループ中の
get_key(self)に、/joyをsubscribeする関数を
入れるつもりなのですが、自分が書いたsubscriber
(添付コードのlistener()関数です)だと、
rospy.spin()で延々とコールバック関数が呼び出されて
その先に進めない問題が発生しています。

(listener_ps3joy.pyの出力)
shinsuke@shinsuke-ThinkPad-W510:~/ros/fuerte/rtm-ros-robotics/agentsystem_ros_tutorials/agentsystem_examples/scripts$ python listener_ps3joy.py

(中略)

seq ...423
stamp ... 1374387473528841378
frame_id ...
axes ... (-0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -0.0, -0.0, 0.07863013446331024, 0.0)
buttons ... (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

seq ...424
stamp ... 1374387473538848465
frame_id ...
axes ... (-0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -0.0, -0.0, 0.07863013446331024, 0.0)
buttons ... (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

^CEnd!

--------------------(ここまで)(^Cで強制終了)--------------------------

rospyだとspinonce()にあたるものは必要ないということ
http://ros-users.122217.n3.nabble.com/ros-spinOnce-equivalent-for-rospy-td2317347.html
らしいのですが

どうすれば、rospyで、ループ中にただ一度だけsubscribeしにいくことが
できるのでしょうか?それとも、
keyboard_teleop中の全処理をこのコールバック関数中に収める
しかないのでしょうか?


よろしくお願い致します。



listener_ps3joy.py

Shohei Fujii

unread,
Jul 21, 2013, 3:00:52 AM7/21/13
to rtm-ros-...@googlegroups.com
藤井です

subscriberの中でunregister()するはどうでしょうか

http://mirror.umd.edu/roswiki/doc/diamondback/api/rospy/html/rospy.topics.Subscriber-class.html#unregister

http://answers.ros.org/question/30490/rospy-suscriber-run-a-callback-once-using-rospyspin/

2013年7月21日日曜日 15時43分44秒 UTC+9 Shinsuke Nakashima:

Shinsuke Nakashima

unread,
Jul 21, 2013, 10:15:47 PM7/21/13
to rtm-ros-...@googlegroups.com
藤井くん


ご返答をありがとうございます。
unregister()というのがあるのですね。
(ROS-Answersをもっと入念にチェックするようにします。)

unregister()を使ってみたところ(添付したlistener_ps3joy_rev1.pyです)
確かに1度だけ値をsubscribeすることはできたのですが、
なぜかrospy.spin()(あるいはコールバック?)から抜け出せなくなるという問題が
発生してしまいました。

----(以下、端末出力)----------------------------------------------------------------------------------------
before spin
data ...header:
  seq: 10928
  stamp:
    secs: 1374456984
    nsecs: 415586826
  frame_id: ''
axes: [-0.0, -0.0, -0.0, 0.0993184745311737, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, -0.0, -0.0, 0.07863013446331024, 0.0]
buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Unregistered!!
----(以上...ここでストップ、Ctrl+Cするまで反応しない。)------------------------------------------------



そこで、
いろいろ試行錯誤して
spin()の代わりにsleep()を入れたら(listener_ps3joy_rev2.pyです)
目的に近い挙動ができたので報告いたします。


shinsuke@shinsuke-ThinkPad-W510:~/ros/fuerte/rtm-ros-robotics/agentsystem_ros_tutorials/agentsystem_examples/scripts$ python listener_ps3joy.py

(中略)

data ...header:
  seq: 10967
  stamp:
    secs: 1374457602
    nsecs: 443031200
  frame_id: ''
axes: [-0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, -0.0, -0.0, 0.07863013446331024, 0.0]
buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

data ...header:
  seq: 10968
  stamp:
    secs: 1374457602
    nsecs: 453041368
  frame_id: ''
axes: [-0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, -0.0, -0.0, 0.07589953392744064, 0.0]
buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

^Cshinsuke@shinsuke-ThinkPad-W510:~/ros/fuerte/rtm-ros-robotics/agentsystem_ros_tutorials/agentsystem_amples/scripts$


なぜこうなったかがあまり理解できていないのですが、とりあえず
これをkeyboard_teleop()に入れてみようと思います。



###--------------------------------------------------------------------------------------------------------------
余談ですが、これはつまりrospy.spin()が
do-until-(publish?)のような働きをしていて、それが
unregisterによって無限ループになった、というような解釈でよろしいのでしょうか?


どなたかご教授をくださると大変ありがたいです。



2013年7月21日日曜日 16時00分52秒 UTC+9 Shohei Fujii:
listener_ps3joy_rev1.py
listener_ps3joy_rev2.py

you...@jsk.imi.i.u-tokyo.ac.jp

unread,
Jul 22, 2013, 3:21:39 AM7/22/13
to rtm-ros-...@googlegroups.com
spinの動作はrosが生きている限りブロックします。

Cだとこんな感じの実装のはずです。
while(ros.ok()) { 
  ros.spinonce()
}

pythonは実装が違うので、(たぶんスピンスレッドがある)ので
sleepすると裏のスレッドでsubscribeが行われます。

> keyboard_teleop中の全処理をこのコールバック関数中に収める
> しかないのでしょうか?
こちらにするのがいいだろうと思います。
こちらを選ばない理由は何があるでしょうか?

2013年7月21日日曜日 15時43分44秒 UTC+9 Shinsuke Nakashima:
エージェントシステム受講者の中島です。


現在、課題5でkeyboard_teleop.pyを
Reply all
Reply to author
Forward
0 new messages