Limiting velocity in CURRENT_CONTROL_MODE

Hello folks,

in CURRENT_CONTROL_MODE iam experiencing an unexpected behaviour:

with .vel_limit = 1000000.0f the motor accelerates to a certain speed regardless of the .current_setpoint.
I expected the motor to accelerate up to .vel_limit or .current_lim or .max_allowed_current.
The applied current falls to roughly 0.2A when entering the stable rotational speed.

Is it possible to change this behaviour?

Thanks in advance, Stephan

1 Like

hi folks,

when in current control mode and braking down the motor to zero speed with external force, the applied current suddenly drops to a quite low value when the motor is at a low speed. Is this a safety feature and is it possible to disable this behaviour?

Another thing: Is it possible to apply current in forward direction while the motor is turning backwards? In this case do i need a brake resistor or can the drive handle this case without it?

In my application i need to set current, not speed or position to get a certain momentum on the shaft.

Hi, so there are a couple of different things I think that are causing confusion. The primary one is what weput in the documentation: “Note: The motor current, and the current drawn from the power supply, is not the same in general. You should not look at the power supply current to see what is going on with the motor current.”
The motor current is indeed proportional to torque, while the power supply current is proportional to motor power. At low speeds, they are very different: high torque but almost no power, this is why you see it drop when you stop the motor.

To see the actual motor current, you can use the liveplotter. By default it’s plotting the position of motor 0, but you can change the code: change my_odrive.motor0.encoder.pll_pos to my_odrive.motor0.current_control.Iq_measured to plot the motor current instead.

Limiting velocity

So actually .vel_lim is not used in current mode (CURRENT_CONTROL_MODE). Current mode will just put the current you ask for on the motor, no limits applied. That is, if you ask for a current then your motor will get a torque and just accelerate, until it hits the base speed for your bus voltage, at which point it’s not possible to go any faster (ignoring field weakening, which is not used). You can use the ODrive Motor Guide to check the base speed of your motor and bus voltage.

We can add a speed-limited current control mode, I think it’s something I think other people can make use of too. So here is my understanding of what you want, let me know how accurate that is:

  1. Nominal current command, sent in realtime from some source. We can use current_setpoint for that.
  2. I think it makes sense to use vel_lim for this.
  3. A ramp-down gradient to make the transition into vel_limit operation smooth. This is actually equivalent to vel_gain, so we can use that.

Hello madcowswe,

thanks for the hint with amps shown on the power supply. I already had that in mind. But i brake the free running motor with my finger and i can feel the drop in momentum when the motor is very close to omega=0. But now knowing the existence of your live plotter (:+1:) i will investigate in more detail on that issue (within the next few days).
EDIT: may it help to adjust the .calibration_current? I just read in your documentation, that this applies to a stationary motor.

Concerning the vel_limit: I think it would be good to have the possibility to set a vel_limit in Current_control_mode but thats not what i meant in my (quite a bit unclear) post. I want the motor to accelerate but it does not.

Iam a little surprised now that there actually is no limiting as i encounter a definite limit in omega. For the time i can only guess how big it is, but it is much below the maximum possible speed. I think it is roughly at 100rpm but iam gonna measure it later on. And it is the same for different current set points.

For the sake of a bit more clarity, iam the guy with the 100kV 12V 16A motor from here.

i now checked the final rpm after applying a set_current of different amperes in range of 0 to 2A and it is always stable at around 900rpm.
Iam using the ATM Encoder set to 2048 full pulses wich gives 8192 pulses absolute and therefore 122.880 pulses per second on the oDrive.

Might it be possible, that i hit the max possible field rotation speed here?

Btw: Your Iq_measured attribute is not in the list of exposed attributes.

Okay, 900 RPM is different from 100 rpm.
900 rpm is completely expected if you are running on 12V: a 100kV motor at 12V bus voltage has a theoretical base speed of 960 RPM: 12V x 100 rpm/V x 0.8.
The 0.8 is because the ODrive has a 80% modulation limit.

I don’t know what this term means, but if you mean back-emf, then yes: this is equivalent to hitting base speed.

You can find Iq_measured exposed here. Make sure you are using the .current_control part, as I described above.

ok, everything makes sense now, thanks for taking your time to help and explain.

This is a link to a video of the project iam working on:
Still some tuning to do but it works perfect with the direct driven motors!

As english is not my mother tongue, let me explain “max field rotation speed”: You need some time to calculate the vector orientation of your field oriented control and i think, due to the duration of this calculation there is a limit in rotational speed for your magnetic field that turns the motor. But that was just some thoughts.

No worries. Nice project! You can add a weak feedback term from the integral of the wheel speeds, then it will stop trying to run away ;D.

Ah okay I see what you mean, no the maximum vector rotation speed is in the many thousands of RPM.

I would very much appreciate a velocity limit to current control mode. I’m planning on building a force feedback steering wheel and it is mostly about applying stall torque forces. However if the user drops the wheel and it gets a wild force feedback push I dont want the wheel to spin up to violently, where it can be dangerous. I guess I could monitor this from the arduino controller, but it would be very nice to have it in the Odrive firmware as a safety precaution.
The wheel would have 900 degrees of rotation, and when that is reached a strong counter force would be applied outside that range to act as a “physical” steering limit. That would stop the spin, but it might be too late if a finger gets snapped. ouch.

Hi all,

I needed such a functionality recently so I went ahead and implemented a basic velocity limiter, which I am contributing back to ODrive.

The PR is here:

1 Like

Awesome, thanks!
I just want to amend my original diagram to include all quadrants:

1 Like

If you want current control with proper speed limit and not with gradually reducing the current with gradient you should implement it differently.
Put drive into speed control with desired speed at speed limit and then use desired current for setting the output limit of speed controller.
Also speed controller shall have integral windup with back calculation.

Thanks for the reply. There’s a bug in the current implementation that needs fixing.

Regarding the updated diagram: I’m wondering if it’s desired behavior to actively limit overspeed, in other words, if vel_estimate > vel_limit, should it be that Iq < 0 ? or should it be Iq == 0 ? (similarly for negative velocity) My opinion would be towards the latter, as otherwise vel_limit functions as a kind of setpoint.

@markorman Yes your suggestion works, but it may be tedious or infeasible to keep changing the velocity setpoint between the min and max speed limit. So it’s better to have a special mode for it where it happens automatically.

@yconst I think as shown is correct, i.e. if vel_estimate > vel_limit you want to be actively braking, not just coast. Otherwise you couldn’t speed limit a system with an external torque applied (active braking situation). vel_limit as a kind of setpoint is the desired behaviour I think.

Ok, however then another issue arises: If vel_limit == 0, should limiting be disabled or active but always braking? In the second case, maybe a separete limit_enable flag should be there.

btw, I’ve found out in discord that @Wetmelon already made the bugfix to another branch, maybe it’s better to merge from his branch.

Yes we either need a separate “velocity limited current control” control mode, or we need limit_enable flag. But if the limit is enabled and set to 0, it should always be braking.

Yes I saw that, indeed maybe we can use @Wetmelon’s branch going forward.

Any updates on a velocity limited current control mode? It would make my life easier. :slight_smile:

It seems like this is now achieved by using vel_limit in torque control mode? “Note: If you exceed vel_limit in torque control mode, the current is reduced.”

It’s been enabled by default since 0.5.1 released in October…