Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / traffic_navigation / collision_avoid.c @ 2010

History | View | Annotate | Download (6.91 KB)

1 1893 azl
/* TODO:
2
 *  - Document how to call functions.
3
 *  - Actually Test this stuff. Especially the intersection rotating thing. and the parts marked sketchy.
4
 *  - Integrate into main.c
5
 *  - In the intersection queue in main.c, allow bots to skip each other (since this code allows it).
6 1938 azl
 *    (because some bot at another intersection entrance may be able to go before another bot at another
7
 *    intersection entrance, but their order in the queue may not allow this.).
8 1894 azl
*/
9 1966 alevkoy
10 1892 azl
#include "collision_avoid.h"
11
#include "traffic_navigation.h"
12 1966 alevkoy
#include "../linefollowing/lineDrive.h"
13
14 1892 azl
static unsigned int my_path = 0;
15 1894 azl
static unsigned int first_hop = 0;
16 1892 azl
static char intersection = 0;
17
18
/*           Dir0
19
 *         [0 ][4 ]
20 1894 azl
 *Dir1  [5][8 ][9 ][3]   Dir3
21
 *      [1][11][10][7]
22
 *         [6 ][2 ]
23
 *           Dir2
24 1895 azl
 *
25
 *            Dir0
26
 *          [D0E][D0X]
27
 *Dir1  [D1X][I0][I1][D3E]   Dir3
28
 *      [D1E][12][13][D3X]
29
 *          [D2X][D2E]
30
 *            Dir2
31 1894 azl
 */
32 1897 azl
33
/* Upon entering an intersection, this function should be called. To achieve
34
 * nonstop motion when possible, it is preferable to call this right after
35
 * reading the barcode.
36
 *
37
 * This function sets up the "my_path" variable with the proper bits representing
38
 * the path that the bot will travel in the intersection.
39
 *
40
 * char intersectionNum: The # of the intersection
41
 * char fromDir: The direction the bot is entering the intersection
42
 * char nextDir: The direction the bot is exiting the intersection
43
 */
44 1892 azl
void ca_EnterIntersection(char intersectionNum, char fromDir, char nextDir){
45
        /* Generic turn model condenses all turns into either:
46
         * - a right turn from dir0 to dir1
47
         * - a straight from dir0 to dir2
48
         * - a left turn dir0 to dir3
49
         * - maybe a U-turn from dir0 to dir0 **UNIMPLEMENTED*
50
         */
51
        /* Fill in dir0 */
52
        my_path = 0;
53 1898 azl
        my_path = my_path | D0E;
54
        my_path = my_path | I0;
55 1892 azl
        char genericNext = nextDir-fromDir;
56 1938 azl
        if(genericNext < 0){
57
                genericNext += 4;
58
        }
59 1892 azl
        if(genericNext == 1){ //right turn
60
#ifdef DEBUG_CA
61
                usb_puts("CA: Setting up Generic Right Turn\n");
62
#endif
63 1898 azl
                my_path = my_path | D1X;
64 1892 azl
        }
65
        else if(genericNext == 2){ //straight turn
66
#ifdef DEBUG_CA
67
                usb_puts("CA: Setting up Generic Straight Turn\n");
68
#endif
69 1898 azl
                my_path = my_path | D2X;
70
                my_path = my_path | I2;
71 1892 azl
        }
72
        else{ //left turn
73
#ifdef DEBUG_CA
74
                if(genericNext != 3)
75
                        usb_puts("CA ERROR: Error in generic turn generator (CA_E0)\n");
76
                usb_puts("CA: Setting up Generic Left Turn\n");
77
#endif
78 1898 azl
                my_path = my_path | D3X;
79
                my_path = my_path | I2;
80
                my_path = my_path | I3;
81 1892 azl
82
        }
83
        //now rotate turn to match what it's really supposed to be
84
        for(int i = 0; i < fromDir; i++){
85
                int new_path = 0;
86
                char temp = my_path & DAE;
87 1895 azl
                char shiftoff = temp & 0x8;
88
                temp = temp << 1;
89
                temp = temp | (shiftoff >> 3);
90 1898 azl
                new_path = new_path | temp;
91 1892 azl
92 1898 azl
                temp = (my_path & DAX) >> DAXS;
93
                shiftoff = temp & 0x1;
94 1895 azl
                temp = temp << 1;
95
                temp = temp | (shiftoff >> 3);
96 1898 azl
                new_path = new_path | (temp << DAXS);
97 1892 azl
98 1898 azl
                temp = (my_path & DAX) >> IAS;
99
                shiftoff = temp & 0x1;
100 1895 azl
                temp = temp << 1;
101
                temp = temp | (shiftoff >> 3);
102 1898 azl
                new_path = new_path | (temp << IAS);
103
                my_path = new_path;
104 1895 azl
105 1892 azl
        }
106 1898 azl
        first_hop = fromDir;
107
        intersection = intersectionNum;
108 1892 azl
}
109 1897 azl
110
/* Call this function when the bot has left the intersection.
111
 *
112
 * All this function does is clear some variables. I guess
113
 * this is optional but it is nice for debugging. */
114 1966 alevkoy
void ca_ExitIntersection(void){
115 1898 azl
        my_path = 0;
116
        first_hop = -1;
117 1897 azl
        intersection = -1;
118 1892 azl
}
119 1897 azl
120
/* Don't call this function. This is strictly an internal function to this library.
121
 *
122
 * int path: Takes the path to be sent in the packet.
123
 *
124
 * This will send a collision avoidance packet with the bot id, the intersection # and path */
125
void ca_sendPacket(char id, int path){
126 1892 azl
        if(path & D0E && path & D1E && path & D2E && path & D3E){
127
#ifdef DEBUG_CA
128
                usb_puts("CA: No open entry ways to intersection, so not sending CA packet.");
129
#endif
130
                return;
131
        }
132
        char sendBuffer[PACKET_LENGTH];
133
        sendBuffer[0] = WCOLLISIONAVOID;
134
        sendBuffer[1] = id;
135
        sendBuffer[2] = intersection;
136 1938 azl
        sendBuffer[3] = path; /* sketchy because path is an int. so will it take both sendBuffer[3] and sendBuffer[4]? */
137 1892 azl
        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
138
}
139 1897 azl
140
/* Call this if the bot is the first in the queue for the intersection and wishes
141
 * to attempt collision avoidance.
142
 *
143
 * char id: the bot's id.
144
 *
145
 * What this does is send a collision avoidance packet with this bot's path.
146
 */
147 1892 azl
void ca_Initiator(char id){ //args: (This bot's ID)
148
#ifdef DEBUG_CA
149
        if(mypath == 0)
150
                usb_puts("CA ERROR: Someone Forgot to call ca_EnterIntersection. mypath == 0 (CA_E1)\n");
151
#endif
152 1897 azl
        ca_sendPacket(id, my_path);
153 1892 azl
}
154 1897 azl
155
/* Call this when the bot gets a collision avoidance packet that *MATCHES*
156 1938 azl
 * the intersection it is in and the id identifying the sender in the packet
157
 * matches the bot id that is in line in front. (so the collision avoidance
158
 * packet sent by the bot last in the queue gets no listener. This is expected.)
159
 * This function will return whether it is okay for
160 1897 azl
 * the bot to proceed into the intersection with a true or false.
161
 *
162
 * char id: the bot's id
163
 * char recieve[]: the wireless packet recieved.
164
 *
165
 * What this does is check if the path that the bot needs to travel is clear by
166
 * comparing my_path and the path in the packet.
167
 * If it is clear, the bot will add my_path to the path it got in the wireless
168 1938 azl
 * packet and then send it. Then the function will return true.
169 1897 azl
 * Otherwise, the bot will only fill in the entrance bit in the function it
170
 * recieved in the wireless packet to indicate it is sitting at the entrance
171
 * to the intersection so that bots behind it won't try to enter the intersection
172
 * and crash into the bot at the front of the line for that intersection.
173
 */
174 1892 azl
bool ca_Process(char id, char recieve[]){ //args: (This bot's ID, a pointer to the packet recieved)
175
        bool result = false;
176
#ifdef DEBUG_CA
177
        if(recieve[0] != WCOLLISIONAVOID)
178
                usb_puts("CA ERROR: You didn't call ca_Process with a WCOLLISIONAVOID type packet (CA_E2)\n");
179
        if(recieve[1] < 0)
180
                usb_puts("CA ERROR: Recieved Packet indicates sending bot has a negative ID. (CA_E3)\n");
181 1894 azl
        if(recieve[2] != intersection)
182
                usb_puts("CA ERROR: Recieved Packet's intersection doesn't match the intersection CA is operating on in this Bot.. (CA_E4)\n");
183 1892 azl
#endif
184 1938 azl
        if((*(recieve+3) & my_path) != 0){ /* Sketchy Code because recieve is made of chars and my_path is an int */
185 1892 azl
#ifdef DEBUG_CA
186
                usb_puts("CA: My Path is occupied through intersection ");
187
                usb_puti(intersection);
188
                usb_putc('\n');
189
#endif
190
                result = false;
191 1938 azl
                ca_sendPacket(id, 1 << first_hop | *(recieve+3)); /* Sketchy Code because recieve is made of chars and ca_send_packet expects an int. we need the whole int to make it through*/
192 1892 azl
        }
193
        else{
194
#ifdef DEBUG_CA
195
                usb_puts("CA: My Path is clear through intersection ");
196
                usb_puti(intersection);
197
                usb_putc('\n');
198
#endif
199
                result = true;
200 1938 azl
                ca_sendPacket(id, my_path | *(recieve+3)); /* Sketchy Code because recieve is made of chars and ca_send_packet expects an int.  we need the whole int to make it through. Also, my_path is an int.*/
201 1892 azl
        }
202
        return result;
203
}