navigation_safety 0.9.0
navigation_safety: ^0.9.0 copied to clipboard
Show drivers what matters before it's too late. Safety alert overlay that stays on top of your navigation UI. Navigation session state machine with configurable severity thresholds. Display-only, neve [...]
navigation_safety #
Show drivers what matters before it's too late. Safety alerts that stay on top of your navigation UI — always visible, never controlling.
Use navigation_safety when you need a navigation session state machine with a
safety overlay that renders alerts (ice, low visibility, GPS loss) without
blocking the driver's view or controlling the vehicle.
Features #
NavigationBlocfor navigation session lifecycle: idle, navigating, deviated, arrived.SafetyOverlaywidget that stays at the top of the UI stack when alerts are active.- Pure Dart
_coreexports forSafetyScore,AlertSeverity, andNavigationSafetyConfig. - Configurable severity thresholds for score-based safety alerts.
- Composable with
routing_blocandvoice_guidancewithout coupling to either.
Install #
dependencies:
navigation_safety: ^0.3.0
Quick Start #
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:navigation_safety/navigation_safety.dart';
import 'package:routing_engine/routing_engine.dart';
class MyNavScreen extends StatelessWidget {
const MyNavScreen({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => NavigationBloc(),
child: Scaffold(
body: Stack(
children: const [
Placeholder(),
SafetyOverlay(),
],
),
),
);
}
}
API Overview #
| API | Purpose |
|---|---|
NavigationBloc |
Navigation session lifecycle and alert state |
NavigationState |
Session state, maneuver progress, active alert |
NavigationEvent |
Navigation start/stop, maneuver advance, alert input |
SafetyOverlay |
Safety alert presentation layer |
SafetyScore |
Pure Dart score model for grip, visibility, fleet confidence |
NavigationSafetyConfig |
Pure Dart threshold configuration |
AlertSeverity |
info, warning, critical |
OODA Latency Budget #
| Phase | Budget | Owner |
|---|---|---|
| Observe | < 200 ms | Sensor streams |
| Orient | < 500 ms | NavigationBloc |
| Display | < 300 ms | SafetyOverlay |
| Total to display | < 1 second | SNGNav domain |
SafetyOverlay Rules #
| Rule | Requirement |
|---|---|
| 1 | Always rendered - never removed from the widget tree |
| 2 | Always on top - Z=5 (topmost) |
| 3 | Passthrough when inactive - no input blocking |
| 4 | Modal when active - blocks interaction until acknowledged |
| 5 | Independent state - not reset by unrelated navigation transitions |
Threshold Configuration #
import 'package:navigation_safety/navigation_safety_core.dart';
final config = NavigationSafetyConfig(
safeScoreFloor: 0.80,
infoScoreFloor: 0.50,
warningScoreFloor: 0.30,
criticalTemperatureCelsius: -5,
warningVisibilityMeters: 200,
);
final score = SafetyScore(
overall: 0.42,
gripScore: 0.35,
visibilityScore: 0.40,
fleetConfidenceScore: 0.75,
);
final severity = score.toAlertSeverity(config);
Safety Boundary (SOTIF scope) #
This package is responsible for display. You are responsible for score computation.
If your score is uncertain, pass 0.0 — the package will alert conservatively.
This package must not be used to issue vehicle control commands or to imply ADAS
certification. Classification: ASIL-QM (display-only). No actuator path.
SafetyScore Computation #
SafetyScore.overall is compared against thresholds in NavigationSafetyConfig:
overall < warningScoreFloor → AlertSeverity.critical
overall < infoScoreFloor → AlertSeverity.warning
overall < safeScoreFloor → AlertSeverity.info
otherwise → no alert
The component scores (gripScore, visibilityScore, fleetConfidenceScore) are
inputs you compute from your sensor data. The package does not read sensors — it
displays what you give it. Each component is clamped to [0.0, 1.0].
Contributing a Signal #
You can extend this package to cover a new threat scenario in about 3 hours:
- Read
lib/src/models/safety_score.dart(72 lines) andlib/src/models/navigation_safety_config.dart - Add one field to
SafetyScorefor your scenario (e.g.,infrastructureRiskScore) - Add a corresponding threshold to
NavigationSafetyConfig - Update
toAlertSeverity()to check your new field - Write 3 tests: boundary value, clamp behaviour, severity mapping
- Open a PR referencing the scenario ID from CONTRIBUTING.md
No KUKSA, Valhalla, or embedded Linux knowledge required. The SOTIF boundary above is what protects you — you only need to compute a float and pass it in.
See CONTRIBUTING.md for the list of open scenario slots.
Works With #
| Package | How |
|---|---|
| driving_weather | Weather conditions feed into safety score computation |
| driving_conditions | Road surface and grip data drive alert severity |
| map_viewport_bloc | Safety overlay sits at Z5 in the viewport layer stack |
See Also #
- kalman_dr — Dead reckoning through GPS loss
- routing_bloc — Route lifecycle state machine
- driving_consent — Privacy consent with Jidoka semantics
Part of SNGNav — 11 packages for offline-first navigation on Flutter.
License #
BSD-3-Clause — see LICENSE.