Dynamics & Torque Control, bonus step
Bonus: Weigh the payload
Hold the arm still at a few poses, read the motor torques, and solve for the unknown payload by least squares.
Builds on Least squares: fitting noisy data, from the free Foundations.
Write and run this step in the simulator with ProWeighing with the motors
Step 3's I term found the torque the model was missing, but only for one pose, and it has to find it again whenever the arm moves. Better to work out the payload itself and put it in the model.
Gravity is linear in the payload
Take a payload of mass sitting past the wrist, along the hand. The links tilt , and from vertical, so the payload sits above the shoulder, with = 0.30 m and = 0.25 m. Holding it still takes on joint , with = 9.81 m/s²:
where . The unknowns appear linearly, so every held pose gives three equations: shoulder, elbow and wrist (gravity can't turn the base).
Least squares
Held still at pose , the motors supply exactly the gravity torques, so the payload's share is , where is arm.gravity_torques, which doesn't know the payload. Stack every pose's into one tall matrix and every share into one vector: np.linalg.lstsq finds the that fits them best (Foundations: Least squares). Then .
The program
It glides to six poses, brakes with arm.hold() and reads arm.applied_torques. After your fit it holds a test pose with PD + , first with the arm's model alone and then with your payload added: .
Your task
Write payload_regressor(q) and fit_payload(qs, taus). Your mass must be within 3 % of the truth, and with it in the model the test pose must hold within 0.2°.