Context
The SparkFun OTOS optical tracking sensor is being added as a localization source for the robot (cogip/mcu-firmware#243). It has two calibration scalars (linear_scalar, angular_scalar, each in [0.872, 1.127]) that compensate systematic distance and rotation biases between what the chip reports and the physical motion. Without runtime tuning, these scalars are baked into robot6_conf.hpp and every tweak requires a recompile + flash cycle.
The existing cogip-odometry-calibration tool (cogip/tools/firmware_odometry_calibration/) is encoder-based (wheels distance, left/right wheel radius, alpha/beta coefficients). It is not reusable: OTOS has no ticks, no wheel geometry, and the ground truth must come from the operator's physical measurement instead of from encoder counts.
Proposed tool
New cogip-otos-calibration CLI under cogip/tools/firmware_otos_calibration/, mirroring the structure of the odometry tool (__init__, __main__, otos_calibration, firmware_adapter, calculator, sio_events, types, otos_parameters.yaml).
Two calibration phases driven against the /calibration SocketIO namespace:
- Linear scalar: reset the OTOS-reported pose to
(0, 0, 0), command a straight line of N mm, prompt the operator for the physically measured distance, compute new = current * measured / commanded, clamp to the OTOS allowed range, write back.
- Angular scalar: reset to
(0, 0, 0), command N full in-place turns (four 90° sub-moves per turn so the control loop takes the short path), prompt for the actually rotated angle in degrees, same ratio, write back.
Reuses:
FirmwareParameterManager (get/set by name) against the OTOS parameter keys exposed by the firmware.
- The
pose_start / pose_order / pose_reached motion pattern already used by firmware_odometry_calibration.
ConsoleUI for prompts and tables.
New pydantic models in cogip/models/otos_calibration.py: OTOSParameters, OTOSCalibrationResult, plus OTOS_SCALAR_MIN / OTOS_SCALAR_MAX constants.
Firmware prerequisites
otos_linear_scalar and otos_angular_scalar must be live Parameter<float> registered in the CAN parameter handler.
- After a successful
set, the firmware must push the new scalars to the OTOS chip (LocalizationOTOS::apply_scalars).
Both are done in cogip/mcu-firmware#243.
Out of scope
- Sensor mounting offsets (
otos_offset_*): physical geometry measured at assembly, stay constexpr.
- IMU calibration: already done at boot in
LocalizationOTOS::init().
- Native simulation: real-sensor only.
Status
Implemented on branch add-firmware-otos-calibration-tool; PR will follow once the firmware side (cogip/mcu-firmware#243) is merged so the OTOS parameter keys are available on master.
Context
The SparkFun OTOS optical tracking sensor is being added as a localization source for the robot (cogip/mcu-firmware#243). It has two calibration scalars (
linear_scalar,angular_scalar, each in[0.872, 1.127]) that compensate systematic distance and rotation biases between what the chip reports and the physical motion. Without runtime tuning, these scalars are baked intorobot6_conf.hppand every tweak requires a recompile + flash cycle.The existing
cogip-odometry-calibrationtool (cogip/tools/firmware_odometry_calibration/) is encoder-based (wheels distance, left/right wheel radius, alpha/beta coefficients). It is not reusable: OTOS has no ticks, no wheel geometry, and the ground truth must come from the operator's physical measurement instead of from encoder counts.Proposed tool
New
cogip-otos-calibrationCLI undercogip/tools/firmware_otos_calibration/, mirroring the structure of the odometry tool (__init__,__main__,otos_calibration,firmware_adapter,calculator,sio_events,types,otos_parameters.yaml).Two calibration phases driven against the
/calibrationSocketIO namespace:(0, 0, 0), command a straight line ofN mm, prompt the operator for the physically measured distance, computenew = current * measured / commanded, clamp to the OTOS allowed range, write back.(0, 0, 0), commandNfull in-place turns (four90°sub-moves per turn so the control loop takes the short path), prompt for the actually rotated angle in degrees, same ratio, write back.Reuses:
FirmwareParameterManager(get/set by name) against the OTOS parameter keys exposed by the firmware.pose_start/pose_order/pose_reachedmotion pattern already used byfirmware_odometry_calibration.ConsoleUIfor prompts and tables.New pydantic models in
cogip/models/otos_calibration.py:OTOSParameters,OTOSCalibrationResult, plusOTOS_SCALAR_MIN/OTOS_SCALAR_MAXconstants.Firmware prerequisites
otos_linear_scalarandotos_angular_scalarmust be liveParameter<float>registered in the CAN parameter handler.set, the firmware must push the new scalars to the OTOS chip (LocalizationOTOS::apply_scalars).Both are done in cogip/mcu-firmware#243.
Out of scope
otos_offset_*): physical geometry measured at assembly, stayconstexpr.LocalizationOTOS::init().Status
Implemented on branch
add-firmware-otos-calibration-tool; PR will follow once the firmware side (cogip/mcu-firmware#243) is merged so the OTOS parameter keys are available on master.