Problem with Closed Loop Velocity Control


#1

This is configuration steps I have followed

    odrv0.erase_configuration()
    odrv0.reboot()
    odrv0.config.brake_resistance=0				
    odrv0.axis0.motor.config.pole_pairs=20			
    odrv0.axis0.motor.config.motor_type =MOTOR_TYPE_HIGH_CURRENT
    odrv0.axis0.encoder.config.cpr =9568				
    odrv0.save_configuration()
    odrv0.reboot()

Then for Velocity Control i have followed.

    odrv0.axis0.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL
    odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
    odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
    odrv0.axis0.controller.vel_setpoint = 20000			

Problem faced:
For few seconds motor rotates and then decelerates and stops. After stopping it starts drawing a lot of current and eventually gets hot.
then it remains in the same state (drawing current and being still) even after changing the vel_setpoint value.


#2

It is likely that your CPR value is a few % off. What encoder are you using?


#3

Thanks @madcowswe for your reply.
Encoder Used of 4096 CPR but as I have used gear to couple motor and encoder the approx gear ratio is 56: 24. So for one revolution, it comes to be 4096*56/24= 9557.33. Rounding it off to 9556.
Which accounts to the error of 0.0139%.
Here is the video link https://drive.google.com/open?id=1cg9Z0RGb8J-CrqUaVHTjBmtq54O-j7ho
The Motor starts and reaches the required velocity for few seconds then it stops all of sudden and starts vibrating.
And if I try to manually rotate the shaft it gets back to the original position(mean position) where it was vibrating.
I have also checked for error but all the bits were 0.


Hopes for a quick reply!!


#4

Rounding is not acceptable. The CPR must be an exact integer. If you can’t do that you need to change your encoder or gear ratio.
You may also use an exact multiple of a revolution as your CPR. So you can use CPR = 9557.33 * 3 = 28672, which is an integer.


#5

Sir, When I am trying to implement this I am getting CPR_OUT_OF_RANGE error.

So I again tried to put the approximate value of 9556 and checked for error. the following I am getting are;

error = 0x0060 (int)
step_dir_active = False (bool)
current_state = 1 (int)
requested_state = 0 (int)
loop_counter = 22084690 (int)
config:
 startup_motor_calibration = False (bool)
 startup_encoder_index_search = False (bool)
 startup_encoder_offset_calibration = False (bool)
 startup_closed_loop_control = False (bool)
 startup_sensorless_control = False (bool)
 enable_step_dir = False (bool)
 counts_per_step = 2.0 (float)
 step_gpio_pin = 1 (int)
 dir_gpio_pin = 2 (int)
 ramp_up_time = 0.4000000059604645 (float)
 ramp_up_distance = 12.566370964050293 (float)
 spin_up_current = 10.0 (float)
 spin_up_acceleration = 400.0 (float)
 spin_up_target_vel = 400.0 (float)
get_temp()
motor:
 error = 0x0400 (int)
 armed_state = 0 (int)
 is_calibrated = True (bool)
 current_meas_phB = -0.15730547904968262 (float)
 current_meas_phC = -0.23599112033843994 (float)
 DC_calib_phB = -1.9779436588287354 (float)
 DC_calib_phC = -1.4970515966415405 (float)
 phase_current_rev_gain = 0.02500000037252903 (float)
 current_control: ...
 gate_driver: ...
 timing_log: ...
 config: ...
controller:
 error = 0x0000 (int)
 pos_setpoint = -27502.236328125 (float)
 vel_setpoint = 200.0 (float)
 vel_integrator_current = -3.0297353267669678 (float)
 current_setpoint = 0.0 (float)
 vel_ramp_target = 0.0 (float)
 vel_ramp_enable = False (bool)
 config: ...
 set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
 set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
 set_current_setpoint(current_setpoint: float)
 move_to_pos(goal_point: float)
 start_anticogging_calibration()
encoder:
 error = 0x0000 (int)
 is_ready = True (bool)
 index_found = False (bool)
 shadow_count = 1940 (int)
 count_in_cpr = 1940 (int)
 interpolation = 0.5 (float)
 phase = -2.5858144760131836 (float)
 pos_estimate = 1940.248046875 (float)
 pos_cpr = 1940.238037109375 (float)
 hall_state = 5 (int)
 vel_estimate = 0.0 (float)
 config: ...
