Motor not calibrating with relatively high friction load

One of my motors is set up to a mini capstan kind of like this (link) that moves a trolley along a rail. So the load is just a friction load, albeit a fairly high amount of friction.

The problem I’m having is that the calibration doesn’t seem to have enough force to be able to run any of the calibration sequences. I’ve bumped up the calibration current up to 25 amps but when I looked at the graph during various calibration sequences it doesn’t even get close to that high (the highest amps I saw was about 7 or 8). I also tried bumping up the odrv0.axis1.motor.config.resistance_calib_max_voltage which didn’t seem to help either.

Here are my config parameters:

odrv0.config.enable_brake_resistor = True				
odrv0.config.brake_resistance = 2
odrv0.config.dc_max_negative_current = -0.01
odrv0.axis1.config.startup_encoder_index_search = False
odrv0.axis1.motor.config.pole_pairs = 7
odrv0.axis1.motor.config.torque_constant = 8.27/150
odrv0.axis1.motor.config.motor_type = 0
odrv0.axis1.motor.config.pre_calibrated = True
odrv0.axis1.encoder.config.cpr = 8192
odrv0.axis1.encoder.config.use_index = True
odrv0.axis1.encoder.config.mode = ENCODER_MODE_INCREMENTAL
odrv0.axis1.controller.config.vel_limit = 10
odrv0.axis1.motor.config.current_lim = 20
odrv0.axis1.motor.config.calibration_current = 20
odrv0.axis1.motor.config.requested_current_range = 40
odrv0.axis1.encoder.config.pre_calibrated = True
odrv0.save_configuration()

The error that appears after trying the full calibration sequence is:

system: no error
axis0
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: Error(s):
    MOTOR_ERROR_PHASE_INDUCTANCE_OUT_OF_RANGE
    MOTOR_ERROR_CURRENT_LIMIT_VIOLATION
  sensorless_estimator: no error
  encoder: no error
  controller: no error

Oddly enough I manually pushed the motor to the point where the index is, then ran the odrv0.axis1.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH
and this made the full calibration sequence work properly and allowed me to go into closed loop control and move around.
Obviously that’s not a real solution so I’m scratching my head to figure out what else to try.
Thanks for your help!

Oh and I’m using this encoder: 8192 CPR Encoder with ODrive v3 Cable — ODrive
and this motor: Dual Shaft Motor - D6374 150kv — ODrive

Im interested to learn how you solved the problem. Im to having similar aplication with a lot of friction, and the motor cannot calibrate it self properly.

Just to clarify: I see that you have motor.config.pre_calibrated = True, you did successfully run either MOTOR_CALIBRATION or FULL_CALIBRATION_SEQUENCE before setting this value and then saved the configuration? These errors suggest that the motor calibration did not run successfully or was not saved.
Are you able to get the ODrive and motor fully calibrated and running closed loop control with the high friction load removed?

I hadn’t actually successfully run those before saving the calibration config, good point. I’ll try this without and report back. Thanks for noticing that.

Unfortunately that didn’t make a difference thanks for your idea anyway.

I had a similar situation and issue. I was able to resolve it by increasing calibration_lockin.current and general_lockin.currrent (I think the default is 10 amps).

2 Likes

Like Nick said, you can’t set pre_calibrated to True until after calibration is complete.

encoder.config.use_index = True
<Motor Calibration>
<Encoder Index Search>
<Encoder Offset Calibration>
motor.config.pre_calibrated = True
encoder.config.pre_calibrated = True
odrv0.save_configuration()

Then at reboot you just do the index search (not the offset calibration) and you should be good. If you need more torque then increase the calibration and general lockin currents as suggested by trumans24.

  1. The motor was under a decent friction load. I removed the load.
  2. rebooted the system.
  3. started going through the setup proceedure that has worked with axis0 on this odrive (axis0 performs a different function).
  4. checked the lockin currents. considering there is no more load, they seem high.
  5. rebooted
  6. checked the current values were still set
  7. tried running index search and it failed
  8. cleared errors
  9. tried running full calibration sequence and it failed again.
    completely lost
In [3]: odrv0.axis1.motor.config.pre_calibrated = False

In [4]: odrv0.save_configuration()
Oh no odrv0 disappeared

Reconnected to ODrive 206235A55748 as odrv0

In [5]: odrv0.axis1.config.general_lockin.current
Out[5]: 10.0

In [6]: odrv0.axis1.config.calibration_lockin.current
Out[6]: 10.0

In [7]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive 206235A55748 as odrv0
In [8]: odrv0.axis1.config.calibration_lockin.current
Out[8]: 10.0

In [9]: odrv0.axis1.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH

In [10]: dump_errors(odrv0)
system: no error
axis0
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: Error(s):
    MOTOR_ERROR_MODULATION_IS_NAN
  sensorless_estimator: no error
  encoder: no error
  controller: no error

In [11]: odrv0.clear_errors()

In [12]: odrv0.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE

