Skip to content

Dive planner Phase 4: CCR planning and worst-case bailout#488

Merged
ericgriffin merged 9 commits into
mainfrom
worktree-dive-planner-phase4-ccr
Jul 6, 2026
Merged

Dive planner Phase 4: CCR planning and worst-case bailout#488
ericgriffin merged 9 commits into
mainfrom
worktree-dive-planner-phase4-ccr

Conversation

@ericgriffin

@ericgriffin ericgriffin commented Jul 5, 2026

Copy link
Copy Markdown
Member

Summary

Phase 4 of the dive planner redesign (plan). Stacked on #486 (Phase 3 canvas) — review #484#485#486 first.

Removes the Phase 1 limitation "CCR deco schedules still breathe OC": CCR plans now get real loop decompression schedules, setpoint handling, O2/diluent consumption, and a worst-case bailout solver with scrub-to-bailout.

The key move

CcrLoopAscentGas expresses the constant-ppO2 loop as a depth-dependent effective-fraction ascent gas: at any depth, the loop's inspired partial pressures (via ClosedCircuit) divide by alveolar pressure to give exact effective fN2/fHe — so the unchanged Bühlmann stop-search machinery computes loop deco exactly at constant-depth stops (proven by a round-trip equivalence test). Zero engine-core edits; setpoint switches split ascent legs like gas switches.

PlanEngine CCR mode

  • Loading, NDL, and schedules at the setpoints (low/high with a configurable switch depth; defaults 0.7 / 1.3 / 10 m per spec); segments' gases are the diluent.
  • ppO2/CNS/OTU run on the (clamped) setpoint, not diluent fractions; END/density still evaluate the diluent.
  • Consumption: metabolic O2 (default 1.0 L/min) × runtime to the oxygen-supply tank; descent loop-fill diluent (6 L loop × depth pressure delta) to the diluent tank; bailout tanks consume nothing in the main plan.
  • New noBailoutCarried alert for CCR deco plans without a bailout tank (the OC "no deco gas" alert correctly no longer fires for CCR).

Bailout solver

Walks the bottom phase at bounded sample intervals (≤ ~40 samples), computing the full OC bailout from each instant — schedule on the bailout-role gases, stressed SAC liters over travel legs + stops — and reports the worst case vs the compressibility-corrected carried volume. Verified: worst case lands at end-of-bottom for square profiles, demand is monotonic across the bottom, and sufficiency flips with cylinder size.

Canvas UI

  • The OC/CCR badge is now a mode toggle; setpoint low/high/switch-depth fields appear in plan settings (sheet + wide editor column) when CCR.
  • Results sheet gains a Bailout section: worst case (RT @ depth), bailout TTS, required vs available liters with an error row when short.
  • Scrub-to-bailout: the scrub readout appends BO {tts}′ from the nearest sampled instant — point at any moment of the dive and see the bailout time home.
  • 11 new l10n keys translated into all 10 non-en locales (gen-l10n: zero untranslated).

Verification

310 deco + 113 planner/dive_planner tests green; flutter analyze clean; python3-derived vectors for the loop's effective fractions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements Phase 4 of the dive planner redesign by adding true CCR planning support (constant-ppO₂ loop schedules, setpoint handling, and CCR-specific consumption) plus a worst-case open-circuit bailout solver and corresponding canvas UI readouts.

Changes:

  • Add CcrLoopAscentGas to compute loop decompression schedules via depth-dependent effective inert fractions (no engine-core stop-search changes).
  • Extend PlanEngine with CCR mode (setpoint breathing, loop schedule, metabolic O₂ + loop-fill diluent consumption, new noBailoutCarried issue) and add BailoutSolver + provider for worst-case bailout sizing.
  • Update canvas UI to toggle OC/CCR, edit setpoints, and display bailout results + scrub-to-bailout; add l10n keys and tests.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/features/planner/plan_engine_ccr_test.dart Adds unit tests covering CCR schedule, consumption, and CCR-specific issues.
