Increase in vel_gain issue

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.

Thank you so much!

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.

Hey, I’m sorry I meant Kd, I got a bit confused. Increasing Kd to 1.0, is making the buzz noise.

I don’t think there’s a Kd anywhere in the ODrive gains. What parameter specifically are you changing? Or are you running a PID loop externally?

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?

Hi, thank you so much for the prompt reply! I really appreciate it.

That makes a lot of sense! Thank you for explaining. There isn’t a specific reason for PD. The nested loop looks more convenient. I’ll use that.

Gotcha! Yes, would definitely recommend just going with the standard approach. We have a tuning guide here: Tuning the Controller — ODrive Documentation 0.6.11 documentation

Thank you so much for your help! I really appreciate it!