Motor = spring ?how?

Hi All,

I have the following set:
ODrive 56V v3.6
D6374 motor with 10cm lever attached to its shaft
AS5047p (AB mode; cpr=4000) encoder
20Amps power supply.

odrive tool setup:
odrv0.axis0.encoder.config.cpr = 4000
odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

When I move the motor shaft out of the balanced position the motor counteracts
(trying to move its shaft back to the origin),
I can feel that torque produced by the motor is … how to say… not smooth

  1. Which parameters should I change to get the smoothest possible torque?
    (to make my motor torque similar to a spring?)

  2. Which parameters should I change to get:

Thanks in advance.

Get a different motor with no cogging torque.

That should just work out of the box. Do you have any errors (dump_errors(odrv0))?

any examples? is there any parameter I should take into account (no. of pole pairs?)
I have to produce quite significant torque (35kgx10cm) most probably I will have to use a gearbox.
(the gearbox should be …reversible? - when I move the last gear I should be able to move the motor shaft. I think 10:1 chain drive will do).
Which parameters should be changed to play with spring parameters of the motor?
(pos_gain, vel_gain, vel_integrator_gain?)

no errors.
I tried different combinations of:
the shaft is slowly moving back and forth (eventually doing a full revolution)
when I call odrv0.axis0.controller.start_anticogging_calibration() function, odrivetool goes to a new line immediately:
In [xx]:
when I check: odrv0.axis.controller.anticogging_valid after a while (even 12minutes) I always get False.

Ideally you’d use a motor that doesn’t have iron in it, i.e. ‘slotless’ ‘coreless’ ‘ironless’ etc.
e.g. AFPM motors designed for wind turbines

What about something like this:

No, this is probably the opposite of what you want. E-Bike motors (like mine) have quite a high cogging torque. Although the inertia is usually so high that you don’t notice it. They also have a lot of magnetic hysteresis drag.
Unless it specifically says slotless/coreless/ironless, then it’s most likely a standard radial-flux motor with straight iron slots, because that produces the most power for a given volume. (volumetric power density)

This one should do (this is a generator)?
I have different parameters to chose from:
Voltage: 12/24/48

Which one should I chose to get:

  1. Highest torque
  2. Lowest power supply demands

As this is a 100W gen/motor
With 12v it should draw 100W/12=~8A ?
With 48V ~ 2A
Is that correct?

Which parameters/commands in the odrivetool are responsible for setting „spring parameters” of motor?

And what about anticogging feature?
Should this help in my present setup?

Yes, same thing. They are current/torque transducers. Both are quantities that can be positive or negative :stuck_out_tongue:
If you reverse the current, you reverse the torque, and so you reverse the flow of energy (if you don’t also reverse the velocity)

If you pick the 48V motor, then you will get maximum efficiency (because resistive power loss goes with the square of current) but beware that you might not be able to reach the rated RPM with the ODrive (because the ODrive limits the applied voltage to 80% of the supply voltage) so you might want to pick a slightly higher rated RPM than you need, or use a lower voltage motor and drive it with a higher voltage - it’ll be fine since the ODrive controls the current.
If you also pick the lowest RPM rating too, then you get the highest “torque efficiency” i.e. it costs very little energy to hold a static load - i.e. closest to a real spring. But obviously it can’t move very fast. If you are interested mainly in low speed / static conditions and high efficiency, then go with the 130RPM 48V motor (i.e. lowest “Kv”, highest “Kt”). This has both the highest torque AND lowest power demands, in theory.
That said, the ODrive is designed for higher currents closer to standard hobby motors. There are a couple other threads where people have needed to change the shunt resistors in order to get good control performance in the 10A range. So if you don’t want to do that, go for a lower voltage motor and/or a higher speed motor. (increased ‘Kv’, decreased ‘Kt’. The velocity constant of a motor is actually the inverse of the torque constant if you use the right units :wink:

It’s not so much how much power the motor will ‘draw’ it’s more about how much power you can put into it before it overheats. The 100W figure is probably quoted as a generator (i.e. it can usefully provide 100W power output when backdriven). That means as a motor you can probably send more than that (but you’d get 100W of mechanical output) assuming the efficiency is the same.
Your calculations are roughly correct, but remember that you can always run the ODrive at a higher DC voltage than the motor needs. It will regulate the voltage & current by itself i.e. you can run a 12V motor from a 48V supply with the ODrive, and it would send 4A to the motor while drawing not much more than 1A from the supply.

The “spring parameters” are force/displacement. But the controller is a nested velocity controller inside a position controller. If you set the velocity integrator to zero, then I’d guess your spring constant should be proportional to the product of the position gain, the velocity gain and the motor’s torque constant Kt.

YES, anticogging would help on your current setup. Try that first :slight_smile:

1 Like

ufff :slight_smile:

ok. First I’m gonna try anticogging feature however It doesnt work in my setup :confused:
I dont get any dump_errors,
When I call anticogging function it seems to do nothing.
Any idea which parameters I should change to make it working?

Probably, you have too much noise on your encoder. You need to increase controller.anticogging.config.in_position_tolerance (or something like that)
Basically the velocity must be zero and the position be correct to a certain number of coutnts and counts/sec to move on to the next step of the calibration. If you have a high-res encoder with some noise on the lower bits, that will get stuck.
You can see controller.anticogging.calibration_step (or something like that) increasing as it moves around the rotation. Once it reaches the encoder resolution (ie one rotation) it’s done.

default value is 1.0

what should be the behaviour of motor during anticogging calibration?
(one smooth revolution?)

with all ODrive parameters set to default (exept cpr), the motor goes nicely through FULL CALIB,
than in anticogging calib it slowly moves forward (with some back and forth movements), it takes a couple of minutes to do the full revolution.

That’s the one. Increase that to 2, 3, 4 or whatever until it starts to move. If it’s already moving at 1.0, leave it alone.
Is there also a vel_calib_threshold?

Yes it should go through one whole revolution, unless they’ve since improved it to do multiple revolutions forwards and back (as it really should)

When it’s finished and returned to normal operation, you can set anticogging_active to true, put it in current control mode at zero, and give it a turn by hand to see if you can feel any improvement.

there is : .calib_vel_threshold = 1.0

in a closed_loop i start anticogging calib, and during this calib I can change all necessary parameters, right? or I have to stop, change parameters and start again?

You can change them during the process, but if you do, I’d probably run it once more when it finishes so that the whole table is created with the same settings.


set cpr = 4000
full calib
closed loop
start_anticogging_calibration() - does nothing,
When I changed pos_gain from 20(default) to 200 the rotor started to move.
It takes a couple of minutes to finish the calibration (one revolution).
is that normal?

Are anticogging_calibration results always the same?
(or maybe they depend on my gain, vel etc…settings?)
is it possible to make it sometimes better sometimes worse (depending on my odrive settings)?

after a couple of minutes:
odrv0.axis0.controller.anticogging_valid ======> TRUE :slight_smile:

is it normal that when I rotate the motor (current_control mode = 0) to one direction (same direction as during anticogging calib) the force I feel on the shaft is different then when I rotate the shaft to the opposite direction?
(it is easier to rotate the shaft to the ‘right’ than to the ‘left’)

is it possible to store anticogging_calibration?
(It looks like it is . after save_configuration() and reboot, I changed anticogging_valid = True (was false), and when I toggle between
anticogging_enabled = True/False I can feel a difference; or maybe It was a power of suggestion :rofl:)

Read through this blog post, and pay special attention to the picture in chapter 5. To summarize, the larger the least-common-denominator of your magnetic + winding poles the less cogging torque you will have.

Also be careful with the anti-cogging function. Compensating for cogging torque requires additional control effort, which increases the likelyhood of overheating your board or motor.

I use 20Amps max (power supply capability), the motor can draw 70Amps max.
Should I still be affraid?

Hmm, does it? I’m not following you there.
Yes, cogging is a ‘torque disturbance’ as a function of position, and anticogging is a ‘current disturbance’ as a function of position. But it applies to the demand input of the current controller, not the actual output. I’m not sure how it would affect its stability or envelope. The configured current limit should still be in force, for example.

You are correct.

The reason I mention it is primarily annecdotal. I burnt out one of my boards running the anti-cogging software. My motor had very high cogging torque, and maintaining position during the anti-cogging-calibration algorithm required relatively high continuous currents (and control effort). My normal use-case didn’t require accuracy between “cog’s”, so I wasn’t familiar with the power required to hold these positions. In the end I moved to motors with less cogging torque, and I realised it was something I should have done earlier.

Here’s a link to the motor, it’s an inrunner with something like 6s18p.

Guys, coming back to my question,
I would appreciate your further help:

  1. Are anticogging_calibration results always the same?
    (or maybe they depend on my gain, vel, other…settings?)
    is it possible to make it sometimes better sometimes worse (depending on my odrive settings)?
    What should I do to get the best anticogging calibration results?

  2. Im gonna use anticogging feature in POSITION_CONTROL, are there any limitations?
    (I think Ive read somewhere about current_control&anticogging limitations)
    (I need to set a zero position, than rotate (by hand) the shaft by ~3 revolutions, and It should come back to the origin)

  3. in the position_control mode:
    pos_gain - “coresponds to the accuracy of setting present position”
    vel_gain - “proportional to the strength of the motor shaft - current”
    vel_integrator_gain -“corresponds to origin position overshooting”
    is that ~correct?

  4. is there anything else I could tune to get the smoothest motor shaft behavior in the position_control mode (motor shaft rotated by hand from its zero position)

  5. i think that when using anticogging feature, motor shaft respons to manual-hand disturbance is different in left vs right direction