# What is the mechanism of "run_offset_calibration" function?

I think there are three stages in this function.At the beginning, we have `num_steps = (int)(config_.calib_scan_distance / config_.calib_scan_omega * (float)current_meas_hz);` In my opinion,"config_.calib_scan_omega " is the speed of scanning whose unit is count/s and the result of “config_.calib_scan_distance / config_.calib_scan_omega” is a time for scanning the special distance.By multiplying “current_meas_hz”,we get the needed number of encoder.update() function’s executing.The first stage,make the rotor located in zero phase by only giving alpha axis some voltage.The second stage is running scan forward and at the same time, a variable called encvaluesum accumulate shadow_count_ which represents the absolute position.The third stage just do the same thing.I just don’t understand the usage of these operations.Finally ,we get offset by " encvaluesum/num_steps ".How does it work? Why can we get the offset between the electrical phase 0 and the encoder state 0 when these operations done? Any explanation about it is greatly appreciated.Thanks.

Hello shoufei403,
I think accumulating shadow_count_ to encvaluesum and dividing it by number of steps averages out some non-ideal behavior of the motors. Since motor is turned 8pi and back to 0 in a sinusoid step vs. encvaluesum is a triangle and the average value should represent 4pi. If you put a breakpoint after the first turn and compare, encvaluesum/num_steps in forward turn and backward turn are little different and offset comes out as the average. Compared to using init_enc_val as offset, the value obtained from average may better represent the motor as a whole.
Does anyone know if the processes of turning forward and backward openloop in a sinusoid has a self aligning effect?(say if init_enc_val was a bit off?)

Hello naktamello
I still cannot get the mechanism and don’t know why this offset can be used, could you say a little more?

hello blue, the offset between electrical phase and actual position of the rotor is needed for FOC. This part of the firmware first energizes single phase of the stator to align the rotor approximately, then turns the rotor in a open loop fashion forward and backward, then finally compares expected encoder counts to actual counts and checks if the difference falls between the requested calibration range (one of encoder.config). Can you be more specific about what you want to know?

1 Like

Hello naktamello
I know that FOC needs the electrical phase. But I don’t understand why this operation can tell me the electrical phase. Because when I restart odrive, the offset cannot be used any more. (Does this operation runs every time I start odrive? It seems not, please let me know if it does )In my opinion, only the index of incremental enoder or absolute encoder can do this thing.

Electrical phase is known because it is arbitrarily set to zero when firmware starts the offset calibration. The offset in encoder counts from this electrical zero is obtained during the process. Even with index pin or absolute encoder, the orientation it was mounted is not known to the firmware, so offset calibration needs to be run at least once then saved.

Without the index pin, this operation needs to run every time on startup.
With index pin, rotor needs to at least turn until index pin is found. (assuming saved previously)
With absolute encoder, firmware can know the offset right away. (assuming saved previously)

Seems like you already know all this but just confused with what ODrives does on startup.
By default config, ODrive doesn’t run the calibration by itself until commanded. You can configure its startup behavior using odrvX.axisX.config. I don’t think absolute encoder startup procedures are in master branch yet, so please check out RazorsEdge branch in Wetmelon’s fork.

You should be able to find many posts talking about startup procedures in this forum as well. I hope this was helpful.

I am OK with the encoder thing.
Still I cannot understand why you say " open loop fashion forward and backward" will make this alignment more accrate.
What is config_.offset and “add 0.5 to center-align state to phase” mean
Thank you

Other than confirming that the cpr is correct and motor is spinning as expected, turning in both directions will average out frictional forces and imperfections in motor’s symmetry.

config_.offset is the resulting value extracted by the calibration process (offset from electrical phase 0 to rotor’s position)

I think adding 0.5 to offset_float is done because on each run_control_loop, the encvaluesum is incremented right away but we want the value to be as if it was incremented right in the middle of the loop.

I don’t think I know enough about the firmware to be answering these questions. If you want to see other examples of this calibration process, here is another firmware using FOC and TI’s DRV chip (MIT mini cheetah actuator by Ben Katz).

1 Like

THat helps a lot ， thank you