Joint target velocity with maximum force
I'm attempting to model a joint as a simple servo motor with a plugin. As is customary for a servo, it has a specified maximum velocity as well as a maximum torque. I'm trying to control the joint in such a way that neither of these properties is violated (at least not significantly) but I can't figure out how. Basically I see these two options:
- Control the joint's velocity using
Joint::SetVelocity()
. The problem with this is that it seems to bypass all the physics, the velocity is achieved regardless of how much force is required for it. - Control the joint's velocity through applied forces by using
Joint::SetForce()
alongside a PID controller, which appears to be the most realistic approach. This in turn has the issue of ignoring the maximum velocity. Depending on the situation (weight and position of the attached links) the force required to achieve this velocity may be very large or very small, and it's impossible to say how much is needed. Using this approach I often see the velocity overshoot by as much as 1000% in a single time step when there's little weight or gravitational pull on the links. Gazebo will truncate further forces if this happens, but by then it's already too late.
Basically I'm looking for the ODE behavior (which judging by my Googling efforts was used in Gazebo as well in previous versions, but changed in favor of a Coulomb Friction implementation) where you set dParamFMax
in conjunction with dParamVel
and the applied force is calculatedb by the engine. I know that I could probably achieve this by talking to ODE directly from Gazebo, but I feel like this should be a common problem, and there should be some way of abstractly achieving this so it works in other physics engines as well.
Can anyone help me out with this problem? Maybe link to another place this has been solved that I've not been able to find?
Update: Link to the pull request that changes the ODE behavior. A comment there refers to the "joint motor" behavior that I'm looking for. Bullet Physics itself seems to have this as well, though I cannot reach it through the Gazebo API as I can with ODE (the relevant member is private).
Hey, I am attempting to model a servo motor as well (without using ROS). Could you give me more details on your implementation ? Did you implement the PID yourself ? Do you use a Joint plugin for that ?
It currently only works in ODE by calling `Joint::SetParam("fmax", 0, maxEffort)` in conjunction with `Joint::SetParam("vel", 0, targetVelocity)`. This sets `dParamFMax` and `dParamVel` in ODE, taking both constraints into account in the integrator. I've created an issue (https://bitbucket.org/osrf/gazebo/issues/1696/expose-joint-motor-functionality) to expose this in other engines, but I don't have much hope the team will implement it any time soon.