Sensorless at high speed

Hi, at the moment I try to get the D5065 motor to run sensorless at higher speed and with no load via python code. The code works fine til 850rpm, above the motor spin up for some seconds and then suddenly stops. To change the acceleration value do not really changes the effect.
What must be changed to reach higher speed limits in sensorless mode? The motor should work til ~5000rpm.

  • Supply 24V / 3A

  • HW V3.6 56V & firmware version 0.5.1

  • my py code (core part without calibration part) →

    my_drive.axis0.sensorless_estimator.config.pm_flux_linkage = 5.51328895422 / (7 * 270)
    my_drive.axis0.controller.config.vel_gain = 0.01
    my_drive.axis0.controller.config.vel_integrator_gain = 0.05
    my_drive.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL

    SPEED = 850 # rpm
    RAMPTIME = 8 # sec
    radvel = (SPEED / 60) * 6.28 # rad/s mech
    radvel = radvel * 7 # rad/s el

    accel = radvel / RAMPTIME
    my_drive.axis0.config.sensorless_ramp.accel = accel # rad/s^2 el
    my_drive.axis0.config.sensorless_ramp.vel = radvel # rad/s el

    velocity = my_drive.axis0.config.sensorless_ramp.vel / (6.28*7) # turns/s me
    my_drive.axis0.controller.input_vel = velocity

    print("Velocity el [rad/s] = " + str(radvel))
    print("Velocity me [turns/s] = " + str(velocity))
    print("Acceleration me [rad/s^2] = " + str(accel))

    my_drive.axis0.controller.config.vel_limit = 1.2 * velocity
    my_drive.axis0.config.sensorless_ramp.current = 10
    my_drive.axis0.motor.config.current_lim = 2.0 * my_drive.axis0.config.sensorless_ramp.current
    my_drive.axis0.motor.config.direction = 1

    my_drive.axis0.requested_state = AXIS_STATE_SENSORLESS_CONTROL

thx for help Hannes

I’m confused about how you’re using the sensorless ramp vel here… You want it to start (sensorless_ramp) and then be controllable via input_vel, right?

Also, as of 0.5.1 the velocity units in sensorless are in terms of turns/sec not rad/s, so you might just be off by a factor of 2*pi

thx for the 2*PI hint, but in the docu I found rad/s… ok
Yes my aim is to get in linear/continuous ramp up to the disired speed [rpm] without speed-steps. The motor runs now like that, but what do you mean exact about the confusing code? Are the lines missing or wrong? What must be changed?

modified py code:

SPEED = 2000 # rpm

vel = (SPEED / 60) * 7 # turns/sec el
my_drive.axis0.config.sensorless_ramp.vel = vel
velocity = my_drive.axis0.config.sensorless_ramp.vel / 7 # turns/sec mech
my_drive.axis0.controller.config.vel_limit = 1.05 * velocity # 5% tolerance
my_drive.axis0.controller.input_vel = velocity

my_drive.axis0.controller.config.vel_gain = 0.01
my_drive.axis0.controller.config.vel_integrator_gain = 0.05
my_drive.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL
my_drive.axis0.sensorless_estimator.config.pm_flux_linkage = 5.51328895422 / (7 * 270)
my_drive.axis0.motor.config.direction = 1

my_drive.axis0.requested_state = AXIS_STATE_SENSORLESS_CONTROL

If anyone has better running code, I would be very happy!

Can you link where that is (or just fix it via PR?)

Don’t set sensorless_ramp.vel to max, set it to like… 5 or 10. Then it will switch to normal input_vel at that point. Use INPUT_MODE_VEL_RAMP

1 Like

to your question about the rad/s stuff: Parameters & Commands | ODrive (odriverobotics.com)

now…
this is my current running code, but I am not sure if I am real in sensorless mode, because of the very early switching from mode idle (1) to sensorless(5) → see at the following screenshot

SPEED = 1000 # rpm
RAMPTIME = 5 # sec

Parameters & Commands | ODrive

cnt = 0
print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate*60)
my_drive.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
my_drive.axis0.controller.config.vel_gain = 0.01
my_drive.axis0.controller.config.vel_integrator_gain = 0.05
my_drive.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL
my_drive.axis0.sensorless_estimator.config.pm_flux_linkage = 5.51328895422 / (7 * 270)

my calculations

velocity = SPEED / 60
accel = velocity / RAMPTIME
my_drive.axis0.config.sensorless_ramp.vel = velocity / 5 # trial

#ODrive | High performance motor control
print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate*60)
my_drive.axis0.controller.config.vel_ramp_rate = accel
my_drive.axis0.controller.config.input_mode = INPUT_MODE_VEL_RAMP
my_drive.axis0.controller.input_vel = velocity

#Parameters & Commands | ODrive
print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate*60)
my_drive.axis0.controller.config.vel_limit = 1.05 * velocity
my_drive.axis0.config.sensorless_ramp.current = 3
my_drive.axis0.motor.config.current_lim = 2.0 * my_drive.axis0.config.sensorless_ramp.current
my_drive.axis0.motor.config.direction = 1

print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate * 60)
my_drive.axis0.requested_state = AXIS_STATE_SENSORLESS_CONTROL
print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate*60)

while cnt < TIME_LIMIT:
cnt = cnt + 1
time.sleep(0.5)
print(cnt,my_drive.axis0.current_state, my_drive.axis0.lockin_state,
my_drive.axis0.sensorless_estimator.vel_estimate*60)

the log prints looks like that:

thx everyone who can help :slight_smile: