/*
 * AltaRica 3.0 model 
 * System of interest : AIDA Library
 * by Anthony Legendre - Fractus
 *
 * This file is part of the S2C project.
 * Copyright (c) 2021-2022 Fractus - All Rights Reserved.
 */

/* Table of Contents
 * --------------
 * 0. Domain
 * 1. Abstract Classes
 * 2. Classes component_behavior
 * 3. Class concrete_component
 */


/*
 * 0. Domain
 * -------------------
 */
domain Status {OK, LOST, ERR}

/*
 * 1. Abstract Classes
 * -------------------
 */

class ObjetState
	//internal state
	Status vsWorking (init = OK);
end

class FM_Loss_Behaviour
	extends ObjetState;
	//parameter
	parameter Real lambda_Loss = 0.0003;

	//event
	event ev_Loss_Failure (delay = exponential(lambda_Loss));
	//transition
    transition
        ev_Loss_Failure: vsWorking==OK -> vsWorking := LOST;
end

class FM_Erroneous_Behaviour
	extends ObjetState;
	//parameter
	parameter Real lambda_ERR = 0.00003;
	//event
	event ev_ERR_Failure (delay = exponential(lambda_ERR));
	//transition
    transition
        ev_ERR_Failure: vsWorking==OK -> vsWorking := ERR;
end

class FM_Erroneous_Loss_Behaviour
	extends ObjetState;
	//parameter
	parameter Real lambda_Loss = 0.00003;
	parameter Real lambda_ERR = 0.00003;
	//event
	event ev_Loss_Failure (delay = exponential(lambda_Loss));
	event ev_ERR_Failure (delay = exponential(lambda_ERR));
	//transition
    transition
        ev_Loss_Failure: vsWorking==OK -> vsWorking := LOST;
        ev_ERR_Failure: vsWorking==OK -> vsWorking := ERR;
end

class FM_Erroneous_Loss_CANbus_Behaviour
	extends ObjetState;
	//parameter
	parameter Real lambda_Loss = 0.00003;
	parameter Real lambda_ERR = 0.00003;
	parameter Real lambda_CANbus_Loss = 0.0003;
	parameter Real lambda_CANbus_ERR = 0.00003;
	//event
	event ev_Loss_Failure (delay = exponential(lambda_Loss));
	event ev_ERR_Failure (delay = exponential(lambda_ERR));
	event ev_CANbus_Loss_Failure (delay = exponential(lambda_CANbus_Loss));
	event ev_CANbus_ERR_Failure (delay = exponential(lambda_CANbus_ERR));
	//transition
    transition
        ev_Loss_Failure: vsWorking==OK -> vsWorking := LOST;
        ev_ERR_Failure: vsWorking==OK -> vsWorking := ERR;
        ev_CANbus_Loss_Failure: vsWorking==OK -> vsWorking := LOST;
        ev_CANbus_ERR_Failure: vsWorking==OK -> vsWorking := ERR;
end



/*
 * 2. Classes component_behavior
 * -------------------
 */
class flow1_behavior
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in (reset = LOST);
	Status out (reset = LOST);
	assertion
		if (vsWorking==OK) then out := in;
		if (vsWorking==ERR) and not (in==LOST) then out := ERR;
end

class flow2_behavior 
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in1, in2 (reset = LOST);
	Status out1, out2 (reset = LOST);
	assertion
		if (vsWorking==OK) then out1 := in1;
		if (vsWorking==ERR) and not (in1==LOST) then out1 := ERR;
		if (vsWorking==OK) then out2 := in2;
		if (vsWorking==ERR) and not (in2==LOST) then out2 := ERR;
end

class Power_Supply_behavior
	extends FM_Loss_Behaviour; // a mettre à jour en fonction des In et Out
	//flow variables
	Status out_EPL_Power_supply (reset = LOST);
	// assertion
	assertion
		out_EPL_Power_supply := vsWorking;
end

