Repository navigation
docs(roadmap): add the localization specs (E1–E5) - #31
Merged
Merged
Conversation
Spec files for the localization family, in the new `localization` module: - E1 OdometryFusion: EKF on (x, y, θ, gyro bias). The wheel yaw rate is a χ²-gated bias measurement, so a rejected update flags slip. Optional heading and position fixes go through the same update. - E2 OccupancyGridMap: clamped log-odds along Bresenham rays. Max-range readings only clear cells, and rays stop at the map border. - E3 LandmarkLocalization: range–bearing EKF with Mahalanobis association, a gate and wrapped bearing residuals. - E4 MonteCarloLocalization: ParticleFilter with an odometry motion model and a likelihood field built by a two-pass chamfer transform. The caller injects the samplers. - E5 ScanMatcher: point-to-point (Kabsch) or point-to-line (Levenberg–Marquardt) ICP, with outlier rejection and a check that reports corridor degeneracy. E1 and E3 build on the new upstream ResidualKalmanUpdate (NT74, spec in numerical-toolbox-cpp#364), E4 on ParticleFilter (NT70) and E5 on PointSetAlignment (NT67). F1 gains the shared odometry noise model (OdometryNoise, IncrementDeviation). It adds noise to the body-frame increment rather than using the rotate–translate–rotate split, so reversing does not make the first rotation jump by π. Every reference value was checked against a Python reference implementation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mmp77ieEy16GxJL8KsLsVx
The single-line bullet was 615 characters, over markdownlint's 400-character limit (MegaLinter MD013). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mmp77ieEy16GxJL8KsLsVx
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Max errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|---|
| ✅ ACTION | actionlint | 7 | 0 | 0 | 0.71s | ||
| ✅ CPP | clang-format | 35 | 0 | 0 | 0 | 0.93s | |
| ✅ CPP | cppcheck | 35 | 0 | 0 | 1.34s | ||
| ✅ DOCKERFILE | hadolint | 1 | 0 | 0 | 0.46s | ||
| ✅ JSON | jsonlint | 8 | 0 | 0 | 0.11s | ||
| ✅ JSON | prettier | 8 | 2 | 0 | 0 | 0.42s | |
| ✅ MARKDOWN | markdownlint | 164 | 0 | 0 | 0 | 2.71s | |
| ✅ MARKDOWN | markdown-table-formatter | 164 | 0 | 0 | 0 | 0.25s | |
| lychee | 198 | 1 | 0 | 2.32s | |||
| ✅ YAML | prettier | 12 | 0 | 0 | 0 | 0.58s | |
| ✅ YAML | yamllint | 12 | 0 | 0 | 0.79s |
Detailed Issues
⚠️ SPELL / lychee - 1 error
📝 Summary
---------------------
🔍 Total..........135
🔗 Unique..........71
✅ Successful.....124
⏳ Timeouts.........0
🔀 Redirected.......5
👻 Excluded.........9
❓ Unknown..........0
🚫 Errors...........1
⛔ Unsupported......1
Errors in .github/workflows/static-analysis.yml
[403] https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$ (at 37:21) | Rejected status code: 403 Forbidden
Hint: Followed 5 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
Hint: You can configure accepted/rejected response codes with `-a` or `--accept`
Notices
REPOSITORY_GITLEAKS, REPOSITORY_KICS. See Removed linters to find their replacements.
See detailed reports in MegaLinter artifacts
Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)
- Documentation: Custom Flavors
- Command:
npx mega-linter-runner@10.1.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,CPP_CPPCHECK,CPP_CLANG_FORMAT,DOCKERFILE_HADOLINT,JSON_JSONLINT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT

Show us your support by starring ⭐ the repository
|
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.



Adds spec files (
implementation.md,tests.md,explanation.md) for the localization family, in the newroadmap/localization/module.OdometryFusion— EKF on(x, y, θ, gyro bias).OccupancyGridMap— clamped log-odds along Bresenham rays. Max-range readings only clear cells, and rays stop at the map border.LandmarkLocalization— range–bearing EKF with nearest-neighbour Mahalanobis association, a χ² gate, and bearing residuals wrapped across ±π.MonteCarloLocalization—ParticleFilter(NT70) with the odometry motion model and a likelihood field built by a two-pass chamfer transform. The caller injects normal and uniform samplers, so runs are deterministic.ScanMatcher— point-to-point ICP (Kabsch, NT67) or point-to-line ICP (Levenberg–Marquardt, NT64). It rejects outlier pairs and returnsnulloptfor a degenerate corridor instead of drifting.Upstream dependencies. E1 and E3 build on the new
ResidualKalmanUpdate(NT74).ExtendedKalmanFiltercan't wrap residuals, use a per-landmark measurement model, or exposeSfor gating. NT67, NT70 and NT74 came in with embedded-pro/numerical-toolbox-cpp#364, which has merged.F1 change.
PlanarOdometrygains the shared odometry noise model (OdometryNoise,IncrementDeviation), which E3 and E4 both use. The noise is added to the body-frame increment instead of using Thrun's rotate–translate–rotate split, whose first rotation jumps by π when the robot reverses.ROADMAP and index.
ExtendedKalmanFilter.roadmap/README.mdhas an index entry forlocalization.Carried fix. The destructor-rule bullet in
.github/instructions/robotics-cpp.instructions.mdfrom #30 was 615 characters, over markdownlint's 400-character limit (the one MegaLinter warning on #30). It is now wrapped. The fix was pushed after #30 had already merged.Verification. Every reference value in the test plans comes from a Python reference implementation:
The point-to-line ICP removes a 3 cm bias that point-to-point keeps when the scans sample the walls at different spots.
Generated by Claude Code