Project 2 - Implement the Code for controlling the retraction and extension of Airplane’s landing gear
/*This program shows an implementation to control
the retraction and extension of the Airplane’s landing gear
using Finite State Machine (FSM)*/
//
//Here, the state "GEAR_UP" refers to the Extended gear
// ...while "GEAR_DOWN" refers to the Retracted gear
//
#include<stdio.h>
#include<stdbool.h>
// Function declarations
void Initialise_State_Machine(void);
void GearDown(void);
void CheckingBeforeTakeOFF(void);
void RaisingGear(void);
void GearUp(void);
void CheckBeforeLanding(void);
void LoweringGear(void);
// Function pointers
static void (*statetable[])(void) = {
GearDown, CheckingBeforeTakeOFF, RaisingGear, GearUp, CheckBeforeLanding, LoweringGear
};
// State enumeration
typedef enum
{
GEAR_DOWN,
CHECKING_BEFORE_TAKEOFF,
RAISING_GEAR,
GEAR_UP,
CHECK_BEFORE_LANDING,
LOWERING_GEAR
} State_Type;
// Switch status enumeration
typedef enum
{
SWITCH_ON,
SWITCH_OFF
} Switch_status;
// Pilot lever status enumeration
typedef enum
{
LEVER_RAISING,
LEVER_FALLING
} Lever_status;
// Hydraulic mechanism status enumeration
typedef enum
{
HYDRAULIC_WORKING,
HYDRAULIC_NOT_WORKING
} Hydraulic_status;
// Global variables
static Lever_status pl = LEVER_FALLING;
static Switch_status squat_switch = SWITCH_OFF;
static Switch_status limit_switch = SWITCH_OFF;
static Hydraulic_status hm = HYDRAULIC_WORKING;
static State_Type current_state;
// State machine structure
typedef struct
{
const char* current_state_indication;
const char* light;
const char* direction_valve_status;
const char* landing_gear_hydraulic_control;
const char* gasPressurised_springSystem_status;
} State_Table;
// State machine array
static State_Table State_Machine[6] = {
{"GearDown", "Green", "Down", "Enabled", "Enabled"},
{"CheckingBeforeTakeOFF", "Green", "Down", "Enabled", "Enabled"},
{"RaisingGear", "Red", "Up", "Enabled", "Disabled"},
{"GearUp", "off", "NULL", "Disabled", "Disabled"},
{"CheckBeforeLanding", "Red", "Down", "Enabled", "Enabled"},
{"LoweringGear", "Green", "Down", "Enabled", "Enabled"}
};
// Function prototypes
void displayStatusOfComponents();
void getUserInputForTransition(State_Type target_state);
int main(void)
{
Initialise_State_Machine();
while (true)
{
statetable[current_state]();
}
return 0;
}
//function to show the status of the states
void displayStatusOfComponents()
{
printf("\nCurrent State: %s\n", State_Machine[current_state].current_state_indication);
printf("Light is: %s\n", State_Machine[current_state].light);
printf("Direction Valve: %s\n", State_Machine[current_state].direction_valve_status);
printf("Hydraulic System: %s\n", State_Machine[current_state].landing_gear_hydraulic_control);
printf("Gas Spring System: %s\n", State_Machine[current_state].gasPressurised_springSystem_status);
}
//function to check for transition state
void getUserInputForTransition(State_Type target_state)
{
int choice;
switch (target_state)
{
case CHECKING_BEFORE_TAKEOFF:
printf("\nSelect an option for the pilot lever (1 = Raising, 2 = Falling): ");
if (scanf("%d", &choice) == 1 && (choice == 1 || choice == 2))
{
pl = (choice == 1) ? LEVER_RAISING : LEVER_FALLING;
}
else
{
printf("Invalid input. Defaulting to LEVER_FALLING.\n");
pl = LEVER_FALLING;
}
printf("\nSelect an option for the squat switch (3 = on, 4 = off): ");
if (scanf("%d", &choice) == 1 && (choice == 3 || choice == 4))
{
squat_switch = (choice == 3) ? SWITCH_ON : SWITCH_OFF;
}
else
{
printf("Invalid input. Defaulting to SWITCH_OFF.\n");
squat_switch = SWITCH_OFF;
}
break;
case RAISING_GEAR:
printf("\nSelect an option for the hydraulic mechanism (1 = working, 2 = not working): ");
if (scanf("%d", &choice) == 1 && (choice == 1 || choice == 2))
{
hm = (choice == 1) ? HYDRAULIC_WORKING : HYDRAULIC_NOT_WORKING;
}
else
{
printf("Invalid input. Defaulting to working.\n");
hm = HYDRAULIC_WORKING;
}
printf("\nSelect an option for the pilot lever (1 = Raising, 2 = Falling): ");
if (scanf("%d", &choice) == 1 && (choice == 1 || choice == 2))
{
pl = (choice == 1) ? LEVER_RAISING : LEVER_FALLING;
}
else
{
printf("Invalid input. Defaulting to LEVER_FALLING.\n");
pl = LEVER_FALLING;
}
printf("\nSelect an option for the squat switch (3 = on, 4 = off): ");
if (scanf("%d", &choice) == 1 && (choice == 3 || choice == 4))
{
squat_switch = (choice == 3) ? SWITCH_ON : SWITCH_OFF;
}
else
{
printf("Invalid input. Defaulting to SWITCH_OFF.\n");
squat_switch = SWITCH_OFF;
}
break;
case CHECK_BEFORE_LANDING:
printf("\nSelect an option for the pilot lever (1 = Raising, 2 = Falling): ");
if (scanf("%d", &choice) == 1 && (choice == 1 || choice == 2)) {
pl = (choice == 1) ? LEVER_RAISING : LEVER_FALLING;
}
else
{
printf("Invalid input. Defaulting to LEVER_FALLING.\n");
pl = LEVER_FALLING;
}
break;
case LOWERING_GEAR:
printf("\nSelect an option for the limit switch (3 = on, 4 = off): ");
if (scanf("%d", &choice) == 1 && (choice == 3 || choice == 4))
{
limit_switch = (choice == 3) ? SWITCH_ON : SWITCH_OFF;
}
else
{
printf("Invalid input. Defaulting to SWITCH_OFF.\n");
limit_switch = SWITCH_OFF;
}
break;
case GEAR_UP:
printf("\nSelect an option for the limit switch (3 = on, 4 = off): ");
if (scanf("%d", &choice) == 1 && (choice == 3 || choice == 4))
{
limit_switch = (choice == 3) ? SWITCH_ON : SWITCH_OFF;
}
else
{
printf("Invalid input. Defaulting to SWITCH_OFF.\n");
limit_switch = SWITCH_OFF;
}
break;
case GEAR_DOWN:
printf("\nSelect an option for the pilot lever (1 = Raising, 2 = Falling): ");
if (scanf("%d", &choice) == 1 && (choice == 1 || choice == 2))
{
pl = (choice == 1) ? LEVER_RAISING : LEVER_FALLING;
}
else
{
printf("Invalid input. Defaulting to LEVER_FALLING.\n");
pl = LEVER_FALLING;
}
break;
}
}
//function for the Retracted state of the gear
void GearDown(void)
{
current_state = GEAR_DOWN;
printf("\nCurrent State: %s\n", State_Machine[current_state].current_state_indication);
printf("Light is: %s\n", State_Machine[current_state].light);
getUserInputForTransition(CHECKING_BEFORE_TAKEOFF);
if (pl == LEVER_RAISING && squat_switch == SWITCH_ON)
{
current_state = CHECKING_BEFORE_TAKEOFF;
}
}
//function to check the state before takeoff
void CheckingBeforeTakeOFF(void)
{
current_state = CHECKING_BEFORE_TAKEOFF;
displayStatusOfComponents();
getUserInputForTransition(RAISING_GEAR);
if (pl == LEVER_FALLING && squat_switch == SWITCH_OFF)
{
current_state = GEAR_DOWN;
} else if (pl == LEVER_RAISING && squat_switch == SWITCH_ON && hm == HYDRAULIC_WORKING)
{
current_state = RAISING_GEAR;
} else if (pl == LEVER_RAISING && squat_switch == SWITCH_ON && hm == HYDRAULIC_NOT_WORKING)
{
current_state = RAISING_GEAR;
}
}
//function for the state when the gear is being raised
void RaisingGear(void)
{
current_state = RAISING_GEAR;
displayStatusOfComponents();
getUserInputForTransition(CHECK_BEFORE_LANDING);
if (pl == LEVER_FALLING && limit_switch == SWITCH_ON)
{
current_state = CHECK_BEFORE_LANDING;
} else if (pl == LEVER_RAISING && limit_switch == SWITCH_OFF)
{
current_state = GEAR_UP;
}
}
//function for Extended state of the gear
void GearUp(void)
{
current_state = GEAR_UP;
displayStatusOfComponents();
getUserInputForTransition(CHECK_BEFORE_LANDING);
if (pl == LEVER_FALLING)
{
current_state = CHECK_BEFORE_LANDING;
}
}
//function to check the state before landing
void CheckBeforeLanding(void)
{
current_state = CHECK_BEFORE_LANDING;
displayStatusOfComponents();
getUserInputForTransition(LOWERING_GEAR);
if (pl == LEVER_FALLING && hm == HYDRAULIC_WORKING)
{
current_state = LOWERING_GEAR;
} else if (pl == LEVER_FALLING && hm == HYDRAULIC_NOT_WORKING)
{
current_state = LOWERING_GEAR;
}
}
//function for the state when gear is being lowered
void LoweringGear(void)
{
current_state = LOWERING_GEAR;
displayStatusOfComponents();
getUserInputForTransition(CHECKING_BEFORE_TAKEOFF);
if (pl == LEVER_FALLING && limit_switch == SWITCH_ON)
{
current_state = CHECKING_BEFORE_TAKEOFF;
}
else if (pl == LEVER_FALLING && limit_switch == SWITCH_OFF)
{
current_state = GEAR_DOWN;
}
}
//function to show the initial state
void Initialise_State_Machine(void)
{
current_state = GEAR_DOWN;
//initially, the current state is GEAR_DOWN
printf("\nThe Finite State Machine is Initialized.\n\n");
}