The calibration is fine, but the index search has failed. The initialisation of the motor position using the index pulse gave an incorrect offset, because noise caused a signal to be seen in the index wire before the real index pulse (is my guess)
Yes, the ODrive only needs the index signal once.
The ‘FULL_CALIBRATION_SEQUENCE’ does two things:
Firstly, it runs MOTOR_CALIBRATION which measures the resistance and inductance of the motor.
Secondly, it runs ENCODER_OFFSET_CALIBRATION which micro-steps the motor in open loop, at the configured calibration_current, moving it by the configured ‘calib_scan_distance’.
This checks that the encoder CPR is consistent with the pole_pairs and sets encoder.config.offset so that ‘zero’ is aligned with the start of the electrical cycle.
If an index is configured, then it will also store the offset between the index pulse and this zero position, so that next time it boots up, you only need to run INDEX_SEARCH, not ENCODER_OFFSET_CALIBRATION. This is useful because ENCODER_OFFSET_CALIBRATION is open loop, and only works if there is no mechanical load on the motor.
So when you reset the ODrive, you would normally need to run INDEX_SEARCH. This still moves the motor in open loop, but it can tolerate a lot more mechanical load than ENCODER_OFFSET_CALIBRATION.
Or alternatively you can move the motor by hand until it sees an index pulse, which will initialise its zero position until you reboot again.
But if there is noise between rebooting and finding an index pulse, it may set the wrong offset.
Can you post your encoder.config ?