Skip to content

feat(mobile): jitter-resistant step advance via entry+exit condition - #66

Merged
cafca merged 3 commits into
mainfrom
claude/focused-khorana-57911c
Apr 25, 2026
Merged

feat(mobile): jitter-resistant step advance via entry+exit condition#66
cafca merged 3 commits into
mainfrom
claude/focused-khorana-57911c

Conversation

@cafca

@cafca cafca commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

Two changes to Ferrostar's NavigationControllerConfig in packages/ferrostar_flutter/ios/ferrostar_flutter/Sources/ferrostar_flutter/Serialization.swift:

1. Jitter-resistant step advance

Switch stepAdvanceCondition from DistanceToEndOfStep (single 10m threshold) to DistanceEntryAndExit. The user must enter the zone near a maneuver and travel past it before the step advances, which prevents premature advance from GPS jitter at intersections.

stepAdvanceCondition: stepAdvanceDistanceEntryAndExit(
  minimumHorizontalAccuracy: 32, distanceToEndOfStep: 30, distanceAfterEndStep: 5)

Values lifted from the Ferrostar docs' recommended defaults. Users who skip a maneuver entirely still get rerouted via the existing routeDeviationTracking.

2. Fix: arrival screen never fired

While reviewing the config, found that arrivalStepAdvanceCondition: stepAdvanceManual() was preventing the arrival flow from ever running. The app's map_screen.dart:367 listens for TripStatus.complete to play "you have arrived" TTS, fire haptics, switch the camera to arrived mode, and show ArrivedSheet. With stepAdvanceManual(), Ferrostar's final step never advances on its own — it requires an explicit advanceToNextStep() call, which nothing in the repo makes.

Switched to:

arrivalStepAdvanceCondition: stepAdvanceDistanceToEndOfStep(
  distance: 30, minimumHorizontalAccuracy: 32)

Now TripState.complete fires automatically when the user reaches the destination, driving the existing arrival UI.

Test plan

  • Run just dev-ios-device <DEVICE> and ride a route with several turns; verify steps advance just past each maneuver, not before
  • Stand at a known step end with GPS jitter; verify puck does not skip ahead
  • Skip a turn deliberately; verify deviation tracking triggers reroute
  • Ride to the destination; verify arrival TTS, haptic, camera transition, and ArrivedSheet all appear (previously broken)

cafca added 3 commits April 25, 2026 10:40
Switches Ferrostar's stepAdvanceCondition from DistanceToEndOfStep
(single 10m threshold) to DistanceEntryAndExit (30m entry + 5m exit).
The user must enter the zone near the maneuver and then travel past
it before advancing, which prevents premature advance from GPS jitter
near intersections. Values follow the Ferrostar docs' recommended
defaults; route deviation tracking still catches users who skip a
maneuver entirely.
The arrival flow in map_screen.dart waits for TripStatus.complete
to play "you have arrived" TTS, fire haptics, switch the camera to
arrived mode, and show ArrivedSheet. Ferrostar only emits .complete
after the final step advances, which with stepAdvanceManual() requires
an explicit advanceToNextStep() call. Nothing in the repo ever calls
that, so arrival never fired.

Switch arrivalStepAdvanceCondition to stepAdvanceDistanceToEndOfStep
(30m, matching the Ferrostar docs' recommended default) so the trip
auto-completes when the user reaches the destination and the existing
arrival UI runs.
@cafca
cafca merged commit da232cb into main Apr 25, 2026
8 of 9 checks passed
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.

1 participant