Uh oh!
There was an error while loading. Please reload this page.
Guard invalid ReadPos to avoid servo angle jump on bus read failure - #5
Open
GOB52 wants to merge 2 commits into
Open
Guard invalid ReadPos to avoid servo angle jump on bus read failure#5GOB52 wants to merge 2 commits into
GOB52 wants to merge 2 commits into
Conversation
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 freeto 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
ScsServo::getCurrentAngle()can return a large, out-of-range angle when theunderlying serial bus read fails, causing the head to jerk to a physical
extreme. This PR validates the raw position before converting it to an angle and
falls back to the commanded angle on failure. It also prevents a failed read
from corrupting the stored zero (home) calibration.
Problem
_scs_bus.ReadPos()returns-1when the half-duplex servo bus read fails(no/unstable response). The previous code converted that value directly:
With
current_pos == -1, this produces a large negative angle that clamps tothe angle limit, i.e. full deflection. Any caller that builds a relative
move on top of
getCurrentAngle()(e.g. "look slightly left from the currentpose") then snaps the head hard to one side. On a StackChan this shows up as the
head violently slamming to the extreme when a bus read intermittently fails.
The same unchecked read in
setCurrentAngleAsZero()would store-1as thezero position, permanently corrupting the home calibration.
Fix
is_raw_pos_valid()(checks_config.rawPosLimit) and a smallraw_pos_to_angle()helper.getCurrentAngle(): on an invalid raw position, log a warning and return thecommanded (spring) angle, clamped to the angle limit, instead of a bogus
extreme.
setCurrentAngleAsZero(): on an invalid raw position, keep the existing zeroand skip the write, so a transient read failure cannot corrupt calibration.
No behavior change on a successful read.
Consistency with the StackChan firmware
This uses the same handling the official StackChan firmware applies to servo
positions: it validates the position against
_config.rawPosLimitand fallsback to a safe value when the position is out of range. The firmware does this
for the stored zero position in
get_zero_pos_from_nvs()(
firmware/main/hal/hal_servo.cpp):This PR applies that same
rawPosLimitvalidation to the liveReadPos()results in
getCurrentAngle()/setCurrentAngleAsZero(), which are otherwiseused unguarded, so a transient bus failure cannot turn into a bogus angle or a
corrupted zero.
Testing
deflection during relative moves (idle motion / head-pet gestures).
behave normally; home calibration is preserved across transient failures.