No torque in torque mode

Hi together!

i am trying to get my motor (https://alienpowersystem.com/product-category/brushless-motors/50mm/) running on the 56V-ODrive. After trying for hours, i finally managed to get a successfull calibration run, motor is now calibrated, encoder is ready. Now i wanted to test the torque mode and see, if i get any force on the motor shaft. So i set

odrv0.axis1.controller.input_torque = 1
odrv0.axis1.controller.config.control_mode = 1

and set state to closed loop. The ODrive switches successfully, i hear some current flowing but the motor has now force at all, i can rotate it easily. Can someone please point me in some direction to get that running? Should / can i somehow post the complete configuration of my odrive?

Thanks, Max

I managed to get the motor turning in velocity control, but i had to manually push the motor to get turning. It feels like i have accidantely limitted the motor current, but can’t find any setting telling me so:

odrv0.axis1.motor.config.current_lim = 10

Also, the motor runs very very jerky, it feels like i could feel every magnet when rotating…

That is normal, it’s called “Cogging Torque”. It’s a struggle with these hobby motors.

For the torque mode case, check your errors dump_errors(odrv0)

Hi Wetmelon,

thanks for your reply. Today i wanted to reproduce the behaviour but couldn’t really. Today, as soon as i activate closed loop control with controller.control_mode = 1 and controller.input_torque = 1 the motor makes one short enourmous jump (very fast) and immediately stops. The following is the error-dump after that event:

  axis: Error(s):
    AXIS_ERROR_MOTOR_FAILED
  motor: Error(s):
    MOTOR_ERROR_CURRENT_LIMIT_VIOLATION
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error```

It looks like the controller total runs crazy and shoots way over the top..

Thanks for your help,

Max

The same happens when using positon control mode. It feels like the controler wants to reach a position very far away with a very high speed and then exceeds the given velocitiy or current limits…
The only reason i can think of would be a very wrong encoder signal, but the calibration process (including encoder calibration) runs successfully…

Keep in mind you’re setting input torque, which uses the odrv.axis.motor.config.torque_constant, in Nm/A. So if you want 1 Nm of torque, you’re going to get something like 25A by default ( 1 / 0.04). That will probably exceed the ability of the odrive to keep up with the acceleration.

Maybe i am getting Torque Mode wrong then. But what about the Position Control Mode, where i am experiencing the same behaviour? Its not that i am confused about the Errors, they absolutely make Sense because the Motor ist Shooting away. My Problem is that i dont know why it shoots away Like this…

Thank you for your Help!

In position mode, make sure you set controller.input_pos = encoder.pos_estimate first. Otherwise it might immediately try to reach some other position (such as zero) when it is not starting at zero.

Also input_torque should = 0, even in position mode (unless you know ahead of time how much torque you need)

Ok thank you for your help, that cleared many problems in understanding. I now am trying to make some moves with the trap_traj mode, which basically works. None the less, the motor behaviour is very strange and it feels like there is something terribly wrong.

The following is the picture of a motion profile from pos 0 to 50:
image

Can anyone point me in a direction how i could tune the controller behaviour here? Also, the motor cogging feels very extreme, i have never seen / felt a motor that bumpy before. It really shakes my whole hand when driving.

Thank you so much for your help, a great community you have here!

Regards,
Max

Also very strange: when the motor wants to keep its current position, the controler moves by several turns, which is way to much:

I have a very strong feeling, that something in the encoder <-> motor loop is very wrong…

In the following picture you see the current (motor.current_meas_phC, green) rising over a long time which finally results in a huge jump in the current position (encoder.pos_estimate, blue). That looks like the motor needs to much current to even begin to drive… could you think of any reason for that?

This behaviour is caused by incorrect commutation i.e. the encoder calibration is wrong. Maybe the encoder is slipping on the shaft?

should the calibration process detecet such an issue?
The encoder is mounted inside the motor case, i can not see something slipping. Can i somehow debug that, e.g. by turning the shaft manually and observing the encoder output? What would be the parameters to watch and what would be expected values for that?

Thank you for your help!

If you reset the encoder counts to zero with encoder.set_linera_count(0) and then turn the motor by hand by exactly one turn, then encoder.pos_estimate should match encoder.config.cpr. You can do this a few times to make sure the encoder is not slipping.

my cpr is 42 (7 pole pairs * 6), here are the pos_estimate_counts after several turns:

1 turn:   42.234375
2 turns:  84.234375
3 turns: 126.234375
8 turns: 336.75

so it looks basically correct event though not 100% accurate. I’d expected it to be “integer” counts, or am i wrong? E.g. 42, 84, 126, 336, …

That does look pretty rough! Have you tuned the controller gains? Here is a description of how to do so: https://docs.odriverobotics.com/control#tuning. Also, hall effect encoders are low resolution (you have 42cpr, but even the cheapest incremental encoder will be a few hundred). You should be able to get better behavior, but with only 42 recognizable positions in a revolution, there is a limit to position control performance. Especially at low speed.

I know about the low hall resoltion, but it really doesn’t feel as if the controller uses the 42 values, it feels way rougher.

Regarding the tuning: i am struggling with that description. What does “stable system” mean in my case? Without changing anything, i have a “stable system” in terms of the motor is not really moving :sweat_smile: In which mode would you suggest to run the tuning process? I am currently in position control… Do i have to run some movements for calibration or is it meant to be tuned in static position?

Another strange thing: when in position control mode, i would expect that i need at least some amount of force to rotate the motor manually against the currently commanded position. But that is not the case here, i can manually rotate the motor with almost no force at all. The motor seems to has absolutely now power! It feels like the current limit is set to almost zero, but these are the settings:

Motor.Config:

pre_calibrated = False (bool)
pole_pairs = 7 (int)
calibration_current = 10.0 (float)
resistance_calib_max_voltage = 2.0 (float)
phase_inductance = 0.0 (float)
phase_resistance = 0.0 (float)
torque_constant = 0.03999999910593033 (float)
direction = 0 (int)
motor_type = 0 (int)
current_lim = 10.0 (float)
current_lim_margin = 8.0 (float)
torque_lim = inf (float)
inverter_temp_limit_lower = 100.0 (float)
inverter_temp_limit_upper = 120.0 (float)
requested_current_range = 60.0 (float)
current_control_bandwidth = 1000.0 (float)
acim_slip_velocity = 14.706000328063965 (float)
acim_gain_min_flux = 10.0 (float)
acim_autoflux_min_Id = 10.0 (float)
acim_autoflux_enable = False (bool)
acim_autoflux_attack_gain = 10.0 (float)
acim_autoflux_decay_gain = 1.0 (float)

Controller.Config:

gain_scheduling_width = 10.0 (float)
enable_vel_limit = True (bool)
enable_current_mode_vel_limit = True (bool)
enable_gain_scheduling = False (bool)
enable_overspeed_error = True (bool)
control_mode = 3 (int)
input_mode = 1 (int)
pos_gain = 20.0 (float)
vel_gain = 0.0005000000237487257 (float)
vel_integrator_gain = 0.0010000000474974513 (float)
vel_limit = 20000.0 (float)
vel_limit_tolerance = 1.2000000476837158 (float)
vel_ramp_rate = 10000.0 (float)
torque_ramp_rate = 0.009999999776482582 (float)
circular_setpoints = False (bool)
circular_setpoint_range = 1.0 (float)
homing_speed = 0.25 (float)
inertia = 0.0 (float)
axis_to_mirror = 255 (int)
mirror_ratio = 1.0 (float)
load_encoder_axis = 0 (int)
input_filter_bandwidth = 2.0 (float)
anticogging:
  index = 0 (int)
  pre_calibrated = False (bool)
  calib_anticogging = False (bool)
  calib_pos_threshold = 1.0 (float)
  calib_vel_threshold = 1.0 (float)
  cogging_ratio = 1.0 (float)
  anticogging_enabled = True (bool)

Unfortunately, the API-Reference-Docs do not mention the units of the values at all. I assume that all current values are in ampere, all voltage values are in volt and all velocity values are in rounds per second?

Thank you for your help!! It is really great to have such an active community!!

I am so sorry about all my confusing problems, but now i am not even able to run encoder calibration anymore… i erased the configuration and ran the following commands:

odrv0.axis0.encoder.config.mode = 1
odrv0.axis0.encoder.config.cpr = 42
odrv0.axis0.motor.config.pole_pairs = 7

Now i get the ERROR_CPR_POLEPAIRS_MISMATCH which i can’t understand, because my motor defintively has 7 Polepairs, and 6*7=42.

EDIT: it looks like i have to reboot after applying these settings, now it worked again (the calibration)

1 Like

Save your config, reboot, and try again. Sometimes i’ve had weird issues with a newly-erased config.

1 Like