sensorless_estimator:
 error = 0x0000 (int)
 phase = 2.6372718811035156 (float)
 pll_pos = 2.6369779109954834 (float)
 vel_estimate = -0.04548677057027817 (float)
 config: ...
trap_traj:
 config: ...

Error are : ERROR_MOTOR_DISARMED = 0x20, ERROR_MOTOR_FAILED = 0x40,
ERROR_CURRENT_SENSE_SATURATION = 0x0400.

What is meant by ERROR_MOTOR_DISARMED?
and why there is ERROR_CURRENT_SENSE_SATURATION error even though I have set odrv0.axis0.motor.config.current_lim = 80.0.

I am using LiPo Battery with discharge current of 240Amps

Please help me out.


#6

Apologies, I forgot to mention that if you multiply up the CPR, you need to also multiply up the pole pairs of the motor.
So you can use CPR = 9557.33 * 3 = 28672, which is an integer
AND set odrv0.axis0.motor.config.pole_pairs to 3x the number you would otherwise set it to.


#7

It worked!!
But on even a small external retarding torque on shaft (by slightly holding by fingers)cause a fault
ERROR_DRV_FAULT and ERROR_CONTROLLER_FAILED


#8

Can you dump what you get for odrv0.axis, so I can decode the error flags to verify?


#9
error = 0x0200 (int)
step_dir_active = False (bool)
current_state = 1 (int)
requested_state = 0 (int)
loop_counter = 2061657 (int)
config:
  startup_motor_calibration = False (bool)
  startup_encoder_index_search = False (bool)
  startup_encoder_offset_calibration = False (bool)
  startup_closed_loop_control = False (bool)
  startup_sensorless_control = False (bool)
  enable_step_dir = False (bool)
  counts_per_step = 2.0 (float)
  step_gpio_pin = 1 (int)
  dir_gpio_pin = 2 (int)
  ramp_up_time = 0.4000000059604645 (float)
  ramp_up_distance = 12.566370964050293 (float)
  spin_up_current = 10.0 (float)
  spin_up_acceleration = 400.0 (float)
  spin_up_target_vel = 400.0 (float)
get_temp()
motor:
  error = 0x0010 (int)
  armed_state = 0 (int)
  is_calibrated = True (bool)
  current_meas_phB = 0.0730060338973999 (float)
  current_meas_phC = -0.033002614974975586 (float)
  DC_calib_phB = -2.0466277599334717 (float)
  DC_calib_phC = -1.5783289670944214 (float)
  phase_current_rev_gain = 0.02500000037252903 (float)
  current_control: ...
  gate_driver: ...
  timing_log: ...
  config: ...
controller:
  error = 0x0001 (int)
  pos_setpoint = -33.25 (float)
  vel_setpoint = 40000.0 (float)
  vel_integrator_current = 2.1428003311157227 (float)
  current_setpoint = 0.0 (float)
  vel_ramp_target = 0.0 (float)
  vel_ramp_enable = False (bool)
  config: ...
  set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
  set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
  set_current_setpoint(current_setpoint: float)
  move_to_pos(goal_point: float)
  start_anticogging_calibration()
encoder:
  error = 0x0000 (int)
  is_ready = True (bool)
  index_found = False (bool)
  shadow_count = 983238 (int)
  count_in_cpr = 8838 (int)
  interpolation = 0.5 (float)
  phase = -2.8266897201538086 (float)
  pos_estimate = 983238.0625 (float)
  pos_cpr = 8838.2412109375 (float)
  hall_state = 5 (int)
  vel_estimate = 0.0 (float)
  config: ...
sensorless_estimator:
  error = 0x0000 (int)
  phase = -1.4754602909088135 (float)
  pll_pos = -1.473772406578064 (float)
  vel_estimate = 0.058250755071640015 (float)
  config: ...
trap_traj:
  config: ...

#10

Hm it is not normal to have Motor error (in this case 0x0010) without having a corresponding Axis error AXIS_ERROR_MOTOR_FAILED.

Either way, your controller error is ERROR_OVERSPEED. Probably because your vel_lim is very low and your tuning makes it overshoot the speed. Either raise the controller.config.vel_limit_tolerance or improve the tuning to avoid overshoot.


#11

Sir, I am retarding the motion so definitely it won’t be overshooting the speed. And on retarding it throws the error and stops.


#12

Thanks. I got it working. Problem was with the current limit as there was spikes beyond 60A.
Setting the

odrv0.axis0.motor.config.requested_current_range = 80

Solved the problem.


#13

Okay glad to hear it.