Repository navigation
feat(firmware)!: adopt DCMotorServo 2.0's speed loop and SET_SPEED_FF - #116
Merged
Merged
Conversation
The E-S Motor 36PG-3429-19-EN measured 848 counts per output turn on the bench (#103), not 798, so speeds read about 6 % high. Held back: at 848 test_speed_entry_62 reverse fails on a one-sample -18 PWM from the position loop at speed entry, which also occurs at 798 for other entry timings (#105). Refs #103
The README still listed 798, and the changelog had no entry for the change to 848 (#103).
Adopt DCMotorServo ^2.0.0 and bread-crumbs-contracts ^0.13.0. The speed loop now sets PWM as feedforward plus a PI trim on the measured speed, instead of a PID moving the position target. - SET_PID speed gains (and PIDSPEED=) are Kp in PWM per RPM and Ki in PWM per RPM-second; kd is stored and unused. Defaults 0.6, 3.0, 0. - New SET_SPEED_FF (DCMT_CAP_SPEED_FEEDFORWARD, bit 13, advertised only where the speed loop is built) sets each motor's static PWM, RPM per PWM step and trim bound. The loop applies them as setFeedforward() with kv = rpm_per_pwm * CPR / 60 counts/s per PWM, and setTrimLimit(). Until one is sent the loop is a plain PI. A payload that isn't 8 bytes is refused MALFORMED, a build without the speed loop refuses it NOT_BUILT; it is taken during a hold, as SET_PID is. - Serial SPEEDFF=static1,rpp1,trim1,static2,rpp2,trim2, rpp in RPM per PWM step. - Remove setMaxLead(), DCMT_TACHO_MAX_LEAD and the Ki freeze while the lead cap clamped; the library's conditional integration replaces them. Stall detection is unchanged. Host tests: test_speed_ff covers the new frame, serial command, caps and module major 3 on every env; test_max_lead and test_speed_freeze go with the code they tested. The motor tests now configure the model motor's feedforward (static 10, 1.719 RPM per PWM, trim 20) and Kp 0.6 Ki 3.0, and test_speed_entry_62 adds a sweep of the reverse entry over 550 to 750 ms in 2 ms steps: 0 of 101 timings drive backwards, where 2fda4c3 with DCMotorServo 1.2.1 gave 15 of 101. BREAKING CHANGE: GET_VERSION reports module major 3, and SET_PID's speed gains are read in PWM units. Speed gains tuned for major 2 firmware don't carry over.
CameronBrooks11
added a commit
that referenced
this pull request
Nov 8, 2026
docs(bench): add the 2026-11-07 speed and position record Adds the 2026-11-07 bench record for #116 on a gen2 Nano Every with both motors and 848-count encoders, from main at c276d88. Passed: - Open-loop sweeps gave M1 static 10, 2.024 RPM per PWM and M2 static 7, 2.005, sent with SET_SPEED_FF (trim 20). A 4-byte payload was refused. - Closed-loop speed at +10, -60, +120 and -150 RPM on each motor: within 5 % at 0.22-0.23 s, and the last-5 s means within 0.4 RPM of the target. - A 0.5 s grip at 60 RPM recovered in 0.2 s with no fault; entry from -255 into +60 RPM never drove backwards (PWM 39-41, #62). - Both motors at 120 RPM for 5 minutes with GET_STATE every 100 ms: no lockup and no lease trip (#109). Findings: - A -7282 -> 0 position move stopped at +48 with no drive for 60 s. DCMotorServo 2.0.1 (feastorg/dcmotorservo#30) fixes it; with the fix moves of 7282, 16000 and 20725 counts ended within 6 counts. - 32 of 2968 polls (1.1 %) failed CRC with both motors running. - A steady hand load on a held position latched M1_STALL within about a second (#102). Not checked: the saturated-hold case of the fix, M2 grip and entry, #102's small step, and the analog builds on this board.
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.
Adopts DCMotorServo ^2.0.0 (feastorg/dcmotorservo#26) and bread-crumbs-contracts ^0.13.0 (feastorg/bread-crumbs-contracts#75). The speed loop now sets PWM as feedforward plus a PI trim on the measured speed, instead of a PID moving the position target. Fixes #105, and the encoder default moves to the measured 848 counts per turn (#103).
SET_PIDspeed gains (andPIDSPEED=) are Kp in PWM per RPM and Ki in PWM per RPM-second. kd is stored and unused. Defaults are 0.6, 3.0 and 0.DCMT_CAP_SPEED_FEEDFORWARD(bit 13), which is advertised only where the speed loop is built. It sets each motor's static PWM, RPM per PWM step and trim bound.setFeedforward()with kv = rpm_per_pwm × CPR / 60 counts/s per PWM, plussetTrimLimit(). Until one is sent, the loop is a plain PI.SPEEDFF=static1,rpp1,trim1,static2,rpp2,trim2, with rpp in RPM per PWM step.setMaxLead(),DCMT_TACHO_MAX_LEADand the feat(firmware): latch a stall fault, freeze the speed integral, Ki 0.2 #97 Ki freeze while the lead cap clamped. The library's conditional integration replaces them. Stall detection is unchanged.MOTOR1_CPRandMOTOR2_CPRare 848, and the README and CHANGELOG say so.Checks
Host suite:
make -C firmware/test/hostgives 1872 ok in 168 runs, 0 failed. main had 1726 ok in 162 runs, and the CPR commit alone failed Entering closed-loop speed starts from a stale servo target and encoder baseline #62 reverse twice.test_speed_ffcovers the frame, the serial command, the caps and module major 3 on every env.test_max_leadandtest_speed_freezego with the code they tested.Entering closed-loop speed starts from a stale servo target and encoder baseline #62 sweep: reverse entry swept over 550–750 ms in 2 ms steps. 0 of 101 timings drive backwards on both Nano Every envs, against 15 of 101 on DCMotorServo 1.2.1.
Builds: all 12 envs build with 0 warnings.
Mutations: each was applied with the file hashed before and after, then restored. Each fails a named check:
Not checked
Hardware. The bench step is next:
dcmt_bench.py ffsweep).BREAKING CHANGE: GET_VERSION reports module major 3, and SET_PID's speed gains are read in PWM units. Speed gains tuned for major-2 firmware don't carry over.