Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion apps/obc-web-demo/src/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,12 @@ mod tests {
drive(&mut d, &mut now, "step:1", "StartAway");
drive(&mut d, &mut now, "press", "Map");
assert!(d.app.recording(), "Join nearest begins the session before the next chapter");
assert!(d.app.progress_m() > 1_000, "the ride joins the route mid-climb");
d.cmd("play");
for _ in 0..4 {
now += 250.0;
d.tick(now);
}
assert!(d.app.progress_m() > 1_000, "the first riding fix joins the route mid-climb");
}

#[test]
Expand Down
5 changes: 3 additions & 2 deletions firmware/obc-app/i18n/de.toml
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,11 @@ not_found_hint = "Kein Weg in der Nähe - an einer Straße starten."

# --- Start away from the route start: Ride to start or Join nearest ---
[start_away]
title = "ZUM START"
title = "ROUTE ERREICHEN"
you_are = "Du bist "
from_start = " vom Start entfernt."
no_route = "Keine Route zum Start von hier."
no_route = "Keine Verbindung von hier."
start_without = "Trotzdem starten"
ride_to_start = "Zum Start fahren"
then_route = ", dann Route"
join_nearest = "Nächster Einstieg"
Expand Down
5 changes: 3 additions & 2 deletions firmware/obc-app/i18n/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -502,10 +502,11 @@ not_found_hint = "No rideable way nearby - try from a road."
# hint are fragments around a distance: `you_are` + "3.2 km" + `from_start`, and
# "400 m" + `away_at` + "km 12". ---
[start_away]
title = "RIDE TO START"
title = "JOIN ROUTE"
you_are = "You are "
from_start = " from the start."
no_route = "No route to the start from here."
no_route = "No connecting route from here."
start_without = "Start anyway"
ride_to_start = "Ride to start"
then_route = ", then route"
join_nearest = "Join nearest"
Expand Down
5 changes: 3 additions & 2 deletions firmware/obc-app/i18n/es.toml
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,11 @@ not_found_hint = "No hay camino cerca - prueba desde una carretera."

# --- Start away from the route start: Ride to start or Join nearest ---
[start_away]
title = "IR AL INICIO"
title = "UNIRSE A LA RUTA"
you_are = "Estás a "
from_start = " del inicio."
no_route = "No hay ruta al inicio desde aquí."
no_route = "No hay conexión desde aquí."
start_without = "Iniciar sin guía"
ride_to_start = "Ir al inicio"
then_route = ", luego la ruta"
join_nearest = "Punto más cercano"
Expand Down
5 changes: 3 additions & 2 deletions firmware/obc-app/i18n/fr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,11 @@ not_found_hint = "Aucune voie proche - partez d'une route."

# --- Start away from the route start: Ride to start or Join nearest ---
[start_away]
title = "VERS LE DÉPART"
title = "REJOINDRE LE TRACÉ"
you_are = "Vous êtes à "
from_start = " du départ."
no_route = "Pas de parcours vers le départ d'ici."
no_route = "Pas de liaison depuis ici."
start_without = "Partir quand même"
ride_to_start = "Aller au départ"
then_route = ", puis parcours"
join_nearest = "Rejoindre le tracé"
Expand Down
8 changes: 4 additions & 4 deletions firmware/obc-app/src/activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ pub struct DetourRequest {
/// The chosen rejoin distance along the route — the corridor's end and the splice point.
pub target_m: u32,
/// What the leg does to the route. An approach has no corridor and no trim, and its splice puts
/// it in front of the whole route.
/// it in front of the route from the join point.
pub leg: obc_route::Leg,
}

