I wrote this post in case I forgot.
This post is about the bug happens in the condition when
Joint::SetPosition function without specifying
_preserveWorldVelocity as true.
Then this happens when
"position_controllers/PositionJointController" is used without specifying
pid_gains in ROS and Gazebo integration.
This time, we ran into this problem exactly.
We investigated a lot about this bug, so I try to summarize in this post.
What kind of problem this is
This question and answer describe this problem well.
This problem is that model behaves strangely when
ros_control plugin is loaded.
Joint::SetPosition is the main cause, and
"position_controllers/PositionJointController call this function. (Around here)
The answer shows two workarounds:
However, workaround 1. is not suitable for out humanoid because we control servos using position control. Also, when we want to control robot without PID, 2. is not good.
How to Fix?
So how can we deal with this. from Gazebo 9, the parameter named
_preserveWorldVelocity was added to
Details are written in these Issue and PR:
They seemed to fix this behavior as to be expected. (1. 2.)
However, there were some use cases in current behavior, then
_preserveWorldVelocity was introduced. Passing
true to this parameter, then fixed (3.)
Yeah, it’s all good, but
_preserveWorldVelocity‘s default value is
And there seems to be no way to set this parameter in URDF or roslaunch.
That means… I have to build it from source.
Fixes in sources
I wrote needed fixes in This patch.
Taking some code from the patch, I set the default argument to true.
/// \return returns true if operation succeeds, false if it fails.
public: virtual bool SetPosition(
const unsigned int _index, const double _position,
- const bool _preserveWorldVelocity = false);
+ const bool _preserveWorldVelocity = true);
Also, I found that someone calls this by explicitly specifying false, so I made a change like this:
bool ODEJoint::SetPosition(const unsigned int _index, const double _position,
- const bool _preserveWorldVelocity)
+ const bool /*_preserveWorldVelocity*/)
- return Joint::SetPositionMaximal(_index, _position, _preserveWorldVelocity);
+ return Joint::SetPositionMaximal(_index, _position, true);
You know, this change is crazy. But it worked, so I don’t care anymore…
So please be careful if you’re willing to use this patch. This can be a cause of another bug.
Left: before patching, Right: after patching.
The weird behvior in falling is fixed. Cool!
Wait a minute
…well, as some of you noticed,
_preserveWorldVelocity to be true.
Then it’s so mysterious who passed false to that, but I don’t want to think about this anymore because it has just worked, and I’m no longer using Gazebo anymore…