SHOW:
|
|
- or go back to the newest paste.
| 1 | #include<stdio.h> | |
| 2 | #include<stdlib.h> | |
| 3 | #include<string.h> | |
| 4 | ||
| 5 | #define MAX_NAME_LENGTH 20 | |
| 6 | #define STIMULI_AMOUNT 4 | |
| 7 | #define STATE_AMOUNT 5 | |
| 8 | ||
| 9 | enum Stimuli {
| |
| 10 | TurnOn, | |
| 11 | TurnOff, | |
| 12 | SpeedUp, | |
| 13 | SpeedDown | |
| 14 | }; | |
| 15 | ||
| 16 | enum State {
| |
| 17 | Off, | |
| 18 | Stopped, | |
| 19 | Walking, | |
| 20 | Running, | |
| 21 | Error | |
| 22 | }; | |
| 23 | ||
| 24 | struct Transition {
| |
| 25 | enum State prev_state; | |
| 26 | enum Stimuli stimulus; | |
| 27 | enum State next_state; | |
| 28 | }; | |
| 29 | ||
| 30 | typedef struct Transition transition; | |
| 31 | ||
| 32 | struct FSM {
| |
| 33 | - | transition * transition_logic; |
| 33 | + | |
| 34 | transition ** transition_logic; | |
| 35 | const char* printable_stimuli[4]; | |
| 36 | const char* printable_states[5]; | |
| 37 | }; | |
| 38 | ||
| 39 | void stimulate (struct FSM* fsm, enum Stimuli stimulus); | |
| 40 | void print_transition (const transition trans, const char** printable_stimuli, const char** printable_states); | |
| 41 | void initialize (struct FSM* fsm); | |
| 42 | ||
| 43 | int main (void) {
| |
| 44 | ||
| 45 | int input; | |
| 46 | struct FSM the_machine; | |
| 47 | ||
| 48 | initialize (&the_machine); | |
| 49 | input = 0; | |
| 50 | ||
| 51 | while (input != 4) {
| |
| 52 | printf("Input stimulus: 0_On, 1_Off, 2_SpUp, 3_SpDn, 4_Exit \n");
| |
| 53 | scanf("%i", &input);
| |
| 54 | ||
| 55 | if ((0 <= input) && (input < 4)){
| |
| 56 | stimulate (&the_machine, input); | |
| 57 | } | |
| 58 | } | |
| 59 | ||
| 60 | return EXIT_SUCCESS; | |
| 61 | ||
| 62 | } | |
| 63 | ||
| 64 | void stimulate(struct FSM* fsm, enum Stimuli stimulus) {
| |
| 65 | ||
| 66 | - | int index; |
| 66 | + | |
| 67 | ||
| 68 | previous = (*fsm).curr_state; | |
| 69 | - | index = previous*STIMULI_AMOUNT + stimulus; |
| 69 | + | |
| 70 | (*fsm).curr_state = (((*fsm).transition_logic)[previous][stimulus]).next_state; | |
| 71 | - | (*fsm).curr_state = (((*fsm).transition_logic)[index]).next_state; |
| 71 | + | |
| 72 | print_transition (((*fsm).transition_logic)[previous][stimulus], (*fsm).printable_stimuli, (*fsm).printable_states); | |
| 73 | - | print_transition (((*fsm).transition_logic)[index], (*fsm).printable_stimuli, (*fsm).printable_states); |
| 73 | + | |
| 74 | } | |
| 75 | ||
| 76 | void print_transition (const transition trans, const char** printable_stimuli, const char** printable_states) {
| |
| 77 | ||
| 78 | char prev_state[MAX_NAME_LENGTH]; | |
| 79 | char stimulus[MAX_NAME_LENGTH]; | |
| 80 | char next_state[MAX_NAME_LENGTH]; | |
| 81 | ||
| 82 | strncpy (prev_state, printable_states[trans.prev_state], MAX_NAME_LENGTH); | |
| 83 | strncpy (stimulus, printable_stimuli[trans.stimulus], MAX_NAME_LENGTH); | |
| 84 | strncpy (next_state, printable_states[trans.next_state], MAX_NAME_LENGTH); | |
| 85 | ||
| 86 | printf("[%s]---[%s]--->[%s]\n", prev_state, stimulus, next_state);
| |
| 87 | } | |
| 88 | ||
| 89 | void initialize (struct FSM* fsm) {
| |
| 90 | ||
| 91 | int i; | |
| 92 | ||
| 93 | (*fsm).curr_state = Off; | |
| 94 | ||
| 95 | (*fsm).printable_stimuli[0] = "TurnOn"; | |
| 96 | (*fsm).printable_stimuli[1] = "TurnOff"; | |
| 97 | (*fsm).printable_stimuli[2] = "SpeedUp"; | |
| 98 | (*fsm).printable_stimuli[3] = "SpeedDown"; | |
| 99 | ||
| 100 | (*fsm).printable_states[0] = "Off"; | |
| 101 | (*fsm).printable_states[1] = "Stopped"; | |
| 102 | (*fsm).printable_states[2] = "Walking"; | |
| 103 | (*fsm).printable_states[3] = "Running"; | |
| 104 | (*fsm).printable_states[4] = "Error"; | |
| 105 | - | (*fsm).transition_logic = (transition *) calloc (20 ,sizeof(transition)); |
| 105 | + | |
| 106 | (*fsm).transition_logic = (transition **) calloc (STATE_AMOUNT ,sizeof(transition*)); | |
| 107 | ||
| 108 | for (i=0; i<STATE_AMOUNT; i++) {
| |
| 109 | - | (((*fsm).transition_logic)[0]).prev_state = Off; |
| 109 | + | (*fsm).transition_logic[i] = (transition *) calloc (STIMULI_AMOUNT ,sizeof(transition)); |
| 110 | - | (((*fsm).transition_logic)[0]).stimulus = TurnOn; |
| 110 | + | |
| 111 | - | (((*fsm).transition_logic)[0]).next_state = Stopped; |
| 111 | + | |
| 112 | /** OFF STATE */ | |
| 113 | /* TURNON STIMULUS */ | |
| 114 | - | (((*fsm).transition_logic)[1]).prev_state = Off; |
| 114 | + | (((*fsm).transition_logic)[0][0]).prev_state = Off; |
| 115 | - | (((*fsm).transition_logic)[1]).stimulus = TurnOff; |
| 115 | + | (((*fsm).transition_logic)[0][0]).stimulus = TurnOn; |
| 116 | - | (((*fsm).transition_logic)[1]).next_state = Off; |
| 116 | + | (((*fsm).transition_logic)[0][0]).next_state = Stopped; |
| 117 | ||
| 118 | /* TURNOFF STIMULUS */ | |
| 119 | - | (((*fsm).transition_logic)[2]).prev_state = Off; |
| 119 | + | (((*fsm).transition_logic)[0][1]).prev_state = Off; |
| 120 | - | (((*fsm).transition_logic)[2]).stimulus = SpeedUp; |
| 120 | + | (((*fsm).transition_logic)[0][1]).stimulus = TurnOff; |
| 121 | - | (((*fsm).transition_logic)[2]).next_state = Off; |
| 121 | + | (((*fsm).transition_logic)[0][1]).next_state = Off; |
| 122 | ||
| 123 | /* SPEEDUP STIMULUS */ | |
| 124 | - | (((*fsm).transition_logic)[3]).prev_state = Off; |
| 124 | + | (((*fsm).transition_logic)[0][2]).prev_state = Off; |
| 125 | - | (((*fsm).transition_logic)[3]).stimulus = SpeedDown; |
| 125 | + | (((*fsm).transition_logic)[0][2]).stimulus = SpeedUp; |
| 126 | - | (((*fsm).transition_logic)[3]).next_state = Off; |
| 126 | + | (((*fsm).transition_logic)[0][2]).next_state = Off; |
| 127 | ||
| 128 | /* SPEEDDOWN STIMULUS */ | |
| 129 | (((*fsm).transition_logic)[0][3]).prev_state = Off; | |
| 130 | - | (((*fsm).transition_logic)[4]).prev_state = Stopped; |
| 130 | + | (((*fsm).transition_logic)[0][3]).stimulus = SpeedDown; |
| 131 | - | (((*fsm).transition_logic)[4]).stimulus = TurnOn; |
| 131 | + | (((*fsm).transition_logic)[0][3]).next_state = Off; |
| 132 | - | (((*fsm).transition_logic)[4]).next_state = Stopped; |
| 132 | + | |
| 133 | /** STOPPED STATE */ | |
| 134 | /* TURNON STIMULUS */ | |
| 135 | - | (((*fsm).transition_logic)[5]).prev_state = Stopped; |
| 135 | + | (((*fsm).transition_logic)[1][0]).prev_state = Stopped; |
| 136 | - | (((*fsm).transition_logic)[5]).stimulus = TurnOff; |
| 136 | + | (((*fsm).transition_logic)[1][0]).stimulus = TurnOn; |
| 137 | - | (((*fsm).transition_logic)[5]).next_state = Off; |
| 137 | + | (((*fsm).transition_logic)[1][0]).next_state = Stopped; |
| 138 | ||
| 139 | /* TURNOFF STIMULUS */ | |
| 140 | - | (((*fsm).transition_logic)[6]).prev_state = Stopped; |
| 140 | + | (((*fsm).transition_logic)[1][1]).prev_state = Stopped; |
| 141 | - | (((*fsm).transition_logic)[6]).stimulus = SpeedUp; |
| 141 | + | (((*fsm).transition_logic)[1][1]).stimulus = TurnOff; |
| 142 | - | (((*fsm).transition_logic)[6]).next_state = Walking; |
| 142 | + | (((*fsm).transition_logic)[1][1]).next_state = Off; |
| 143 | ||
| 144 | /* SPEEDUP STIMULUS */ | |
| 145 | - | (((*fsm).transition_logic)[7]).prev_state = Stopped; |
| 145 | + | (((*fsm).transition_logic)[1][2]).prev_state = Stopped; |
| 146 | - | (((*fsm).transition_logic)[7]).stimulus = SpeedDown; |
| 146 | + | (((*fsm).transition_logic)[1][2]).stimulus = SpeedUp; |
| 147 | - | (((*fsm).transition_logic)[7]).next_state = Error; |
| 147 | + | (((*fsm).transition_logic)[1][2]).next_state = Walking; |
| 148 | ||
| 149 | /* SPEEDDOWN STIMULUS */ | |
| 150 | (((*fsm).transition_logic)[1][3]).prev_state = Stopped; | |
| 151 | - | (((*fsm).transition_logic)[8]).prev_state = Walking; |
| 151 | + | (((*fsm).transition_logic)[1][3]).stimulus = SpeedDown; |
| 152 | - | (((*fsm).transition_logic)[8]).stimulus = TurnOn; |
| 152 | + | (((*fsm).transition_logic)[1][3]).next_state = Error; |
| 153 | - | (((*fsm).transition_logic)[8]).next_state = Walking; |
| 153 | + | |
| 154 | /** WALKING STATE */ | |
| 155 | /* TURNON STIMULUS */ | |
| 156 | - | (((*fsm).transition_logic)[9]).prev_state = Walking; |
| 156 | + | (((*fsm).transition_logic)[2][0]).prev_state = Walking; |
| 157 | - | (((*fsm).transition_logic)[9]).stimulus = TurnOff; |
| 157 | + | (((*fsm).transition_logic)[2][0]).stimulus = TurnOn; |
| 158 | - | (((*fsm).transition_logic)[9]).next_state = Off; |
| 158 | + | (((*fsm).transition_logic)[2][0]).next_state = Walking; |
| 159 | ||
| 160 | /* TURNOFF STIMULUS */ | |
| 161 | - | (((*fsm).transition_logic)[10]).prev_state = Walking; |
| 161 | + | (((*fsm).transition_logic)[2][1]).prev_state = Walking; |
| 162 | - | (((*fsm).transition_logic)[10]).stimulus = SpeedUp; |
| 162 | + | (((*fsm).transition_logic)[2][1]).stimulus = TurnOff; |
| 163 | - | (((*fsm).transition_logic)[10]).next_state = Running; |
| 163 | + | (((*fsm).transition_logic)[2][1]).next_state = Off; |
| 164 | ||
| 165 | /* SPEEDUP STIMULUS */ | |
| 166 | - | (((*fsm).transition_logic)[11]).prev_state = Walking; |
| 166 | + | (((*fsm).transition_logic)[2][2]).prev_state = Walking; |
| 167 | - | (((*fsm).transition_logic)[11]).stimulus = SpeedDown; |
| 167 | + | (((*fsm).transition_logic)[2][2]).stimulus = SpeedUp; |
| 168 | - | (((*fsm).transition_logic)[11]).next_state = Stopped; |
| 168 | + | (((*fsm).transition_logic)[2][2]).next_state = Running; |
| 169 | ||
| 170 | /* SPEEDDOWN STIMULUS */ | |
| 171 | (((*fsm).transition_logic)[2][3]).prev_state = Walking; | |
| 172 | - | (((*fsm).transition_logic)[12]).prev_state = Running; |
| 172 | + | (((*fsm).transition_logic)[2][3]).stimulus = SpeedDown; |
| 173 | - | (((*fsm).transition_logic)[12]).stimulus = TurnOn; |
| 173 | + | (((*fsm).transition_logic)[2][3]).next_state = Stopped; |
| 174 | - | (((*fsm).transition_logic)[12]).next_state = Running; |
| 174 | + | |
| 175 | /** RUNNING STATE */ | |
| 176 | /* TURNON STIMULUS */ | |
| 177 | - | (((*fsm).transition_logic)[13]).prev_state = Running; |
| 177 | + | (((*fsm).transition_logic)[3][0]).prev_state = Running; |
| 178 | - | (((*fsm).transition_logic)[13]).stimulus = TurnOff; |
| 178 | + | (((*fsm).transition_logic)[3][0]).stimulus = TurnOn; |
| 179 | - | (((*fsm).transition_logic)[13]).next_state = Off; |
| 179 | + | (((*fsm).transition_logic)[3][0]).next_state = Running; |
| 180 | ||
| 181 | /* TURNOFF STIMULUS */ | |
| 182 | - | (((*fsm).transition_logic)[14]).prev_state = Running; |
| 182 | + | (((*fsm).transition_logic)[3][1]).prev_state = Running; |
| 183 | - | (((*fsm).transition_logic)[14]).stimulus = SpeedUp; |
| 183 | + | (((*fsm).transition_logic)[3][1]).stimulus = TurnOff; |
| 184 | - | (((*fsm).transition_logic)[14]).next_state = Error; |
| 184 | + | (((*fsm).transition_logic)[3][1]).next_state = Off; |
| 185 | ||
| 186 | /* SPEEDUP STIMULUS */ | |
| 187 | - | (((*fsm).transition_logic)[15]).prev_state = Running; |
| 187 | + | (((*fsm).transition_logic)[3][2]).prev_state = Running; |
| 188 | - | (((*fsm).transition_logic)[15]).stimulus = SpeedDown; |
| 188 | + | (((*fsm).transition_logic)[3][2]).stimulus = SpeedUp; |
| 189 | - | (((*fsm).transition_logic)[15]).next_state = Walking; |
| 189 | + | (((*fsm).transition_logic)[3][2]).next_state = Error; |
| 190 | ||
| 191 | /* SPEEDDOWN STIMULUS */ | |
| 192 | (((*fsm).transition_logic)[3][3]).prev_state = Running; | |
| 193 | - | (((*fsm).transition_logic)[16]).prev_state = Error; |
| 193 | + | (((*fsm).transition_logic)[3][3]).stimulus = SpeedDown; |
| 194 | - | (((*fsm).transition_logic)[16]).stimulus = TurnOn; |
| 194 | + | (((*fsm).transition_logic)[3][3]).next_state = Walking; |
| 195 | - | (((*fsm).transition_logic)[16]).next_state = Error; |
| 195 | + | |
| 196 | /** ERROR STATE */ | |
| 197 | /* TURNON STIMULUS */ | |
| 198 | - | (((*fsm).transition_logic)[17]).prev_state = Error; |
| 198 | + | (((*fsm).transition_logic)[4][0]).prev_state = Error; |
| 199 | - | (((*fsm).transition_logic)[17]).stimulus = TurnOff; |
| 199 | + | (((*fsm).transition_logic)[4][0]).stimulus = TurnOn; |
| 200 | - | (((*fsm).transition_logic)[17]).next_state = Off; |
| 200 | + | (((*fsm).transition_logic)[4][0]).next_state = Error; |
| 201 | ||
| 202 | /* TURNOFF STIMULUS */ | |
| 203 | - | (((*fsm).transition_logic)[18]).prev_state = Error; |
| 203 | + | (((*fsm).transition_logic)[4][1]).prev_state = Error; |
| 204 | - | (((*fsm).transition_logic)[18]).stimulus = SpeedUp; |
| 204 | + | (((*fsm).transition_logic)[4][1]).stimulus = TurnOff; |
| 205 | - | (((*fsm).transition_logic)[18]).next_state = Error; |
| 205 | + | (((*fsm).transition_logic)[4][1]).next_state = Off; |
| 206 | ||
| 207 | /* SPEEDUP STIMULUS */ | |
| 208 | - | (((*fsm).transition_logic)[19]).prev_state = Error; |
| 208 | + | (((*fsm).transition_logic)[4][2]).prev_state = Error; |
| 209 | - | (((*fsm).transition_logic)[19]).stimulus = SpeedDown; |
| 209 | + | (((*fsm).transition_logic)[4][2]).stimulus = SpeedUp; |
| 210 | - | (((*fsm).transition_logic)[19]).next_state = Error; |
| 210 | + | (((*fsm).transition_logic)[4][2]).next_state = Error; |
| 211 | ||
| 212 | /* SPEEDDOWN STIMULUS */ | |
| 213 | (((*fsm).transition_logic)[4][3]).prev_state = Error; | |
| 214 | (((*fsm).transition_logic)[4][3]).stimulus = SpeedDown; | |
| 215 | (((*fsm).transition_logic)[4][3]).next_state = Error; | |
| 216 | ||
| 217 | } |