Saving Startup Calibration?


I apologize if it is already documented somewhere but. If you can, how do you save the startup calibration (rotating one direction, then the other) so it doesn’t do it each time?

Also, does anyone have any idea why the startup calibration will turn one way sometimes and the other way other times? Everything is hard wired in so the cables haven’t changed. Sometimes the direction it turns to locate the index mark changes too seems a bit odd…

Not sure if this helps but here are the config settings:

In [5]: odrv0.axis0
error = 0x0000 (int)
enable_step_dir = False (bool)
current_state = 8 (int)
requested_state = 0 (int)
loop_counter = 3574902 (int)
  startup_motor_calibration = False (bool)
  startup_encoder_index_search = True (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)
  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)
  error = 0x0000 (int)
  armed_state = 3 (int)
  is_calibrated = True (bool)
  current_meas_phB = -0.10100078582763672 (float)
  current_meas_phC = -0.1333787441253662 (float)
  DC_calib_phB = -2.276343584060669 (float)
  DC_calib_phC = -1.5992008447647095 (float)
  phase_current_rev_gain = 0.02500000037252903 (float)
  current_control: ...
  gate_driver: ...
  timing_log: ...
  config: ...
  pos_setpoint = -4200.0 (float)
  vel_setpoint = 0.0 (float)
  vel_integrator_current = -0.027316205203533173 (float)
  current_setpoint = 0.0 (float)
  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)
  error = 0x0000 (int)
  is_ready = True (bool)
  index_found = True (bool)
  shadow_count = -4201 (int)
  count_in_cpr = 3991 (int)
  interpolation = 0.5 (float)
  phase = 2.667912244796753 (float)
  pos_estimate = -4200.8828125 (float)
  pos_cpr = 3991.23046875 (float)
  hall_state = 2 (int)
  vel_estimate = 0.0 (float)
  config: ...
  error = 0x0000 (int)
  phase = 2.2241086959838867 (float)
  pll_pos = 2.2200675010681152 (float)
  vel_estimate = -9.548842430114746 (float)
  config: ...
  config: ...


By coincidence this is what I wondered myself yesterday.
Answer is:
There are two important calibration steps, first the motor and second the encoder.
As long as the motor does not change, the odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION can be done once and then set the odrv0.axis0.motor.config.pre_calibrated = True makes sure these values are retained - after odrv0.save_configuration() of course. I assume this you have done already.

The encoder is a problem. How does the motor know which angle the motor shaft is at startup?

Option 1: Absolute encoders - an encoder that tells the current angle. Not supported yet.
Option 2: The encoder has an index signal and the motor turns until it finds it. Then it knows that this position is 0°. The AMT102 does not have an index pin. Yours seem to have one. Hence it has to turn up to 360° if configured for index search.
Option 3: The encoder is turned by the motor, thus by knowing which winding is magnetized at the moment and what the encoder counter value is, it knows the relationship.

To cut a long story short, in option 2 and 3 the motor has to be moved.

The point I do not get is, yes, a complete 360°+ turn in both direction gives the best precision but wouldn’t it be enough to slowly power one winding and then read the encoder counter value?

Last point, by setting odrv0.axis0.config.startup_encoder_offset_calibration = False/True the “turning the motor for the encoder calibration” can be done at request or automatically at startup.