Skip to content

feat(motion_profiles): add polynomial, trapezoidal and S-curve profiles - #356

Merged
gabrielfrasantos merged 5 commits into
claude/brave-einstein-5nj7y6-tier1from
claude/brave-einstein-5nj7y6-tier2
Oct 23, 2026
Merged

gabrielfrasantos merged 5 commits into
claude/brave-einstein-5nj7y6-tier1from
claude/brave-einstein-5nj7y6-tier2

Conversation

@gabrielfrasantos

Copy link
Copy Markdown
Contributor

Summary

Tier 2 of the roadmap items added in #353: the new motion_profiles module. It has its own CMake target, test target, doc folder, and an entry in the AGENTS.md namespace list. The shared TrajectoryState / MotionLimits types live in MotionProfileTypes.hpp.

  • chore: add compile optimizations #55 Polynomial profile: closed-form cubic or quintic coefficients, solved once. Sampling is four Horner evaluations (position, velocity, acceleration, jerk).
  • chore: modify compiler optimizations #56 Trapezoidal (LSPB) profile: minimum-time trapezoid or triangle. PlanWithDuration keeps aMax and lowers the cruise speed for multi-axis sync, using the cancellation-free root.
  • chore(main): release 2.0.0 #60 S-curve profile: seven-phase jerk-limited profile from the closed-form three-step planner (Biagiotti & Melchiorri §3.4). Adds math::Cbrt: a generic wrapper with no ARM override.

At and after tf, both limit-driven profiles hold the goal at rest. Before t = 0 they hold the start, including for zero-distance moves. Found while documenting: a zero-distance trapezoid sampled at t < 0 used to report a nonzero acceleration.

Verification

  • 31 unit tests pass on host GCC and Clang.
  • 20 000 random (h, vMax, aMax, jMax) plans: each S-curve and trapezoid ends within 1e-6 of h at rest and never exceeds its limits.
  • Coverage: 100% line coverage of all three profile headers.

Stack

Stacked on #355 (base: claude/brave-einstein-5nj7y6-tier1). Merge #355 first; this PR is then retargeted to main.


Generated by Claude Code

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

✅⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Max errors Warnings Elapsed time
✅ ACTION actionlint 7 0 0 0.73s
✅ CPP clang-format 456 11 0 0 4.22s
✅ CPP cppcheck 456 0 0 9.32s
✅ DOCKERFILE hadolint 1 0 0 0.49s
✅ JSON jsonlint 8 0 0 0.1s
✅ JSON prettier 8 8 0 0 0.49s
⚠️ MARKDOWN markdownlint 156 2 148 0 3.54s
✅ MARKDOWN markdown-table-formatter 156 12 0 0 0.36s
⚠️ SPELL lychee 267 19 0 24.64s
✅ YAML prettier 12 3 0 0 0.61s
✅ YAML yamllint 12 0 0 0.61s

Detailed Issues

⚠️ SPELL / lychee - 19 errors
📝 Summary
---------------------
🔍 Total..........591
🔗 Unique.........450
✅ Successful.....560
⏳ Timeouts.........0
🔀 Redirected.....154
👻 Excluded........11
❓ Unknown..........0
🚫 Errors..........19
⛔ Unsupported.....19

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

Errors in CHANGELOG.md
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/1 (at 206:31) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/13 (at 220:7) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/15 (at 215:18) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/18 (at 205:62) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/24 (at 210:19) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/4 (at 214:34) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/6 (at 212:53) | Rejected status code: 404 Not Found
[404] https://github.com/embedded-pro/embedded-numerical-toolbox/issues/7 (at 209:32) | Rejected status code: 404 Not Found

Errors in doc/filters/active/AhrsMadgwickMahony.md
[ERROR] file://doc/filters/ComplementaryFilter.md (at 131:3) | File not found. Check if file exists and path is correct

Errors in doc/filters/active/ExtendedKalmanFilter.md
[ERROR] file://doc/dynamics/EulerLagrange.md (at 130:3) | File not found. Check if file exists and path is correct

