navigation_safety_core 0.10.0 copy "navigation_safety_core: ^0.10.0" to clipboard
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 [...]

example/main.dart

// Example: navigation_safety_core
//
// A runnable, Pure-Dart walkthrough of the public API surface:
//
//   1. NavigationSafetyConfig.forProfile         — driver-class baseline
//   2. NavigationSafetyConfig.forProfileWithContext
//                                                — adds live driving conditions
//   3. NavigationSafetyConfig.forDriverContext   — adds live driver state
//   4. AlertDensityThrottle                      — per-profile alerts/min cap
//   5. AlertExplainer                            — per-(condition, profile) text
//
// No Flutter dependency. Run with: `dart run example/main.dart`.

import 'package:navigation_safety_core/navigation_safety_core.dart';

void main() {
  print('--- navigation_safety_core: example/main.dart ---\n');

  _showProfileBaseline();
  _showProfileWithContext();
  _showProfileWithDriverState();
  _showAlertDensityThrottle();
  _showAlertExplainer();
  _showSeverityIsLoadBearing();
}

/// 1. Driver-class baseline: pick a profile, get tuned thresholds.
void _showProfileBaseline() {
  print('[1] forProfile — driver-class baseline');

  final novice = NavigationSafetyConfig.forProfile(DriverProfile.noviceUrban);
  final tourist = NavigationSafetyConfig.forProfile(
    DriverProfile.foreignTouristSnowZone,
  );

  print('  noviceUrban warning visibility:           '
      '${novice.warningVisibilityMeters} m');
  print('  foreignTouristSnowZone warning visibility: '
      '${tourist.warningVisibilityMeters} m   '
      '(more conservative)');
  print('  noviceUrban warning temperature:           '
      '${novice.warningTemperatureCelsius} C');
  print('');
}

/// 2. Profile + live driving context: speed, humidity, time-since-rain.
///
/// Each context input can only make thresholds more conservative
/// (warn earlier, never later) than the per-profile baseline.
void _showProfileWithContext() {
  print('[2] forProfileWithContext — adds live conditions');

  // 80 km/h ≈ 22.2 m/s; 92% RH; ambient 1°C; rain ended 30 min ago.
  const conditions = DrivingContext(
    speedMps: 22.2,
    humidityRH: 0.92,
    ambientTempCelsius: 1.0,
    timeSincePrecipitation: Duration(minutes: 30),
  );

  final base = NavigationSafetyConfig.forProfile(
    DriverProfile.snowZoneExperienced,
  );
  final tuned = NavigationSafetyConfig.forProfileWithContext(
    DriverProfile.snowZoneExperienced,
    context: conditions,
  );

  print('  baseline warning visibility:    '
      '${base.warningVisibilityMeters} m');
  print('  context-tuned warning visibility: '
      '${tuned.warningVisibilityMeters} m   '
      '(speed + recent-rain margin)');
  print('  baseline warning temperature:     '
      '${base.warningTemperatureCelsius} C');
  print('  context-tuned warning temperature: '
      '${tuned.warningTemperatureCelsius} C   '
      '(humidity-aware black-ice margin)');
  print('');
}

/// 3. Profile + live driver state (fatigued / distracted / impaired vision).
///
/// State is opt-in via DriverContext. Pass profile-only to the older
/// factories and behaviour is unchanged.
void _showProfileWithDriverState() {
  print('[3] forDriverContext — adds live driver state');

  final alert = NavigationSafetyConfig.forDriverContext(
    const DriverContext(
      profile: DriverProfile.snowZoneExperienced,
      state: DriverState.alert,
    ),
  );
  final fatigued = NavigationSafetyConfig.forDriverContext(
    const DriverContext(
      profile: DriverProfile.snowZoneExperienced,
      state: DriverState.fatigued,
    ),
    environmentalContext: const DrivingContext(speedMps: 22.2),
  );

  print('  alert state warning visibility:    '
      '${alert.warningVisibilityMeters} m');
  print('  fatigued state warning visibility: '
      '${fatigued.warningVisibilityMeters} m   '
      '(reaction-time penalty applied)');
  print('  alert state warning temperature:    '
      '${alert.warningTemperatureCelsius} C');
  print('  fatigued state warning temperature: '
      '${fatigued.warningTemperatureCelsius} C   '
      '(small additive lift)');
  print('');
}

/// 4. Alert-density throttle: cap advisory alerts/min per profile.
///
/// Critical alerts always fire (safety invariant). Info and warning
/// alerts are gated by the profile's alerts/min cap so the driver
/// is not desensitised by over-warning.
void _showAlertDensityThrottle() {
  print('[4] AlertDensityThrottle — per-profile alerts/min cap');

  final throttle = AlertDensityThrottle.forProfile(
    DriverProfile.noviceUrban,
  );
  print('  noviceUrban cap:   ${throttle.alertsPerMinuteCap} / min');

  final base = DateTime(2026, 1, 1, 8, 0, 0);
  final fire1 = throttle.shouldFire(base, AlertSeverity.info);
  final fire2 = throttle.shouldFire(
    base.add(const Duration(seconds: 10)),
    AlertSeverity.warning,
  );
  final fire3 = throttle.shouldFire(
    base.add(const Duration(seconds: 20)),
    AlertSeverity.warning,
  );
  final fire4 = throttle.shouldFire(
    base.add(const Duration(seconds: 25)),
    AlertSeverity.critical,
  );

  print('  alert 1 (info)     -> fire? $fire1   (cold-start always fires)');
  print('  alert 2 (warning)  -> fire? $fire2');
  print('  alert 3 (warning)  -> fire? $fire3   (cap reached -> dropped)');
  print('  alert 4 (critical) -> fire? $fire4   (criticals bypass cap)');
  print('');
}

/// 5. Alert explainer: pre-localised (condition, action) tuple per profile.
///
/// The factory picks verbosity (terse / brief / standard / full) and
/// locale (ja / en) for the active profile.
void _showAlertExplainer() {
  print('[5] AlertExplainer — action-coupled per-(condition, profile)');

  for (final profile in [
    DriverProfile.professional,
    DriverProfile.snowZoneExperienced,
    DriverProfile.noviceUrban,
    DriverProfile.foreignTouristSnowZone,
  ]) {
    final explainer = AlertExplainer.forConditionAndProfile(
      RoadSurfaceCondition.ice,
      profile,
    );
    print('  ${profile.name.padRight(24)} '
        '(${explainer.localeTag} / ${explainer.verbosity.name})');
    print('    -> ${explainer.action}');
  }
  print('');
}

/// 6. Severity ordering is load-bearing — declaration order matters.
///
/// Callers can compare `.index` to enforce monotonic upgrades: a
/// lower-severity alert must never replace a higher one already
/// shown to the driver.
void _showSeverityIsLoadBearing() {
  print('[6] AlertSeverity — declaration order is load-bearing');

  print('  info.index     = ${AlertSeverity.info.index}');
  print('  warning.index  = ${AlertSeverity.warning.index}');
  print('  critical.index = ${AlertSeverity.critical.index}');
  print('  monotonic upgrade rule: '
      'never replace higher with lower (compare .index).');
  print('');
}
0
likes
150
points
462
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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 (the full Flutter + BLoC package) and any other pure-Dart consumer that needs the safety vocabulary without paying for the Flutter rendering surface.

Repository (GitHub)
View/report issues
Contributing

Topics

#navigation #safety #automotive #winter-driving

License

BSD-3-Clause (license)

Dependencies

equatable, latlong2

More

Packages that depend on navigation_safety_core