Hello,
I spent a couple of hours on the discourse searching for a solution for my problem, but I am yet to find something.
I am trying to configure Odrive for a hoverboard motor, but I want to use an incremental encoder instead of the built-in HAL encoder.
I configured the motor according to the ODrive documentation (from git-hub tag fw-0.4.11), but for the encoder configuration I used:
- odrv0.axis0.encoder.config.mode = ENCODER_MODE_INCREMENTAL
- odrv0.axis0.encoder.config.cpr = 8192
- odrv0.axis0.encoder.config.bandwidth = 1000
The calibration for the motor and the encoder are successful (the motor beeps during the motor calibration, and it spins during the encoder calibration), but when I try to test the velocity loop control, the motor does not spin.
Any suggestion what I did wrong, or what do I have to configure extra?
I would prefer not to update for now to the latest firmware, because my robot control SW relies on the FW 0.4 API.
I have the following setup:
- ODrive HW v3.6.56
- ODrive FW v0.4.11
- 10S LiPo (42v) as power supply
- 2 Ohm break resistor
- AMT102 incremental encoder
After configuration I have the following config:
Controller stats:
config:
control_mode: 2 (uint8)
pos_gain: 1.0 (float)
setpoints_in_cpr: False (bool)
vel_gain: 0.019999999552965164 (float)
vel_integrator_gain: 0.10000000149011612 (float)
vel_limit: 1000.0 (float)
vel_limit_tolerance: 1.2000000476837158 (float)
vel_ramp_rate: 10000.0 (float)
current_setpoint: 0.0 (float)
error: 0 (uint8)
move_incremental(obj: object_ref, displacement: float, from_goal_point: bool)
move_to_pos(obj: object_ref, pos_setpoint: float)
pos_setpoint: 0.0 (float)
set_current_setpoint(obj: object_ref, current_setpoint: float)
set_pos_setpoint(obj: object_ref, pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
set_vel_setpoint(obj: object_ref, vel_setpoint: float, current_feed_forward: float)
start_anticogging_calibration(obj: object_ref)
vel_integrator_current: 0.0 (float)
vel_ramp_enable: False (bool)
vel_ramp_target: 0.0 (float)
vel_setpoint: 120.0 (float)
Motor stats:
DC_calib_phB: -0.7780774235725403 (float)
DC_calib_phC: -0.34574565291404724 (float)
armed_state: 0 (uint8)
config:
calibration_current: 10.0 (float)
current_control_bandwidth: 100.0 (float)
current_lim: 10.0 (float)
current_lim_tolerance: 1.25 (float)
direction: -1 (int32)
inverter_temp_limit_lower: 100.0 (float)
inverter_temp_limit_upper: 120.0 (float)
motor_type: 0 (uint8)
phase_inductance: 0.0004055439494550228 (float)
phase_resistance: 0.22742202877998352 (float)
pole_pairs: 15 (int32)
pre_calibrated: True (bool)
requested_current_range: 25.0 (float)
resistance_calib_max_voltage: 4.0 (float)
current_control:
I_measured_report_filter_k: 1.0 (float)
Ibus: 0.0 (float)
Id_measured: 0.0 (float)
Iq_measured: 0.0 (float)
Iq_setpoint: 0.0 (float)
final_v_alpha: 0.0 (float)
final_v_beta: 0.0 (float)
i_gain: 22.742204666137695 (float)
max_allowed_current: 30.375 (float)
overcurrent_trip_level: 33.75 (float)
p_gain: 0.04055439680814743 (float)
v_current_control_integral_d: 0.0 (float)
v_current_control_integral_q: 0.0 (float)
current_meas_phB: 0.05323946475982666 (float)
current_meas_phC: 0.0025625526905059814 (float)
error: 0 (uint16)
gate_driver:
drv_fault: 0 (uint16)
get_inverter_temp(obj: object_ref) -> result: float
is_calibrated: True (bool)
phase_current_rev_gain: 0.012500000186264515 (float)
thermal_current_lim: 43.43867492675781 (float)
Encoder stats:
calib_scan_response: 0.0 (float)
config:
bandwidth: 1000.0 (float)
calib_range: 0.019999999552965164 (float)
calib_scan_distance: 50.26548385620117 (float)
calib_scan_omega: 12.566370964050293 (float)
cpr: 8192 (int32)
enable_phase_interpolation: True (bool)
find_idx_on_lockin_only: False (bool)
idx_search_unidirectional: False (bool)
ignore_illegal_hall_state: False (bool)
mode: 0 (uint8)
offset: -2328 (int32)
offset_float: -0.18335938453674316 (float)
pre_calibrated: False (bool)
use_index: False (bool)
zero_count_on_find_idx: True (bool)
count_in_cpr: 0 (int32)
error: 0 (uint8)
hall_state: 0 (uint8)
index_found: False (bool)
interpolation: 0.5 (float)
is_ready: False (bool)
phase: 1.6584234237670898 (float)
pos_cpr: 0.0 (float)
pos_estimate: 0.0 (float)
set_linear_count(obj: object_ref, count: int32)
shadow_count: 0 (int32)
vel_estimate: 0.0 (float)
EDIT
I noticed that the odrv0.axis0.encoder.config.pre_calibrated is always False, even if I specifically set it to True.
From another post I found out that I need to use index for AMT102; so I set:
odrv0.axis0.encoder.config.use_index = True
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH
# I can notice here the motor moves until the index is found. Also idnex_found = True
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION
# I can notice that the motor rotates again to perform the calibration
odrv0.axis0.encoder.config.pre_calibrated = True
# After this, the pre_calibrated variable is set to True and is persistent after reset
odrv0.save_configuration()
odrv0.reboot()
But when I try again:
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
odrv0.axis0.controller.vel_setpoint = 10
The motor moves a bit (3 degrees) but then it abruptly stops, and I see that the motor has the error 16 (ERROR_CONTROL_DEADLINE_MISSED)
Motor stats
DC_calib_phB: -0.7711188197135925 (float)
DC_calib_phC: -0.3776278793811798 (float)
armed_state: 0 (uint8)
config:
calibration_current: 10.0 (float)
current_control_bandwidth: 100.0 (float)
current_lim: 10.0 (float)
current_lim_tolerance: 1.25 (float)
direction: -1 (int32)
inverter_temp_limit_lower: 100.0 (float)
inverter_temp_limit_upper: 120.0 (float)
motor_type: 0 (uint8)
phase_inductance: 0.0003835245734080672 (float)
phase_resistance: 0.2256225347518921 (float)
pole_pairs: 15 (int32)
pre_calibrated: True (bool)
requested_current_range: 25.0 (float)
resistance_calib_max_voltage: 4.0 (float)
current_control:
I_measured_report_filter_k: 1.0 (float)
Ibus: 0.28113868832588196 (float)
Id_measured: -0.9875475168228149 (float)
Iq_measured: 3.9099690914154053 (float)
Iq_setpoint: 6.422600746154785 (float)
final_v_alpha: 1.7034990787506104 (float)
final_v_beta: 0.9837055802345276 (float)
i_gain: 22.562253952026367 (float)
max_allowed_current: 30.375 (float)
overcurrent_trip_level: 33.75 (float)
p_gain: 0.03835245594382286 (float)
v_current_control_integral_d: 0.11580724269151688 (float)
v_current_control_integral_q: 1.8720605373382568 (float)
current_meas_phB: -0.014534950256347656 (float)
current_meas_phC: -0.00539824366569519 (float)
error: 16 (uint16)
gate_driver:
drv_fault: 0 (uint16)
get_inverter_temp(obj: object_ref) -> result: float
is_calibrated: True (bool)
phase_current_rev_gain: 0.012500000186264515 (float)
thermal_current_lim: 44.876373291015625 (float)
Any ideas?