test/features/planner/dive_plan_state_mapper_test.dart Updates/extends mapping tests to include CCR mode + setpoints round-trip behavior.
test/features/planner/ccr_ui_test.dart Adds widget tests for OC/CCR toggle and bailout section visibility.
test/features/planner/bailout_solver_test.dart Adds tests validating bailout solver behavior (worst case, monotonicity, sufficiency).
test/core/deco/ccr_loop_ascent_gas_test.dart Adds tests proving loop effective-fraction equivalence and switch/clamp behavior.
lib/core/deco/ascent/ccr_loop_ascent_gas.dart New ascent gas plan representing the CCR loop for schedule computation.
lib/features/planner/domain/services/plan_engine.dart Adds CCR breathing/schedule path, CCR consumption model, and noBailoutCarried issue.
lib/features/planner/domain/services/bailout_solver.dart New worst-case bailout solver producing sampled bailout demand and sufficiency.
lib/features/planner/presentation/providers/plan_canvas_providers.dart Adds planBailoutProvider to compute bailout outcome live from current plan state.
lib/features/planner/presentation/widgets/plan_results_sheet.dart Displays bailout section when applicable and localizes noBailoutCarried.
lib/features/planner/presentation/widgets/plan_canvas_chart.dart Adds scrub-to-bailout readout appendage using nearest sampled bailout point.
lib/features/planner/presentation/widgets/ccr_settings_section.dart New UI section for CCR setpoint low/high + switch depth editing.
lib/features/planner/presentation/pages/plan_canvas_page.dart Adds OC/CCR toggle chip and conditionally shows CCR settings section.
lib/features/planner/domain/services/dive_plan_state_mapper.dart Maps mode/setpoints between UI state and persisted plan aggregate.
lib/features/planner/domain/entities/dive_plan.dart Adds effective CCR setpoint getters with spec defaults.
lib/features/planner/domain/entities/plan_outcome.dart Adds new issue type noBailoutCarried.
lib/features/dive_planner/domain/entities/plan_result.dart Extends planner UI state with mode + CCR setpoint fields.
lib/features/dive_planner/presentation/providers/dive_planner_providers.dart Adds notifier methods to update mode and CCR setpoints.
lib/l10n/arb/app_en.arb Adds new planner canvas keys for bailout + CCR setpoint UI.
lib/l10n/arb/app_de.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_ar.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_es.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_fr.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_he.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_hu.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_it.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_nl.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_pt.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_zh.arb Adds translations for new bailout/CCR canvas strings.
lib/l10n/arb/app_localizations.dart Updates generated localization interface for new keys.
lib/l10n/arb/app_localizations_en.dart Updates generated English localization implementation.
lib/l10n/arb/app_localizations_de.dart Updates generated German localization implementation.
lib/l10n/arb/app_localizations_ar.dart Updates generated Arabic localization implementation.
lib/l10n/arb/app_localizations_es.dart Updates generated Spanish localization implementation.
lib/l10n/arb/app_localizations_fr.dart Updates generated French localization implementation.
lib/l10n/arb/app_localizations_he.dart Updates generated Hebrew localization implementation.
lib/l10n/arb/app_localizations_hu.dart Updates generated Hungarian localization implementation.
lib/l10n/arb/app_localizations_it.dart Updates generated Italian localization implementation.
lib/l10n/arb/app_localizations_nl.dart Updates generated Dutch localization implementation.
lib/l10n/arb/app_localizations_pt.dart Updates generated Portuguese localization implementation.
lib/l10n/arb/app_localizations_zh.dart Updates generated Chinese localization implementation.
docs/superpowers/plans/2026-07-05-dive-planner-phase4-ccr.md Adds the Phase 4 implementation plan document (reference/traceability).

Comment thread lib/features/planner/presentation/widgets/plan_results_sheet.dart
Comment thread lib/features/planner/presentation/widgets/ccr_settings_section.dart
…-planner-phase4-ccr

# Conflicts:
#	lib/features/planner/domain/services/plan_engine.dart
#	lib/features/planner/presentation/pages/plan_canvas_page.dart
- CCR switch depth accepts 0 m (surface); setpoints still require a positive
  value (allowZero on that field only)
- Bailout required/available volumes now use UnitFormatter (respect L vs cuft);
  drop the hardcoded L from the bailout strings across locales
- Cover the CCR settings section and the bailout volume formatting
@ericgriffin ericgriffin self-assigned this Jul 6, 2026
@ericgriffin ericgriffin moved this from Backlog to In review in Submersion Release Tracker Jul 6, 2026
Base automatically changed from worktree-dive-planner-phase3-canvas to main July 6, 2026 01:43
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

@ericgriffin ericgriffin merged commit ad30c14 into main Jul 6, 2026
19 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in Submersion Release Tracker Jul 6, 2026
@ericgriffin ericgriffin deleted the worktree-dive-planner-phase4-ccr branch July 6, 2026 02:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants