Skip to content

Joint Damping and Friction ​

Every revolute and prismatic joint can have viscous damping and Coulomb friction, and a spherical joint can have viscous damping. They model bearings, seals and gears. They are passive: they only remove energy, they are not part of the generalized force you set, and they act whether or not the joint is controlled.

Set them with the standard URDF <dynamics> attributes. Both default to zero:

xml
<joint name="knee" type="revolute">
    <parent link="thigh"/>
    <child link="shank"/>
    <axis xyz="0 1 0"/>
    <dynamics damping="0.5" friction="2.0"/>
</joint>
Joint typedamping bfriction τc
revoluteNms/radNm
prismaticNs/mN
sphericalNms/rad, on each of the three angular velocity componentsnot supported (ignored)

The MJCF loader reads the joint damping attribute but not frictionloss.

Both are measured at the joint, i.e., after any gear. If the joint is driven by an actuator, the actuator's output_damping and output_friction add to them (see Actuators).

Damping ​

Damping is the torque τd=−bu on the joint velocity u (relative to the parent body, see Joints). RaiSim integrates it implicitly with the trapezoidal rule, i.e., at the average velocity of the time step Δt:

τd=−but+ut+12.

For example, a free joint with inertia I under a constant torque τ and no gravity accelerates as

Iut+1−utΔt=τ−but+ut+12

and converges to the velocity τ/b. The implicit integration keeps a joint with a large damping stable at any time step. The d gain of the PD controller is integrated the same way. The difference is that damping pulls the velocity to zero, while the d gain pulls it to the velocity target.

To read the current joint damping, call getJointDamping(). It returns a const raisim::VecDyn reference in generalized velocity order, with getDOF() entries. These are the values loaded from the model or last supplied to setJointDamping(); actuator output damping and PD gains are separate. Copy getJointDamping().e() into an Eigen::VectorXd to preserve a baseline before adding temporary damping, such as wheel braking.

To change the damping at runtime, call setJointDamping() with one coefficient per degree of freedom (getDOF() entries). The new values act from the next step. Leave the six entries of a floating base at zero: they are not joints, and their damping would not be integrated implicitly.

The URDF effort limit bounds only the commanded torque (PD plus feedforward). The damping torque is passive and is never clipped. Actuator torques (see Actuators) are not bounded by the effort limit either: they are limited by the operating regions of their motors and are added after the effort clamp.

Friction ​

Friction is Coulomb friction with stiction. It opposes the motion with the constant torque τc, and it holds a joint at rest as long as the other torques on it (actuation, gravity, contacts and the motion of the other bodies) stay below τc:

τf=−τcsgn(ut+1) if ut+1≠0,|τf|≤τc if ut+1=0.

Once the other torques exceed τc, the joint accelerates with their sum minus τc. For the free joint above, that is I(ut+1−ut)/Δt=τ−τcsgn(ut+1).

RaiSim solves friction as a joint impulse bounded by τcΔt in the contact solver, together with the contacts and the joint limits. A joint therefore stops exactly instead of chattering around zero velocity, and the friction torque is consistent with the contact forces on the robot. A robot with friction adds one row to the contact solver; robots without friction do not pay for it.

The joint's own friction is set in the model file; there is no C++ setter for it. The output_friction of an actuator can be changed at runtime by editing the definitions from getActuators() and passing them to setActuators().

RaiSim — physics for robotics and AI.