Implementation of Stable PD controller: RNE, CRB and code migration #424
-
I want to implement stable PD Stable Proportional-Derivative Controllers proposed here, which require the mass matrix and the forces needed to reach the given joint accelerations. Reason to do this:Using larger time steps while keeping large gains stable throughout the simulation Would It be right to assume that Simplified Stable PD from the code here and Leftmost in this deom video: Simplified Implementationdef computePD(self, bodyUniqueId, jointIndices, desiredPositions, desiredVelocities, kps, kds,
maxForces, timeStep):
numJoints = self._pb.getNumJoints(bodyUniqueId)
jointStates = self._pb.getJointStates(bodyUniqueId, jointIndices)
q1 = []
qdot1 = []
zeroAccelerations = []
for i in range(numJoints):
q1.append(jointStates[i][0])
qdot1.append(jointStates[i][1])
zeroAccelerations.append(0)
q = np.array(q1)
qdot = np.array(qdot1)
qdes = np.array(desiredPositions)
qdotdes = np.array(desiredVelocities)
qError = qdes - q
qdotError = qdotdes - qdot
Kp = np.diagflat(kps)
Kd = np.diagflat(kds)
# Compute -Kp(q + qdot - qdes)
p_term = Kp.dot(qError - qdot*timeStep)
# Compute -Kd(qdot - qdotdes)
d_term = Kd.dot(qdotError)
# Compute Inertia matrix M(q)
M = self._pb.calculateMassMatrix(bodyUniqueId, q1)
M = np.array(M)
# Given: M(q) * qddot + C(q, qdot) = T_ext + T_int
# Compute Coriolis and External (Gravitational) terms G = C - T_ext
G = self._pb.calculateInverseDynamics(bodyUniqueId, q1, qdot1, zeroAccelerations)
G = np.array(G)
# Obtain estimated generalized accelerations, considering Coriolis and Gravitational forces, and stable PD actions
qddot = np.linalg.solve(a=(M + Kd * timeStep),
b=(-G + p_term + d_term))
# Compute control generalized forces (T_int)
tau = p_term + d_term - (Kd.dot(qddot) * timeStep)
# Clip generalized forces to actuator limits
maxF = np.array(maxForces)
generalized_forces = np.clip(tau, -maxF, maxF)
return generalized_forces
Centrifugal force, gravity, etc: (
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 18 replies
-
If I understand correctly, you are looking for the bias forces and the mass matrix. These are computer during |
Beta Was this translation helpful? Give feedback.
If I understand correctly, you are looking for the bias forces and the mass matrix. These are computer during
mj_forward()
and then you can just read them out frommjData
. You can also call sub-component functions if you want this to be faster. The bias forces live inmjData.qfrc_bias
(computed bymj_rne()
). The mass matrix lives inmjData.qM
(computed bymj_crb()
) but it is in sparse form. Callmj_fullM()
to get the dense representation.