change joint characteristics at runtime
I would like to inject faults into a simulation. Faults may include locking a joint in place, letting a joint move freely, or changing the limits, damping, or friction on a joint. Locking a joint could possibly be accomplished by setting new limits on it. Are there mechanisms in ROS/Gazebo that can help with this?
So far it appears I can set friction and limits using a Gazebo ModelPlugin. Are there other ways to do it, possibly with an external script or program? I have not yet found a way to let a joint go limp, possibly by disabling a controller.
Asked by mogumbo on 2020-02-20 19:24:01 UTC
Answers
You can use the gazebo_ros set_joint_properties service (implementation here), which uses the ODEJointProperties message. Limits and damping are listed in that message. To lock a joint, I would set the fmax
field to a large value and vel
to 0 (this is also how we set joint friction, using both fmax
and vel
).
While inspecting the DefaultRobotHWSim::writeSim function, I've also noticed the e_stop_active_
variable, which appears to cause effort controllers to go limp. In order to enable the e-stop, it looks like you need to add a eStopTopic element to the gazebo_ros_control_plugin
with the name of the e-stop topic. Unfortunately, I think that applies to all joints; I don't see a way to apply the e-stop to a subset of joints.
Asked by scpeters on 2020-02-28 14:45:17 UTC
Comments
I am able to use apply_joint_effort successfully using the Service Caller in rqt. However, setting fmax=1000000000000 and vel=0 appears to have no effect. I can still command the joint the same with my controller.
I also can't find a way to use gazebo_ros_api_plugin to set a joint's effort to 0. After using controller_manager to stop a controller, the effort sometimes goes to 0 on its own after a few minutes. I want to force it to 0 right when I stop the controller.
Asked by mogumbo on 2020-03-13 18:18:46 UTC
Trying to use effort_controllers::JointPositionController, I noticed it does not implement a stopping() method. If you add this method and make it do joint_.setCommand(0.0); then your joint's effort goes to 0 when this controller it stopped. However, I'm not sure if it should be the controller's responsibility to do this.
Asked by mogumbo on 2020-03-18 10:47:23 UTC
I just updated my answer with some discussion of the e-stop, which may not be useful to you as it's a bit heavy-handed. I'll try testing the fmax / vel approach to see if I can get it working.
Asked by scpeters on 2020-04-01 19:17:40 UTC
I need to affect joints individually, so I don't think e-stop is the solution for me. I also tried using the rqt Service Caller to set a joint fmax=0. Shouldn't this make a joint go limp? I see no change in effort when I echo /joint_states.
Asked by mogumbo on 2020-04-09 16:26:18 UTC
fmax is only relevant for VelocityJointInterface; it matters for the SetParam("val", ...) call in https://github.com/ros-simulation/gazebo_ros_pkgs/blob/melodic-devel/gazebo_ros_control/src/default_robot_hw_sim.cpp#L363
Asked by scpeters on 2020-04-15 17:29:25 UTC
Comments
You can find all the available methods you can use in Gazebo plugin in Gazebo API. If you are using the ros_control to manage your joint, you can find commands to unload the controllers here.
Asked by kumpakri on 2020-02-21 03:22:10 UTC
Thanks. I am able to stop controllers with rosrun controller_manager controller_manager stop. However, afterwards I see that the joint maintains the effort it had before stopping the controller; I can confirm this by echoing /joint_states. I would expect the effort to go to 0 with the controller stopped. What can be done about this?
I tried using a plugin to set the effort to 0 with physics::Joint::SetForce() and physics::JointController::SetForce(), but there's no effect.
Asked by mogumbo on 2020-03-11 12:41:02 UTC