Skip to content

Scenario 1: Fatigue Risk Management Systems (FRMS)

In modern airline operations, simply following basic EASA or FAA flight time limitations is not always enough. Airlines implement Fatigue Risk Management Systems (FRMS) to proactively prevent crew exhaustion by limiting specific patterns of work, even if those patterns are technically legal under basic FTL rules.


📌 The Scenario

Background: Data from the airline's safety department shows that crews flying more than three consecutive "Early Start" duties (reporting before 06:00 local time) experience a severe drop in alertness.

The Requirements:

  1. Define what constitutes an "Early Start".
  2. Write a hard constraint to prevent a crew member from being rostered for more than three consecutive early starts.
  3. This rule must evaluate at the Roster (Plan) level, as it spans across multiple pairings/trips.

💻 The Rave Solution

// ====================================================================
// MODULE: FRMS - Consecutive Early Starts
// ====================================================================

CONSTANTS:
  %early_start_threshold% = 06:00;
  %max_consecutive_early_starts% = 3;
ENDCONSTANTS

// 1. Define an Early Start at the Duty level
%is_early_start% = 
  duty.%start_local_time% < %early_start_threshold%;

// 2. Aggregate across the Roster level to find consecutive patterns
// We use a rolling counter to track consecutive early starts across the month.
%consecutive_early_starts_counter% =
  if %is_early_start% then
    prev(duty(roster), %consecutive_early_starts_counter%) + 1
  else
    0;

// 3. Hard Constraint to prevent rosters that violate the FRMS policy
CONSTRAINT max_consecutive_early_starts OF Roster
  COMMENT: "A crew member cannot fly more than 3 consecutive early start duties."
  STATUS: ON;
  RULE:
    all(duty(roster), %consecutive_early_starts_counter% <= %max_consecutive_early_starts%);
ENDCONSTRAINT

🧠 Developer Notes:

  • Level Context: Notice how we define the boolean %is_early_start% at the Duty level, but we evaluate the all(...) traverser at the Roster level.
  • Statefulness: The expression %consecutive_early_starts_counter% uses the prev() traverser to look backward in the roster timeline, effectively creating a stateful rolling counter in a stateless declarative language.