Add OTOS calibration tool - #203
Open
gdoffe wants to merge 5 commits into
Open
Conversation
…nsumers Replace the global `consumer_count_` and single `sem_update_` semaphore with a shared memory array of up to 32 consumer PIDs (`consumer_pids_`) and dedicated per-PID semaphores (e.g., `/<name>_update_<PID>`). This prevents ghost processes (e.g., consumers that crashed or were killed abruptly) from desynchronizing the update signals for other active consumers. Key changes: - Implement ghost process cleanup in `registerConsumer()` using `kill(pid, 0)` to detect dead processes, reclaim their slots, and unlink orphaned semaphores. - Update `postUpdate()` to signal each registered PID individually. - Add an `unordered_map` cache (`update_sems_cache_`) in `postUpdate()` to store opened semaphores, ensuring the hot path remains extremely fast without syscall overhead. - Ensure graceful cleanup of semaphores and PID slots in the destructor. Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Pydantic OTOSParameters / OTOSCalibrationResult pair and the OTOS_SCALAR_MIN / OTOS_SCALAR_MAX bounds (0.872 / 1.127, per the OTOS spec). Used by the upcoming firmware_otos_calibration tool to read the current sensor scalars from firmware, clamp computed values to the allowed range, and write the corrected ones back. Signed-off-by: Gilles DOFFE <g.doffe@gmail.com>
Host-side calibration tool for the SparkFun OTOS sensor, published as the cogip-otos-calibration entrypoint. Two phases: - Linear scalar: drive a commanded straight line, ask the operator for the physically measured distance, derive the corrected linear_scalar and write it back. - Angular scalar: rotate N full turns, ask the operator for the physically measured rotation, derive the corrected angular_scalar and write it back. Motion is sent via the existing /calibration SocketIO namespace (pose_start + pose_order + pose_reached). Parameters are read and written through FirmwareParameterManager against the new OTOS parameter keys exposed by the firmware. Computed scalars are clamped to the OTOS allowed range [0.872, 1.127]; out-of-range results raise a console warning pointing at a mechanical issue. Signed-off-by: Gilles DOFFE <g.doffe@gmail.com>
copilot.sio_events.on_pose_order references models.MotionDirection.FORWARD_ONLY without importing it directly, so the handler raised AttributeError and crashed silently the moment any tool sent a pose_order on SocketIO (systemd StandardOutput=null hid the traceback). test_squares kept working only because it goes through the shared-memory path in copilot.py, which uses the C++ import explicitly. Re-exporting the enum from the models package fixes the calibration tools pose_order flow without touching the copilot code. Signed-off-by: Gilles DOFFE <g.doffe@gmail.com>
A 1000 mm straight-line calibration move completes in ~3 s at the default speed ratio. A 60 s timeout masked the silent pose_order failure for a full minute each time, and added nothing once the move is actually wired through. 10 s leaves comfortable margin without hiding stalls. Signed-off-by: Gilles DOFFE <g.doffe@gmail.com>
gdoffe
force-pushed
the
202-add-otos-calibration-tool
branch
from
April 20, 2026 17:39
74431eb to
9706b5d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New
cogip-otos-calibrationCLI undercogip/tools/firmware_otos_calibration/that mirrors the structure offirmware_odometry_calibrationbut drives the two OTOS scalars exposed by the firmware (cogip/mcu-firmware#243).Two calibration phases driven through the
/calibrationSocketIO namespace:(0, 0, 0), command a straight line ofN mm, prompt the operator for the physically measured distance,new = current * measured / commanded, clamp to[0.872, 1.127], 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, same ratio, write back.Reuses the existing
FirmwareParameterManager,ConsoleUI, and thepose_start/pose_order/pose_reachedmotion pattern. No change to server, copilot or planner apart from theMotionDirectionre-export below.Also in this PR
models: export MotionDirection from cogip.models—copilot/sio_events.py:on_pose_orderwas referencingmodels.MotionDirection.FORWARD_ONLYwithout importing it directly, so every pose_order sent on SocketIO crashed silently withAttributeError(systemdStandardOutput=nullon the robot hid the traceback).test_squareskept working because it goes through the shared-memory path incopilot.py, which uses the C++ import directly. Re-exporting the enum fixes the SocketIO pose_order flow without touching copilot.tools: firmware_otos_calibration: shorten straight-line timeout to 10s— 60 s masked silent stalls; a 1000 mm straight-line completes in ~3 s.Depends on
otos_linear_scalar/otos_angular_scalaras liveParameter<float>and reapplies them to the chip on change via thehas_changed/clear_changedpolling API.Closes
Closes #202.