-
Notifications
You must be signed in to change notification settings - Fork 0
/
FSM.ino
208 lines (195 loc) · 6.53 KB
/
FSM.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//http://www.arduino.cc/playground/uploads/Code/FSM_1-6.zip
#include <FiniteStateMachine.h>
State powerOnState = State(powerOnUpdate); //According to RobotChallenge rules
State idleRunState = State(idleRunUpdate);
State spinState = State(spinEnter, spinUpdate, NULL);
State lineAvoidState = State(lineAvoidEnter, lineAvoidUpdate, NULL);
//State attackState = State(attackEnter, attackUpdate, NULL);
//State overfallAvoidState = State(overfallAvoidEnter, overfallAvoidUpdate, NULL);
State stoppedState = State(stoppedSafe,stoppedUpdate, NULL); //According to RobotChallenge rules
FiniteStateMachine stateMachine = FiniteStateMachine(powerOnState);
/*POWER ON STATE*/
void powerOnEnter(){
// Serial.println("PowerOnState");
digitalWrite(LED, LOW);
}
void powerOnUpdate(){
}
/*STOPPED_SAFE STATE*/
void stoppedSafe(){
// Serial.println("StoppedState");
for(byte i=0; i<10; i++){
LED_FLASHING();
}
StateValue = POWERON;
EEPROMwrite();
}
/*STOPPED STATE*/
void stoppedUpdate(){
while(1){
LED_FLASHING();
}
}
/*IDLE RUN STATE*/
void idleRunUpdate(){
// Serial.println("idleRunUpdate");
//Conditions for transition to a Spin State
// if(sensorSum==1||sensorSum==3||sensorSum==8||sensorSum==12){
// stateMachine.transitionTo(spinState);
// }
//Conditions for transition to a Line Avoid State
if((sensorSum>=16 && sensorSum<=63)||(sensorSum>=80 && sensorSum<=127)||(sensorSum>=208 && sensorSum<=255)){
stateMachine.transitionTo(lineAvoidState);
}
//Conditions for transition to a Attack State
// if(sensorSum==2||sensorSum==4||sensorSum==6||sensorSum==7||sensorSum==14){
// stateMachine.transitionTo(attackState);
// }
//Conditions for transition to a Overfall Avoid State
// if((sensorSum>=64 && sensorSum<=79)||(sensorSum>=128 && sensorSum<=143)||(sensorSum>=192 && sensorSum<=207)){
// stateMachine.transitionTo(overfallAvoidState);
// }
}
/*LINE AVOID STATE*/
void lineAvoidEnter(){
// Serial.println("LineAvoid");
//Trim other sensoric values
switch(sensorSum & 48){
case 16: //Set mask for Left Line sensor
sensorMask=!16;
//Remember the Left Line sensor, to track the position
lastLineSensor=Left;
//Set timer
timer=500;
SetSpeed(10, -5);
break;
case 32: //Set mask for Right Line sensor
sensorMask=!32;
//Remember the Right Line sensor, to track the position
lastLineSensor=Right;
//Set timer
timer=500;
SetSpeed(-5, 10);
break;
case 48: //Set mask for Both Line sensors
sensorMask=!48;
// Set timer for 600ms
timer=1000;
SetSpeed(-10, -10);
break;
}
//Reset timer
TimeOld=millis();
}
void lineAvoidUpdate(){
//Check on other active sensor or timeout
if(sensorSum & sensorMask > 0 || millis()-TimeOld >=timer*8){
//If no sensor activated
if(sensorSum & sensorMask==0 && sensorMask==!48 && millis()-TimeOld>=timer*8){
//Find out which was the last
switch(lastLineSensor){
case Left: //Set diferential motor speed to 25%
SetSpeed(+25, -25); break;
case Right://Set diferential motor speed to 25%
SetSpeed(-25, +25); break;
}
//Transit to Spin State to make 180 degrees spin
stateMachine.immediateTransitionTo(spinState);
}
//Find out which was the last
switch(lastLineSensor){
case Left: //Set diferential motor speed to 25%
SetSpeed(+30, +15); break;
case Right://Set diferential motor speed to 25%
SetSpeed(+15, +30); break;
}
//Transit to Idle Run State
stateMachine.immediateTransitionTo(idleRunState);
}
}
/*SPIN STATE*/
void spinEnter(){
//Trim other sensoric values
switch(sensorSum & 9){
case 1: //Set mask for SHARP_SL sensor
sensorMask=!(sensorSum & 1);
// Set timer for 600ms
timer=600;
// Set diferential motor speed to 25%
SetSpeed(-25, +25); break;
case 8: sensorMask=!(sensorSum & 8);
// Set timer for 600ms
timer=600;
// Set diferential motor speed to 25%
SetSpeed(+25, -25); break; //Set timer for 1000ms and both motor cross reverse speed to 50
}
//Reset timer
TimeOld=millis();
}
void spinUpdate(){
//Read the sensor byte value
SensorSum();
//Check on other active sensor or timeout
if(sensorSum & sensorMask > 0 || millis()-TimeOld >=timer*8){
//Transit to Idle Run State to make another decition
stateMachine.immediateTransitionTo(idleRunState);
}
}
/*ATTACK STATE*/
void attackEnter(){
//Trim other sensoric values
switch(sensorSum & 6){
case 2: //Set mask for SHARP front left sensor
sensorMask=!13;
//Remember the left front sensor, to track the opponent
lastFrontSensor=Left;
//Set motor differential speed forward 20/30%
SetSpeed(+20, +30); break;
case 4: //Set mask for SHARP front right sensor
sensorMask=!11;
//Remember the right front sensor, to track the opponent
lastFrontSensor=Right;
//Set motor differential speed forward 30/20%
SetSpeed(+30, +20); break;
//No need memory for this condition
//Impossible to disappear at the same time for both sensors
case 6: //Set mask for SHARP Front both sensors
sensorMask=!15;
//Set both motor speed forward 30%
SetSpeed(+30, +30); break;
}
}
void attackUpdate(){
//Read the sensor byte value
SensorSum();
//Prevent target lost
if(sensorSum == 0){
// Set timer for 300ms
timer=300;
//Recall the last Front sensor from the memory
switch(lastFrontSensor){
case Left: //Set left motor speed reverse 30%
SetSpeed(-30, 0); break;
case Right://Set right motor speed reverse 30%
SetSpeed(0, -30); break;
}
//Transit to Spin State to detect opponent again
stateMachine.immediateTransitionTo(spinState);
}
//Check calibration
if(sensorSum & sensorMask>0){
//Transit to Idle Run State to make another decition
stateMachine.immediateTransitionTo(idleRunState);
}
//Check if one of front sensors deactivated
if(sensorMask==!15 && sensorSum & 6 <6){
//Transit to Idle Run State to make another decition
stateMachine.immediateTransitionTo(idleRunState);
}
}
void overfallAvoidEnter(){
}
void overfallAvoidUpdate(){
}
void overfallAvoidExit(){
}