ODrive Pro Position Control Problems

Hello,

I’m setting up my motor in closed loop control with a magnetic ring encoder. My encoder offset calibration is finally working with no issues (motor rotates both directions with no errors during calibration), but once I put the motor in to closed loop mode, I cannot control it using any control mode. During the offset calibration, the motor is pulling 3 or 4 (negative) DC amps from my power supply. When I try to command it to a position, I can’t seem to reach that same DC current level even though the iq_measured is showing the same level it gets to during calibration (around 1A). I tried increasing the gains until the iq_measured was up around 10A, and still the motor would not turn until I increased it to the point of spinout. Even at these higher motor current values, the motor was not pulling more than -.5A DC from my power supply. Any thoughts on what could be causing this? I can add screenshots of graphs, etc. tomorrow. I feel like there’s a parameter I’m missing or some setting I have flipped here, so let me know if you have any ideas!

First graph: encoder offset calibration, which works perfectly every time. Red line is measured current (iq_measured), blue line is measured position. Power supply DC current output around -3 to -4A.

Second graph: system trying to go to pos=1 in pos_filter mode. Red line is measured current (iq_measured), blue line is measured position. Note the far higher current measured. Power supply DC current output around -.2A.

Here is my odrv0.axis0.controller readout during a pos=1 command

autotuning:
frequency: 0.0 (float)
pos_amplitude: 0.0 (float)
torque_amplitude: 0.0 (float)
vel_amplitude: 0.0 (float)
vel_burst_factor: 0 (uint8)
autotuning_phase: -1.5707963705062866 (float)
config:
absolute_setpoints: False (bool)
circular_setpoint_range: 1.0 (float)
circular_setpoints: False (bool)
commutation_vel_scale: 1.0 (float)
control_mode: 3 (uint8)
enable_gain_scheduling: False (bool)
enable_overspeed_error: True (bool)
enable_torque_mode_vel_limit: True (bool)
enable_vel_limit: True (bool)
gain_scheduling_width: 0.0010000000474974513 (float)
homing_speed: 0.25 (float)
inertia: 0.0 (float)
input_filter_bandwidth: 2.0 (float)
input_mode: 1 (uint8)
pos_gain: 6.0 (float)
spinout_electrical_power_bandwidth: 20.0 (float)
spinout_electrical_power_threshold: 10.0 (float)
spinout_mechanical_power_bandwidth: 20.0 (float)
spinout_mechanical_power_threshold: -10.0 (float)
steps_per_circular_range: 1024 (int32)
torque_ramp_rate: 5.0 (float)
use_commutation_vel: False (bool)
vel_gain: 1.0 (float)
vel_integrator_gain: 0.10000000149011612 (float)
vel_integrator_limit: inf (float)
vel_limit: 6.659999847412109 (float)
vel_limit_tolerance: 1.2000000476837158 (float)
vel_ramp_rate: 2.0 (float)
effective_torque_setpoint: 7.604598045349121 (float)
input_pos: 1.0 (float)
input_torque: 0.0 (float)
input_vel: 0.0 (float)
move_incremental(obj: object_ref, displacement: float, from_input_pos: bool)
pos_setpoint: 1.0 (float)
spinout_electrical_power: 13.554516792297363 (float)
spinout_mechanical_power: 3.174600582411813e-09 (float)
torque_setpoint: 0.0 (float)
trajectory_done: True (bool)
vel_integrator_torque: 1.5223556756973267 (float)
vel_setpoint: 0.0 (float)

Hi MCL - sorry to hear you’ve been having this issue!

Would you mind posting your config.json (odrivetool backup-config config.json) and providing more details as to your motor and encoder? Specifically, what ring magnet you’re using and what encoder IC?

Here’s my JSON file. We’re using a MR075 incremental magnetic ring encoder from RLS, the encoder system has a CPR of 48000. The motor is a 40-pole-pair 48V high-torque BLDC motor with a KV of 13.75 RPM/V

