Hi.
I’m recently making mobile robot using scooter motors and incremental encoders.
There was a problem during tuning.
Test Environment
ubuntu 16.04
With a load of 60 kg on the robot
odrive V3.6-56V, and 0.4.10 is the latest firmware version.
Scooter motor
Encoder (HEDR-5421-EP111)
only a, b pulse
2100 cpr (include reduction ratio)
=> startup_encoder_offset_calibration = True (bool)
The variable I am touching while tuning
controller.config.pos_gain (fixed at 0.5)
controller.config.vel_gain = 0.014
controller.config.vel_integrator_gain = 0.007
controller.config.vel_limit = 5000
motor.config.current_control_bandwidth (fixed at 100)
encoder.config.bandwidth (fixed at 100)
Tunning step
python3 tunning.py
- set parameter & set closed loop state
- vel_setpoint -1000 ( my motor direction is “-1”)
- 2 sec
- vel_Setpoint 0
- idle state
Symptom
In [4]: dump_errors(odrv0)
axis0
axis: no error
motor: no error
encoder: no error
controller: no error
axis1
axis: Error(s):
ERROR_CONTROLLER_FAILED
motor: Error(s):
ERROR_CONTROL_DEADLINE_MISSED
encoder: no error
controller: Error(s):
ERROR_OVERSPEED
start_liveplotter(lambda: [ odrv0.axis0.controller.vel_setpoint, odrv0.axis0.encoder.vel_estimate, odrv0.axis0.motor.current_control.Iq_setpoint*100., odrv0.axis0.motor.current_control.Iq_measured*100., odrv0.axis1.controller.vel_setpoint, odrv0.axis1.encoder.vel_estimate, odrv0.axis1.motor.current_control.Iq_setpoint*100., odrv0.axis1.motor.current_control.Iq_measured*100. ])
It is done well once at first.
Repeatedly doing the same experiment.
The axis1 motor suddenly rotates as dangerously as above.
As you can see, axis1…iq_setpoint is very high.
After above situation, Parameter list
In [5]: odrv0.axis1.motor
Out[5]:
armed_state = 0 (int)
DC_calib_phB = -0.753932535648346 (float)
is_calibrated = True (bool)
error = 0x0010 (int)
DC_calib_phC = 0.43294408917427063 (float)
timing_log:
TIMING_LOG_ADC_CB_DC = 14550 (int)
TIMING_LOG_FOC_CURRENT = 10486 (int)
TIMING_LOG_MEAS_L = 0 (int)
TIMING_LOG_FOC_VOLTAGE = 8882 (int)
TIMING_LOG_GENERAL = 0 (int)
TIMING_LOG_IDX_SEARCH = 0 (int)
TIMING_LOG_ADC_CB_I = 3902 (int)
TIMING_LOG_MEAS_R = 0 (int)
TIMING_LOG_ENC_CALIB = 8934 (int)
gate_driver:
drv_fault = 0 (int)
current_control:
overcurrent_trip_level = 33.75 (float)
v_current_control_integral_q = 0.0 (float)
v_current_control_integral_d = 0.0 (float)
final_v_alpha = -10.750458717346191 (float)
Iq_setpoint = 30.0 (float)
Ibus = 14.393915176391602 (float)
I_measured_report_filter_k = 1.0 (float)
p_gain = 0.055089570581912994 (float)
Id_measured = -0.6554780006408691 (float)
final_v_beta = 3.133859634399414 (float)
i_gain = 27.047452926635742 (float)
Iq_measured = 21.923112869262695 (float)
max_allowed_current = 30.375 (float)
config:
motor_type = 0 (int)
phase_inductance = 0.0005508956965059042 (float)
phase_resistance = 0.27047452330589294 (float)
inverter_temp_limit_lower = 100.0 (float)
requested_current_range = 25.0 (float)
current_control_bandwidth = 100.0 (float)
calibration_current = 10.0 (float)
current_lim = 30.0 (float)
pre_calibrated = True (bool)
pole_pairs = 15 (int)
inverter_temp_limit_upper = 120.0 (float)
resistance_calib_max_voltage = 4.0 (float)
direction = -1 (int)
get_inverter_temp()
thermal_current_lim = 139.79164123535156 (float)
current_meas_phC = -0.05028080940246582 (float)
phase_current_rev_gain = 0.012500000186264515 (float)
current_meas_phB = -0.0312504768371582 (float)
In [6]: odrv0.axis1.encoder
Out[6]:
set_linear_count(count: int)
shadow_count = 855 (int)
error = 0x0000 (int)
interpolation = 0.5 (float)
phase = -1.2407751083374023 (float)
calib_scan_response = 1125.0 (float)
pos_estimate = 855.9981079101562 (float)
pos_cpr = 855.97509765625 (float)
hall_state = 5 (int)
config:
enable_phase_interpolation = True (bool)
calib_range = 0.019999999552965164 (float)
use_index = False (bool)
calib_scan_distance = 50.26548385620117 (float)
calib_scan_omega = 12.566370964050293 (float)
ignore_illegal_hall_state = False (bool)
mode = 0 (int)
offset_float = 0.14659374952316284 (float)
offset = -517 (int)
cpr = 2100 (int)
idx_search_unidirectional = False (bool)
pre_calibrated = True (bool)
bandwidth = 100.0 (float)
zero_count_on_find_idx = True (bool)
find_idx_on_lockin_only = False (bool)
count_in_cpr = 855 (int)
vel_estimate = 0.0 (float)
index_found = False (bool)
is_ready = True (bool)
In [7]: odrv0.axis1.config
Out[7]:
lockin:
vel = 40.0 (float)
current = 10.0 (float)
accel = 20.0 (float)
finish_distance = 100.0 (float)
ramp_time = 0.4000000059604645 (float)
finish_on_vel = False (bool)
finish_on_distance = False (bool)
ramp_distance = 3.1415927410125732 (float)
finish_on_enc_idx = False (bool)
startup_sensorless_control = False (bool)
startup_encoder_offset_calibration = True (bool)
enable_step_dir = False (bool)
startup_encoder_index_search = False (bool)
counts_per_step = 2.0 (float)
step_gpio_pin = 7 (int)
dir_gpio_pin = 8 (int)
startup_motor_calibration = False (bool)
watchdog_timeout = 0.0 (float)
startup_closed_loop_control = False (bool)
In [8]: odrv0.axis1.controller
Out[8]:
set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
vel_ramp_enable = False (bool)
error = 0x0001 (int)
current_setpoint = 0.0 (float)
vel_integrator_current = 0.0 (float)
move_to_pos(pos_setpoint: float)
config:
vel_gain = 0.014000000432133675 (float)
vel_limit = 5000.0 (float)
control_mode = 2 (int)
setpoints_in_cpr = False (bool)
vel_limit_tolerance = 1.2000000476837158 (float)
vel_integrator_gain = 0.009999999776482582 (float)
vel_ramp_rate = 10000.0 (float)
pos_gain = 0.5 (float)
vel_ramp_target = 0.0 (float)
vel_setpoint = 0.0 (float)
set_current_setpoint(current_setpoint: float)
move_incremental(displacement: float, from_goal_point: bool)
start_anticogging_calibration()
set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
pos_setpoint = 0.0 (float)
Suspicious point
(After above situation)
Iq_setpoint = 30.0 (float) => I don’t touch any current_setpoint.
Is the current integral variable inside the controller too high?
Question
- Is it simply a gain problem? Is my gain too high?
- Why is the current target value raised?
- Is there any other checkable variable?
Thank you.