Hi, I’m seeing an issue with ODrive position control; when I set vel_gain (kd) to 0.95 the motor is stable and quiet. But after increasing it slightly to 1.0, the motor starts buzzing. I’m not sure why is this happening. I would really appreciate any guidance on what might cause this and how to avoid it.
vel_gain isn’t a Kd – it’s a proportional velocity gain. So it makes sense that increasing it could make the gains unstable. It may be worth even lowering it a bit, so that any changes in your system’s physical parameters don’t inadvertently cause the gains to become unstable.
I’m trying to run a PD loop, I was using axis0.controller.config.vel_gain for changing Kd parameter. I want to change the proportional velocity gain, but I’m not sure which parameter command to use.
Gotcha. The ODrive loop structure is not a PD loop, but with a bit of math, you can transform the two to be equivalent. Derivation below:
Definitions:
t_ref is the torque setpoint output from the controller
w is the measured velocity
w_ref is the velocity setpoint
θ is the measured position
θ_ref is the position setpoint
w_err is the velocity error, defined as (w_ref - w)
θ_err is the position error, defined as (θ_ref - θ)
pos_gain (units of Nm/rev) and vel_gain (units of Nm/rev/s) are the standard ODrive gains for the nested control loop. We’re ignoring vel_integrator_gain, and assuming it’s set to 0.
The ODrive control loop has the structure of:
(1) w_ref = pos_gain * (θ_ref - θ)
(2) t_ref = vel_gain * (w_ref - w)
Or, combining and simplifying eqn (1) and (2):
(3) t_ref = vel_gain * (pos_gain * θ_err - w)
For a PD loop, we want the structure of:
(4) t_ref = Kp * θ_err + Kd * d/dt(θ_err)
The derivative of the position error is just the negative velocity, so this is the same as:
(5) t_ref = Kp * θ_err + Kd * -w
If we reformat eqn (3) to look like a PD controller (5), we get:
(6) t_ref = vel_gain * pos_gain * θ_err + vel_gain * -w
So here, we can say that our Kp is vel_gain * pos_gain, and that our Kd is vel_gain. But it’s very important to note that Kp is not just pos_gain.
So if you have some given Kp/Kd, you can transform that to pos/vel gains with: pos_gain == Kp/Kd vel_gain == Kd
As an additional point, we generally think the nested control structure we use is easier/simpler to tune and understand than a PD controller. Is there a specific reason you’re trying to go for PD control?