navigation_safety_core 0.10.0
navigation_safety_core: ^0.10.0 copied to clipboard
Pure Dart core models for navigation safety: alert severity, safety score, threshold config, navigation route, and safety scenario identifiers. No Flutter dependency. Consumed by navigation_safety (th [...]
navigation_safety_core #
Pure-Dart core models for driving-navigation safety. Threshold
configuration, road-surface vocabulary, alert severity, alert-density
throttle, and an action-coupled alert explainer — tuned per
driver-class, optionally tuned to live driving conditions and live
driver state. Suitable for navigation apps that surface advisory
alerts (winter weather, low visibility, hazardous surface) over a base
map. No Flutter dependency: the Pure-Dart shape lets CLI tools,
server-side logic, test fixtures, and other pure-Dart packages depend
on the safety vocabulary without inheriting Flutter or
flutter_bloc. The companion package
navigation_safety
re-exports everything here and adds a Flutter BLoC layer.
Quick start #
a. Install + import #
Add to pubspec.yaml:
dependencies:
navigation_safety_core: ^0.6.0
Then import:
import 'package:navigation_safety_core/navigation_safety_core.dart';
b. Basic usage — forProfile #
Pick a driver-class profile; receive a config tuned for that class:
final config = NavigationSafetyConfig.forProfile(
DriverProfile.snowZoneExperienced,
);
print(config.warningVisibilityMeters); // 200
print(config.warningTemperatureCelsius); // 0
The six profiles (ageingRural, snowZoneExperienced, noviceUrban,
professional, agriculturalForestry, foreignTouristSnowZone) ship
literature-anchored thresholds for visibility, temperature, and score
floors. Pick the one closest to the active driver context; fall back
to snowZoneExperienced (the historical default) when uncertain.
c. Advanced usage — context-aware factories #
When the app has live driving conditions (current speed, humidity,
ambient temperature, time-since-precipitation), pass a DrivingContext
to forProfileWithContext and the relevant thresholds adjust:
final config = NavigationSafetyConfig.forProfileWithContext(
DriverProfile.snowZoneExperienced,
context: const DrivingContext(
speedMps: 22.2, // ~80 km/h
humidityRH: 0.92,
ambientTempCelsius: 1.0,
timeSincePrecipitation: Duration(minutes: 30),
),
);
When the app additionally has a live driver-state signal (fatigued,
distracted, sensorily-impaired), pair it with the profile in a
DriverContext and pass to forDriverContext:
final config = NavigationSafetyConfig.forDriverContext(
const DriverContext(
profile: DriverProfile.snowZoneExperienced,
state: DriverState.fatigued,
),
environmentalContext: const DrivingContext(speedMps: 22.2),
);
d. Vehicle-class threshold tuning (0.9.0) #
When the app has a vehicle-class signal (e.g. a fleet integrator
serving kei-cars in rural Hokkaido), implement
VehicleClassProvider and pass the token through DrivingContext:
class MyVehicleClassProvider implements VehicleClassProvider {
@override
String? get vehicleClassToken => 'kei-car';
}
final provider = MyVehicleClassProvider();
final config = NavigationSafetyConfig.forProfileWithContext(
DriverProfile.ageingRural,
context: DrivingContext(
speedMps: 18.0,
vehicleClassToken: provider.vehicleClassToken,
),
vehicleOverrides: VehicleThresholdOverrides.withKeiCarDefault(),
);
The built-in withKeiCarDefault() registry adds caution to the
warning visibility floor (+50m) and warning temperature (+1°C) for
the 'kei-car' token; integrators with their own measured
vehicle-class data should compose their own
VehicleThresholdOverrides. Tokens are advisory strings, NOT
control inputs: vehicle-class tunes the warning TIMING only, never
the alert SEVERITY.
Every context input is conservative-only: it can make the thresholds warn earlier than the per-profile baseline, never later. The per-profile baseline is the floor; vehicle-class overrides apply AFTER the baseline AND AFTER the live-context adjustments and are themselves caution-add-only (asserted at runtime in debug builds).
A runnable end-to-end walkthrough lives in
example/main.dart.
Concepts #
The package separates three orthogonal axes:
| Axis | Type | Question | Lifetime |
|---|---|---|---|
| Trait | DriverProfile |
Who is the driver (class)? | Per-trip / per-session |
| State | DriverState |
What state are they in right now? | Sub-trip; can change mid-trip |
| Live conditions | DrivingContext |
What does the road / weather look like right now? | Real-time; updates on every sample |
The trait + state pairing is DriverContext, anchored to the
trait/state distinction in the driver-distraction literature
(Regan, Hallett & Gordon, 2011). Trait is who the driver is; state is
what state the driver is in right now. The two are independent inputs
to threshold tuning. State adjustments at 0.6.0 are intentionally
small — the API shape is stable; the magnitudes are flagged
UNVERIFIED in KNOWN_LIMITATIONS.md pending
state-axis literature anchoring.
Two runtime helpers ship alongside the threshold config:
AlertDensityThrottle— per-profile alerts/min cap with a rolling 60-second window. Critical alerts always fire (documented invariant); info and warning alerts are gated to prevent driver desensitisation. Per-profile cap defaults are anchored to the alarm-fatigue and ADAS driver-workload literature.AlertExplainer— pre-localised(condition, action, verbosity, locale)tuple for each(RoadSurfaceCondition, DriverProfile)pair. Action vocabulary sourced from JAF / MLIT / NEXCO published driver-guidance materials. Action mood is advisory ("reduce", "avoid", "maintain"), never imperative-on-control.
Calibration formulas #
Three context-dependent calibrations live in
lib/src/calibration/:
- Speed-dependent visibility (
speed_dependent_visibility.dart) — at higher speed the warning visibility floor must cover reaction time + braking distance; the per-profile reaction-time default is used to translate a live speed sample into an additional visibility margin. - Humidity-dependent effective temperature
(
humidity_dependent_temperature.dart) — black ice forms at road-surface temperature ≤ 0 °C, which can be several degrees below ambient when humidity is high; the dew-point-aware effective temperature replaces ambient when it crosses the warning threshold earlier. - Time-since-precipitation surface moisture
(
precipitation_history_decay.dart) — surface moisture decays exponentially after the last rain or snowfall; the residual moisture fraction adds a margin to the visibility floor proportional to how wet the road still is.
Per-formula citations live in each calibration module's header comment.
Standards mapping #
This package is intended for SAE J3016 Level 0 and Level 1 supportive use — the driver performs the dynamic driving task at all times; the package's surfaces inform the driver but never actuate the vehicle and never close a control loop.
| Standard | Mapping |
|---|---|
| SAE J3016 | L0 / L1 supportive. No L2+ claim. |
| ISO 26262 | Product-quality scope at the package boundary, not functional-safety scope. The integrator performs the hazard analysis and decides the final ASIL classification for their integration. The package's wording discipline is consistent with QM at the application layer. |
| JIS / JASO (Japanese-domestic automotive standards) | Not mapped at this scope. Consult a qualified Japanese-domestic functional-safety partner before any IVI-vendor or OEM-pilot integration that targets the Japanese-domestic certification surface. |
Full standards-mapping detail and the per-formula UNVERIFIED-magnitude
flags live in
KNOWN_LIMITATIONS.md.
What this is NOT #
- Not an L2+ automation or handover-class supervision package. Any deployment where alert acknowledgment is part of an automation-handover safety contract requires the integrator to add their own handover-class driver-attention monitoring, take-over-request signalling, and minimum-risk-manoeuvre fallback.
- Not ASIL-certified. No functional-safety case is asserted at the package boundary; the integrator owns the hazard analysis and the certification path for their integration.
- Not JIS / JASO conformant. Japanese-domestic certification is out of scope at this layer.
- Not a control surface. Action verbs in
AlertExplainerare advisory; speed numbers are published reference points, not system-enforced limits. The driver retains full control authority. - Not a routing engine.
NavigationRouteis a typed route representation independent of any specific routing engine; it describes a route, it does not compute one.
Equal-dignity invariant #
Alert visibility, severity ordering, and plane-allocation priority in
the consuming HMI MUST be severity-driven, never profile-driven.
Per-profile differentiation belongs in verbosity, locale, and
density-cap surfaces (provided by AlertExplainer and
AlertDensityThrottle); it MUST NOT enter the visibility or
preemption path. See KNOWN_LIMITATIONS.md
for the full discussion.
Public API surface #
NavigationSafetyConfig— threshold configuration with three factories:forProfile,forProfileWithContext,forDriverContext. As of 0.9.0,forProfileWithContextaccepts an optionalvehicleOverridesparameter for vehicle-class threshold tuning.DriverProfile— six driver-class profiles (trait axis).DriverState— four live-state values (transient state axis).DriverContext— trait + state composite.DrivingContext— live driving-conditions value-object. As of 0.9.0, carries an optionalvehicleClassTokenfield.VehicleClassProvider(0.9.0) — abstract interface returningString? get vehicleClassTokenfor integrator-supplied vehicle-class signals.VehicleThresholdOverrides(0.9.0) — registry of vehicle-class-token → caution-adding-only threshold-transform mappings; ships a built-in'kei-car'default viaVehicleThresholdOverrides.withKeiCarDefault().AlertDensityThrottle— per-profile alerts/min cap with critical-bypass invariant.AlertExplainer— action-coupled per-(condition, profile) text with verbosity + locale.AlertSeverity—info/warning/critical. Declaration order is load-bearing.RoadSurfaceCondition— eight road-surface vocabulary values with a published glossary.SafetyScore— composite score across road-surface, visibility, hazard-density, and route-condition axes.SafetyScenario— enumeration of driving-condition scenarios used by the score computation.NavigationRoute— typed route representation independent of any specific routing engine.
Further reading #
example/main.dart— runnable walkthrough of every public surface.CHANGELOG.md— per-version behaviour deltas.KNOWN_LIMITATIONS.md— UNVERIFIED-magnitude disclosures, standards-mapping detail, and the full equal-dignity-invariant discussion.LOOMS.md— runtime-loom catalog (theAlertDensityThrottleandAlertExplainerpair).
License #
BSD-3-Clause. See LICENSE.