This patch depends on my ConsumeQueue patch submitted earlier.
When you subscribe to an interface and unsubscribe afterwards, all other
supported interfaces will be unsubscribed in Stage, even though they
were not subscribed. The model's reference count is decreased to below zero
and this causes Stage's internal data structures to get out of whack.
For example, if you subscribe and unsubscribe repeatedly to the Position2D
interface of a Stage robot, you can control the robot on the first try,
maybe on the second, but probably not on the third.
Steps to reproduce:
1. Begin from current Player/Stage source.
I used revision 8762 from
and revision 1980 from https://svn.github.com/rtv/Stage
2. Apply stage-3.2.2-consumequeue-20100614.patch from
For debugging uncomment the printf lines in Model::Subscribe() and
Model::Unsubscribe() in libstage/model.cc. Note: You'll need to
replace `token' by `Token()' since only the latter is a const char*.
4. Build Player and Stage and run simple.world.
5. Run playerv.
6. In playerv subscribe to the position2d interface and check `Command'.
You can control the robot.
7. Unsubscribe and then subscribe again. (Repeat this one or two times.)
You will no longer be able to control the robot.
I have attached some player debug output.
The attached patch changes InterfaceModel in libstageplugin/p_driver.h
and libstageplugin/p_driver.cc. It adds a private field `subscribed' which is
set to true when the interface is subscribed. If it is false, an Unsubscribe
call (e.g. from StgDriver::Shutdown()) has no effect. This fixes the problem.