sl-perception created pull request seb/saltylab-firmware#642

sl-perception
Sun, 15 Mar 2026 14:50:29 -0400

642#feat: Encoder odometry and wheel speed feedback (Issue #632)#

Summary

TIM2 (32-bit) left encoder / TIM3 (16-bit) right encoder in quadrature mode 3 (×4 resolution)

RPM computation with int16 saturation; 16-bit counter wrap handled correctly via signed delta cast

Differential-drive odometry: x/y (mm) and theta (rad, wrapped ±π) via Euler-forward integration

Flash config at sector 7 (0x0807FF00, 64 bytes) stores ticks_per_rev, wheel_diam_mm, wheel_base_mm with magic validation and default fallback

JLINK_TLM_ODOM (0x8C) 22-byte frame at 50 Hz: rpm_left, rpm_right, x_mm, y_mm, theta_cdeg, speed_mmps

75/75 unit tests passing (TEST_HOST build, gcc -I include -I src -DTEST_HOST -lm)

Files changed

include/encoder_odom.h — API, flash struct, state struct, defaults

src/encoder_odom.c — TIM2/TIM3 init, tick/RPM/odometry, flash load/save, TLM send

test/test_encoder_odom.c — 75 unit tests

include/jlink.h — JLINK_TLM_ODOM 0x8C, jlink_tlm_odom_t (16 bytes), declaration

src/jlink.c — jlink_send_odom_tlm() 22-byte frame implementation

include/config.h — ENC_LEFT_TIM/ENC_RIGHT_TIM pin/AF constants

Closes #632