In [13]: dump_errors(odrv0)
system: no error
axis0
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: Error(s):
    MOTOR_ERROR_PHASE_INDUCTANCE_OUT_OF_RANGE
    MOTOR_ERROR_CURRENT_LIMIT_VIOLATION
  sensorless_estimator: no error
  encoder: no error
  controller: no error

This helped me a lot with similar situation. Have you tried that @sage?

they are set at 10 A. The system has no resistance. 10A can move a couple lbs. This should be more than enough. I could try increasing it still, but I’d be surprised if it helped so i didn’t try it yesterday

In [5]: odrv0.axis1.config.general_lockin.current
Out[5]: 10.0

In [6]: odrv0.axis1.config.calibration_lockin.current
Out[6]: 10.0

This means the motor didn’t calibrate properly. Can you paste your whole procedure? Just the commands you’re sending in a blob. If the motor and encoder are physically working correctly, this is all you should need:

odrv0.erase_configuration()

odrv0.config.enable_brake_resistor = True
odrv0.config.dc_max_negative_current = -1
odrv0.axis0.encoder.config.use_index = True
odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION
odrv0.axis0.motor.config.pre_calibrated = True
odrv0.axis0.encoder.config.pre_calibrated = True
odrv0.save_configuration()

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
1 Like

You can plot the current consumption during closed loop(which you can start manually, as you described above) and see what current does your motor need to move in closed loop. Then you can set the locking currents high enough so the motor can overcome the load while calibrating. That is what i have done and it worked for me.

!!!
it works now! I thought my motor was broken. the erase_configuration() was the key for sure.

The odrv0.axis1.config.general_lockin.current and odrv0.axis1.config.calibration_lockin.current might come in handy when I add the friction back on, but for now its nice to know it moves.

Problem not fully solved, but subproblem solved. will update once I try again with friction load.

1 Like

i tried again and it failed. friction is still off the system and i ran the following

In [6]: odrv0.erase_configuration()
Oh no odrv0 disappeared

Reconnected to ODrive 206235A55748 as odrv0
In [7]: odrv0.config.enable_brake_resistor = True

In [8]: odrv0.config.dc_max_negative_current = -1

In [9]: odrv0.axis1.encoder.config.use_index = True

In [10]: dump_errors(odrv0)
system: no error
axis0
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error

In [11]: odrv0.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE

In [12]: dump_errors(odrv0)
system: no error
axis0
  axis: no error
  motor: no error
  sensorless_estimator: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: Error(s):
    MOTOR_ERROR_BRAKE_RESISTOR_DISARMED
  sensorless_estimator: no error
  encoder: no error
  controller: no error

is there another company you would recommend that has a more straightforward process of turn on, set amp limit, move motor. Its been days if not weeks of messing around with the tutorials/setups/these threads

Do you have your brake resistor plugged in?

Kollmorgen, Yaskawa, Siemens, Parker. The idea with ODrive is to make motor control more accessible… but there are growing pains. We recognize that the user experience could be better, but I don’t think 6 configuration commands is particularly egregious :wink:

any idea why this one variable isn’t saving. the second disappearing is when I power off the system after the configuration.

In [86]: odrv0.axis1.motor.config.current_lim
Out[86]: 12.0

In [87]: odrv0.axis1.motor.config.current_lim = 20

In [88]: odrv0.clear_errors()

In [89]: odrv0.save_configuration()
Oh no odrv0 disappeared

Reconnected to ODrive 206235A55748 as odrv0
Oh no odrv0 disappeared
Reconnected to ODrive 206235A55748 as odrv0
In [90]: odrv0.axis1.motor.config.current_lim
Out[90]: 12.0

Thanks for noticing the brake resistor had come out and wasn’t plugged in.
The following sequence of events has been working. I’m confused why the one configuration param needs to be reset after every time the system is turned off and on, but its a bug we can work with.

remove load

power on

odrv0.clear_errors()

odrv0.erase_configuration()

odrv0.config.enable_brake_resistor = True
odrv0.config.dc_max_negative_current = -1
odrv0.axis1.encoder.config.use_index = True
odrv0.config.enable_brake_resistor = True
odrv0.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis1.motor.config.pre_calibrated = True
odrv0.axis1.encoder.config.pre_calibrated = True
odrv0.axis1.motor.config.current_lim = 20
odrv0.axis1.config.general_lockin.current = 20
odrv0.axis1.config.calibration_lockin.current =20
odrv0.save_configuration()

power off
put full load on
power on

odrv0.clear_errors()
odrv0.axis1.motor.config.current_lim = 20
odrv0.axis1.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH
start_liveplotter(lambda: [odrv0.axis1.motor.current_control.Iq_measured])
odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
odrv0.axis1.controller.input_pos = 1
1 Like

That generally means you’re having USB noise issues, but since it’s just this one parameter I’m inclined to believe maybe it’s some other device setting the current_lim. Because the default is 10, not 12… So that’s strange.

1 Like

SOLVED
the last little issue isn’t a blocker for us, the main calibration during friction issue is solved so I wanted to mark it solved and thank the support here for the help :clap:

1 Like