Backup- and restore-config cycle error

Hi, all!

When I do a backup- and restore-config with the odrivetool (first ‘odrivetool backup-config’, then ‘odrivetool restore-config’), where I restore the backup file I just created, the setting encoder.config.pre_calibrated is now false, but was true before created the backup. What is wrong here (this setting seems to be lost in backup-restore cycle)?

Thanks!

This Json doesn’t work:

{"config": {"enable_uart": true, "uart_baudrate": 115200, "enable_i2c_instead_of_can": false, "enable_ascii_protocol_on_usb": true, "max_regen_current": 0.0, "brake_resistance": 3.0, "dc_bus_undervoltage_trip_level": 8.0, "dc_bus_overvoltage_trip_level": 59.92000198364258, "enable_dc_bus_overvoltage_ramp": false, "dc_bus_overvoltage_ramp_start": 59.92000198364258, "dc_bus_overvoltage_ramp_end": 59.92000198364258, "dc_max_positive_current": Infinity, "dc_max_negative_current": -9.999999974752427e-07}, "axis0": {"config": {"startup_motor_calibration": false, "startup_encoder_index_search": false, "startup_encoder_offset_calibration": false, "startup_closed_loop_control": false, "startup_sensorless_control": false, "startup_homing": false, "enable_step_dir": false, "step_dir_always_on": false, "turns_per_step": 0.0009765625, "watchdog_timeout": 0.0, "enable_watchdog": false, "step_gpio_pin": 1, "dir_gpio_pin": 2, "can_node_id": 0, "can_node_id_extended": false, "can_heartbeat_rate_ms": 100}, "fet_thermistor": {"config": {"temp_limit_lower": 100.0, "temp_limit_upper": 120.0, "enabled": true}}, "motor_thermistor": {"config": {"gpio_pin": 4, "poly_coefficient_0": 0.0, "poly_coefficient_1": 0.0, "poly_coefficient_2": 0.0, "poly_coefficient_3": 0.0, "temp_limit_lower": 100.0, "temp_limit_upper": 120.0, "enabled": false}}, "motor": {"config": {"pre_calibrated": true, "pole_pairs": 11, "calibration_current": 10.0, "resistance_calib_max_voltage": 2.0, "phase_inductance": 9.170889825327322e-05, "phase_resistance": 0.16107943654060364, "torque_constant": 0.05168750137090683, "direction": 1, "motor_type": 0, "current_lim": 10.0, "current_lim_margin": 8.0, "torque_lim": Infinity, "inverter_temp_limit_lower": 100.0, "inverter_temp_limit_upper": 120.0, "requested_current_range": 60.0, "current_control_bandwidth": 1000.0, "acim_slip_velocity": 14.706000328063965, "acim_gain_min_flux": 10.0, "acim_autoflux_min_Id": 10.0, "acim_autoflux_enable": false, "acim_autoflux_attack_gain": 10.0, "acim_autoflux_decay_gain": 1.0}}, "controller": {"config": {"gain_scheduling_width": 10.0, "enable_vel_limit": true, "enable_current_mode_vel_limit": true, "enable_gain_scheduling": false, "enable_overspeed_error": true, "control_mode": 1, "input_mode": 1, "pos_gain": 20.0, "vel_gain": 0.1666666716337204, "vel_integrator_gain": 0.3333333432674408, "vel_limit": 20.0, "vel_limit_tolerance": 1.2000000476837158, "vel_ramp_rate": 0.4000000059604645, "torque_ramp_rate": 0.009999999776482582, "circular_setpoints": false, "circular_setpoint_range": 1.0, "homing_speed": 0.25, "inertia": 0.0, "axis_to_mirror": 255, "mirror_ratio": 1.0, "load_encoder_axis": 0, "input_filter_bandwidth": 2.0}}, "encoder": {"config": {"mode": 0, "use_index": true, "find_idx_on_lockin_only": false, "abs_spi_cs_gpio_pin": 1, "zero_count_on_find_idx": true, "cpr": 4096, "offset": 1588, "pre_calibrated": true, "offset_float": 1.4825313091278076, "enable_phase_interpolation": true, "bandwidth": 1000.0, "calib_range": 0.019999999552965164, "calib_scan_distance": 50.26548385620117, "calib_scan_omega": 12.566370964050293, "idx_search_unidirectional": false, "ignore_illegal_hall_state": false, "sincos_gpio_pin_sin": 3, "sincos_gpio_pin_cos": 4}}, "sensorless_estimator": {"config": {"observer_gain": 1000.0, "pll_bandwidth": 1000.0, "pm_flux_linkage": 0.0015800000401213765}}, "trap_traj": {"config": {"vel_limit": 2.0, "accel_limit": 0.5, "decel_limit": 0.5}}, "min_endstop": {"config": {"gpio_num": 0, "enabled": false, "offset": 0.0, "is_active_high": false, "pullup": true, "debounce_ms": 50}}, "max_endstop": {"config": {"gpio_num": 0, "enabled": false, "offset": 0.0, "is_active_high": false, "pullup": true, "debounce_ms": 50}}}, "axis1": {"config": {"startup_motor_calibration": false, "startup_encoder_index_search": false, "startup_encoder_offset_calibration": false, "startup_closed_loop_control": false, "startup_sensorless_control": false, "startup_homing": false, "enable_step_dir": false, "step_dir_always_on": false, "turns_per_step": 0.0009765625, "watchdog_timeout": 0.0, "enable_watchdog": false, "step_gpio_pin": 7, "dir_gpio_pin": 8, "can_node_id": 1, "can_node_id_extended": false, "can_heartbeat_rate_ms": 100}, "fet_thermistor": {"config": {"temp_limit_lower": 100.0, "temp_limit_upper": 120.0, "enabled": true}}, "motor_thermistor": {"config": {"gpio_pin": 4, "poly_coefficient_0": 0.0, "poly_coefficient_1": 0.0, "poly_coefficient_2": 0.0, "poly_coefficient_3": 0.0, "temp_limit_lower": 100.0, "temp_limit_upper": 120.0, "enabled": false}}, "motor": {"config": {"pre_calibrated": true, "pole_pairs": 11, "calibration_current": 10.0, "resistance_calib_max_voltage": 2.0, "phase_inductance": 8.54182944749482e-05, "phase_resistance": 0.16203509271144867, "torque_constant": 0.05168750137090683, "direction": 1, "motor_type": 0, "current_lim": 10.0, "current_lim_margin": 8.0, "torque_lim": Infinity, "inverter_temp_limit_lower": 100.0, "inverter_temp_limit_upper": 120.0, "requested_current_range": 60.0, "current_control_bandwidth": 1000.0, "acim_slip_velocity": 14.706000328063965, "acim_gain_min_flux": 10.0, "acim_autoflux_min_Id": 10.0, "acim_autoflux_enable": false, "acim_autoflux_attack_gain": 10.0, "acim_autoflux_decay_gain": 1.0}}, "controller": {"config": {"gain_scheduling_width": 10.0, "enable_vel_limit": true, "enable_current_mode_vel_limit": true, "enable_gain_scheduling": false, "enable_overspeed_error": true, "control_mode": 1, "input_mode": 1, "pos_gain": 20.0, "vel_gain": 0.1666666716337204, "vel_integrator_gain": 0.3333333432674408, "vel_limit": 20.0, "vel_limit_tolerance": 1.2000000476837158, "vel_ramp_rate": 0.4000000059604645, "torque_ramp_rate": 0.009999999776482582, "circular_setpoints": false, "circular_setpoint_range": 1.0, "homing_speed": 0.25, "inertia": 0.0, "axis_to_mirror": 255, "mirror_ratio": 1.0, "load_encoder_axis": 1, "input_filter_bandwidth": 2.0}}, "encoder": {"config": {"mode": 0, "use_index": true, "find_idx_on_lockin_only": false, "abs_spi_cs_gpio_pin": 1, "zero_count_on_find_idx": true, "cpr": 4096, "offset": 2583, "pre_calibrated": true, "offset_float": 0.5364999771118164, "enable_phase_interpolation": true, "bandwidth": 1000.0, "calib_range": 0.019999999552965164, "calib_scan_distance": 50.26548385620117, "calib_scan_omega": 12.566370964050293, "idx_search_unidirectional": false, "ignore_illegal_hall_state": false, "sincos_gpio_pin_sin": 3, "sincos_gpio_pin_cos": 4}}, "sensorless_estimator": {"config": {"observer_gain": 1000.0, "pll_bandwidth": 1000.0, "pm_flux_linkage": 0.0015800000401213765}}, "trap_traj": {"config": {"vel_limit": 2.0, "accel_limit": 0.5, "decel_limit": 0.5}}, "min_endstop": {"config": {"gpio_num": 0, "enabled": false, "offset": 0.0, "is_active_high": false, "pullup": true, "debounce_ms": 50}}, "max_endstop": {"config": {"gpio_num": 0, "enabled": false, "offset": 0.0, "is_active_high": false, "pullup": true, "debounce_ms": 50}}}, "can": {"config": {"baud_rate": 250000, "protocol": 0}}}

That one doesn’t work either:

{
    "axis0": {
        "config": {
            "can_heartbeat_rate_ms": 100,
            "can_node_id": 0,
            "can_node_id_extended": false,
            "dir_gpio_pin": 2,
            "enable_step_dir": false,
            "enable_watchdog": false,
            "startup_closed_loop_control": false,
            "startup_encoder_index_search": false,
            "startup_encoder_offset_calibration": false,
            "startup_homing": false,
            "startup_motor_calibration": false,
            "startup_sensorless_control": false,
            "step_dir_always_on": false,
            "step_gpio_pin": 1,
            "turns_per_step": 0.0009765625,
            "watchdog_timeout": 0.0
        },
        "controller": {
            "config": {
                "axis_to_mirror": 255,
                "circular_setpoint_range": 1.0,
                "circular_setpoints": false,
                "control_mode": 1,
                "enable_current_mode_vel_limit": true,
                "enable_gain_scheduling": false,
                "enable_overspeed_error": true,
                "enable_vel_limit": true,
                "gain_scheduling_width": 10.0,
                "homing_speed": 0.25,
                "inertia": 0.0,
                "input_filter_bandwidth": 2.0,
                "input_mode": 6,
                "load_encoder_axis": 0,
                "mirror_ratio": 1.0,
                "pos_gain": 20.0,
                "torque_ramp_rate": 0.009999999776482582,
                "vel_gain": 0.1666666716337204,
                "vel_integrator_gain": 0.3333333432674408,
                "vel_limit": 20.0,
                "vel_limit_tolerance": 1.2000000476837158,
                "vel_ramp_rate": 0.4000000059604645
            }
        },
        "encoder": {
            "config": {
                "abs_spi_cs_gpio_pin": 1,
                "bandwidth": 1000.0,
                "calib_range": 0.019999999552965164,
                "calib_scan_distance": 50.26548385620117,
                "calib_scan_omega": 12.566370964050293,
                "cpr": 4096,
                "enable_phase_interpolation": true,
                "find_idx_on_lockin_only": false,
                "idx_search_unidirectional": false,
                "ignore_illegal_hall_state": false,
                "mode": 0,
                "offset": 1586,
                "offset_float": 0.7461405992507935,
                "pre_calibrated": true,
                "sincos_gpio_pin_cos": 4,
                "sincos_gpio_pin_sin": 3,
                "use_index": true,
                "zero_count_on_find_idx": true
            }
        },
        "fet_thermistor": {
            "config": {
                "enabled": true,
                "temp_limit_lower": 100.0,
                "temp_limit_upper": 120.0
            }
        },
        "max_endstop": {
            "config": {
                "debounce_ms": 50,
                "enabled": false,
                "gpio_num": 0,
                "is_active_high": false,
                "offset": 0.0,
                "pullup": true
            }
        },
        "min_endstop": {
            "config": {
                "debounce_ms": 50,
                "enabled": false,
                "gpio_num": 0,
                "is_active_high": false,
                "offset": 0.0,
                "pullup": true
            }
        },
        "motor": {
            "config": {
                "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_slip_velocity": 14.706000328063965,
                "calibration_current": 10.0,
                "current_control_bandwidth": 1000.0,
                "current_lim": 10.0,
                "current_lim_margin": 8.0,
                "direction": 1,
                "inverter_temp_limit_lower": 100.0,
                "inverter_temp_limit_upper": 120.0,
                "motor_type": 0,
                "phase_inductance": 9.212127042701468e-05,
                "phase_resistance": 0.15011364221572876,
                "pole_pairs": 11,
                "pre_calibrated": true,
                "requested_current_range": 60.0,
                "resistance_calib_max_voltage": 2.0,
                "torque_constant": 0.03999999910593033,
                "torque_lim": Infinity
            }
        },
        "motor_thermistor": {
            "config": {
                "enabled": false,
                "gpio_pin": 4,
                "poly_coefficient_0": 0.0,
                "poly_coefficient_1": 0.0,
                "poly_coefficient_2": 0.0,
                "poly_coefficient_3": 0.0,
                "temp_limit_lower": 100.0,
                "temp_limit_upper": 120.0
            }
        },
        "sensorless_estimator": {
            "config": {
                "observer_gain": 1000.0,
                "pll_bandwidth": 1000.0,
                "pm_flux_linkage": 0.0015800000401213765
            }
        },
        "trap_traj": {
            "config": {
                "accel_limit": 0.5,
                "decel_limit": 0.5,
                "vel_limit": 2.0
            }
        }
    },
    "axis1": {
        "config": {
            "can_heartbeat_rate_ms": 100,
            "can_node_id": 1,
            "can_node_id_extended": false,
            "dir_gpio_pin": 8,
            "enable_step_dir": false,
            "enable_watchdog": false,
            "startup_closed_loop_control": false,
            "startup_encoder_index_search": false,
            "startup_encoder_offset_calibration": false,
            "startup_homing": false,
            "startup_motor_calibration": false,
            "startup_sensorless_control": false,
            "step_dir_always_on": false,
            "step_gpio_pin": 7,
            "turns_per_step": 0.0009765625,
            "watchdog_timeout": 0.0
        },
        "controller": {
            "config": {
                "axis_to_mirror": 255,
                "circular_setpoint_range": 1.0,
                "circular_setpoints": false,
                "control_mode": 2,
                "enable_current_mode_vel_limit": true,
                "enable_gain_scheduling": false,
                "enable_overspeed_error": true,
                "enable_vel_limit": true,
                "gain_scheduling_width": 10.0,
                "homing_speed": 0.25,
                "inertia": 0.0,
                "input_filter_bandwidth": 2.0,
                "input_mode": 2,
                "load_encoder_axis": 1,
                "mirror_ratio": 1.0,
                "pos_gain": 20.0,
                "torque_ramp_rate": 0.009999999776482582,
                "vel_gain": 0.1666666716337204,
                "vel_integrator_gain": 0.3333333432674408,
                "vel_limit": 20.0,
                "vel_limit_tolerance": 1.2000000476837158,
                "vel_ramp_rate": 0.4000000059604645
            }
        },
        "encoder": {
            "config": {
                "abs_spi_cs_gpio_pin": 1,
                "bandwidth": 1000.0,
                "calib_range": 0.019999999552965164,
                "calib_scan_distance": 50.26548385620117,
                "calib_scan_omega": 12.566370964050293,
                "cpr": 4096,
                "enable_phase_interpolation": true,
                "find_idx_on_lockin_only": false,
                "idx_search_unidirectional": false,
                "ignore_illegal_hall_state": false,
                "mode": 0,
                "offset": 2583,
                "offset_float": 0.7067656517028809,
                "pre_calibrated": true,
                "sincos_gpio_pin_cos": 4,
                "sincos_gpio_pin_sin": 3,
                "use_index": true,
                "zero_count_on_find_idx": true
            }
        },
        "fet_thermistor": {
            "config": {
                "enabled": true,
                "temp_limit_lower": 100.0,
                "temp_limit_upper": 120.0
            }
        },
        "max_endstop": {
            "config": {
                "debounce_ms": 50,
                "enabled": false,
                "gpio_num": 0,
                "is_active_high": false,
                "offset": 0.0,
                "pullup": true
            }
        },
        "min_endstop": {
            "config": {
                "debounce_ms": 50,
                "enabled": false,
                "gpio_num": 0,
                "is_active_high": false,
                "offset": 0.0,
                "pullup": true
            }
        },
        "motor": {
            "config": {
                "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_slip_velocity": 14.706000328063965,
                "calibration_current": 10.0,
                "current_control_bandwidth": 1000.0,
                "current_lim": 10.0,
                "current_lim_margin": 8.0,
                "direction": 1,
                "inverter_temp_limit_lower": 100.0,
                "inverter_temp_limit_upper": 120.0,
                "motor_type": 0,
                "phase_inductance": 8.462630648864433e-05,
                "phase_resistance": 0.1519850790500641,
                "pole_pairs": 11,
                "pre_calibrated": true,
                "requested_current_range": 60.0,
                "resistance_calib_max_voltage": 2.0,
                "torque_constant": 0.03999999910593033,
                "torque_lim": Infinity
            }
        },
        "motor_thermistor": {
            "config": {
                "enabled": false,
                "gpio_pin": 4,
                "poly_coefficient_0": 0.0,
                "poly_coefficient_1": 0.0,
                "poly_coefficient_2": 0.0,
                "poly_coefficient_3": 0.0,
                "temp_limit_lower": 100.0,
                "temp_limit_upper": 120.0
            }
        },
        "sensorless_estimator": {
            "config": {
                "observer_gain": 1000.0,
                "pll_bandwidth": 1000.0,
                "pm_flux_linkage": 0.0015800000401213765
            }
        },
        "trap_traj": {
            "config": {
                "accel_limit": 0.5,
                "decel_limit": 0.5,
                "vel_limit": 2.0
            }
        }
    },
    "can": {
        "config": {
            "baud_rate": 250000,
            "protocol": 0
        }
    },
    "config": {
        "brake_resistance": 3.0,
        "dc_bus_overvoltage_ramp_end": 59.92000198364258,
        "dc_bus_overvoltage_ramp_start": 59.92000198364258,
        "dc_bus_overvoltage_trip_level": 59.92000198364258,
        "dc_bus_undervoltage_trip_level": 8.0,
        "dc_max_negative_current": -9.999999974752427e-07,
        "dc_max_positive_current": Infinity,
        "enable_ascii_protocol_on_usb": true,
        "enable_dc_bus_overvoltage_ramp": false,
        "enable_i2c_instead_of_can": false,
        "enable_uart": true,
        "max_regen_current": 0.0,
        "uart_baudrate": 115200
    }
}