{“amt21_encoder_group0”: {“config”: {“addr0”: 84, “enable”: false, “event_driven_mode”: false, “gpio”: 0, “rs485”: 0}}, “axis0”: {“commutation_mapper”: {“config”: {“approx_init_pos”: 0.0, “approx_init_pos_valid”: false, “circular_output_range”: 1.0, “circular”: true, “index_gpio”: 7, “index_offset”: 0.0, “index_offset_valid”: false, “index_search_always_on”: false, “offset”: 0.0, “offset_valid”: false, “scale”: 40.0, “use_endstop”: false, “use_index_gpio”: false}}, “config”: {“I_bus_hard_max”: Infinity, “I_bus_hard_min”: -Infinity, “calib_range”: 1.0, “calib_scan_distance”: 16.0, “calib_scan_vel”: 5.0, “commutation_encoder”: 1, “dir_gpio_pin”: 9, “enable_error_gpio”: false, “enable_step_dir”: false, “enable_watchdog”: false, “encoder_bandwidth”: 1000.0, “error_gpio_pin”: 10, “index_search_at_target_vel_only”: false, “load_encoder”: 1, “startup_closed_loop_control”: true, “startup_encoder_index_search”: false, “startup_encoder_offset_calibration”: true, “startup_homing”: false, “startup_max_wait_for_ready”: 3.0, “startup_motor_calibration”: false, “step_dir_always_on”: false, “step_gpio_pin”: 8, “torque_soft_max”: Infinity, “torque_soft_min”: -Infinity, “watchdog_timeout”: 0.0, “anticogging”: {“calib_coarse_integrator_gain”: 100.0, “calib_coarse_tuning_duration”: 60.0, “calib_end_vel”: 0.07000000029802322, “calib_fine_tuning_duration”: 120.0, “calib_start_vel”: 4.0, “enabled”: false, “max_torque”: 0.15000000596046448}, “calibration_lockin”: {“accel”: 20.0, “current”: 15.0, “ramp_distance”: 0.5, “ramp_time”: 0.10000000149011612, “vel”: 300.0}, “can”: {“bus_voltage_msg_rate_ms”: 0, “encoder_msg_rate_ms”: 10, “error_msg_rate_ms”: 0, “heartbeat_msg_rate_ms”: 300, “iq_msg_rate_ms”: 0, “is_extended”: false, “node_id”: 32, “temperature_msg_rate_ms”: 0, “torques_msg_rate_ms”: 0, “version_msg_rate_ms”: 0}, “general_lockin”: {“accel”: 20.0, “current”: 20.0, “finish_distance”: 100.0, “finish_on_distance”: false, “finish_on_vel”: false, “initial_pos”: 0.0, “ramp_distance”: 3.1415927410125732, “ramp_time”: 0.4000000059604645, “vel”: 40.0}, “motor”: {“acim_autoflux_attack_gain”: 10.0, “acim_autoflux_decay_gain”: 1.0, “acim_autoflux_enable”: false, “acim_autoflux_min_Id”: 10.0, “acim_gain_min_flux”: 10.0, “acim_nominal_slip_vel”: 2.3399999141693115, “bEMF_FF_enable”: false, “calibration_current”: 30.0, “current_control_bandwidth”: 1000.0, “current_hard_max”: 90.0, “current_slew_rate_limit”: 10000.0, “current_soft_max”: 70.0, “direction”: 1.0, “ff_pm_flux_linkage”: 0.0, “ff_pm_flux_linkage_valid”: false, “fw_enable”: false, “fw_fb_bandwidth”: 500.0, “fw_mod_setpoint”: 0.7813565135002136, “motor_model_l_d”: 0.0, “motor_model_l_dq_valid”: false, “motor_model_l_q”: 0.0, “motor_type”: 0, “phase_inductance”: 0.00019094912568107247, “phase_inductance_valid”: true, “phase_resistance”: 0.05920412391424179, “phase_resistance_valid”: true, “pole_pairs”: 40, “resistance_calib_max_voltage”: 2.0, “sensorless_observer_gain”: 1000.0, “sensorless_pll_bandwidth”: 1000.0, “sensorless_pm_flux_linkage”: 0.0, “sensorless_pm_flux_linkage_valid”: false, “torque_constant”: 13.074999809265137, “wL_FF_enable”: false}, “sensorless_ramp”: {“accel”: 31.83098793029785, “current”: 10.0, “finish_distance”: 15.915493965148926, “finish_on_distance”: false, “finish_on_vel”: true, “initial_pos”: 0.0, “ramp_distance”: 0.5, “ramp_time”: 0.4000000059604645, “vel”: 63.6619758605957}}, “controller”: {“config”: {“absolute_setpoints”: false, “circular_setpoint_range”: 1.0, “circular_setpoints”: false, “commutation_vel_scale”: 1.0, “control_mode”: 2, “enable_gain_scheduling”: false, “enable_overspeed_error”: true, “enable_torque_mode_vel_limit”: false, “enable_vel_limit”: true, “gain_scheduling_width”: 0.0010000000474974513, “homing_speed”: 0.25, “inertia”: 0.0, “input_filter_bandwidth”: 2.0, “input_mode”: 2, “pos_gain”: 6.0, “spinout_electrical_power_bandwidth”: 50.0, “spinout_electrical_power_threshold”: 25.0, “spinout_mechanical_power_bandwidth”: 20.0, “spinout_mechanical_power_threshold”: -10.0, “steps_per_circular_range”: 1024, “torque_ramp_rate”: 5.0, “use_commutation_vel”: false, “vel_gain”: 1.0, “vel_integrator_gain”: 0.009999999776482582, “vel_integrator_limit”: Infinity, “vel_limit”: 6.659999847412109, “vel_limit_tolerance”: 1.2000000476837158, “vel_ramp_rate”: 2.0}}, “interpolator”: {“config”: {“dynamic”: true}}, “max_endstop”: {“config”: {“debounce_ms”: 50, “enabled”: false, “gpio_num”: 0, “is_active_high”: false, “offset”: 0.0}}, “mechanical_brake”: {“config”: {“gpio_num”: 0, “is_active_low”: true}}, “min_endstop”: {“config”: {“debounce_ms”: 50, “enabled”: true, “gpio_num”: 8, “is_active_high”: false, “offset”: 0.0}}, “motor”: {“motor_thermistor”: {“config”: {“beta”: 0.0, “enabled”: false, “gpio_pin”: 3, “r_ref”: 0.0, “t_ref”: 25.0, “temp_limit_lower”: 100.0, “temp_limit_upper”: 120.0}}}, “pos_vel_mapper”: {“config”: {“approx_init_pos”: 0.0, “approx_init_pos_valid”: false, “circular_output_range”: 1.0, “circular”: false, “index_gpio”: 7, “index_offset”: 0.0, “index_offset_valid”: false, “index_search_always_on”: false, “offset”: 0.0, “offset_valid”: false, “scale”: 1.0, “use_endstop”: true, “use_index_gpio”: false}}, “trap_traj”: {“config”: {“accel_limit”: 2.0, “decel_limit”: 2.0, “vel_limit”: 10.0}}}, “can”: {“config”: {“baud_rate”: 250000, “protocol”: 1}}, “config”: {“dc_bus_overvoltage_trip_level”: 60.0, “dc_bus_undervoltage_trip_level”: 10.5, “dc_max_negative_current”: -13.0, “dc_max_positive_current”: 13.0, “enable_can_a”: true, “enable_uart_a”: false, “gpio0_mode”: 17, “gpio10_mode”: 17, “gpio11_mode”: 17, “gpio12_mode”: 17, “gpio13_mode”: 17, “gpio14_mode”: 17, “gpio15_mode”: 17, “gpio16_mode”: 17, “gpio17_mode”: 17, “gpio18_mode”: 17, “gpio1_mode”: 17, “gpio2_mode”: 17, “gpio3_mode”: 17, “gpio4_mode”: 17, “gpio5_mode”: 17, “gpio6_mode”: 17, “gpio7_mode”: 17, “gpio8_mode”: 1, “gpio9_mode”: 17, “max_regen_current”: 0.0, “uart0_protocol”: 3, “uart_a_baudrate”: 115200, “usb_cdc_protocol”: 3, “gpio15_analog_mapping”: {“endpoint”: null, “max”: 0.0, “min”: 0.0}, “gpio16_analog_mapping”: {“endpoint”: null, “max”: 0.0, “min”: 0.0}, “gpio8_pwm_mapping”: {“endpoint”: null, “max”: 0.0, “min”: 0.0}, “gpio9_pwm_mapping”: {“endpoint”: null, “max”: 0.0, “min”: 0.0}, “inverter0”: {“current_hard_max”: 150.0, “current_soft_max”: 100.0, “drv_config”: 9029553772700800, “shunt_conductance”: 1999.9998779296875, “temp_limit_lower”: 83.95999908447266, “temp_limit_upper”: 103.11000061035156}, “motor_fan”: {“enabled”: false, “lower”: 70.0, “upper”: 80.0}, “odrv_fan”: {“enabled”: false, “lower”: 70.0, “upper”: 80.0}}, “hall_encoder0”: {“config”: {“enabled”: false, “hall_polarity_calibrated”: false, “hall_polarity”: 0, “ignore_illegal_hall_state”: false}}, “hall_encoder1”: {“config”: {“enabled”: false, “hall_polarity_calibrated”: false, “hall_polarity”: 0, “ignore_illegal_hall_state”: false}}, “inc_encoder0”: {“config”: {“cpr”: 19200, “enabled”: true}}, “inc_encoder1”: {“config”: {“cpr”: 8192, “enabled”: false}}, “spi_encoder0”: {“config”: {“baudrate”: 1687500, “delay”: 0.0, “max_error_rate”: 0.004999999888241291, “mode”: 0, “ncs_gpio”: 17}}, “spi_encoder1”: {“config”: {“baudrate”: 1687500, “delay”: 0.0, “max_error_rate”: 0.004999999888241291, “mode”: 0, “ncs_gpio”: 17}}}

Got it working, there was an issue with the encoder CPR and I had errantly set calib_range to 1.0 which was a big problem.

1 Like