class Main_flight_control_board
	//class instances
	flow2_behavior can_sensor (lambda_ERR = 4.501e-07, lambda_Loss = 1.121e-05);
	flow2_behavior ccdl_behavior (lambda_ERR = 1.713e-07, lambda_Loss = 5.213e-06);
	flow1_behavior rc_acquisition (lambda_ERR = 1.273e-06, lambda_Loss = 2.670e-05);
	flow1_behavior wifi_driver (lambda_ERR = 3.734e-06, lambda_Loss = 1.294e-07);
	flow1_behavior wifi_acquisition (lambda_ERR = 7.379e-06, lambda_Loss = 9.613e-06);
	flow1_behavior pwm1_driver (lambda_ERR = 2.961e-06, lambda_Loss = 3.322e-05);
	flow1_behavior pwm2_driver (lambda_ERR = 1.830e-06, lambda_Loss = 1.559e-05);
	flow1_behavior pwm3_driver (lambda_ERR = 9.833e-07, lambda_Loss = 3.016e-05);
	flow1_behavior pwm4_driver (lambda_ERR = 3.236e-07, lambda_Loss = 2.451e-05);
	flow1_behavior global_flight_control_board (lambda_ERR = 1e-09, lambda_Loss = 4.920e-06);

	//flow variables
    Status in_PowerSupply (reset = LOST);
	Status in_Inertial_reference_sensors_behavior (reset = LOST);	
	Status in_Magnetometer_behavior (reset = LOST);	
	Status in_Pressure_sensor_behavior (reset = LOST);

	Status in_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status in_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status in_CAN_Wire_GPS_Receiver (reset = LOST);

	Status in_RC_Serial_Bus (reset = LOST);
	Status in_WIFI_Serial_Bus (reset = LOST);
	Status in_WSL_Cross_channel_data_link (reset = LOST);

	Status out_WSL_Cross_channel_data_link (reset = LOST);
	Status out_WIFI_Serial_Bus (reset = LOST);

	Status out_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status out_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status out_CAN_Wire_GPS_Receiver (reset = LOST);

	Status out_PWM1 (reset = LOST);
	Status out_PWM2 (reset = LOST);
	Status out_PWM3 (reset = LOST);
	Status out_PWM4 (reset = LOST);	
	// local flow
	Status in_CAN_flows(reset = LOST);
	Status in_local_flow(reset = LOST);
	//assertion
	assertion
	//CAN SENSOR
	if (in_CAN_Wire_LIDAR_Altimeter == OK and in_CAN_Wire_Optical_Flow_Sensor == OK and in_CAN_Wire_GPS_Receiver == OK) then in_CAN_flows := OK;
	if (in_CAN_Wire_LIDAR_Altimeter == ERR or in_CAN_Wire_Optical_Flow_Sensor == ERR or in_CAN_Wire_GPS_Receiver == ERR) and not (in_CAN_Wire_LIDAR_Altimeter == LOST or in_CAN_Wire_Optical_Flow_Sensor == LOST or in_CAN_Wire_GPS_Receiver == LOST) then in_CAN_flows := ERR ;
	can_sensor.in1 := in_CAN_flows;
	out_CAN_Wire_LIDAR_Altimeter:=	can_sensor.out2;
	out_CAN_Wire_Optical_Flow_Sensor:=	can_sensor.out2;
	out_CAN_Wire_GPS_Receiver:=	can_sensor.out2;
	//WIFI ACQ
	wifi_acquisition.in := in_WIFI_Serial_Bus;
	//RC ACQ
	rc_acquisition.in := in_RC_Serial_Bus;	
	//WIFI driver
	out_WIFI_Serial_Bus := wifi_driver.out;
	//CCDL
	ccdl_behavior.in1 := in_WSL_Cross_channel_data_link;
	out_WSL_Cross_channel_data_link := ccdl_behavior.out2;

	//PWMDriver
	out_PWM1 := pwm1_driver.out ;
	out_PWM2 := pwm2_driver.out ;
	out_PWM3 := pwm3_driver.out ;
	out_PWM4 := pwm4_driver.out ;
	// Global in
	if (can_sensor.out1== OK and wifi_acquisition.out== OK and rc_acquisition.out== OK and ccdl_behavior.out1== OK and in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then in_local_flow := OK;
	if (can_sensor.out1== ERR or wifi_acquisition.out== ERR or rc_acquisition.out== ERR or ccdl_behavior.out1== ERR or in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) and not (can_sensor.out1== LOST or wifi_acquisition.out== LOST or rc_acquisition.out== LOST or ccdl_behavior.out1== LOST or in_PowerSupply== LOST or in_Inertial_reference_sensors_behavior== LOST or in_Magnetometer_behavior== LOST or in_Pressure_sensor_behavior== LOST) then in_local_flow := ERR;
	global_flight_control_board.in := in_local_flow;

	// Global out
		//Global Out CAN SENSOR
		// pour déboucler le loop de controle entre Main et CAN SENSOR 
	if (/*ccdl_behavior.out1== OK and */in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then can_sensor.in2 := global_flight_control_board.vsWorking; 
	if (/*ccdl_behavior.out1== ERR or */in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) or global_flight_control_board.vsWorking == ERR then can_sensor.in2 := ERR;

		//Global Out Wifi Driver
		// pour déboucler le loop de controle entre Main et Wifi
	if (/*ccdl_behavior.out1== OK and */in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then wifi_driver.in := global_flight_control_board.vsWorking;
	if (/*ccdl_behavior.out1== ERR or */in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) or global_flight_control_board.vsWorking == ERR then wifi_driver.in := ERR;

		//Global Out MAIN et Monitoring
		// pour déboucler le loop de controle  MAIN et Monitoring
	if (can_sensor.vsWorking== OK and wifi_acquisition.vsWorking== OK and rc_acquisition.vsWorking== OK and ccdl_behavior.vsWorking== OK and pwm1_driver.vsWorking== OK and pwm2_driver.vsWorking== OK and pwm3_driver.vsWorking== OK and pwm4_driver.vsWorking== OK and wifi_driver.vsWorking== OK) then ccdl_behavior.in2 := global_flight_control_board.vsWorking;
	if (can_sensor.vsWorking== ERR or wifi_acquisition.vsWorking== ERR or rc_acquisition.vsWorking== ERR or ccdl_behavior.vsWorking== ERR or pwm1_driver.vsWorking== ERR or pwm2_driver.vsWorking== ERR or pwm3_driver.vsWorking== ERR or pwm4_driver.vsWorking== ERR or wifi_driver.vsWorking== ERR or global_flight_control_board.vsWorking==ERR) and not (can_sensor.vsWorking== LOST or wifi_acquisition.vsWorking== LOST or rc_acquisition.vsWorking== LOST or ccdl_behavior.vsWorking== LOST or pwm1_driver.vsWorking== LOST or pwm2_driver.vsWorking== LOST or pwm3_driver.vsWorking== LOST or pwm4_driver.vsWorking== LOST or wifi_driver.vsWorking== LOST or global_flight_control_board.vsWorking==LOST) then ccdl_behavior.in2 := ERR; 

		//Global Out MAIN et PWM
	pwm1_driver.in := global_flight_control_board.out;
	pwm2_driver.in := global_flight_control_board.out;
	pwm3_driver.in := global_flight_control_board.out;
	pwm4_driver.in := global_flight_control_board.out;
end

class Monitoring_flight_control_board
	//class instances
	flow2_behavior MON_can_sensor (lambda_ERR = 4.501e-07, lambda_Loss = 1.121e-05);
	flow2_behavior MON_ccdl_behavior (lambda_ERR = 5.482e-06, lambda_Loss = 1.059e-06);
	flow1_behavior MON_rc_acquisition (lambda_ERR = 3.497e-07, lambda_Loss = 2.936e-05);
	flow1_behavior MON_wifi_driver (lambda_ERR = 5.767e-06, lambda_Loss = 3.308e-06);
	flow1_behavior MON_wifi_acquisition (lambda_ERR = 6.241e-06, lambda_Loss = 2.280e-06);
	flow2_behavior MON_CAN_motor_driver (lambda_ERR = 1.121e-05, lambda_Loss = 4.501e-07);
	flow1_behavior MON_global_flight_control_board (lambda_ERR = 1e-09, lambda_Loss = 4.237e-05);
	//flow variables
	Status in_Inertial_reference_sensors_behavior (reset = LOST);	
	Status in_Magnetometer_behavior (reset = LOST);	
	Status in_Pressure_sensor_behavior (reset = LOST);
    Status in_PowerSupply (reset = LOST);

	Status in_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status in_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status in_CAN_Wire_GPS_Receiver (reset = LOST);

	Status in_RC_Serial_Bus (reset = LOST);
	Status in_WIFI_Serial_Bus (reset = LOST);
	Status in_WSL_Cross_channel_data_link (reset = LOST);

	Status out_WSL_Cross_channel_data_link (reset = LOST);
	Status out_WIFI_Serial_Bus (reset = LOST);

	Status out_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status out_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status out_CAN_Wire_GPS_Receiver (reset = LOST);

	Status in_CAN_Wire_motor1 (reset = LOST);
	Status in_CAN_Wire_motor2 (reset = LOST);
	Status in_CAN_Wire_motor3 (reset = LOST);
	Status in_CAN_Wire_motor4 (reset = LOST);

	Status out_CAN_Wire_motor1 (reset = LOST);
	Status out_CAN_Wire_motor2 (reset = LOST);
	Status out_CAN_Wire_motor3 (reset = LOST);
	Status out_CAN_Wire_motor4 (reset = LOST);	

	// local flow
	Status in_CAN_sensors_flows(reset = LOST);
	Status in_local_flow(reset = LOST);
	//assertion TODO
	assertion
	//CAN SENSOR
	if (in_CAN_Wire_LIDAR_Altimeter == OK and in_CAN_Wire_Optical_Flow_Sensor == OK and in_CAN_Wire_GPS_Receiver == OK) then in_CAN_sensors_flows := OK;
	if (in_CAN_Wire_LIDAR_Altimeter == ERR or in_CAN_Wire_Optical_Flow_Sensor == ERR or in_CAN_Wire_GPS_Receiver == ERR) and not (in_CAN_Wire_LIDAR_Altimeter == LOST or in_CAN_Wire_Optical_Flow_Sensor == LOST or in_CAN_Wire_GPS_Receiver == LOST) then in_CAN_sensors_flows := ERR ;

	MON_can_sensor.in1 := in_CAN_sensors_flows;
	out_CAN_Wire_LIDAR_Altimeter:=	MON_can_sensor.out2;
	out_CAN_Wire_Optical_Flow_Sensor:=	MON_can_sensor.out2;
	out_CAN_Wire_GPS_Receiver:=	MON_can_sensor.out2;

	//WIFI ACQ
	MON_wifi_acquisition.in := in_WIFI_Serial_Bus;
	//RC ACQ
	MON_rc_acquisition.in := in_RC_Serial_Bus;	
	//WIFI driver
	out_WIFI_Serial_Bus := MON_wifi_driver.out;

	//CCDL
	MON_ccdl_behavior.in1 := in_WSL_Cross_channel_data_link;
	out_WSL_Cross_channel_data_link := MON_ccdl_behavior.out2;


	MON_ccdl_behavior.in2 := MON_global_flight_control_board.out;

	//CAN WIRE motor
	out_CAN_Wire_motor1 := MON_CAN_motor_driver.out2 ;
	out_CAN_Wire_motor2 := MON_CAN_motor_driver.out2 ;
	out_CAN_Wire_motor3 := MON_CAN_motor_driver.out2 ;
	out_CAN_Wire_motor4 := MON_CAN_motor_driver.out2 ;
	if (in_CAN_Wire_motor1 == OK and in_CAN_Wire_motor2 == OK and in_CAN_Wire_motor3 == OK and in_CAN_Wire_motor4 == OK) then MON_CAN_motor_driver.in1 := OK;
	if (in_CAN_Wire_motor1== ERR or in_CAN_Wire_motor2== ERR or in_CAN_Wire_motor3== ERR or in_CAN_Wire_motor4== ERR) and not (in_CAN_Wire_motor1== LOST or in_CAN_Wire_motor2== LOST or in_CAN_Wire_motor3== LOST or in_CAN_Wire_motor4== LOST) then MON_CAN_motor_driver.in1 := ERR;

	// Global in
	if (MON_can_sensor.out1== OK and MON_wifi_acquisition.out== OK and MON_rc_acquisition.out== OK and MON_ccdl_behavior.out1== OK and MON_CAN_motor_driver.out1 == OK and in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then in_local_flow := OK;
	if (MON_can_sensor.out1== ERR or MON_wifi_acquisition.out== ERR or MON_rc_acquisition.out== ERR or MON_ccdl_behavior.out1== ERR or MON_CAN_motor_driver.out1 == ERR or in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) and not (MON_can_sensor.out1== LOST or MON_wifi_acquisition.out== LOST or MON_rc_acquisition.out== LOST or MON_ccdl_behavior.out1== LOST or MON_CAN_motor_driver.out1 == LOST or in_PowerSupply== LOST or in_Inertial_reference_sensors_behavior== LOST or in_Magnetometer_behavior== LOST or in_Pressure_sensor_behavior== LOST) then in_local_flow := ERR;
	MON_global_flight_control_board.in := in_local_flow;

	// Global out
		//Global Out CAN SENSOR
		// pour déboucler le loop de controle entre MONITORING et CAN SENSOR 
		if (/*MON_ccdl_behavior.out1== OK and*/ in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then MON_can_sensor.in2 := MON_global_flight_control_board.vsWorking;
	if (/*MON_ccdl_behavior.out1== ERR or */in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) or MON_global_flight_control_board.vsWorking == ERR then MON_can_sensor.in2 := ERR;

		//Global Out Wifi
		// pour déboucler le loop de controle entre MONITORING et Wifi
		if (/*MON_ccdl_behavior.out1== OK and */in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then MON_wifi_driver.in := MON_global_flight_control_board.vsWorking;
	if (/*MON_ccdl_behavior.out1== ERR or */in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) or MON_global_flight_control_board.vsWorking == ERR then MON_wifi_driver.in := ERR;

		//Global Out CAN MOTOR
		// pour déboucler le loop de controle entre MONITORING et CAN MOTOR
		if (/*MON_ccdl_behavior.out1== OK and */in_PowerSupply== OK and in_Inertial_reference_sensors_behavior== OK and in_Magnetometer_behavior== OK and in_Pressure_sensor_behavior== OK) then MON_CAN_motor_driver.in2 := MON_global_flight_control_board.vsWorking;
	if (/*MON_ccdl_behavior.out1== ERR or */in_PowerSupply== ERR or in_Inertial_reference_sensors_behavior== ERR or in_Magnetometer_behavior== ERR or in_Pressure_sensor_behavior== ERR) or MON_global_flight_control_board.vsWorking == ERR then MON_CAN_motor_driver.in2 := ERR;

end

class sensors_behavior
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in_PowerSupply (reset = LOST);
	Status out_cmd (reset = LOST);
	//local flow variables 
	Status in_local_flow (reset = LOST);

	assertion
		if (in_PowerSupply == OK) then in_local_flow := OK;
		if (in_PowerSupply == ERR) and not (in_PowerSupply == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK and in_local_flow == OK) then out_cmd := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_cmd := ERR;
end

class Flight_control_main_channel_behavior
	//class instances
	Main_flight_control_board main_flight_control_board;
	sensors_behavior inertial_reference_sensors_behavior(lambda_ERR = 1.483e-07, lambda_Loss = 3.017e-05);
	sensors_behavior magnetometer_behavior(lambda_ERR = 2.559e-07, lambda_Loss = 3.077e-06);
	sensors_behavior pressure_sensor_behavior(lambda_ERR = 3.302e-06, lambda_Loss = 1.116e-05);

	//flow variables
    Status in_PowerSupply (reset = LOST);

	assertion
		inertial_reference_sensors_behavior.in_PowerSupply:= in_PowerSupply;
		magnetometer_behavior.in_PowerSupply:= in_PowerSupply;
		pressure_sensor_behavior.in_PowerSupply:= in_PowerSupply;
		main_flight_control_board.in_PowerSupply:= in_PowerSupply;
		main_flight_control_board.in_Inertial_reference_sensors_behavior := inertial_reference_sensors_behavior.out_cmd;
		main_flight_control_board.in_Magnetometer_behavior := magnetometer_behavior.out_cmd;
		main_flight_control_board.in_Pressure_sensor_behavior := pressure_sensor_behavior.out_cmd;
end

class Flight_control_monitoring_channel_behavior
	//class instances
	Monitoring_flight_control_board monitoring_flight_control_board;
	sensors_behavior inertial_reference_sensors_MON_behavior(lambda_ERR = 2.628e-06, lambda_Loss = 1.419e-06);
	sensors_behavior magnetometer_MON_behavior(lambda_ERR = 1.901e-07, lambda_Loss = 1.286e-05);
	sensors_behavior pressure_sensor_MON_behavior(lambda_ERR = 4.594e-07, lambda_Loss = 3.949e-05);

	//flow variables
    Status in_PowerSupply (reset = LOST);

	assertion
		inertial_reference_sensors_MON_behavior.in_PowerSupply:= in_PowerSupply;
		magnetometer_MON_behavior.in_PowerSupply:= in_PowerSupply;
		pressure_sensor_MON_behavior.in_PowerSupply:= in_PowerSupply;
		monitoring_flight_control_board.in_PowerSupply:= in_PowerSupply;
		monitoring_flight_control_board.in_Inertial_reference_sensors_behavior := inertial_reference_sensors_MON_behavior.out_cmd;
		monitoring_flight_control_board.in_Magnetometer_behavior := magnetometer_MON_behavior.out_cmd;
		monitoring_flight_control_board.in_Pressure_sensor_behavior := pressure_sensor_MON_behavior.out_cmd;
end

class Motor_controller_behavior
	extends FM_Erroneous_Loss_Behaviour; 
	//flow variables
	Status in_EPL_Power_Supply (reset = LOST);
	Status in_WSL_Motor_voltage_feedback (reset = LOST);
	Status in_PWM (reset = LOST);
	Status out_Command (reset = LOST);

	//assertion
	assertion
		//assertion avec la boucle
//		if (in_EPL_Power_Supply == OK and in_WSL_Motor_voltage_feedback == OK and in_PWM == OK and vsWorking==OK) then out_Command := OK ;
//		if (in_EPL_Power_Supply == ERR or in_WSL_Motor_voltage_feedback == ERR or in_PWM == ERR or vsWorking==ERR) and not (in_EPL_Power_Supply == LOST or in_WSL_Motor_voltage_feedback == LOST or in_PWM == LOST or vsWorking==LOST) then out_Command := ERR ;
		//assertion sans la boucle
		if (in_EPL_Power_Supply == OK and in_PWM == OK and vsWorking==OK) then out_Command := OK ;
		if (in_EPL_Power_Supply == ERR or in_PWM == ERR and vsWorking==ERR) and not (in_EPL_Power_Supply == LOST or in_PWM == LOST or vsWorking==LOST) then out_Command := ERR ;
end

class Motor_protection_behavior 
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
	Status in_EPL_Power_Supply (reset = LOST);
	Status in_Command (reset = LOST);
	Status in_Speed_measure (reset = LOST);
	Status in_Can_transmission (reset = LOST);
	Status out_Can_transmission (reset = LOST);
	Status out_Command (reset = LOST);

	//assertion
	assertion
		if (in_EPL_Power_Supply == OK and in_Command == OK and in_Can_transmission == OK and vsWorking==OK) then out_Command := OK ;
		if (in_EPL_Power_Supply == ERR or in_Command == ERR or in_Can_transmission == ERR or vsWorking==ERR) and not (in_EPL_Power_Supply == LOST or in_Command == LOST or in_Can_transmission == LOST or vsWorking==LOST) then out_Command := ERR ;

		if (in_EPL_Power_Supply == OK and in_Speed_measure == OK) then out_Can_transmission := OK ;
		if (in_EPL_Power_Supply == ERR or in_Speed_measure == ERR) and not (in_EPL_Power_Supply == LOST or in_Speed_measure == LOST) then out_Can_transmission := ERR ;
end

/*
 * 3. Class concrete_component
 * -------------------
 * 3.1 Classes for system level 3
 * -------------------
 */

//concrete class for system level 3
class Propeller
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
	Status out_ML_Propeller_thrust_and_torque (reset = LOST);
	Status in_ML_rotation (reset = LOST);
	//assertion
	assertion
		if (vsWorking == OK) then out_ML_Propeller_thrust_and_torque := in_ML_rotation ;
		if (vsWorking == ERR) and not(vsWorking == LOST) then out_ML_Propeller_thrust_and_torque := ERR;
end

class Motor
	extends FM_Loss_Behaviour;
	//class instances
	flow1_behavior rotation_generation (lambda_ERR = 8.648e-06, lambda_Loss = 6.409e-05);
	flow1_behavior speed_measurement (lambda_ERR = 1.154e-07, lambda_Loss = 1.332e-06);

	//flow variables
	Status in_ML (reset = LOST);
	Status in_command (reset = LOST);
	Status out_Speed_measure (reset = LOST);
	Status out_WSL_Motor_voltage_feedback (reset = LOST);
	Status out_ML_rotation (reset = LOST);
	//assertion
	assertion
		if (in_ML == OK and vsWorking==OK) then rotation_generation.in := in_command;
		if (in_ML == ERR) then rotation_generation.in := ERR;
		if (in_ML == OK and vsWorking==OK) then out_WSL_Motor_voltage_feedback := rotation_generation.out;
		if (in_ML == ERR) then out_WSL_Motor_voltage_feedback := ERR;
		if (in_ML == OK and vsWorking==OK) then out_ML_rotation := rotation_generation.out;
		if (in_ML == ERR) then out_ML_rotation := ERR;	

		if (in_ML == OK and vsWorking==OK) then speed_measurement.in := in_command;
		if (in_ML == ERR) then speed_measurement.in := ERR;	
		if (in_ML == OK) then out_Speed_measure := speed_measurement.vsWorking; // debouclage des motors et du bus can motor
end

class Motor_Control_Protection
	//class instances
	Motor_controller_behavior motor_controller_behavior (lambda_ERR = 1.089e-07, lambda_Loss = 1.218e-05);
	Motor_protection_behavior motor_protection_behavior (lambda_ERR = 1.301e-06, lambda_Loss = 1.425e-06);
	flow2_behavior can_motor_driver (lambda_ERR = 4.501e-07, lambda_Loss = 1.121e-05);

	//flow variables
	Status in_ML (reset = LOST);
	Status in_CAN_Wire_motor (reset = LOST);
	Status in_PWM (reset = LOST);
	Status in_EPL_Power_Supply (reset = LOST);
	Status in_WSL_Motor_voltage_feedback (reset = LOST);
	Status in_Speed_measure (reset = LOST);

	Status out_CAN_Wire_motor (reset = LOST);
	Status out_command (reset = LOST);
	//assertion
	assertion
        if (in_ML==OK) then motor_protection_behavior.in_EPL_Power_Supply:= in_EPL_Power_Supply;
        if (in_ML==OK) then motor_protection_behavior.in_Can_transmission := can_motor_driver.out1 ;
        if (in_ML==OK) then motor_controller_behavior.in_WSL_Motor_voltage_feedback := in_WSL_Motor_voltage_feedback;
        if (in_ML==OK) then motor_controller_behavior.in_EPL_Power_Supply:= in_EPL_Power_Supply;
        if (in_ML==OK) then motor_controller_behavior.in_PWM := in_PWM;

        if (in_ML==OK) then can_motor_driver.in1 := in_CAN_Wire_motor;
        if (in_ML==OK) then can_motor_driver.in2 := motor_protection_behavior.out_Can_transmission ;
		
        if (in_ML==OK) then out_CAN_Wire_motor := can_motor_driver.out2 ;	
        if (in_ML==OK) then motor_protection_behavior.in_Command := motor_controller_behavior.out_Command;
        if (in_ML==OK) then out_command := motor_protection_behavior.out_Command;
        if (in_ML==OK) then motor_protection_behavior.in_Speed_measure := in_Speed_measure;
end

/*
 * 3.2 Classes for system level 2
 * -------------------
 */

class Propulsion_Unit 
	//class instances
	Motor motor (lambda_Loss = 2.392e-06);
	Propeller propeller (lambda_ERR = 3.326e-07, lambda_Loss = 1.918e-05);
	Motor_Control_Protection motor_Control_Protection;

	//flow variables
	Status in_ML (reset = LOST);
	//assertion
	assertion
	motor_Control_Protection.in_ML:=in_ML;
	motor.in_ML:=in_ML;
	motor_Control_Protection.in_WSL_Motor_voltage_feedback  := motor.out_WSL_Motor_voltage_feedback ;
	motor_Control_Protection.in_Speed_measure  := motor.out_Speed_measure ;
	motor.in_command  := motor_Control_Protection.out_command ;	
	propeller.in_ML_rotation := motor.out_ML_rotation ;
end

class RC_Receiver 
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in_USL_Remote_Control (reset = LOST);
    Status in_ML (reset = LOST);
    Status in_RC_Serial_Bus_Supply (reset = LOST);
    Status out_RC_serial_Bus (reset = LOST);

	//local flow variables 
	Status in_local_flow (reset = LOST);

	//assertion
	assertion
		if (in_USL_Remote_Control == OK and in_ML == OK and in_RC_Serial_Bus_Supply == OK) then in_local_flow := OK ;
		if (in_USL_Remote_Control == ERR or in_ML == ERR or in_RC_Serial_Bus_Supply == ERR) and not (in_USL_Remote_Control == LOST or in_ML == LOST or in_RC_Serial_Bus_Supply == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK and in_local_flow == OK) then out_RC_serial_Bus := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_RC_serial_Bus := ERR;
end

class Wifi_Controller
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in_USL_Mission_Data (reset = LOST);
    Status in_ML (reset = LOST);
    Status in_WIFI_Serial_Bus (reset = LOST);
    Status in_WIFI_Serial_Bus_Supply (reset = LOST);
    Status out_WIFI_Serial_Bus (reset = LOST);
    Status out_USL_Mission_Data (reset = LOST);
	//local flow variables 
	Status in_local_flow (reset = LOST);
	//assertion
	assertion
		if (in_USL_Mission_Data == OK and in_ML == OK and in_WIFI_Serial_Bus == OK and in_WIFI_Serial_Bus_Supply == OK) then in_local_flow := OK ;
		if (in_USL_Mission_Data == ERR or in_ML == ERR or in_WIFI_Serial_Bus == ERR or in_WIFI_Serial_Bus_Supply == ERR) and not (in_USL_Mission_Data == LOST or in_ML == LOST or in_WIFI_Serial_Bus == LOST or in_WIFI_Serial_Bus_Supply == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK) then out_WIFI_Serial_Bus := in_local_flow;
		if (vsWorking==OK) then out_USL_Mission_Data := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_WIFI_Serial_Bus := ERR;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_USL_Mission_Data := ERR;
end

class LIDAR_Altimeter
	extends FM_Erroneous_Loss_CANbus_Behaviour;

	//flow variables
    Status in_ML (reset = LOST);
    Status in_CAN_Wire (reset = LOST);
    Status out_CAN_Wire (reset = LOST);
	//local flow variables 
	Status in_local_flow (reset = LOST);

	//assertion
	assertion
		if (in_ML == OK and in_CAN_Wire == OK) then in_local_flow := OK;
		if (in_ML == ERR or in_CAN_Wire == ERR) and not (in_ML == LOST or in_CAN_Wire == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK and in_local_flow == OK) then out_CAN_Wire := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_CAN_Wire := ERR;
end

class GPS_Receiver 
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
//    Status in_USL_Positioning_Signal (reset = LOST); //inutile car aucune défaillance définis pour Positioning system
    Status in_ML (reset = LOST);
    Status in_CAN_Wire (reset = LOST);
    Status out_CAN_Wire (reset = LOST);
	//local flow variables 
	Status in_local_flow (reset = LOST);

	parameter Real lambda_CANbus_Loss = 0.0003;
	parameter Real lambda_CANbus_ERR = 0.00003;
	//event
	event ev_CANbus_Loss_Failure (delay = exponential(lambda_CANbus_Loss));
	event ev_CANbus_ERR_Failure (delay = exponential(lambda_CANbus_ERR));
	//transition
    transition
        ev_CANbus_Loss_Failure: vsWorking==OK -> vsWorking := LOST;
        ev_CANbus_ERR_Failure: vsWorking==OK -> vsWorking := ERR;

	//assertion
	assertion

		if (in_ML == OK and in_CAN_Wire == OK) then in_local_flow := OK ;
		if (in_CAN_Wire == ERR) and not (in_ML == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK and in_local_flow == OK) then out_CAN_Wire := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_CAN_Wire := ERR;
end

class Optical_Flow_Sensor
	extends FM_Erroneous_Loss_CANbus_Behaviour;

	//flow variables
    Status in_ML (reset = LOST);
    Status in_CAN_Wire (reset = LOST);
    Status out_CAN_Wire (reset = LOST);
	//local flow variables 
	Status in_local_flow (reset = LOST);

	//assertion
	assertion
		if (in_ML == OK and in_CAN_Wire == OK) then in_local_flow := OK;
		if (in_ML == ERR or in_CAN_Wire == ERR) and not (in_ML == LOST or in_CAN_Wire == LOST) then in_local_flow := ERR ;

		if (vsWorking==OK and in_local_flow == OK) then out_CAN_Wire := in_local_flow;
		if (vsWorking==ERR or in_local_flow == ERR) and not (vsWorking==LOST or in_local_flow ==LOST) then out_CAN_Wire := ERR;
end

class Flight_Controller
	extends FM_Loss_Behaviour;
	//class instances
	Flight_control_main_channel_behavior Flight_control_main_channel_behavior_AIDA;
	Flight_control_monitoring_channel_behavior Flight_control_monitoring_channel_behavior_AIDA;

	//flow variables
    Status in_ML (reset = LOST);
    Status in_PowerSupply (reset = LOST);

	Status in_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status in_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status in_CAN_Wire_GPS_Receiver (reset = LOST);

	Status in_RC_Serial_Bus (reset = LOST);
	Status in_WIFI_Serial_Bus (reset = LOST);

	Status in_CAN_Wire_motor1 (reset = LOST);
	Status in_CAN_Wire_motor2 (reset = LOST);
	Status in_CAN_Wire_motor3 (reset = LOST);
	Status in_CAN_Wire_motor4 (reset = LOST);

    Status out_WIFI_Serial_Bus_Supply (reset = LOST);
    Status out_RC_Serial_Bus_Supply (reset = LOST);

	Status out_WIFI_Serial_Bus (reset = LOST);

	Status out_CAN_Wire_LIDAR_Altimeter (reset = LOST);
	Status out_CAN_Wire_Optical_Flow_Sensor (reset = LOST);
	Status out_CAN_Wire_GPS_Receiver (reset = LOST);

	Status out_CAN_Wire_motor1 (reset = LOST);
	Status out_CAN_Wire_motor2 (reset = LOST);
	Status out_CAN_Wire_motor3 (reset = LOST);
	Status out_CAN_Wire_motor4 (reset = LOST);

	Status out_PWM1 (reset = LOST);
	Status out_PWM2 (reset = LOST);
	Status out_PWM3 (reset = LOST);
	Status out_PWM4 (reset = LOST);	
	//local flow variables 
	Status in_local_flow (reset = LOST);

	//assertion
	assertion
		//in distribution
			//energy distribution
			if (in_PowerSupply == OK and in_ML == OK) then in_local_flow := OK;
			if (in_PowerSupply == ERR or in_ML == ERR) and not (in_PowerSupply == LOST or in_ML == LOST) then in_local_flow := ERR;
		
			if (vsWorking==OK) then out_RC_Serial_Bus_Supply := in_local_flow;
			if (vsWorking==ERR) then out_RC_Serial_Bus_Supply := ERR;

			if (vsWorking==OK) then out_WIFI_Serial_Bus_Supply := in_local_flow;
			if (vsWorking==ERR) then out_WIFI_Serial_Bus_Supply := ERR;

			if (vsWorking==OK) then Flight_control_main_channel_behavior_AIDA.in_PowerSupply := in_local_flow;
			if (vsWorking==ERR) then Flight_control_main_channel_behavior_AIDA.in_PowerSupply := ERR;

			if (vsWorking==OK) then Flight_control_monitoring_channel_behavior_AIDA.in_PowerSupply := in_local_flow;
			if (vsWorking==ERR) then Flight_control_monitoring_channel_behavior_AIDA.in_PowerSupply := ERR;

		if (in_ML == OK) then Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_CAN_Wire_LIDAR_Altimeter:= in_CAN_Wire_LIDAR_Altimeter;
		if (in_ML == OK) then Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_CAN_Wire_Optical_Flow_Sensor:= in_CAN_Wire_Optical_Flow_Sensor;
		if (in_ML == OK) then Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_CAN_Wire_GPS_Receiver:= in_CAN_Wire_GPS_Receiver;
		if (in_ML == OK) then Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_RC_Serial_Bus:= in_RC_Serial_Bus;
		if (in_ML == OK) then Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_WIFI_Serial_Bus:= in_WIFI_Serial_Bus;
	
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_LIDAR_Altimeter:= in_CAN_Wire_LIDAR_Altimeter;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_Optical_Flow_Sensor:= in_CAN_Wire_Optical_Flow_Sensor;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_GPS_Receiver:= in_CAN_Wire_GPS_Receiver;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_RC_Serial_Bus:= in_RC_Serial_Bus;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_WIFI_Serial_Bus:= in_WIFI_Serial_Bus;
		
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_motor1:=in_CAN_Wire_motor1;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_motor2:=in_CAN_Wire_motor2;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_motor3:=in_CAN_Wire_motor3;
		if (in_ML == OK) then Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_CAN_Wire_motor4:=in_CAN_Wire_motor4;

		//out distribution
		//QUESTION : test a modifier plus tard - en fonction de la question 8 pour le porjet S2C - si il faut prendre en compte le retour du monitoring
		if (in_ML == OK and Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_WIFI_Serial_Bus==OK and Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_WIFI_Serial_Bus==OK) then out_WIFI_Serial_Bus :=OK;
		if (Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_WIFI_Serial_Bus==ERR or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_WIFI_Serial_Bus==ERR) and not (in_ML == LOST or Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_WIFI_Serial_Bus==LOST or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_WIFI_Serial_Bus==LOST) then out_WIFI_Serial_Bus :=ERR;

		if (in_ML == OK and Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==OK and Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==OK) then out_CAN_Wire_LIDAR_Altimeter :=OK;
		if (Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==ERR or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==ERR) and not (in_ML == LOST or Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==LOST or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_LIDAR_Altimeter==LOST) then out_CAN_Wire_LIDAR_Altimeter :=ERR;

		if (in_ML == OK and Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==OK and Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==OK) then out_CAN_Wire_Optical_Flow_Sensor :=OK;
		if (Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==ERR or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==ERR) and not (in_ML == LOST or Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==LOST or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor==LOST) then out_CAN_Wire_Optical_Flow_Sensor :=ERR;

		if (in_ML == OK and Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_GPS_Receiver==OK and Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_GPS_Receiver==OK) then out_CAN_Wire_GPS_Receiver :=OK;
		if (Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_GPS_Receiver==ERR or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_GPS_Receiver==ERR) and not (in_ML == LOST or Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_GPS_Receiver==LOST or Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_GPS_Receiver==LOST) then out_CAN_Wire_GPS_Receiver :=ERR;

	//	if (in_ML == OK) then out_WIFI_Serial_Bus := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_WIFI_Serial_Bus;
	//	if (in_ML == OK) then out_CAN_Wire_LIDAR_Altimeter := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_LIDAR_Altimeter;
	//	if (in_ML == OK) then out_CAN_Wire_Optical_Flow_Sensor := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_Optical_Flow_Sensor;
	//	if (in_ML == OK) then out_CAN_Wire_GPS_Receiver := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_CAN_Wire_GPS_Receiver;





		if (in_ML == OK) then out_PWM1 := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_PWM1;
		if (in_ML == OK) then out_PWM2 := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_PWM2;
		if (in_ML == OK) then out_PWM3 := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_PWM3;
		if (in_ML == OK) then out_PWM4 := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_PWM4;

		if (in_ML == OK) then out_CAN_Wire_motor1 := Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_motor1;
		if (in_ML == OK) then out_CAN_Wire_motor2 := Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_motor2;
		if (in_ML == OK) then out_CAN_Wire_motor3 := Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_motor3;
		if (in_ML == OK) then out_CAN_Wire_motor4 := Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_CAN_Wire_motor4;

		// WSL Connection main and monitoring
		if (in_ML == OK) then	Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.in_WSL_Cross_channel_data_link := Flight_control_main_channel_behavior_AIDA.main_flight_control_board.out_WSL_Cross_channel_data_link ;
		if (in_ML == OK) then	Flight_control_main_channel_behavior_AIDA.main_flight_control_board.in_WSL_Cross_channel_data_link := Flight_control_monitoring_channel_behavior_AIDA.monitoring_flight_control_board.out_WSL_Cross_channel_data_link ;
end

/*class Payload_Control 	extends component_flowInOut; // a mettre à jour en fonction des In et Out
end
class Camera_Rotary_Support	extends component_flowInOut; // a mettre à jour en fonction des In et Out
end
class Camera_Sensor 	extends component_flowInOut; // a mettre à jour en fonction des In et Out
end*/

/*
 * 3.3 Classes for system level 1
 * -------------------
 */
class Flight_Control_System 
	//class instances
	RC_Receiver RC_Receiver_AIDA (lambda_ERR = 1e-09, lambda_Loss = 1.338e-05); 
	Wifi_Controller Wifi_Controller_AIDA (lambda_ERR = 1.744e-05, lambda_Loss = 1.338e-07);
	GPS_Receiver GPS_Receiver_AIDA (lambda_ERR = 4.846e-07, lambda_Loss = 6.546e-06, lambda_CANbus_ERR = 4.501e-07, lambda_CANbus_Loss = 1.121e-05);
	FM_Erroneous_Behaviour GPS_Receiver_ERR (lambda_ERR = 4.846e-07);
	FM_Erroneous_Behaviour GPS_Receiver_CANBus_ERR (lambda_ERR = 4.501e-07);
	Optical_Flow_Sensor Optical_Flow_Sensor_AIDA (lambda_ERR = 9.468e-07, lambda_Loss = 8.244e-05, lambda_CANbus_ERR = 4.501e-07,lambda_CANbus_Loss = 1.121e-05);
	LIDAR_Altimeter LIDAR_Altimeter_AIDA (lambda_ERR = 4.501e-07, lambda_Loss = 1.121e-05, lambda_CANbus_ERR = 4.501e-07,lambda_CANbus_Loss = 1.121e-05);
	Flight_Controller Flight_Controller_AIDA (lambda_Loss = 9.660e-05);

	// assertion
	assertion
		//energy distribution
		RC_Receiver_AIDA.in_RC_Serial_Bus_Supply := Flight_Controller_AIDA.out_RC_Serial_Bus_Supply;
		Wifi_Controller_AIDA.in_WIFI_Serial_Bus_Supply := Flight_Controller_AIDA.out_WIFI_Serial_Bus_Supply;

		// RC serieal bus
		Flight_Controller_AIDA.in_RC_Serial_Bus := RC_Receiver_AIDA.out_RC_serial_Bus;

		// WIFI serial bus
		Wifi_Controller_AIDA.in_WIFI_Serial_Bus := Flight_Controller_AIDA.out_WIFI_Serial_Bus;
		Flight_Controller_AIDA.in_WIFI_Serial_Bus := Wifi_Controller_AIDA.out_WIFI_Serial_Bus;

		//CAN WIRE SENSOR
		LIDAR_Altimeter_AIDA.in_CAN_Wire := Flight_Controller_AIDA.out_CAN_Wire_LIDAR_Altimeter;
		Flight_Controller_AIDA.in_CAN_Wire_LIDAR_Altimeter := LIDAR_Altimeter_AIDA.out_CAN_Wire;

		Optical_Flow_Sensor_AIDA.in_CAN_Wire := Flight_Controller_AIDA.out_CAN_Wire_Optical_Flow_Sensor;
		Flight_Controller_AIDA.in_CAN_Wire_Optical_Flow_Sensor := Optical_Flow_Sensor_AIDA.out_CAN_Wire;

		GPS_Receiver_AIDA.in_CAN_Wire := Flight_Controller_AIDA.out_CAN_Wire_GPS_Receiver;
		Flight_Controller_AIDA.in_CAN_Wire_GPS_Receiver := GPS_Receiver_AIDA.out_CAN_Wire;

end
/*class Payload //Out of the scope
end*/
class Power_Supply_System
	extends FM_Loss_Behaviour; //commun Loss
	//class instances
	Power_Supply_behavior flightControlSupply_behavior (lambda_Loss = 8.363e-08);
	Power_Supply_behavior propulsionSupply_1_behavior (lambda_Loss = 8.041e-11);
	Power_Supply_behavior propulsionSupply_2_behavior (lambda_Loss = 8.041e-11);
	Power_Supply_behavior propulsionSupply_3_behavior (lambda_Loss = 8.041e-11);
	Power_Supply_behavior propulsionSupply_4_behavior (lambda_Loss = 8.041e-11);

	//flow variables
	Status in_ML_power_supply (reset = LOST);
    Status out_EPL_Power_supply_flight_control_system (reset = LOST);
    Status out_EPL_Power_supply_PU1 (reset = LOST);
    Status out_EPL_Power_supply_PU2 (reset = LOST);
    Status out_EPL_Power_supply_PU3 (reset = LOST);
    Status out_EPL_Power_supply_PU4 (reset = LOST);

	// assertion
	assertion
		if (vsWorking==OK and in_ML_power_supply == OK) then out_EPL_Power_supply_flight_control_system := flightControlSupply_behavior.out_EPL_Power_supply;
		if (vsWorking==OK and in_ML_power_supply == OK) then out_EPL_Power_supply_PU1 := propulsionSupply_1_behavior.out_EPL_Power_supply;
		if (vsWorking==OK and in_ML_power_supply == OK) then out_EPL_Power_supply_PU2 := propulsionSupply_2_behavior.out_EPL_Power_supply;
		if (vsWorking==OK and in_ML_power_supply == OK) then out_EPL_Power_supply_PU3 := propulsionSupply_3_behavior.out_EPL_Power_supply;
		if (vsWorking==OK and in_ML_power_supply == OK) then out_EPL_Power_supply_PU4 := propulsionSupply_4_behavior.out_EPL_Power_supply;

		if (vsWorking==OK and in_ML_power_supply == ERR) then out_EPL_Power_supply_flight_control_system := ERR;
		if (vsWorking==OK and in_ML_power_supply == ERR) then out_EPL_Power_supply_PU1 := ERR;
		if (vsWorking==OK and in_ML_power_supply == ERR) then out_EPL_Power_supply_PU2 := ERR;
		if (vsWorking==OK and in_ML_power_supply == ERR) then out_EPL_Power_supply_PU3 := ERR;
		if (vsWorking==OK and in_ML_power_supply == ERR) then out_EPL_Power_supply_PU4 := ERR;
end

class Structure
	extends FM_Loss_Behaviour;
	//flow variables Flight control system
    Status out_ML_RC_Receiver (reset = LOST);
    Status out_ML_Wifi_Controller (reset = LOST);
    Status out_ML_LIDAR_Altimeter (reset = LOST);
    Status out_ML_GPS_Recerver (reset = LOST);
    Status out_ML_Optical_Flow_Sensor (reset = LOST);
    Status out_ML_Flight_Controller (reset = LOST);

	//flow variables Propulsion system
//    Status in_ML_Propeller_1_thrust_and_torque (reset = LOST);
//    Status in_ML_Propeller_2_thrust_and_torque (reset = LOST);
//    Status in_ML_Propeller_3_thrust_and_torque (reset = LOST);
//    Status in_ML_Propeller_4_thrust_and_torque (reset = LOST);

    Status out_ML_Propulsion_Unit1 (reset = LOST);
    Status out_ML_Propulsion_Unit2 (reset = LOST);
    Status out_ML_Propulsion_Unit3 (reset = LOST);
    Status out_ML_Propulsion_Unit4 (reset = LOST);

	//flow variables Flight control system
    Status out_ML_power_supply (reset = LOST);

	//local flow variables 
	Status in_local_flow (reset = LOST);

	// assertion
	assertion
//		if (in_ML_Propeller_1_thrust_and_torque == OK and in_ML_Propeller_2_thrust_and_torque == OK and in_ML_Propeller_3_thrust_and_torque == OK and in_ML_Propeller_4_thrust_and_torque == OK) then in_local_flow := OK ;
//		if (in_ML_Propeller_1_thrust_and_torque == ERR or in_ML_Propeller_2_thrust_and_torque == ERR or in_ML_Propeller_3_thrust_and_torque == ERR or in_ML_Propeller_4_thrust_and_torque == ERR) then in_local_flow := ERR ;
		in_local_flow := OK;

		if (vsWorking==OK) then out_ML_RC_Receiver := in_local_flow;
		if (vsWorking==OK) then out_ML_Wifi_Controller := in_local_flow;
		if (vsWorking==OK) then out_ML_LIDAR_Altimeter := in_local_flow;
		if (vsWorking==OK) then out_ML_GPS_Recerver := in_local_flow;
		if (vsWorking==OK) then out_ML_Optical_Flow_Sensor := in_local_flow;
		if (vsWorking==OK) then out_ML_Flight_Controller := in_local_flow;
		if (vsWorking==OK) then out_ML_Propulsion_Unit1 := in_local_flow;
		if (vsWorking==OK) then out_ML_Propulsion_Unit2 := in_local_flow;
		if (vsWorking==OK) then out_ML_Propulsion_Unit3 := in_local_flow;
		if (vsWorking==OK) then out_ML_Propulsion_Unit4 := in_local_flow;
		if (vsWorking==OK) then out_ML_power_supply := in_local_flow;
end

class Propulsion_System 
	//class instances
	Propulsion_Unit propulsion_Unit1;
	Propulsion_Unit propulsion_Unit2;
	Propulsion_Unit propulsion_Unit3;
	Propulsion_Unit propulsion_Unit4;

end
/*------------------------------
//concrete class for system level 0
-----------------------------*/

class Drone 
	//class instances
	Flight_Control_System Flight_Control_System_AIDA;
	Power_Supply_System Power_Supply_System_AIDA (lambda_Loss = 1.415e-08);
	Structure Structure_AIDA(lambda_Loss = 1.744e-05);
	Propulsion_System Propulsion_System_AIDA;

	//flow variables
    Status in_USL_Remote_Control (reset = LOST);
//    Status in_USL_Positioning_Signal (reset = LOST);
    Status in_USL_Mission_Data (reset = LOST);

	// assertion
	assertion

		// ML assertion
//		Structure_AIDA.in_ML_Propeller_1_thrust_and_torque := Propulsion_System_AIDA.propulsion_Unit1.propeller.out_ML_Propeller_thrust_and_torque;
//		Structure_AIDA.in_ML_Propeller_2_thrust_and_torque := Propulsion_System_AIDA.propulsion_Unit2.propeller.out_ML_Propeller_thrust_and_torque;
//		Structure_AIDA.in_ML_Propeller_3_thrust_and_torque := Propulsion_System_AIDA.propulsion_Unit3.propeller.out_ML_Propeller_thrust_and_torque;
//		Structure_AIDA.in_ML_Propeller_4_thrust_and_torque := Propulsion_System_AIDA.propulsion_Unit4.propeller.out_ML_Propeller_thrust_and_torque;

		Flight_Control_System_AIDA.RC_Receiver_AIDA.in_ML := Structure_AIDA.out_ML_RC_Receiver; 
		Flight_Control_System_AIDA.Wifi_Controller_AIDA.in_ML := Structure_AIDA.out_ML_Wifi_Controller;
		Flight_Control_System_AIDA.LIDAR_Altimeter_AIDA.in_ML := Structure_AIDA.out_ML_LIDAR_Altimeter;
		Flight_Control_System_AIDA.Optical_Flow_Sensor_AIDA.in_ML := Structure_AIDA.out_ML_Optical_Flow_Sensor;
		Flight_Control_System_AIDA.GPS_Receiver_AIDA.in_ML := Structure_AIDA.out_ML_GPS_Recerver;
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_ML := Structure_AIDA.out_ML_Flight_Controller;

		Power_Supply_System_AIDA.in_ML_power_supply := Structure_AIDA.out_ML_power_supply;

		Propulsion_System_AIDA.propulsion_Unit1.in_ML := Structure_AIDA.out_ML_Propulsion_Unit1;
		Propulsion_System_AIDA.propulsion_Unit2.in_ML := Structure_AIDA.out_ML_Propulsion_Unit2;
		Propulsion_System_AIDA.propulsion_Unit3.in_ML := Structure_AIDA.out_ML_Propulsion_Unit3;
		Propulsion_System_AIDA.propulsion_Unit4.in_ML := Structure_AIDA.out_ML_Propulsion_Unit4;

		// USL assertion
		Flight_Control_System_AIDA.RC_Receiver_AIDA.in_USL_Remote_Control := in_USL_Remote_Control;
		Flight_Control_System_AIDA.Wifi_Controller_AIDA.in_USL_Mission_Data := in_USL_Mission_Data;
//		Flight_Control_System_AIDA.GPS_Receiver_AIDA.in_USL_Positioning_Signal := in_USL_Positioning_Signal;

		//CAN MOTOR
		Propulsion_System_AIDA.propulsion_Unit1.motor_Control_Protection.in_CAN_Wire_motor := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_CAN_Wire_motor1;
		Propulsion_System_AIDA.propulsion_Unit2.motor_Control_Protection.in_CAN_Wire_motor := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_CAN_Wire_motor2;
		Propulsion_System_AIDA.propulsion_Unit3.motor_Control_Protection.in_CAN_Wire_motor := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_CAN_Wire_motor3;
		Propulsion_System_AIDA.propulsion_Unit4.motor_Control_Protection.in_CAN_Wire_motor := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_CAN_Wire_motor4;
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_CAN_Wire_motor1 := Propulsion_System_AIDA.propulsion_Unit1.motor_Control_Protection.out_CAN_Wire_motor;
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_CAN_Wire_motor2 := Propulsion_System_AIDA.propulsion_Unit2.motor_Control_Protection.out_CAN_Wire_motor;
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_CAN_Wire_motor3 := Propulsion_System_AIDA.propulsion_Unit3.motor_Control_Protection.out_CAN_Wire_motor;
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_CAN_Wire_motor4 := Propulsion_System_AIDA.propulsion_Unit4.motor_Control_Protection.out_CAN_Wire_motor;

		//PWM MOTOR
		Propulsion_System_AIDA.propulsion_Unit1.motor_Control_Protection.in_PWM := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_PWM1;
		Propulsion_System_AIDA.propulsion_Unit2.motor_Control_Protection.in_PWM := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_PWM2;
		Propulsion_System_AIDA.propulsion_Unit3.motor_Control_Protection.in_PWM := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_PWM3;
		Propulsion_System_AIDA.propulsion_Unit4.motor_Control_Protection.in_PWM := Flight_Control_System_AIDA.Flight_Controller_AIDA.out_PWM4;

		//Energy Distribution
		Flight_Control_System_AIDA.Flight_Controller_AIDA.in_PowerSupply := Power_Supply_System_AIDA.out_EPL_Power_supply_flight_control_system;
		Propulsion_System_AIDA.propulsion_Unit1.motor_Control_Protection.in_EPL_Power_Supply := Power_Supply_System_AIDA.out_EPL_Power_supply_PU1;
		Propulsion_System_AIDA.propulsion_Unit2.motor_Control_Protection.in_EPL_Power_Supply := Power_Supply_System_AIDA.out_EPL_Power_supply_PU2;
		Propulsion_System_AIDA.propulsion_Unit3.motor_Control_Protection.in_EPL_Power_Supply := Power_Supply_System_AIDA.out_EPL_Power_supply_PU3;
		Propulsion_System_AIDA.propulsion_Unit4.motor_Control_Protection.in_EPL_Power_Supply := Power_Supply_System_AIDA.out_EPL_Power_supply_PU4;

end

class Remote_Battery
	extends FM_Loss_Behaviour;
	//flow variables
    Status out_energy_flow (reset = LOST);
	// assertion
	assertion
        if (vsWorking==OK) then out_energy_flow := OK;
end

class Remote_Communication
	extends FM_Erroneous_Loss_Behaviour;
	//flow variables
    Status in_energy_flow (reset = LOST);
	Status out_USL_Remote_Control (reset = LOST);
	assertion
        if (vsWorking==OK) then out_USL_Remote_Control := in_energy_flow;
        if (vsWorking==ERR) then out_USL_Remote_Control := ERR;
end
//TODO : placer des observers pour chaque SF (suivant l'allocation avec les composants)