Can you upload your JSON config?

I’m going to guess it’s just this problem:

void Encoder::check_pre_calibrated() {
    // TODO: restoring config from python backup is fragile here (ACIM motor type must be set first)
    if (!is_ready_ && axis_->motor_.config_.motor_type != Motor::MOTOR_TYPE_ACIM)
        config_.pre_calibrated = false;
    if (mode_ == MODE_INCREMENTAL && !index_found_)
        config_.pre_calibrated = false;
}

From Discord:
Paul Wetmelon Today at 6:45 PM
I posted a bug for you here https://github.com/madcowswe/ODrive/issues/541

jiuy Today at 6:47 PM

  1. How long do you think until it’s fixed?

  2. Can workaround this issue somehow?

  3. E.g. What if I set motor type to MOTOR_TYPE_ACIM before doing and restoring the backup, and then after set motor type to MOTOR_TYPE_HIGH_CURRENT again?

1 Like

Restoring a backup with encoder.pre_calibrated = True works, if I do a AXIS_STATE_ENCODER_INDEX_SEARCH on both axis before! – And after the backup, encoder pre_calibrated = True!

1 Like

DID NOT WORK: I set motor type to MOTOR_TYPE_ACIM before doing and restoring the backup, and then after set motor type to MOTOR_TYPE_HIGH_CURRENT. – After this, encoder pre_calibrated = false.

1 Like

Any updates on this issue? I’ve seen that you closed the issue, but I still have the same problem

E: My current workaround is starting the odrive, doing an index search and then restoring the configuration. This way the index will be found right on startup and the encoder is still pre calibrated.

Hey Lars, we don’t consider this a bug tbh. We can’t trust that a restored config is valid for encoder alignment. The risk of spinout / damage is too high compared to the inconvenience of having to use a workaround to get a restored config to be valid immediately.