From 2f0e8980b7a19adff7e606238060b717769a8e7d Mon Sep 17 00:00:00 2001 From: Ian Carroll Date: Sun, 22 May 2022 12:26:52 -0230 Subject: [PATCH 1/5] Implemented node state machine --- fsm/fsm.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 fsm/fsm.c diff --git a/fsm/fsm.c b/fsm/fsm.c new file mode 100644 index 0000000..4dd8800 --- /dev/null +++ b/fsm/fsm.c @@ -0,0 +1,100 @@ +#include +#include +#include + +typedef enum +{ + BOOT, + AUTONOMOUS, + MANUAL +} State; + +void get_next_state(char input, State **state); + +int main() +{ + char input; + State * state; + State tmp; + + State boot = BOOT; + + state = &boot; + + while (1) + { + printf("\nCurrent state is: %d\n", *state); + printf("Please enter character input: "); + scanf("%c", &input); + if (input == '\n' || input == EOF) + { + continue; + } + if (input == 'q' || input == 'Q') + { + break; + } + get_next_state(input, &state); + tmp = *state; + fflush(stdin); + state = &tmp; + } +} + +void get_next_state(char input, State **state) +{ + State boot = BOOT; + State autonomous = AUTONOMOUS; + State manual = MANUAL; + + int curr_state = (int)**state; + + if (curr_state == (int)boot) + { + if (input == 'P' || input == 'p' || input == 'W' || input == 'w') + { + *state = &boot; + } + + else if (input == 'A' || input == 'a') + { + *state = &autonomous; + } + + else if (input == 'M' || input == 'm') + { + *state = &manual; + } + } + + else if (curr_state == (int)autonomous) + { + if (input == 'P' || input == 'p' || input == 'W' || input == 'w') + { + *state = &boot; + } + + else + { + *state = &autonomous; + } + } + + else if (curr_state == (int)manual) + { + if (input == 'P' || input == 'p' || input == 'W' || input == 'w') + { + *state = &boot; + } + + else + { + *state = &manual; + } + } + + else + { + printf("Error: Unknown State\n"); + } +} From ab2f2471efd38969054e618ccc3e2a58a73cca32 Mon Sep 17 00:00:00 2001 From: Ian Carroll <67641046+Ian-Carroll@users.noreply.github.com> Date: Sun, 22 May 2022 13:23:28 -0230 Subject: [PATCH 2/5] Create fsm.md --- fsm.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 fsm.md diff --git a/fsm.md b/fsm.md new file mode 100644 index 0000000..ffe7d96 --- /dev/null +++ b/fsm.md @@ -0,0 +1,9 @@ +# Node State Machine +fsm.c implements the state machine for the Node subsystem as shown here: + +![State_Diagram_14-5-22 (1)](https://user-images.githubusercontent.com/67641046/169704065-c144127e-2833-4674-a9cf-f29355fdd1c9.png) + +In order to compile: +- Ensure that your gcc version is up to date with gcc --version (my version is 11.2.0). +- cd into the /fsm subdirectory and do gcc fsm.c -o fsm +- ./fsm From 723be49ccb8fefa3b9078b6ff9af49e8789c4449 Mon Sep 17 00:00:00 2001 From: Ian Carroll Date: Sun, 22 May 2022 13:26:01 -0230 Subject: [PATCH 3/5] Moved fsm.md --- fsm.md => fsm/fsm.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename fsm.md => fsm/fsm.md (100%) diff --git a/fsm.md b/fsm/fsm.md similarity index 100% rename from fsm.md rename to fsm/fsm.md From 8a4fba9e8b0f924e6f83128054c0dbaa6d288a33 Mon Sep 17 00:00:00 2001 From: Ian Carroll Date: Sun, 22 May 2022 13:27:29 -0230 Subject: [PATCH 4/5] Renamed fsm.md to README.md --- fsm/{fsm.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename fsm/{fsm.md => README.md} (100%) diff --git a/fsm/fsm.md b/fsm/README.md similarity index 100% rename from fsm/fsm.md rename to fsm/README.md From 5719801c3867a0ee7f0005a9983fe2c65e41bfcf Mon Sep 17 00:00:00 2001 From: Ian Carroll Date: Mon, 23 May 2022 22:47:44 -0230 Subject: [PATCH 5/5] Implemented unit testing for state machine --- fsm/fsm.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/fsm/fsm.c b/fsm/fsm.c index 4dd8800..677e0d5 100644 --- a/fsm/fsm.c +++ b/fsm/fsm.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -10,6 +11,7 @@ typedef enum } State; void get_next_state(char input, State **state); +void test_fsm(); int main() { @@ -39,8 +41,112 @@ int main() fflush(stdin); state = &tmp; } + + test_fsm(); + printf("Unit Test Passed"); +} + +// Unit test asserting correct state transitions +// returns true if pass, false otherwise +void test_fsm() +{ + char input; + + // Test setup + State * boot; + State boot_val = BOOT; + State * autonomous; + State autonomous_val = AUTONOMOUS; + State * manual; + State manual_val = MANUAL; + + // Boot -> Boot transition tests + boot = &boot_val; + input = 'p'; + get_next_state(input, &boot); + assert(*boot == boot_val); + + boot = &boot_val; + input = 'P'; + get_next_state(input, &boot); + assert(*boot == boot_val); + + boot = &boot_val; + input = 'w'; + get_next_state(input, &boot); + assert(*boot == boot_val); + + boot = &boot_val; + input = 'W'; + get_next_state(input, &boot); + assert(*boot == boot_val); + + // Boot -> Autonomous transition tests + boot = &boot_val; + input = 'a'; + get_next_state(input, &boot); + assert(*boot == autonomous_val); + + boot = &boot_val; + input = 'A'; + get_next_state(input, &boot); + assert(*boot == autonomous_val); + + // Boot -> Manual transition tests + boot = &boot_val; + input = 'm'; + get_next_state(input, &boot); + assert(*boot == manual_val); + + boot = &boot_val; + input = 'M'; + get_next_state(input, &boot); + assert(*boot == manual_val); + + // Autonomous -> Boot transition tests + autonomous = &autonomous_val; + input = 'p'; + get_next_state(input, &autonomous); + assert(*autonomous == boot_val); + + autonomous = &autonomous_val; + input = 'P'; + get_next_state(input, &autonomous); + assert(*autonomous == boot_val); + + autonomous = &autonomous_val; + input = 'w'; + get_next_state(input, &autonomous); + assert(*autonomous == boot_val); + + autonomous = &autonomous_val; + input = 'W'; + get_next_state(input, &autonomous); + assert(*autonomous == boot_val); + + // Manual -> Boot transition tests + manual = &manual_val; + input = 'p'; + get_next_state(input, &manual); + assert(*manual == boot_val); + + manual = &manual_val; + input = 'P'; + get_next_state(input, &manual); + assert(*manual == boot_val); + + manual = &manual_val; + input = 'w'; + get_next_state(input, &manual); + assert(*manual == boot_val); + + manual = &manual_val; + input = 'W'; + get_next_state(input, &manual); + assert(*manual == boot_val); } +// Get the next state based on the current state and input void get_next_state(char input, State **state) { State boot = BOOT;