ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

applying a force to a rigid body

asked 2011-08-29 01:23:09 -0600

erpa gravatar image

updated 2011-08-30 00:20:37 -0600

Hi all, I'm trying to write a controller for a robot that is modelled as a rigid body. In particular the robot is made by several link connected through fixed joints. I would like to apply a simple force along one of the axis to the main link of the robot. I tried to look at the erratic controller but i just found a way to apply velocity to the joints connected to the wheels. Is there a way to apply a force to a link?

thanks for your help!

EDIT: I'm working with gazebo and I would like to apply a force when a certain key is pushed (I already have implemented the teleoperation module). Is it possible to apply both an impulsive force and a continuos force?

edit retag flag offensive close merge delete


Are you talking about Gazebo? If yes, you could add the Gazebo tag to your question.
Martin Günther gravatar image Martin Günther  ( 2011-08-29 21:37:12 -0600 )edit

3 Answers

Sort by » oldest newest most voted

answered 2011-08-29 21:38:52 -0600

updated 2011-08-30 00:44:03 -0600

Assuming you are talking about Gazebo, you can apply a force to a body using this command on the command line:

rosservice call /gazebo/apply_body_wrench '{body_name: "object_1::object_1_base_link", reference_frame: "object_1::object_1_base_link", wrench: { force: { x: 0, y: 0, z: -20.0 } }, start_time: 0, duration: -1 }'

Of course, you can also call the apply_body_wrench service from a program.

Edit: Another alternative is accessing the body from a Gazebo plugin. I haven't done that yet, but I think it should run along these lines:

  • you get a Gazebo Model object in the constructor of your controller

  • use Model->GetBody(const std::string &name) to get the body representing your link by name

  • use Body->SetForce(const Vector3 &force) to apply the force

I also found looking at turtlebot_gazebo_plugins as an example for some of these steps very helpful.

edit flag offensive delete link more


hi, thanks for answering! yes i work with gazebo (i edited both the tags and the question for future reference) but rather then calling rosservice through a new terminal i would like to apply it in my controller so i was looking for the cpp function. i'm sorry if my question was missleading.
erpa gravatar image erpa  ( 2011-08-30 00:24:04 -0600 )edit
Okay, I've edited my answer to that effect.
Martin Günther gravatar image Martin Günther  ( 2011-08-30 00:44:27 -0600 )edit
thanks, it's exactly what i was looking for! Just one last question, trying to run my simulation it appears that the force is applied using world reference frame instead then body frame, am i mistaken? I will also take a look at turtlebot_gazebo_plugins as soon as it finish the download :D
erpa gravatar image erpa  ( 2011-08-30 01:29:06 -0600 )edit
That could be true. I don't know if there's a better way, but perhaps you have to rotate the force vector yourself (grep for "rotate" in gazebo_plugins to see some examples).
Martin Günther gravatar image Martin Günther  ( 2011-08-30 21:28:08 -0600 )edit
Solved! To apply the force in the object reference frame first you have to get the pose of the object itself with GetWorldPose() and rotate the force vector accordingly ( i used RotateVector() ), last you can apply the force to the object. thanks again for help.
erpa gravatar image erpa  ( 2011-08-31 03:13:13 -0600 )edit

answered 2018-10-16 07:08:25 -0600

littleghost gravatar image

Firstly, in your URDF file, you need to use its native plugin called "". Secondly, you need to publish "geometry_msgs::Wrench" type data in a node. When you publish the force data you want, you can see the rigid body moves.

edit flag offensive delete link more

answered 2018-08-09 12:27:45 -0600


from gazebo_msgs.srv import ApplyBodyWrench from geometry_msgs.msg import Wrench

Gazebo service call for applying a force on a body

def applyForce(): rospy.wait_for_service('/gazebo/apply_body_wrench') force = rospy.ServiceProxy('/gazebo/apply_body_wrench',ApplyBodyWrench)

wrench          = Wrench()
wrench.force.x  = 0
wrench.force.y  = 0
wrench.force.z  = 0
wrench.torque.x = 0
wrench.torque.y = 0
wrench.torque.z = 0
# You can also define the start time if necessary... 
force(body_name = "base_link",wrench = wrench, duration = rospy.Duration(10))
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2011-08-29 01:23:09 -0600

Seen: 5,957 times

Last updated: Oct 16 '18