Independent Joint Control and PID
Learning Objectives
- Model one joint driven by a geared DC motor, with reflected inertia and damping, and treat the rest of the arm as a disturbance on that joint.
- Implement a discrete PID loop with a named sampling period, integration rule, derivative rule and anti-windup scheme, and choose gains by pole placement.
- Show by simulation why PD alone leaves a gravity error, how the integrator and gravity feed-forward remove it, and what integrator windup does at a saturated actuator.
- Show by simulation what independent joint control ignores: the change of inertia with configuration and the coupling between joints.
Context & Motivation
the-manipulator-equation-inertia-coriolis-gravity wrote the arm as one coupled equation, . The simplest controller ignores most of it. Each joint gets its own loop that reads its own encoder and commands its own motor, as if it were alone. Modern Robotics calls this decentralized control and says it is appropriate when the dynamics are decoupled, at least approximately, as in highly geared robots without gravity. This lesson builds such a loop for the two-link arm of the previous lessons, runs it, and measures what it gets right and what it misses.
Core Theory
A geared joint
A DC motor produces torque from current . In the usual arrangement the amplifier runs in current mode, adjusting the voltage to obtain the commanded current, so the controller commands torque and the electrical dynamics are left out here. A gearhead with ratio turns the motor times faster than the joint and, with efficiency , multiplies the torque: . A rotor of inertia spinning at stores , so the joint sees a reflected inertia ; motor-side viscous friction appears as in the same way. For joint of the arm,
where is a fixed nominal value. Independent joint control designs each loop for the left-hand side and treats as an unknown disturbance. The larger is compared with the link inertia, the smaller is relative to the joint's own dynamics, which is why Modern Robotics says the mass matrix of a highly geared robot is nearly diagonal.
The motor values are assumptions, and : , , N m s/rad, N m/A, current limit 8 A. At the joint this gives a reflected inertia of , damping N m s/rad and a torque limit of N m. The rotor of motor 2 also turns with link 1, at , which adds to and to . With the link values of lagrangian-dynamics-of-an-open-chain-robot, the total inertia at joint 1 is with the arm extended (), at and folded (). At joint 2 it is in every pose.
PID, with gains by pole placement
The continuous PID law is with . For a joint , the error dynamics with PID have the characteristic polynomial . Matching it to gives
With rad/s and rad/s, and nominal inertias taken at :
| Joint | () | (N m/rad) | (N m/(rad s)) | (N m s/rad) |
|---|---|---|---|---|
| 1 | 1.157 | 433.8 | 1301.3 | 39.48 |
| 2 | 0.407 | 152.5 | 457.5 | 13.23 |
Modern Robotics gives the stability conditions for this third-order loop as , and . The upper bounds on are 15182 and 5338 here, far above the gains used. Those conditions hold for the linear model with constant and constant disturbance, which the arm is not, so the simulations below are the real test.
The discrete implementation
The controller runs every ms. Modern Robotics gives about 1 kHz as a typical rate for the commanded torque. At sample :
texte = q_des - q_k v_hat = (q_k - q_{k-1}) / T # backward difference of the measurement v = Kp*e + I + Kd*(qdot_des - v_hat) + tau_ff u = clip(v, -tau_max, +tau_max) # actuator limit I = I + Ki*T*e [+ (T/Tt)*(u - v)] # forward Euler; bracket = back-calculation
The derivative acts on the measured position, not on the error, so a step in the setpoint does not produce a derivative spike; Åström and Murray's Feedback Systems uses the same structure in its pseudocode, together with a filtered derivative that is omitted here because the simulated sensor is ideal, with no noise and no quantization. The torque is held constant between samples. The arm, which is the full coupled model plus the motor terms, is integrated with the classical fourth-order Runge-Kutta method at a fixed step of 0.1 ms, ten steps per control period.
Sampling moves the poles. For joint 1 at its nominal inertia, the closed loop at ms, computed from the exact discretization of , has poles , equivalent to , plus a fast pole at from the backward difference: the double pole at has split. With the same gains the loop becomes unstable at ms for the nominal inertia, at ms with the arm folded and at ms extended. The lighter configuration is the most sensitive, because the same gains act on less inertia.
Anti-windup
When the actuator saturates, the loop is effectively open: the torque stays at the limit whatever the error does, and the integrator keeps accumulating error. When the error finally changes sign, the large integral keeps the actuator saturated, and the result is a large overshoot. Feedback Systems calls this integrator windup. Two remedies are used below. Back-calculation, the scheme of Feedback Systems, feeds the difference between the saturated and the unsaturated output back into the integrator with a tracking time constant ; the book notes that the tracking gain cannot be too large, because measurement noise would then reset the integrator. Clamping (conditional integration) skips the integrator update at any sample where the output is saturated and the error has the same sign as , so integrating would push further into saturation.
Worked Examples
Example 1: gravity, the integrator, and feed-forward
The arm moves in a vertical plane () from rest at to along for s, then holds. Every variant uses the and of the table; "PD" sets , and gravity feed-forward adds . Errors in degrees, joint 1 and joint 2:
textcontroller max |e| during move e at t = 1.5 s e at t = 3 s peak |u| (N m) PD 3.42, 3.22 1.747, -0.713 1.746, -0.714 30.0, 9.7 PID 2.88, 2.73 0.200, -0.003 0.000, 0.000 31.4, 10.3 PD + exact gravity ff 1.61, 1.79 0.001, 0.002 0.000, 0.000 28.4, 9.2 PD + gravity ff, m2 20% low 1.85, 2.08 0.177, -0.145 0.176, -0.147 28.7, 9.3 PID + gravity ff, m2 20% low 1.62, 1.77 0.251, 0.099 0.000, 0.000 29.5, 9.7
No run saturated. PD holds the arm with a steady error because, at rest, its torque is nonzero only if is: Modern Robotics writes this for one joint as . For two joints the steady error solves , and solving that with scipy.optimize.fsolve gives , the simulated value. The integrator removes the error, but slowly, since is still at joint 1. Exact gravity feed-forward removes it with no integrator and halves the error during the move. With a gravity model whose is 20% low, feed-forward alone leaves ; adding the integrator removes it. In these runs feed-forward did the bulk of the work and the integrator corrected the model error.
Example 2: the same gains, three inertias
Gravity off (a horizontal plane), joint 2 held at by its own loop, joint 1 commanded a step. The same joint-1 gains, designed for , meet three different plants:
textq2 J at joint 1 continuous poles (rad/s) overshoot 2% settling joint 2 disturbed by 0 deg 1.557 -10.67 +- 8.07j, -4.67 25.4% 0.833 s 0.23 deg 90 deg 1.157 -15, -15, -5 20.7% 0.864 s 0.09 deg 180 deg 0.757 -40.35, -7.36, -5.79 17.6% 0.892 s 0.08 deg
The poles listed are those of with the actual . Extended, the arm is heavier than the design assumed and the poles become complex; folded, it is lighter, one pole moves far left and, as the previous section showed, the sampled loop loses stability at a shorter sampling period. The link inertia alone varies by a factor of 2.75 between the extended and folded poses; the reflected rotor inertia, the same in every pose, reduces that to 2.06, which keeps the change in the transient moderate. Even the PID at the design inertia overshoots by 20.7% although its poles are real, because the PID adds zeros: the proportional and integral terms act on the error and respond to the step itself.
Example 3: coupling
Gravity off; joint 1 moves in 0.75 s along the cosine profile while joint 2 is commanded to stay at . Along the desired motion, the torque that joint 1's motion imposes on joint 2, , peaks at 2.41 N m. Peak errors in degrees:
textcontroller max |e1| max |e2| PID only 2.007 0.941 PID + per-joint feed-forward J_i qdd_d + B qd_d 0.030 0.866 PID + model feed-forward (M + M_rot) qdd_d + C qd_d + B qd_d 0.033 0.003
Joint 2 was told to stay still and moved almost , purely because joint 1 moved. A per-joint feed-forward, still independent, fixes joint 1 and leaves joint 2 untouched, since what disturbs joint 2 comes from the other joint. Only feed-forward computed from the coupled model, which needs every joint's trajectory, removes it. That is no longer independent joint control; Modern Robotics calls the centralized version computed torque control. Shortening the move to 0.5 s doubled the joint-2 error to and drove joint 1 into the 40 N m limit.
Example 4: windup
Gravity on, joint 2 at , joint 1 steps from hanging () to horizontal (). The proportional term alone asks for N m, so the motor saturates at 40 N m. With s:
textscheme peak q1 lowest q1 after peak within 0.5 deg after time saturated max integral (N m) no anti-windup 67.5 deg -47.9 deg 2.79 s 1.81 s 513 back-calculation, Tt = Ti 15.6 deg 0.0 deg 1.30 s 0.37 s 142 back-calculation, Tt = Ti/10 0.0 deg 0.0 deg 1.26 s 0.15 s 21.1 clamping 4.3 deg 0.0 deg 0.95 s 0.30 s 48.9
Without anti-windup the integral climbs to 513 N m while the arm is still rising, and the arm swings past the target and then below it. In every scheme the integral ends at 21.09 N m, which is : the integrator has learned the gravity torque that feed-forward would have supplied. The faster tracking time removed the overshoot entirely in this simulation; with a noisy sensor that choice would have to be weighed against the noise warning above, which an ideal sensor cannot show. Joint 2, never commanded to move, deviated by up to without anti-windup and to with it.
Common Misconceptions & Pitfalls
- "Each joint is a separate system." Example 3 moved a joint that was commanded to stay still. The independence is a design choice, not a property of the arm.
- "Gains tuned in one pose work in all poses." The inertia at joint 1 changed by a factor of 2 between poses, which moved the poles and the sampling period at which the loop goes unstable.
- "The integrator is the cure for gravity." It works, slowly. Feed-forward of a gravity model does most of the work, and the integrator cleans up the model error. Modern Robotics notes that in practice many robot controllers use "since stability is paramount".
- "Saturation is the actuator's problem." It breaks the loop, and the integrator turns a saturation into a 67.5° overshoot without anti-windup.
- "Continuous gains carry over unchanged." Sampling at 1 ms already split the double pole, and the same gains destabilize the folded arm at about 29 ms.
Summary
Independent joint control treats each joint as a geared motor driving the inertia , and puts everything else, gravity, coupling and the change of , into a disturbance. A discrete PID at ms with forward-Euler integration, a backward-difference derivative of the measurement and gains placed at , , rad/s tracked a 1 s move to within and removed the steady error that PD left ( at joint 1); gravity feed-forward removed it without an integrator and halved the tracking error. Saturation without anti-windup produced a overshoot, and back-calculation or clamping cut it to to . What the method ignores showed up directly: the same gains gave different poles in different poses, and a joint commanded to stay still moved by almost when its neighbor moved, an error that only model-based feed-forward across joints removed.
Documentation Links
- Lynch and Park (2017): Modern Robotics: Mechanics, Planning, and Control (preprint PDF)
- Astrom and Murray (2008): Feedback Systems: An Introduction for Scientists and Engineers (complete PDF)
- Asada (2005): MIT OCW 2.12 Introduction to Robotics, Chapter 2: Actuators and Drive Systems
- SciPy documentation: scipy.linalg.expm