impl DetourRequest {
/// Ride to start: the way from `from` to the start of `route`.
pub fn approach(route: usize, from: (i32, i32)) -> Self {
DetourRequest { route, from, progress_m: 0, target_m: 0, leg: obc_route::Leg::Approach }
/// Connect `from` to `target_m` on the stored route.
pub fn approach(route: usize, from: (i32, i32), target_m: u32) -> Self {
DetourRequest { route, from, progress_m: target_m, target_m, leg: obc_route::Leg::Approach }
}

/// The rest of the day before `route`, `[from_m, to_m]` on that day's route, then `route` from
Expand Down
7 changes: 5 additions & 2 deletions firmware/obc-app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,10 @@ impl App {
self.ui.map_dirty = true;
}
}
/// Temporary directions can be retired after the ride and checkpoint release them.
pub fn set_temporary_routes(&mut self, mask: u64) {
self.navigator.set_temporary_routes(mask);
}
pub fn set_unaccepted_routes(&mut self, mask: u64) {
if self.navigator.unaccepted_routes() != mask {
self.navigator.set_unaccepted_routes(mask);
Expand Down Expand Up @@ -1730,8 +1734,7 @@ impl App {
self.ui.map_dirty = true;
}

/// A lead-in found no way: drop the spinner at `slot`. Ride to start leaves the prompt it came
/// from with Join nearest and Cancel.
/// A lead-in failed: drop the spinner and offer an unguided start on the original route.
fn land_lead_in_failure(&mut self, slot: usize) {
self.ui.stack.truncate(slot.max(1));
if let Some(Screen::StartAway(prompt)) = self.ui.stack.last_mut() {
Expand Down
18 changes: 9 additions & 9 deletions firmware/obc-app/src/catalog_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ use crate::device_core::{CatalogTag, OperationToken, StoreRevision};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CatalogIntent {
/// Remove unaccepted Assistant candidates no review holds, a commit's batch at a time.
RemoveOrphanReviews,
/// Remove unused temporary directions and abandoned candidates, one commit at a time.
RemoveOrphanRoutes,
CleanupRoutes {
before_utc: u32,
store: crate::device_core::StoreIdentity,
Expand Down Expand Up @@ -565,7 +565,7 @@ pub enum CatalogObjectKind {
/// One bounded physical catalog operation, carrying the [`OperationToken`] the domain issued.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CatalogEffect {
RemoveOrphanReviews {
RemoveOrphanRoutes {
token: OperationToken<CatalogTag>,
},
CleanupRoute {
Expand All @@ -590,7 +590,7 @@ impl CatalogEffect {
CatalogEffect::CleanupRoute { token, .. }
| CatalogEffect::ReadCatalog { token }
| CatalogEffect::RemoveObject { token, .. }
| CatalogEffect::RemoveOrphanReviews { token } => *token,
| CatalogEffect::RemoveOrphanRoutes { token } => *token,
}
}
}
Expand All @@ -609,7 +609,7 @@ pub enum CatalogError {
/// The result of one [`CatalogEffect`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CatalogOutcome {
OrphanReviewsRemoved {
OrphanRoutesRemoved {
token: OperationToken<CatalogTag>,
},
CleanupFinished {
Expand Down Expand Up @@ -644,7 +644,7 @@ impl CatalogOutcome {
CatalogOutcome::CleanupFinished { token }
| CatalogOutcome::CatalogRead { token, .. }
| CatalogOutcome::ObjectRemoved { token, .. }
| CatalogOutcome::OrphanReviewsRemoved { token }
| CatalogOutcome::OrphanRoutesRemoved { token }
| CatalogOutcome::Failed { token, .. }
| CatalogOutcome::Cancelled { token } => *token,
}
Expand Down Expand Up @@ -738,7 +738,7 @@ impl CatalogState {
return Some(CatalogEffect::ReadCatalog { token: self.ops.issue() });
};
let effect = match intent {
CatalogIntent::RemoveOrphanReviews => CatalogEffect::RemoveOrphanReviews { token: self.ops.issue() },
CatalogIntent::RemoveOrphanRoutes => CatalogEffect::RemoveOrphanRoutes { token: self.ops.issue() },
CatalogIntent::CleanupRoutes { before_utc, store } => {
self.cleanup_running = true;
self.pending = Some(intent);
Expand Down Expand Up @@ -833,7 +833,7 @@ impl CatalogState {
self.read_retry_at = None;
None
}
CatalogOutcome::OrphanReviewsRemoved { .. } => {
CatalogOutcome::OrphanRoutesRemoved { .. } => {
self.loaded_scope = None;
self.refresh_owed = true;
None
Expand Down Expand Up @@ -1156,7 +1156,7 @@ mod tests {
for _ in 0..=steps.capacity() {
let Some(effect) = catalogs.next_effect() else { break };
match effect {
CatalogEffect::CleanupRoute { .. } | CatalogEffect::RemoveOrphanReviews { .. } => {
CatalogEffect::CleanupRoute { .. } | CatalogEffect::RemoveOrphanRoutes { .. } => {
panic!("unexpected cleanup")
}
CatalogEffect::RemoveObject { token, object, .. } => {
Expand Down
1 change: 1 addition & 0 deletions firmware/obc-app/src/device_core/pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ impl App {
let _ = self.pass.connections.ui_catalog.try_put(full.rejected);
}
}
self.cleanup_orphan_routes();
// The store refuses a removal for an object the checkpoint names, and a refused removal is
// not retried, so the rider's confirmed delete would vanish. Give up the checkpoint first
// and leave the intent admitted: the admitted intent is what the domain would pull next, so
Expand Down
1 change: 0 additions & 1 deletion firmware/obc-app/src/find_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ impl crate::App {
}
}
self.handle_find_exit();
self.cleanup_orphan_reviews();
self.ui.find.review = self.assistant_review_status();
if self.assistant_review_status() == ReviewStatus::Accepted && self.active_visit() {
if let Some(Screen::VisitReview(screen)) = self.ui.stack.last_mut() {
Expand Down
10 changes: 5 additions & 5 deletions firmware/obc-app/src/navigator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ pub struct NavigatorMachine {
climbs_route: Option<usize>,
waypoints: Waypoints,
waypoints_route: Option<usize>,
waypoints_from_m: u32,
/// The loaded route whose bike type the settings do not have yet; see
/// [`take_loaded_bike_type`](Self::take_loaded_bike_type).
bike_type_owed: Option<usize>,
Expand All @@ -353,8 +354,6 @@ pub struct NavigatorMachine {
/// The one route matcher and the active-route key it last locked to.
route_match: RouteMatch,
matched_route: Option<usize>,
/// Where the next fresh ride joins the active route, instead of where its first fix locks.
join_m: Option<u32>,
/// Where the rider stood on the route at Finish, which unloads it before the store confirms the
/// save.
ride_end: Option<following::RideEnd>,
Expand Down Expand Up @@ -387,13 +386,13 @@ impl NavigatorMachine {
climbs_route: None,
waypoints: Waypoints::new(),
waypoints_route: None,
waypoints_from_m: 0,
bike_type_owed: None,
climb_profile: ClimbProfile::new(),
#[cfg(test)]
climb_fill_count: 0,
route_match: RouteMatch::new(),
matched_route: None,
join_m: None,
ride_end: None,
}
);
Expand Down Expand Up @@ -786,12 +785,12 @@ impl NavigatorMachine {
climbs_route,
waypoints,
waypoints_route,
waypoints_from_m,
bike_type_owed,
climb_profile,
climb_fill_count,
route_match,
matched_route,
join_m,
ride_end,
} = self;
assert_eq!(review.status, ReviewStatus::Idle);
Expand All @@ -807,11 +806,12 @@ impl NavigatorMachine {
assert!(profile.cols().iter().all(|&(lo, hi)| lo > hi), "empty profile bands");
assert!(climbs.is_empty() && climbs_route.is_none(), "no climbs before a route loads");
assert!(waypoints.is_empty() && waypoints_route.is_none(), "no waypoints before a route loads");
assert_eq!(*waypoints_from_m, 0);
assert!(bike_type_owed.is_none(), "no route has been loaded");
assert!(climb_profile.cols().iter().all(|&column| column == 0), "the climb detail starts flat");
assert_eq!(*climb_fill_count, 0, "the climb detail has not been filled");
assert!(!route_match.started() && matched_route.is_none(), "the matcher is unlocked");
assert!(join_m.is_none() && ride_end.is_none(), "no ride waits to join or has ended");
assert!(ride_end.is_none(), "no ride has ended");
}
}

Expand Down
Loading
Loading