Commit 0c53c4fd authored by Claire Dross's avatar Claire Dross

Layer2_MMS_SW_SPARK: Reorganize F_FC behavior

parent d821e7d5
...@@ -42,6 +42,8 @@ ACTIVITIES: ...@@ -42,6 +42,8 @@ ACTIVITIES:
A. Additional assumption: Translated into types (validity of inputs). A. Additional assumption: Translated into types (validity of inputs).
6.6.3.1 6.6.3.1
A. Additional guarantee: Translated as a postcondition. A. Additional guarantee: Translated as a postcondition.
6.6.4
Behavioural Specification: Mostly translated as contracts. Parts involving calculations or update frequencies have been kept as comments. Notably missing, external and internal disturbances (linked to weather conditions and AV behavior).
- MMS.F_PT.F_EM: - MMS.F_PT.F_EM:
6.8.3.1 6.8.3.1
...@@ -61,6 +63,15 @@ ACTIVITIES: ...@@ -61,6 +63,15 @@ ACTIVITIES:
7.3.2: 7.3.2:
Guarantees A, B: Not tranlated (linked to weather conditions) Guarantees A, B: Not tranlated (linked to weather conditions)
- MMS.F_FC:
6.7.3.1:
Assumption A: Not tranlated (linked to measurements)
Assumption B: Input safety assumptions are automatic
Assumption C: Not translated, F_FC does not have the necessary inputs.
6.7.3.2:
Guarantees A, B, C: Not translated (linked to weather conditions and mechanical body behavior)
Guarantees D, E: Translated as postconditions.
* Verifications: * Verifications:
The SPARK toolset can be used to check that: The SPARK toolset can be used to check that:
- Ada contracts are consistent. If it is a case by case contract, SPARK can check that all cases are covered and that no two cases can apply to the same inputs. If some properties or some information can only be accessed in some cases, these cases can be expressed as preconditions on property or information functions and SPARK will check that they are always used in valid context. - Ada contracts are consistent. If it is a case by case contract, SPARK can check that all cases are covered and that no two cases can apply to the same inputs. If some properties or some information can only be accessed in some cases, these cases can be expressed as preconditions on property or information functions and SPARK will check that they are always used in valid context.
......
with MMS.F_PT.F_FC.State;
package body MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is package body MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is
procedure Run is procedure Run is
begin begin
MMS.F_PT.F_FC.Behavior.Run; Update_State;
if Mission_State in FLIGHT | LANDING then
Propulsion_Braking_Mutual_Exclusion;
Reference_Trajectory_Computation;
Gain_Scheduling;
if Engine_State = PROPULSION then
Propulsion_Control;
State.Braking_Torque := 0.0;
elsif Engine_State = BRAKING then
Braking_Control;
State.Propulsion_Torque := 0.0;
else
State.Braking_Torque := 0.0;
State.Propulsion_Torque := 0.0;
end if;
end if;
end Run; end Run;
end MMS.F_PT.F_FC.Behavior.Guarantees; end MMS.F_PT.F_FC.Behavior.Guarantees;
...@@ -15,10 +15,12 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is ...@@ -15,10 +15,12 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is
range BRAKING .. WAITING_PROP; range BRAKING .. WAITING_PROP;
function Engine_State_In_Braking return Boolean is function Engine_State_In_Braking return Boolean is
(Mission_State = FLIGHT and then Engine_State in Braking_State_Type); (Mission_State in FLIGHT | LANDING
and then Engine_State in Braking_State_Type);
function Engine_State_In_Propulsion return Boolean is function Engine_State_In_Propulsion return Boolean is
(Mission_State = FLIGHT and then Engine_State in Propulsion_State_Type); (Mission_State in FLIGHT | LANDING
and then Engine_State in Propulsion_State_Type);
----------------------------------- -----------------------------------
-- High-Level Garantees for F_FC -- -- High-Level Garantees for F_FC --
...@@ -27,7 +29,7 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is ...@@ -27,7 +29,7 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is
procedure Run with procedure Run with
Post => Post =>
-- 6.7.3.2.D Propulsion and braking torque actions are in mutual -- 6.7.3.2.D Propulsion and braking torque actions are in mutual
-- exclusion. -- exclusion.
(if (Engine_State_In_Propulsion'Old and then Engine_State_In_Braking) (if (Engine_State_In_Propulsion'Old and then Engine_State_In_Braking)
...@@ -40,6 +42,7 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is ...@@ -40,6 +42,7 @@ package MMS.F_PT.F_FC.Behavior.Guarantees with SPARK_Mode is
and then and then
(if Mission_State = ABORTED and then Mission_State'Old /= ABORTED (if Mission_State = ABORTED and then Mission_State'Old /= ABORTED
and then Aborted_With_Propulsion_Available
then Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Escape_Time); then Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Escape_Time);
end MMS.F_PT.F_FC.Behavior.Guarantees; end MMS.F_PT.F_FC.Behavior.Guarantees;
...@@ -9,53 +9,51 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is ...@@ -9,53 +9,51 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is
-- Inputs -- -- Inputs --
------------ ------------
function P return Distance_Type with Global => Private_State; function P return Distance_Type with Global => Input_State;
function P_Dot return Speed_Type with Global => Private_State; function P_Dot return Speed_Type with Global => Input_State;
function Q return Angle_Type with Global => Private_State; function Q return Angle_Type with Global => Input_State;
function Start_Take_Off return Boolean with function Start_Take_Off return Boolean with
Global => Private_State, Global => (Input => Input_State, Proof_In => Private_State),
Pre => Mission_State = INIT; Pre => Mission_State = INIT;
function Start_Landing return Boolean with function Start_Landing return Boolean with
Global => Private_State, Global => (Input => Input_State, Proof_In => Private_State),
Pre => Mission_State = FLIGHT; Pre => Mission_State = FLIGHT;
function Operating_Point return Operating_Point_Type with function Operating_Point return Operating_Point_Type with
Global => Private_State; Global => Input_State;
function Emergency_Landing return Boolean with
Global => Input_State;
-------------------------- --------------------------
-- Properties on Inputs -- -- Properties on Inputs --
-------------------------- --------------------------
function Operating_Point_Changed return Boolean with function Operating_Point_Changed return Boolean with
Global => Private_State; Global => Input_State;
---------------------- ----------------------
-- Estimated Values -- -- Estimated Values --
---------------------- ----------------------
function Q_Dot return Speed_Type with Global => Private_State; function Q_Dot return Speed_Type with Global => Input_State;
------------ ------------
-- States -- -- States --
------------ ------------
type Mission_State_Type is (INIT, FLIGHT, LANDING, ABORTED, COMPLETE);
function Mission_State return Mission_State_Type with function Mission_State return Mission_State_Type with
Global => Private_State; Global => Private_State;
function Flight_Phase_State return Flight_Phase_Type with
Global => Private_State,
Pre => Mission_State = FLIGHT;
type Engine_State_Type is
(PROPULSION, WAITING_BRAK, BRAKING, WAITING_PROP);
function Engine_State return Engine_State_Type with function Engine_State return Engine_State_Type with
Global => (Input => Mutual_Exclusion_State, Proof_In => Private_State),
Pre => Mission_State in FLIGHT | LANDING;
function Aborted_With_Propulsion_Available return Boolean with
Global => Private_State, Global => Private_State,
Pre => Mission_State = FLIGHT; Pre => Mission_State = ABORTED;
---------------- ----------------
-- Properties -- -- Properties --
...@@ -63,8 +61,12 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is ...@@ -63,8 +61,12 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is
-- From 6.7.3.2 -- From 6.7.3.2
function Flight_Phase return Flight_Phase_Type with
Global => (Input => Trajectory_State, Proof_In => Private_State),
Pre => Mission_State = FLIGHT;
function In_Safety_Envelope return Boolean is function In_Safety_Envelope return Boolean is
(case Flight_Phase_State is (case Flight_Phase is
when CLIMB => when CLIMB =>
Q_Dot in MMS.F_PT.F_FC.Data.Qdot_MinCl .. MMS.F_PT.F_FC.Data.Qdot_MaxCl Q_Dot in MMS.F_PT.F_FC.Data.Qdot_MinCl .. MMS.F_PT.F_FC.Data.Qdot_MaxCl
and Q < MMS.F_PT.F_FC.Data.Q_MaxCl, and Q < MMS.F_PT.F_FC.Data.Q_MaxCl,
...@@ -77,28 +79,30 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is ...@@ -77,28 +79,30 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is
and Q < MMS.F_PT.F_FC.Data.Q_MaxDs) and Q < MMS.F_PT.F_FC.Data.Q_MaxDs)
with Pre => Mission_State = FLIGHT; with Pre => Mission_State = FLIGHT;
function Time_Since_In_Safety_Escape return Time_Type with function Already_Running return Boolean with
Global => Private_State, Global => Private_State,
Pre => Mission_State in FLIGHT | LANDING;
function Time_Since_In_Safety_Escape return Time_Type with
Global => (Input => Private_State,
Proof_In => (Input_State, Trajectory_State)),
Pre => (Mission_State = FLIGHT and then not In_Safety_Envelope) Pre => (Mission_State = FLIGHT and then not In_Safety_Envelope)
or else Mission_State = ABORTED; or else Mission_State = ABORTED;
function Fast_Evolving_Safety_Escape return Boolean with function Fast_Evolving_Safety_Escape return Boolean with
Global => Private_State, Global => (Input => Private_State,
Proof_In => (Input_State, Trajectory_State)),
Pre => Mission_State = FLIGHT and then not In_Safety_Envelope; Pre => Mission_State = FLIGHT and then not In_Safety_Envelope;
function Time_Since_Stopped return Time_Type with function Time_Since_Stopped return Time_Type with
Global => Private_State, Global => (Input => Mutual_Exclusion_State, Proof_In => Private_State),
Pre => Mission_State = FLIGHT; Pre => Mission_State in FLIGHT | LANDING;
-------------
-- Outputs --
-------------
function Propulsion_Torque return Torque_Type with function Propulsion_Torque return Torque_Type with
Global => Private_State; Global => (Input => Propulsion_State, Proof_In => Private_State);
function Braking_Torque return Torque_Type with function Braking_Torque return Torque_Type with
Global => Private_State; Global => (Input => Braking_State, Proof_In => Private_State);
--------------------------------------- ---------------------------------------
-- Behavioural Specification of F_FC -- -- Behavioural Specification of F_FC --
...@@ -106,46 +110,64 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is ...@@ -106,46 +110,64 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is
procedure Read_Inputs with procedure Read_Inputs with
-- Read values of inputs once and for all and update the current state -- Read values of inputs once and for all and update the current state
Global => (In_Out => Private_State,
Input => External.State),
Post => Operating_Point_Changed = Post => Operating_Point_Changed =
(Operating_Point'Old /= Operating_Point); (Operating_Point'Old /= Operating_Point);
procedure Write_Outputs with procedure Write_Outputs with
-- Compute values of outputs from the current state -- Compute values of outputs from the current state
Global => (Input => Private_State,
Global => (Input => (Input_State,
Trajectory_State,
Private_State,
Mutual_Exclusion_State,
Gain_Scheduling_State,
Propulsion_State,
Braking_State),
Output => Output_State); Output => Output_State);
procedure Run with procedure Update_State with
Global => (In_Out => Private_State), Global => (Input => (Input_State, Trajectory_State),
In_Out => Private_State),
Contract_Cases => Contract_Cases =>
-- ??? All these are guesses... -- ??? All these are guesses...
(Mission_State = INIT ((Mission_State in INIT .. LANDING)
and then Emergency_Landing
=>
Mission_State = ABORTED
and then not Aborted_With_Propulsion_Available,
Mission_State = INIT
and then not Emergency_Landing
and then Start_Take_Off and then Start_Take_Off
=> =>
Mission_State = FLIGHT Mission_State = FLIGHT,
and then Engine_State = PROPULSION,
Mission_State = INIT Mission_State = INIT
and then not Emergency_Landing
and then not Start_Take_Off and then not Start_Take_Off
=> =>
Mission_State = INIT, Mission_State = INIT,
Mission_State = FLIGHT Mission_State = FLIGHT
and then not Emergency_Landing
and then Start_Landing and then Start_Landing
=> =>
Mission_State = LANDING, Mission_State = LANDING,
Mission_State = FLIGHT Mission_State = FLIGHT
and then not Emergency_Landing
and then not Start_Landing and then not Start_Landing
=> =>
(if Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Escape_Time then (if Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Escape_Time then
Mission_State = ABORTED Mission_State = ABORTED
and then Aborted_With_Propulsion_Available
else Mission_State = FLIGHT), else Mission_State = FLIGHT),
Mission_State = LANDING Mission_State = LANDING
and then not Emergency_Landing
=> =>
(if P_Dot = 0.0 and then Q_Dot = 0.0 then (if P_Dot = 0.0 and then Q_Dot = 0.0 then
Mission_State = COMPLETE Mission_State = COMPLETE
...@@ -156,64 +178,138 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is ...@@ -156,64 +178,138 @@ package MMS.F_PT.F_FC.Behavior with SPARK_Mode is
Mission_State = Mission_State'Old), Mission_State = Mission_State'Old),
Post => Post =>
(if Mission_State in FLIGHT | LANDING then
-- Changes in the operating point provoque termination of the current Engine_State = Engine_State'Old -- ??? Needed due to current limitation in proof tool
-- cruise phase and activate a transient climb or descent phase to and then Already_Running = (Mission_State'Old in FLIGHT | LANDING))
-- capture the new operating point (see 6.6.4 4. Cruise).
(if Operating_Point_Changed then Flight_Phase_State in CLIMB | DESCENT)
-- Time_Since_In_Safety_Escape is the number of seconds since the first -- Time_Since_In_Safety_Escape is the number of seconds since the first
-- occurrence of safety escapes. -- occurrence of safety escapes.
and then and then
(if not In_Safety_Envelope then (if not In_Safety_Envelope then
(if In_Safety_Envelope'Old then Time_Since_In_Safety_Escape = 0 (if In_Safety_Envelope'Old then Time_Since_In_Safety_Escape = 0
else Time_Since_In_Safety_Escape > Time_Since_In_Safety_Escape'Old)) else Time_Since_In_Safety_Escape > Time_Since_In_Safety_Escape'Old));
function Go_To_Braking return Boolean is
(Mission_State = LANDING
or else
(not In_Safety_Envelope
and then
(Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Hazard_Duration
or else Fast_Evolving_Safety_Escape)))
with
Pre => Mission_State in FLIGHT | LANDING;
function Go_To_Propulsion return Boolean is
(Mission_State = FLIGHT and then In_Safety_Envelope)
with
Pre => Mission_State in FLIGHT | LANDING;
procedure Propulsion_Braking_Mutual_Exclusion with
Global => (Input => (Input_State, Trajectory_State, Private_State),
In_Out => Mutual_Exclusion_State),
Pre => Mission_State in FLIGHT | LANDING,
Contract_Cases =>
(not Already_Running
=>
Engine_State = PROPULSION,
-- 6.7.4 Propulsion braking mutual exclusion -- 6.7.4 Propulsion braking mutual exclusion
and then Already_Running
(if Mission_State = FLIGHT and then Mission_State'Old = FLIGHT then and then Engine_State = PROPULSION
(case Engine_State'Old is and then Go_To_Braking
when PROPULSION => =>
(if not In_Safety_Envelope Engine_State = WAITING_BRAK
and then and then Time_Since_Stopped = 0,
(Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Hazard_Duration
or else Fast_Evolving_Safety_Escape)
then Engine_State = WAITING_BRAK
and then Time_Since_Stopped = 0
else Engine_State = PROPULSION),
when BRAKING =>
(if In_Safety_Envelope
then Engine_State = WAITING_PROP
and then Time_Since_Stopped = 0
else Engine_State = BRAKING),
when WAITING_PROP =>
(if not In_Safety_Envelope
and then (Time_Since_In_Safety_Escape > MMS.F_PT.F_FC.Data.Hazard_Duration
or else Fast_Evolving_Safety_Escape)
then Engine_State = BRAKING
elsif Time_Since_Stopped > MMS.F_PT.F_FC.Data.Commutation_Duration
then Engine_State = PROPULSION
else Engine_State = WAITING_PROP
and then Time_Since_Stopped > Time_Since_Stopped'Old),
when WAITING_BRAK =>
(if In_Safety_Envelope
then Engine_State = PROPULSION
elsif Time_Since_Stopped > MMS.F_PT.F_FC.Data.Commutation_Duration
then Engine_State = BRAKING
else Engine_State = WAITING_BRAK
and then Time_Since_Stopped > Time_Since_Stopped'Old)))
and then Already_Running
(if Mission_State = FLIGHT and then Engine_State /= PROPULSION then and then Engine_State = PROPULSION
Propulsion_Torque = 0.0) and then not Go_To_Braking
and then =>
(if Mission_State = FLIGHT and then Engine_State /= BRAKING then Engine_State = PROPULSION,
Braking_Torque = 0.0);
Already_Running
and then Engine_State = BRAKING
and then Go_To_Propulsion
=>
Engine_State = WAITING_PROP
and then Time_Since_Stopped = 0,
Already_Running
and then Engine_State = BRAKING
and then not Go_To_Propulsion
=>
Engine_State = BRAKING,
Already_Running
and then Engine_State = WAITING_PROP
and then Go_To_Braking
=>
Engine_State = BRAKING,
Already_Running
and then Engine_State = WAITING_PROP
and then not Go_To_Braking
=>
(if Time_Since_Stopped > MMS.F_PT.F_FC.Data.Commutation_Duration
then Engine_State = PROPULSION
else Engine_State = WAITING_PROP
and then Time_Since_Stopped > Time_Since_Stopped'Old),
Already_Running
and then Engine_State = WAITING_BRAK
and then Go_To_Propulsion
=>
Engine_State = PROPULSION,
Already_Running
and then Engine_State = WAITING_BRAK
and then not Go_To_Propulsion
=>
(if Time_Since_Stopped > MMS.F_PT.F_FC.Data.Commutation_Duration
then Engine_State = BRAKING
else Engine_State = WAITING_BRAK
and then Time_Since_Stopped > Time_Since_Stopped'Old));
procedure Reference_Trajectory_Computation with
Global => (Input => (Input_State, Private_State),
In_Out => Trajectory_State),
Pre => Mission_State in FLIGHT .. LANDING,
Post =>
-- Changes in the operating point provoque termination of the current
-- cruise phase and activate a transient climb or descent phase to
-- capture the new operating point (see 6.6.4 4. Cruise).
(if Mission_State = FLIGHT and then Operating_Point_Changed then
Flight_Phase in CLIMB | DESCENT);
procedure Gain_Scheduling with
Global => (Input => (Input_State,
Trajectory_State,
Private_State,
Mutual_Exclusion_State),
In_Out => Gain_Scheduling_State),
Pre => Mission_State in FLIGHT .. LANDING;
procedure Propulsion_Control with
Global => (Input => (Input_State,
Trajectory_State,
Private_State,
Gain_Scheduling_State,
Mutual_Exclusion_State),
In_Out => Propulsion_State),
Pre => Mission_State = FLIGHT and then Engine_State = PROPULSION;
procedure Braking_Control with
Global => (Input => (Input_State,
Trajectory_State,
Private_State,
Gain_Scheduling_State,
Mutual_Exclusion_State),
In_Out => Braking_State),
Pre => Mission_State in FLIGHT .. LANDING
and then Engine_State = BRAKING;
end MMS.F_PT.F_FC.Behavior; end MMS.F_PT.F_FC.Behavior;
...@@ -39,5 +39,8 @@ package MMS.F_PT.F_FC.Input is ...@@ -39,5 +39,8 @@ package MMS.F_PT.F_FC.Input is
function Mission_Range return Current_Range_Type function Mission_Range return Current_Range_Type
renames MMS.F_PT.F_MM.Output.Mission_Range; renames MMS.F_PT.F_MM.Output.Mission_Range;
function Emergency_Landing return Boolean
renames MMS.F_PT.F_MM.Output.Emergency_Landing;
end MMS.F_PT.F_FC.Input; end MMS.F_PT.F_FC.Input;
private
package MMS.F_PT.F_FC.State is
Propulsion_Torque : Torque_Type with Part_Of => Propulsion_State;
Braking_Torque : Torque_Type with Part_Of => Braking_State;
end MMS.F_PT.F_FC.State;
with Types; use Types; with Types; use Types;
package MMS.F_PT.F_FC with Abstract_State => (Private_State, Output_State) is package MMS.F_PT.F_FC with
Abstract_State => (Input_State,
Trajectory_State,
Private_State,
Mutual_Exclusion_State,
Gain_Scheduling_State,
Propulsion_State,
Braking_State,
Output_State)
is
pragma Elaborate_Body (MMS.F_PT.F_FC); pragma Elaborate_Body (MMS.F_PT.F_FC);
type Flight_Cell_Center_Type is record type Flight_Cell_Center_Type is record
...@@ -25,4 +34,9 @@ package MMS.F_PT.F_FC with Abstract_State => (Private_State, Output_State) is ...@@ -25,4 +34,9 @@ package MMS.F_PT.F_FC with Abstract_State => (Private_State, Output_State) is
type Time_Type is new Integer; -- in s ??? some bounds type Time_Type is new Integer; -- in s ??? some bounds
type Mission_State_Type is (INIT, FLIGHT, LANDING, ABORTED, COMPLETE);
type Engine_State_Type is
(PROPULSION, WAITING_BRAK, BRAKING, WAITING_PROP);
end MMS.F_PT.F_FC; end MMS.F_PT.F_FC;
...@@ -41,12 +41,14 @@ package body MMS.F_PT.F_MM.Behavior.Guarantees with SPARK_Mode is ...@@ -41,12 +41,14 @@ package body MMS.F_PT.F_MM.Behavior.Guarantees with SPARK_Mode is
if On_State = RUNNING then if On_State = RUNNING then
In_Flight_Mission_Viability_Logic; In_Flight_Mission_Viability_Logic;
In_Flight_Energy_Test_Done := True; In_Flight_Energy_Test_Done := True;
Energy_Test_Succeded := Energy_Test_Succeded :=
In_Flight_Energy_Compatible_With_Mission; In_Flight_Energy_Compatible_With_Mission;
else else
Initial_Mission_Viability_Logic; Initial_Mission_Viability_Logic;
Initial_Energy_Test_Done := True; Initial_Energy_Test_Done := True;
Energy_Test_Succeded := Energy_Test_Succeded :=
Initial_Energy_Compatible_With_Mission; Initial_Energy_Compatible_With_Mission;
......
...@@ -14,9 +14,9 @@ package MMS.F_PT.F_MM.Output is ...@@ -14,9 +14,9 @@ package MMS.F_PT.F_MM.Output is
function Ready_For_Takeoff return Boolean with Global => Output_State; function Ready_For_Takeoff return Boolean with Global => Output_State;
------------- ----------------------
-- To F_EL -- -- To F_EL and F_CM --
-------------- ----------------------
function Emergency_Landing return Boolean with Global => Output_State; function Emergency_Landing return Boolean with Global => Output_State;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment