Revision 0e6831f5
Initial ported traffic navigation code.
scout/libscout/src/behaviors/trafficNavigation.cpp | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (c) 2011 Colony Project |
|
3 |
* |
|
4 |
* Permission is hereby granted, free of charge, to any person |
|
5 |
* obtaining a copy of this software and associated documentation |
|
6 |
* files (the "Software"), to deal in the Software without |
|
7 |
* restriction, including without limitation the rights to use, |
|
8 |
* copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
9 |
* copies of the Software, and to permit persons to whom the |
|
10 |
* Software is furnished to do so, subject to the following |
|
11 |
* conditions: |
|
12 |
* |
|
13 |
* The above copyright notice and this permission notice shall be |
|
14 |
* included in all copies or substantial portions of the Software. |
|
15 |
* |
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
17 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|
18 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
19 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
20 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|
21 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
22 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|
23 |
* OTHER DEALINGS IN THE SOFTWARE. |
|
24 |
*/ |
|
25 |
|
|
26 |
#include "trafficNavigation.h" |
|
27 |
#include "../linefollowing/lineDrive.h" |
|
28 |
|
|
29 |
#define DEBUG_INTERSECTION |
|
30 |
#ifdef MAIN_NEW |
|
31 |
|
|
32 |
#ifdef DEBUG_INTERSECTION |
|
33 |
#define DBG_USBS(str) usb_puts(str) |
|
34 |
#define DBG_USBI(x) usb_puti(x) |
|
35 |
#else |
|
36 |
#define DBG_USBS(str) |
|
37 |
#define DBG_USBI(x) |
|
38 |
#endif |
|
39 |
|
|
40 |
static int state, sign, turnDir; |
|
41 |
static char sendBuffer[PACKET_LENGTH], queuePrevBot, queueNextBot, id, nextDir, nextPath, intersectionNum, resolvPrevBotID = -3; |
|
42 |
unsigned char resolvSeed = 0xC9, resolvDraw = 0, resolvPrevBotDraw = 0; |
|
43 |
bool done; |
|
44 |
|
|
45 |
|
|
46 |
//TODO: classes for lineDrive::doDrive and other functions in line_drive.h, clock functions, sending/receiving packets, encoder data, initializations, get ids, etc. |
|
47 |
void trafficNavigation::run() |
|
48 |
{ |
|
49 |
|
|
50 |
/* Initialize the dragonfly boards, the xbee, encoders, lineFollowing */ |
|
51 |
|
|
52 |
id = get_robotid(); |
|
53 |
sign = 0; |
|
54 |
delay_ms(500); |
|
55 |
|
|
56 |
//Test code |
|
57 |
state = SROAD; |
|
58 |
|
|
59 |
sendBuffer[1] = id; |
|
60 |
|
|
61 |
|
|
62 |
while (ok()) { |
|
63 |
/*DTN Finite State Machine*/ |
|
64 |
switch(state){ |
|
65 |
case SROAD:/*Following a normal road*/ |
|
66 |
start(); |
|
67 |
done = false; |
|
68 |
|
|
69 |
//finishes when reads a barcode: TODO: how do we detect intersections now? |
|
70 |
while(!done){ |
|
71 |
sign = lineDrive::doDrive(180); |
|
72 |
switch(sign){ |
|
73 |
case NORMAL: |
|
74 |
case FINISHED: |
|
75 |
case LOST: |
|
76 |
case ERROR: |
|
77 |
break; |
|
78 |
default: |
|
79 |
//we have a barcode! |
|
80 |
state = SINTERSECTION_ENTER; |
|
81 |
DBG_USBS("Read Barcode #:"); |
|
82 |
DBG_USBI(sign); |
|
83 |
DBG_USBS("\n"); |
|
84 |
done = true; |
|
85 |
break; |
|
86 |
|
|
87 |
} |
|
88 |
} |
|
89 |
break; |
|
90 |
case SINTERSECTION_ENTER:/*Entering, and in intersection*/ |
|
91 |
stop(); |
|
92 |
lineDrive::doDrive(0); |
|
93 |
|
|
94 |
DBG_USBS("STATE: SINTERSECTION_ENTER\n"); |
|
95 |
|
|
96 |
/*Intersection queue: |
|
97 |
*Each robot when entering the intersection will check for other robots |
|
98 |
*in the intersection, and insert itself in a queue to go through. |
|
99 |
*/ |
|
100 |
queuePrevBot = -1; //the bot that will drive before this bot |
|
101 |
queueNextBot = -1; //the bot that will drive after this bot |
|
102 |
resolvPrevBotID = -3; //in the case of a race, the bot that is |
|
103 |
//to enter the queue before this bot |
|
104 |
resolvPrevBotDraw = 0; //the random priority number that bot has |
|
105 |
resolvDraw = 0; //my random priority number |
|
106 |
|
|
107 |
intersectionNum = getIntersectNum(sign); |
|
108 |
if(intersectionNum == (char) -1){ //invalid |
|
109 |
state = SROAD; |
|
110 |
DBG_USBS("Barcode has invalid intersectionNum\n"); |
|
111 |
break; |
|
112 |
} |
|
113 |
turnDir = validateTurn(sign, getTurnType(sign)); |
|
114 |
if(turnDir == (char) -1){ //invalid |
|
115 |
state = SROAD; |
|
116 |
DBG_USBS("Barcode has invalid turn\n"); |
|
117 |
break; |
|
118 |
} |
|
119 |
|
|
120 |
trafficNavigation::enterIntersection(); //sends wireless packet for entry |
|
121 |
state = SINTERSECTION_WAIT; |
|
122 |
|
|
123 |
rtc_reset(); //reset rtc for timeout wait for reply |
|
124 |
done = false; |
|
125 |
char retried = 0; |
|
126 |
while(rtc_get() < 8 && !done){//waits for a reply, otherwise assumes it is first in queue |
|
127 |
int ret = wirelessPacketHandle(SINTERSECTION_ENTER); |
|
128 |
if(rtc_get() > 6 && !retried){//by now all resolvs should be done from bots that arrived earlier... |
|
129 |
trafficNavigation::enterIntersection(); |
|
130 |
retried = 1; |
|
131 |
} |
|
132 |
switch (ret) { |
|
133 |
case KPLACEDINQUEUE: |
|
134 |
done = true; |
|
135 |
break; |
|
136 |
case KFAILEDTOQUEUE: |
|
137 |
DBG_USBS("Failed to queue\n"); |
|
138 |
trafficNavigation::enterIntersection(); |
|
139 |
rtc_reset(); |
|
140 |
break; |
|
141 |
case KRESOLVINGENTER: |
|
142 |
state = SINTERSECTION_ENTER_RESOLV; |
|
143 |
done = true; |
|
144 |
break; |
|
145 |
} |
|
146 |
} |
|
147 |
break; |
|
148 |
|
|
149 |
case SINTERSECTION_ENTER_RESOLV: |
|
150 |
DBG_USBS("STATE: SINTERSECTION_ENTER_RESOLV\n"); |
|
151 |
|
|
152 |
rtc_reset(); |
|
153 |
done = false; |
|
154 |
retried = 0; |
|
155 |
while(rtc_get() < 4 && !done){ |
|
156 |
int ret = wirelessPacketHandle(SINTERSECTION_ENTER_RESOLV); |
|
157 |
switch (ret) { |
|
158 |
case KRESOLVINGENTER: |
|
159 |
break; |
|
160 |
case KPLACEDINQUEUE: |
|
161 |
done = true; |
|
162 |
break; |
|
163 |
case KFAILEDTOQUEUE: |
|
164 |
DBG_USBS("Failed to queue\n"); |
|
165 |
trafficNavigation::enterIntersection(); |
|
166 |
rtc_reset(); |
|
167 |
break; |
|
168 |
} |
|
169 |
//if resolvPrevBotID == -1, this indicates that |
|
170 |
//there was a prevbot before, but it has entered |
|
171 |
//the queue so it's our turn. |
|
172 |
if(!done && resolvPrevBotID == (char) -1 && !retried){ |
|
173 |
trafficNavigation::enterIntersection(); |
|
174 |
rtc_reset(); |
|
175 |
retried = 1; |
|
176 |
//if resolvPrevBotID == -2, we have been |
|
177 |
//resolving but never have seen a bot with lower |
|
178 |
//priority than us. after the 6/16ths sec |
|
179 |
//timeout, assume we are first. |
|
180 |
} else if(!done && resolvPrevBotID == (char) -2 && rtc_get() > 2){ |
|
181 |
//send a intersection reply to myself to |
|
182 |
//trigger other bots to enter queue. |
|
183 |
sendBuffer[0] = WINTERSECTIONREPLY; |
|
184 |
sendBuffer[2] = intersectionNum; |
|
185 |
sendBuffer[3] = id; |
|
186 |
wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH); |
|
187 |
|
|
188 |
done = true; |
|
189 |
break; |
|
190 |
} |
|
191 |
} |
|
192 |
state = SINTERSECTION_WAIT; |
|
193 |
break; |
|
194 |
case SINTERSECTION_WAIT:/*Waiting in intersection */ |
|
195 |
|
|
196 |
|
|
197 |
DBG_USBS("STATE: SINTERSECTION_WAIT\n"); |
|
198 |
|
|
199 |
done = false; |
|
200 |
while(queuePrevBot != (char) -1){ |
|
201 |
done = true; |
|
202 |
int ret = wirelessPacketHandle(state); |
|
203 |
if (ret==KFIRSTINQUEUE) state = SINTERSECTION_DRIVE; |
|
204 |
} |
|
205 |
//hack to make sure bot that just left intersection is |
|
206 |
//really out of the intersection. |
|
207 |
rtc_reset(); |
|
208 |
while(rtc_get() < 2 && done){//wait one second |
|
209 |
wirelessPacketHandle(state); |
|
210 |
} |
|
211 |
|
|
212 |
state = SINTERSECTION_DRIVE; |
|
213 |
break; |
|
214 |
case SINTERSECTION_DRIVE: |
|
215 |
DBG_USBS("STATE: SINTERSECTION_DRIVE\n"); |
|
216 |
start(); |
|
217 |
turn(getIntersectType(sign), turnDir); |
|
218 |
|
|
219 |
|
|
220 |
//Exits intersection |
|
221 |
sendBuffer[0] = WINTERSECTIONEXIT; |
|
222 |
sendBuffer[2] = intersectionNum;//Intersection # |
|
223 |
wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH); |
|
224 |
|
|
225 |
state = SROAD; |
|
226 |
break; |
|
227 |
default: |
|
228 |
DBG_USBS("I got stuck in an unknown state (Likely highway) My state is "); |
|
229 |
DBG_USBI(state); |
|
230 |
} |
|
231 |
} |
|
232 |
} |
|
233 |
|
|
234 |
int trafficNavigation::wirelessPacketHandle(int state){ |
|
235 |
int dataLength = 0; |
|
236 |
unsigned char *packet = NULL; |
|
237 |
packet = wl_basic_do_default(&dataLength); |
|
238 |
|
|
239 |
/* sanity check */ |
|
240 |
if(dataLength == 0 || packet == NULL) //no packet |
|
241 |
return ENOPACKET; |
|
242 |
|
|
243 |
if(dataLength != PACKET_LENGTH) |
|
244 |
return EPACKETLEN; |
|
245 |
|
|
246 |
DBG_USBS("Recieved Wireless Packet: "); |
|
247 |
for(int i = 0; i < dataLength; i++){ |
|
248 |
DBG_USBI(packet[i]); |
|
249 |
DBG_USBS(" "); |
|
250 |
} |
|
251 |
DBG_USBS("\n"); |
|
252 |
|
|
253 |
switch (packet[0]){ |
|
254 |
case WROADENTRY: //[type, bot, road] |
|
255 |
return ENOACTION; |
|
256 |
break; |
|
257 |
case WROADEXIT: //[type, bot, road] |
|
258 |
return ENOACTION; |
|
259 |
break; |
|
260 |
case WROADSTOP: //[type, bot, road] |
|
261 |
return ENOACTION; |
|
262 |
break; |
|
263 |
case WINTERSECTIONENTRY: //[type, bot, intersection, fromDir, toDir] |
|
264 |
if (packet[2] == intersectionNum){ |
|
265 |
switch (state){ |
|
266 |
case SINTERSECTION_ENTER: |
|
267 |
trafficNavigation::sendResolv(false); |
|
268 |
resolvPrevBotID = -2; |
|
269 |
return KRESOLVINGENTER; |
|
270 |
break; |
|
271 |
case SINTERSECTION_ENTER_RESOLV: |
|
272 |
return ENOACTION; |
|
273 |
case SINTERSECTION_WAIT: |
|
274 |
case SINTERSECTION_DRIVE: |
|
275 |
if(queueNextBot == (char) -1){ |
|
276 |
sendBuffer[0] = WINTERSECTIONREPLY; |
|
277 |
sendBuffer[2] = intersectionNum; |
|
278 |
sendBuffer[3] = packet[1]; |
|
279 |
wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH); |
|
280 |
queueNextBot = packet[1]; |
|
281 |
return KREPLIEDTOENTER; |
|
282 |
} |
|
283 |
break; |
|
284 |
|
|
285 |
} |
|
286 |
} |
|
287 |
break; |
|
288 |
case WINTERSECTIONREPLY: //[type, fromBot, intersection, toBot] |
|
289 |
if (packet[2] == intersectionNum){ |
|
290 |
switch (state){ |
|
291 |
case SINTERSECTION_ENTER: |
|
292 |
case SINTERSECTION_ENTER_RESOLV: |
|
293 |
if(packet[3] == id){ //Reply for me |
|
294 |
queuePrevBot = packet[1]; |
|
295 |
return KPLACEDINQUEUE; |
|
296 |
} else { |
|
297 |
if(packet[3] == resolvPrevBotID) |
|
298 |
resolvPrevBotID = -1; |
|
299 |
return KFAILEDTOQUEUE; |
|
300 |
} |
|
301 |
break; |
|
302 |
default: |
|
303 |
return ENOACTION; |
|
304 |
} |
|
305 |
} |
|
306 |
break; |
|
307 |
case WINTERSECTIONEXIT: //[type, bot, intersection] |
|
308 |
if (packet[2] == intersectionNum){ |
|
309 |
switch (state){ |
|
310 |
case SINTERSECTION_WAIT: |
|
311 |
if(packet[1]==queuePrevBot){ |
|
312 |
queuePrevBot=-1; |
|
313 |
return KFIRSTINQUEUE; |
|
314 |
} |
|
315 |
} |
|
316 |
} |
|
317 |
break; |
|
318 |
case WINTERSECTIONGO: //[type, bot, intersection] |
|
319 |
break; |
|
320 |
case WINTERSECTIONPOLICEENTRY: //[?] |
|
321 |
return ENOACTION; |
|
322 |
break; |
|
323 |
case WINTERSECTIONRESOLVERACE: //[type, bot, intersection, num] |
|
324 |
//in the case robots draw the same number these will be |
|
325 |
//arbitrated using the sending robot's id, prefering |
|
326 |
//lower ids |
|
327 |
DBG_USBS("Now in wireless WINTERSECTIONRESOLVERACE handler: resolvPrevBotID: "); |
|
328 |
DBG_USBI((int) resolvPrevBotID); |
|
329 |
DBG_USBS("\n"); |
|
330 |
if (packet[2] == intersectionNum){ |
|
331 |
switch (state){ |
|
332 |
case SINTERSECTION_ENTER: |
|
333 |
case SINTERSECTION_ENTER_RESOLV: |
|
334 |
if(resolvPrevBotID == (char) -3){ |
|
335 |
DBG_USBS("resolvPrevBotID == -3; sending a resolv packet and setting to -2\n"); |
|
336 |
trafficNavigation::sendResolv(false); |
|
337 |
resolvPrevBotID = -2; |
|
338 |
} |
|
339 |
if((unsigned char) packet[3] == resolvDraw && id > packet[1]){ |
|
340 |
//other bot drew same number as me, |
|
341 |
//and i have a higher id, so it goes first. |
|
342 |
DBG_USBS("bot "); |
|
343 |
DBG_USBI(packet[1]); |
|
344 |
DBG_USBS(" Drew the same number as me and I have a higher id, so it goes first\n"); |
|
345 |
resolvPrevBotID = packet[1]; |
|
346 |
} else if((unsigned char) packet[3] == resolvPrevBotDraw && resolvPrevBotID > packet[1]){ |
|
347 |
//other bot drew same number as the bot before me, |
|
348 |
//so if it has a higher id than the bot before me, |
|
349 |
//it is going to go in between that one and me. |
|
350 |
DBG_USBS("bot "); |
|
351 |
DBG_USBI(packet[1]); |
|
352 |
DBG_USBS(" Drew the same number as the bot before me, and the bot before me has have a higher id, so this goes first\n"); |
|
353 |
resolvPrevBotID = packet[1]; |
|
354 |
} else if((unsigned char)packet[3] < resolvDraw && (unsigned char)packet[3] > resolvPrevBotDraw){ |
|
355 |
//found a bot that goes in between the bot before me |
|
356 |
//and me, so now it is before me. |
|
357 |
DBG_USBS("bot "); |
|
358 |
DBG_USBI(packet[1]); |
|
359 |
DBG_USBS(" Drew a lower number bot before me, and the bot before me has have a higher id, so this goes first\n"); |
|
360 |
resolvPrevBotDraw = packet[3]; |
|
361 |
resolvPrevBotID = packet[1]; |
|
362 |
} |
|
363 |
return KRESOLVINGENTER; |
|
364 |
break; |
|
365 |
case SINTERSECTION_WAIT: |
|
366 |
case SINTERSECTION_DRIVE: |
|
367 |
DBG_USBS("Trying to resolv in non resolv case...queueNextbot = "); DBG_USBI(queueNextBot); DBG_USBS("\n"); |
|
368 |
if(queueNextBot == (char) -1){ |
|
369 |
trafficNavigation::sendResolv(true); |
|
370 |
} |
|
371 |
return KRESOLVINGENTER; |
|
372 |
break; |
|
373 |
} |
|
374 |
|
|
375 |
} |
|
376 |
break; |
|
377 |
case WHIGHWAYENTRY: //[type, bot, highway] |
|
378 |
return ENOACTION; |
|
379 |
break; |
|
380 |
case WHIGHWAYREPLY: //[type, fromBot, highway, toBot] |
|
381 |
return ENOACTION; |
|
382 |
break; |
|
383 |
case WHIGHWAYEXIT: //[type, bot, highway] |
|
384 |
return ENOACTION; |
|
385 |
break; |
|
386 |
case WPINGGLOBAL: //[type, bot] |
|
387 |
return ENOACTION; |
|
388 |
break; |
|
389 |
case WPINGBOT: //[type, fromBot, toBot] |
|
390 |
return ENOACTION; |
|
391 |
break; |
|
392 |
case WPINGQUEUE: //[type, fromBot, toBot] |
|
393 |
return ENOACTION; |
|
394 |
break; |
|
395 |
case WPINGREPLY: //[type, fromBot, toBot] |
|
396 |
return ENOACTION; |
|
397 |
break; |
|
398 |
case WCOLLISIONAVOID: //[type, bot, intersection, collision-int] //Note: collision is an int and thus takes two spaces |
|
399 |
return ENOACTION; |
|
400 |
break; |
|
401 |
default: |
|
402 |
return ENOACTION; |
|
403 |
break; |
|
404 |
} |
|
405 |
} |
|
406 |
|
|
407 |
unsigned char trafficNavigation::resolvRandomNumberGen(){ |
|
408 |
if ((resolvSeed *= (rtc_get() + encoder_read(LEFT))%9) == 0){ |
|
409 |
return resolvSeed + 1; //0 is a reseved priority value for the last |
|
410 |
//bot that is already in the queue. |
|
411 |
} |
|
412 |
return resolvSeed; |
|
413 |
} |
|
414 |
void trafficNavigation::sendResolv(bool override){ |
|
415 |
if(!override) |
|
416 |
resolvDraw = trafficNavigation::resolvRandomNumberGen(); |
|
417 |
else |
|
418 |
resolvDraw = 0; |
|
419 |
sendBuffer[0] = WINTERSECTIONRESOLVERACE; |
|
420 |
sendBuffer[2] = intersectionNum; |
|
421 |
sendBuffer[3] = resolvDraw; |
|
422 |
wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH); |
|
423 |
} |
|
424 |
void trafficNavigation::enterIntersection(void){ |
|
425 |
//Sends packet announcing its entry to the intersection |
|
426 |
sendBuffer[0] = WINTERSECTIONENTRY; |
|
427 |
sendBuffer[2] = intersectionNum;//Intersection # |
|
428 |
sendBuffer[3] = 0; //getIntersectPos(sign); |
|
429 |
sendBuffer[4] = turnDir; |
|
430 |
wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH); |
|
431 |
} |
scout/libscout/src/behaviors/trafficNavigation.h | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (c) 2011 Colony Project |
|
3 |
* |
|
4 |
* Permission is hereby granted, free of charge, to any person |
|
5 |
* obtaining a copy of this software and associated documentation |
|
6 |
* files (the "Software"), to deal in the Software without |
|
7 |
* restriction, including without limitation the rights to use, |
|
8 |
* copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
9 |
* copies of the Software, and to permit persons to whom the |
|
10 |
* Software is furnished to do so, subject to the following |
|
11 |
* conditions: |
|
12 |
* |
|
13 |
* The above copyright notice and this permission notice shall be |
|
14 |
* included in all copies or substantial portions of the Software. |
|
15 |
* |
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
17 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|
18 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
19 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
20 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|
21 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
22 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|
23 |
* OTHER DEALINGS IN THE SOFTWARE. |
|
24 |
*/ |
|
25 |
|
|
26 |
#ifndef _trafficNavigation_H_ |
|
27 |
#define _trafficNavigation_H_ |
|
28 |
|
|
29 |
#include "../Behavior.h" |
|
30 |
|
|
31 |
//from old trafficNavigation.h |
|
32 |
#ifndef trafficNavigation_H |
|
33 |
|
|
34 |
/* Debug Options - These must go before includes */ |
|
35 |
#define MAIN_NEW |
|
36 |
//#define SENDGRAPH |
|
37 |
|
|
38 |
#include <dragonfly_lib.h> |
|
39 |
#include <wl_basic.h> |
|
40 |
#include "../linefollowing/lineDrive.h" |
|
41 |
#include "highways.h" |
|
42 |
#include "intersectData.h" |
|
43 |
#include "validTurns.h" |
|
44 |
|
|
45 |
/*States*/ |
|
46 |
#define SROAD 0 |
|
47 |
#define SINTERSECTION 9 /* for old version */ |
|
48 |
#define SINTERSECTION_ENTER 10 |
|
49 |
#define SINTERSECTION_ENTER_RESOLV 11 |
|
50 |
#define SINTERSECTION_WAIT 12 |
|
51 |
#define SINTERSECTION_DRIVE 13 |
|
52 |
#define SHIGHWAY 20 |
|
53 |
#define SCLEARPACKET 30 |
|
54 |
|
|
55 |
/*Sign Codes |
|
56 |
* bitwise OR labels to create a barcode or read one |
|
57 |
* There should be macros to extract these probably |
|
58 |
* The bits will be stored in some variable (char or short) |
|
59 |
* Bits if road: ? ? ? NAME NAME NAME TYPE CROAD |
|
60 |
* Bits if intersection: ? ? ? ? DIR DIR #WAYS CINTERSECTION |
|
61 |
*/ |
|
62 |
#define CROAD 0x0 //0b |
|
63 |
#define CINTERSECTION 0x1 //1b |
|
64 |
#define CNORMALROAD 0x0 //00b |
|
65 |
#define CHIGHWAYROAD 0x2 //10b |
|
66 |
#define C4WAY 0x0 //00b |
|
67 |
#define C3WAY 0x2 //10b |
|
68 |
#define CNORTH 0x0 //0000b |
|
69 |
#define CEAST 0x4 //0100b |
|
70 |
#define CSOUTH 0x8 //1000b |
|
71 |
#define CWEST 0x12 //1100b |
|
72 |
|
|
73 |
/*Wireless Packet Types |
|
74 |
* The first byte of any wireless packet should be one of these types. |
|
75 |
* Each type will have its own structure |
|
76 |
* The second byte should be the id of the bot sending the packet |
|
77 |
* The third byte should be the number of the intersection or road that |
|
78 |
* the packet pertains to |
|
79 |
*/ |
|
80 |
#define PACKET_LENGTH 5 |
|
81 |
#define WROADENTRY 0 //[type, bot, road] |
|
82 |
#define WROADREPLY 1 //[type, fromBot, road, toBot] |
|
83 |
#define WROADEXIT 2 //[type, bot, road] |
|
84 |
#define WROADSTOP 3 //[type, bot, road] |
|
85 |
#define WINTERSECTIONENTRY 10 //[type, bot, intersection, fromDir, toDir] |
|
86 |
#define WINTERSECTIONREPLY 11 //[type, fromBot, intersection, toBot] |
|
87 |
#define WINTERSECTIONEXIT 12 //[type, bot, intersection] |
|
88 |
#define WINTERSECTIONGO 13 //[type, bot, intersection] |
|
89 |
#define WINTERSECTIONPOLICEENTRY 14 |
|
90 |
#define WINTERSECTIONRESOLVERACE 15 //[type, bot, intersection, num] |
|
91 |
#define WHIGHWAYENTRY 20 //[type, bot, highway] |
|
92 |
#define WHIGHWAYREPLY 21 //[type, fromBot, highway, toBot] |
|
93 |
#define WHIGHWAYEXIT 22 //[type, bot, highway] |
|
94 |
#define WPINGGLOBAL 30 //[type, bot] |
|
95 |
#define WPINGBOT 31 //[type, fromBot, toBot] |
|
96 |
#define WPINGQUEUE 32 //[type, fromBot, toBot] |
|
97 |
#define WPINGREPLY 33 //[type, fromBot, toBot] |
|
98 |
#define WCOLLISIONAVOID 41 //[type, bot, intersection, collision-int] //Note: collision is an int and thus takes two spaces |
|
99 |
#define WGRAPHDATA 80 |
|
100 |
|
|
101 |
/*Wireless Parsing Status |
|
102 |
* For wireless parsing - status codes describing various errors/statuses with wireless |
|
103 |
* parsing. |
|
104 |
* Errors begin with E - Note that all of these errors are actually returned as negative. |
|
105 |
* - values of >= 100 indicate a serious error |
|
106 |
* Non-Errors begin with K - returned as positive. (don't start with S because S |
|
107 |
* is for state) |
|
108 |
*/ |
|
109 |
#define ENOPACKET -10 //The received packet doesn't exist. |
|
110 |
#define ENOACTION -15 //The received packet has no defined action, and this is OK |
|
111 |
#define ENOIMPLEMENT -20 //The received packet has no defined action and needs to be implemented. |
|
112 |
#define EPACKETLEN -100 //The received packet was the wrong length |
|
113 |
#define KOK 1 |
|
114 |
#define KPLACEDINQUEUE 20 |
|
115 |
#define KFAILEDTOQUEUE 21 |
|
116 |
#define KFIRSTINQUEUE 22 |
|
117 |
#define KREPLIEDTOENTER 23 |
|
118 |
#define KRESOLVINGENTER 24 //resolving a race between bots trying to enter intersection at the same time. |
|
119 |
|
|
120 |
/*Macros |
|
121 |
*/ |
|
122 |
#define ISPING(p) ((p)[0]==WPINGGLOBAL || (p)[0]==WPINGBOT || (p)[0]==WPINGQUEUE) |
|
123 |
|
|
124 |
#endif |
|
125 |
// |
|
126 |
|
|
127 |
#ifdef DEBUG_INTERSECTION |
|
128 |
#define DBG_USBS(str) usb_puts(str) |
|
129 |
#define DBG_USBI(x) usb_puti(x) |
|
130 |
#else |
|
131 |
#define DBG_USBS(str) |
|
132 |
#define DBG_USBI(x) |
|
133 |
#endif |
|
134 |
|
|
135 |
|
|
136 |
class trafficNavigation : Behavior |
|
137 |
{ |
|
138 |
public: |
|
139 |
trafficNavigation(std::string scoutname) : Behavior(scoutname) {}; |
|
140 |
|
|
141 |
void run(); |
|
142 |
int wirelessPacketHandle(int state); |
|
143 |
void enterIntersection(void); |
|
144 |
void sendResolv(bool override); |
|
145 |
unsigned char resolvRandomNumberGen(); |
|
146 |
}; |
|
147 |
|
|
148 |
#endif |
Also available in: Unified diff