Errors in doc/filters/active/KalmanFilter.md
[ERROR] file://doc/filters/controllers/Lqr.md (at 114:77) | File not found. Check if file exists and path is correct
[ERROR] file://doc/filters/controllers/Lqr.md (at 133:3) | File not found. Check if file exists and path is correct
[ERROR] file://doc/filters/controllers/Pid.md (at 135:3) | File not found. Check if file exists and path is correct
[ERROR] file://doc/filters/solvers/DiscreteAlgebraicRiccatiEquation.md (at 134:3) | File not found. Check if file exists and path is correct

Errors in doc/performance-optimization/README.md
[403] https://developer.arm.com/documentation/100166/latest/ (at 472:3) | Rejected status code: 403 Forbidden
[403] https://developer.arm.com/documentation/dui0473/latest (at 474:3) | Rejected status code: 403 Forbidden

Errors in README.md
[ERROR] file:///releases/latest (at 39:14) | File not found. Check if file exists and path is correct
[404] https://embedded-pro.github.io/embedded-dsp-control/ (at 38:1) | Rejected status code: 404 Not Found

Hint: Followed 154 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`
⚠️ MARKDOWN / markdownlint - 148 errors
.claude/agents/algo-implementer.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Read `AGENTS.md` and `roadmap/..."]
.claude/agents/executor.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.claude/agents/orchestrator.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Triage requests and route to t..."]
.claude/agents/planner.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.claude/agents/reviewer.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.claude/agents/unit-tester.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Read `AGENTS.md`, `.github/ins..."]
.github/agents/algo-implementer.agent.md:11 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "You deploy ONE algorithm at a ..."]
.github/agents/executor.agent.md:11 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.github/agents/orchestrator.agent.md:21 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Triage requests and route to t..."]
.github/agents/planner.agent.md:11 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.github/agents/reviewer.agent.md:14 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Canonical rules: `AGENTS.md`. ..."]
.github/agents/unit-tester.agent.md:11 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "You add or extend the unit tes..."]
.github/instructions/numerical-cpp.instructions.md:76:401 error MD013/line-length Line length [Expected: 400; Actual: 423]
.github/prompts/orchestrate.prompt.md:8:401 error MD013/line-length Line length [Expected: 400; Actual: 496]
.github/prompts/orchestrate.prompt.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Analyze the following task for..."]
.github/prompts/unit-test.prompt.md:8 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "Author (or extend) the unit te..."]
CHANGELOG.md:26 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:38 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:52 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Build System"]
CHANGELOG.md:64 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:133 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Miscellaneous"]
CHANGELOG.md:151 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Build System"]
CHANGELOG.md:179 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:183 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:195 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:202 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:218 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
doc/analysis/Decibels.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 637]
doc/analysis/GoertzelAlgorithm.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 492]
doc/analysis/GoertzelAlgorithm.md:107:401 error MD013/line-length Line length [Expected: 400; Actual: 451]
doc/analysis/HilbertTransform.md:31:34 error MD056/table-column-count Table column count [Expected: 2; Actual: 4; Too many cells, extra data will be missing]
doc/analysis/PowerDensitySpectrum.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 509]
doc/analysis/PowerDensitySpectrum.md:104:20 error MD056/table-column-count Table column count [Expected: 2; Actual: 6; Too many cells, extra data will be missing]
doc/analysis/PowerDensitySpectrum.md:104:17 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/PowerDensitySpectrum.md:104:20 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/PowerDensitySpectrum.md:104:32 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/PowerDensitySpectrum.md:104:38 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/PowerDensitySpectrum.md:104:45 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/PowerDensitySpectrum.md:104:135 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/analysis/SignalDetectors.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 481]
doc/control_analysis/FrequencyResponse.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 469]
doc/control_analysis/README.md:11:68 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/README.md:11:147 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/README.md:12:53 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/README.md:12:172 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/README.md:13:68 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/README.md:13:151 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/control_analysis/RootLocus.md:69 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
doc/control_analysis/TransferFunctionStateSpace.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 589]
doc/controllers/Feedforward2Dof.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 627]
doc/controllers/FrictionCompensation.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 420]
doc/controllers/FrictionCompensation.md:29:401 error MD013/line-length Line length [Expected: 400; Actual: 406]
doc/controllers/FrictionCompensation.md:44:401 error MD013/line-length Line length [Expected: 400; Actual: 436]
doc/controllers/GainScheduledController.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 454]
doc/controllers/LeadLagCompensator.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 639]
doc/controllers/Lqg.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 428]
doc/controllers/SaturationRateLimiter.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 451]
doc/controllers/SaturationRateLimiter.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 477]
doc/estimators/ExpectationMaximization.md:104:103 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/estimators/LmsAdaptiveFilter.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 547]
doc/estimators/README.md:11:122 error MD056/table-column-count Table column count [Expected: 2; Actual: 3; Too many cells, extra data will be missing]
doc/estimators/README.md:11:122 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/AhrsMadgwickMahony.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 538]
doc/filters/active/AhrsMadgwickMahony.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 554]
doc/filters/active/AlphaBetaFilter.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 419]
doc/filters/active/AlphaBetaFilter.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 451]
doc/filters/active/KalmanSmoother.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 421]
doc/filters/active/KalmanSmoother.md:111:28 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:111:61 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:111:110 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:122:19 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:122:27 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:122:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:123:19 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:123:27 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:123:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:124:19 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:124:27 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:124:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:125:19 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:125:27 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/KalmanSmoother.md:125:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/UnscentedKalmanFilter.md:11:401 error MD013/line-length Line length [Expected: 400; Actual: 468]
doc/filters/active/UnscentedKalmanFilter.md:149:65 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/active/UnscentedKalmanFilter.md:149:153 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/passive/MedianFilter.md:69:25 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/passive/MedianFilter.md:69:43 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/passive/MedianFilter.md:70:51 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/passive/MedianFilter.md:70:96 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:13:74 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:13:179 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:14:74 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:14:179 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:15:74 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:15:179 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:16:74 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:16:179 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:17:74 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/filters/README.md:17:179 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/AngleUtilities.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 603]
doc/math/AngleUtilities.md:58:401 error MD013/line-length Line length [Expected: 400; Actual: 438]
doc/math/GivensRotation.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 429]
doc/math/HouseholderTransform.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 455]
doc/math/MatrixExponential.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 555]
doc/math/MatrixNorms.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 452]
doc/math/MatrixNorms.md:42:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/MatrixNorms.md:43:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/MatrixNorms.md:44:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/MatrixNorms.md:45:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/MatrixNorms.md:46:67 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/math/StepResponseMetrics.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 514]
doc/math/StepResponseMetrics.md:61 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
doc/motion_profiles/SCurveProfile.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 438]
doc/motion_profiles/SCurveProfile.md:53:401 error MD013/line-length Line length [Expected: 400; Actual: 480]
doc/motion_profiles/TrapezoidalProfile.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 474]
doc/nonlinear_control/BacksteppingControl.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 594]
doc/nonlinear_control/FeedbackLinearization.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 533]
doc/nonlinear_control/FeedbackLinearization.md:15:401 error MD013/line-length Line length [Expected: 400; Actual: 491]
doc/nonlinear_control/ModelReferenceAdaptiveControl.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 587]
doc/nonlinear_control/README.md:9:80 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/nonlinear_control/README.md:9:258 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/nonlinear_control/README.md:10:80 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/nonlinear_control/README.md:10:258 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/nonlinear_control/README.md:11:80 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/nonlinear_control/README.md:11:270 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/regularization/Regularization.md:100:32 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/regularization/Regularization.md:100:135 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/robust_control/ActiveDisturbanceRejection.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 699]
doc/robust_control/ActiveDisturbanceRejection.md:85:401 error MD013/line-length Line length [Expected: 400; Actual: 575]
doc/robust_control/ActiveDisturbanceRejection.md:93:401 error MD013/line-length Line length [Expected: 400; Actual: 622]
doc/robust_control/DisturbanceObserver.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 476]
doc/robust_control/README.md:12:259 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
doc/robust_control/SlidingModeControl.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 644]
doc/solvers/ConditionNumber.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 461]
doc/solvers/ConditionNumber.md:51:401 error MD013/line-length Line length [Expected: 400; Actual: 425]
doc/solvers/JacobiEigenSolver.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 443]
doc/solvers/JacobiEigenSolver.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 609]
doc/solvers/JacobiEigenSolver.md:45:401 error MD013/line-length Line length [Expected: 400; Actual: 427]
doc/solvers/RungeKuttaIntegrators.md:9:401 error MD013/line-length Line length [Expected: 400; Actual: 509]
doc/solvers/SpectralRadius.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 665]
doc/solvers/SymplecticIntegrators.md:7:401 error MD013/line-length Line length [Expected: 400; Actual: 486]
doc/solvers/SymplecticIntegrators.md:35:401 error MD013/line-length Line length [Expected: 400; Actual: 476]
doc/solvers/SymplecticIntegrators.md:63:401 error MD013/line-length Line length [Expected: 400; Actual: 431]
doc/windowing/window.md:5:401 error MD013/line-length Line length [Expected: 400; Actual: 415]
README.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "[![Quality Gate Status](https:..."]
README.md:9:401 error MD013/line-length Line length [Expected: 400; Actual: 442]
README.md:17:401 error MD013/line-length Line length [Expected: 400; Actual: 446]
roadmap/README.md:11 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]

Notices

⚠️ Your configuration references items that have been removed from MegaLinter and are ignored: 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

MegaLinter is provided by OX Security
Show us your support by starring ⭐ the repository

@gabrielfrasantos
gabrielfrasantos force-pushed the claude/brave-einstein-5nj7y6-tier2 branch from 690f252 to 3f9b2c4 Compare October 23, 2026 16:26
Deploy roadmap item 55 and create the motion_profiles module with the
shared TrajectoryState / MotionLimits types. PolynomialProfile solves
the closed-form cubic (position + velocity) or quintic (+ acceleration)
coefficients once and samples position, velocity, acceleration and
jerk by Horner evaluation, with time clamped to [0, tf].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5
Deploy roadmap item 56: minimum-time trapezoid / triangle plan from
(vMax, aMax), plus PlanWithDuration, which keeps aMax and lowers the
cruise speed so several axes can finish together. The cruise speed uses
the cancellation-free conjugate form of the smaller root, and
infeasible durations return nullopt. At and after tf the profile holds
the goal at rest; before t = 0 it holds the start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5
Deploy roadmap item 60: seven-phase rest-to-rest profile planned with
the closed-form three-step method of Biagiotti & Melchiorri §3.4 (vMax
reached; else aMax reached; else neither). The boundary states are
integrated once, and each sample evaluates one constant-jerk cubic.

Add math::Cbrt (generic wrapper, no ARM override), which the step-3
branch needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5
Apply markdown-table-formatter's layout to the tables this tier adds
or edits, as suggested by MegaLinter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5
The qemu-cortex-m4/m7 build presets list their test targets
explicitly, so numerical.motion_profiles_test was registered with
CTest but never built, and the QEMU jobs failed with "Could not load
kernel".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5
Comment thread CMakePresets.json
@gabrielfrasantos
gabrielfrasantos force-pushed the claude/brave-einstein-5nj7y6-tier1 branch from a74c0d2 to c975a88 Compare October 23, 2026 16:31
@gabrielfrasantos
gabrielfrasantos force-pushed the claude/brave-einstein-5nj7y6-tier2 branch from d8bce74 to ad3b6a8 Compare October 23, 2026 16:31
@sonarqubecloud

Copy link
Copy Markdown

@gabrielfrasantos
gabrielfrasantos merged commit 44a914f into claude/brave-einstein-5nj7y6-tier1 Oct 23, 2026
14 checks passed
@gabrielfrasantos
gabrielfrasantos deleted the claude/brave-einstein-5nj7y6-tier2 branch October 23, 2026 17:05
gabrielfrasantos added a commit that referenced this pull request Oct 23, 2026
… symplectic integrators and motion profiles (#355)

* feat(math): add angle utilities (wrap, shortest difference, unwrap)

Deploy roadmap item 54. WrapToPi maps into (−π, π] (both ±π → +π),
WrapToTwoPi into [0, 2π) with a guard so rounding never returns 2π,
AngleDifference takes the short way round and UnwrapAngle turns a
wrapped measurement into a continuous signal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* refactor(filters): use math::WrapToPi in ComplementaryFilter

Replace the private heading wrap with the shared angle utilities. The
result changes only at exactly ±π: the estimate is now reported in
(−π, π], so −π maps to +π, matching the library-wide convention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(math): add tridiagonal (Thomas) solver

Deploy roadmap item 59: O(n) factor-once / solve-many solver for
tridiagonal systems. Factor stores reciprocal pivots so Solve has no
division, and reports a pivot with |p| <= eps * scale (or a size outside
[1, MaxSize]) as failure instead of dividing by it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(controllers): add friction compensation feedforward

Deploy roadmap item 57: per-axis Coulomb + viscous + Stribeck friction
model, smoothed through zero velocity with tanh(v/eps) and clamped to
maxCompensation, to be added to a torque or current command.

The spec's "torque ≈ F_s near zero velocity" check is asserted against
the model's exact value at v = 10·eps (0.788237): the Stribeck term has
already decayed by e^-0.04 there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(solvers): add symplectic integrators for second-order systems

Deploy roadmap item 58: semi-implicit Euler and velocity Verlet
(kick-drift-kick) over a new SecondOrderSystem interface. For a
conservative plant the energy error stays bounded instead of drifting.

The second-order check compares h = 0.1 with h = 0.05 rather than the
spec's unspecified small step: at h = 0.01 float32 rounding already
dominates the truncation error and the error ratio reads ≈ 5, not 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* docs: align markdown tables

Apply markdown-table-formatter's layout to the tables this tier adds
or edits, as suggested by MegaLinter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(motion_profiles): add polynomial, trapezoidal and S-curve profiles (#356)

* feat(motion_profiles): add module with polynomial point-to-point profile

Deploy roadmap item 55 and create the motion_profiles module with the
shared TrajectoryState / MotionLimits types. PolynomialProfile solves
the closed-form cubic (position + velocity) or quintic (+ acceleration)
coefficients once and samples position, velocity, acceleration and
jerk by Horner evaluation, with time clamped to [0, tf].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(motion_profiles): add trapezoidal (LSPB) velocity profile

Deploy roadmap item 56: minimum-time trapezoid / triangle plan from
(vMax, aMax), plus PlanWithDuration, which keeps aMax and lowers the
cruise speed so several axes can finish together. The cruise speed uses
the cancellation-free conjugate form of the smaller root, and
infeasible durations return nullopt. At and after tf the profile holds
the goal at rest; before t = 0 it holds the start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* feat(motion_profiles): add S-curve (jerk-limited) profile

Deploy roadmap item 60: seven-phase rest-to-rest profile planned with
the closed-form three-step method of Biagiotti & Melchiorri §3.4 (vMax
reached; else aMax reached; else neither). The boundary states are
integrated once, and each sample evaluates one constant-jerk cubic.

Add math::Cbrt (generic wrapper, no ARM override), which the step-3
branch needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* docs: align markdown tables

Apply markdown-table-formatter's layout to the tables this tier adds
or edits, as suggested by MegaLinter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

* fix(build): build motion_profiles tests in the QEMU presets

The qemu-cortex-m4/m7 build presets list their test targets
explicitly, so numerical.motion_profiles_test was registered with
CTest but never built, and the QEMU jobs failed with "Could not load
kernel".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q53m7MZDmHwocmKbhhd2o5

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants