gazebosim / gazebo-classic

Gazebo classic. For the latest version, see https://github.com/gazebosim/gz-sim
http://classic.gazebosim.org/
Other
1.18k stars 479 forks source link

PID controller broken with non-default max_step_size #2294

Open osrf-migration opened 7 years ago

osrf-migration commented 7 years ago

Original report (archived issue) by Brannon King (Bitbucket: brannonking).


In Gazebo 8.1, I am unable to modify physics/max_step_size without causing error. I wanted to slow down my simulation through changing max_step_size to 0.004 and real_time_update_rate to 250. However, if I change max_step_size from its default of 0.001, the PID controllers I'm using to update joint positions spit out innumerable "inf" and "nan" values. That leads further to this error:

Error [Param.cc:363] Unable to set value [-inf -inf -inf -2.04009 -1.46244 1.64898] for key[pose]
Current Velocity: 0
gzclient: /build/ogre-1.9-mqY1wq/ogre-1.9-1.9.0+dfsg1/OgreMain/include/OgreAxisAlignedBox.h:252: void Ogre::AxisAlignedBox::setExtents(const Ogre::Vector3&, const Ogre::Vector3&): Assertion `(min.x <= max.x && min.y <= max.y && min.z <= max.z) && "The minimum corner of the box must be less than or equal to maximum corner"' failed.
osrf-migration commented 7 years ago

Original comment by Steve Peters (Bitbucket: Steven Peters, GitHub: scpeters).


osrf-migration commented 7 years ago

Original comment by Steve Peters (Bitbucket: Steven Peters, GitHub: scpeters).


How are the PID controllers implemented? Are you using a ModelPlugin?

osrf-migration commented 7 years ago

Original comment by Brannon King (Bitbucket: brannonking).


For implementation, I do inherit ModelPlugin. I use common::PID; I haven't implemented my own. I include these two lines in the Load method:

#!c++

        this->pid = common::PID(40, 0, 0);
        this->model->GetJointController()->SetVelocityPID(this->joint->GetScopedName(), this->pid);

During the update method (subscribed with ConnectWorldBeginUpdate), I do this:

#!c++

        this->model->GetJointController()->SetVelocityTarget(this->joint->GetScopedName(), vel_rad_sec);

where vel_rad_sec ranges -10 to 10.

osrf-migration commented 7 years ago

Original comment by Steve Peters (Bitbucket: Steven Peters, GitHub: scpeters).


Looking at the JointController::Update function, it looks to me like the code is not assuming a time step size, but is inferring it by repeatedly calling World::GetSimTime. If you are having problems with inf and nan, I don't think it is directly coming from the PID calculation.

It could be that the solver is simply unstable with that combination of gains and timestep, or that the solver is not converging with the specified parameters. Can you try increasing the solver iterations and/or setting the SOR parameter to 1.0?

osrf-migration commented 7 years ago

Original comment by Brannon King (Bitbucket: brannonking).


I tried iters at 20, 200, and 1200 with SOR at 1.0. I saw the error in all three situations.