Project

General

Profile

Statistics
| Revision:

root / branches / autonomous_recharging / code / projects / autonomous_recharging / dragonfly / wl_recharge_group.c @ 100

History | View | Annotate | Download (10.7 KB)

1
#include "wl_recharge_group.h"
2

    
3
#include <wireless.h>
4
#include <wl_defs.h>
5
#include <stdio.h>
6
#include <string.h>
7

    
8

    
9
// Function prototypes
10
void wl_recharge_timeout_handler(void);
11
void wl_recharge_response_handler(int frame, int received);
12
void wl_recharge_handle_receive(char type, int source, unsigned char* packet,
13
                                                        int length);
14
void wl_recharge_cleanup(void);
15

    
16
// messgae handlers
17
void wl_recharge_station_available(int source);
18
void wl_recharge_request_accepted(int source);
19
void wl_recharge_verify(int source);
20
void wl_recharge_cancel(int source);
21
void wl_recharge_seeking(int source);
22
void wl_recharge_docked(int source);
23

    
24
// sending packets
25
void wl_recharge_send_poll(void);
26
void wl_recharge_send_request(int dest);
27
void wl_recharge_send_verify(int dest);
28
void wl_recharge_send_cancel(int dest);
29
void wl_recharge_send_seeking(int dest);
30
void wl_recharge_send_docked(int dest);
31

    
32
// the handler
33
PacketGroupHandler wl_recharge_handler =
34
                {WL_RECHARGE_GROUP, wl_recharge_timeout_handler,
35
                wl_recharge_response_handler, wl_recharge_handle_receive,
36
                wl_recharge_cleanup};
37

    
38
//timing
39
//timer ticks between polls
40
#define POLL_DELAY 4
41
#define REQUEST_DELAY 6
42
#define VERIFY_DELAY 8
43
#define VERIFY_FREQUENCY 4
44

    
45
//frames
46
#define REQUEST_FRAME 1
47
#define VERIFY_FRAME 2
48
#define CANCEL_FRAME 3
49
#define SEEKING_FRAME 4
50
#define DOCKED_FRAME 5
51

    
52
//global varaibles
53
//state variables
54
int state = NOT_RECHARGING;
55
int station = -1;
56

    
57
//counter variables
58
int pollCount = 0;
59
int requestCount = 0;
60
int verifyCount = 0;
61

    
62
/**
63
 * Register this packet group with the wireless library.
64
 * This function must be called before any other wl_recharge
65
 * function. Also, wl_token_ring_register must be called
66
 * before this function.
67
 *
68
 * @see wl_recharge_unregister
69
 **/
70
void wl_recharge_register(void)
71
{
72
        wl_register_packet_group(&wl_recharge_handler);
73
}
74

    
75
/**
76
 * Called to unregister this packet group with the wireless
77
 * library.
78
 *
79
 * @see wl_recharge_register
80
 **/
81
void wl_recharge_unregister(void)
82
{
83
        wl_unregister_packet_group(&wl_recharge_handler);
84
}
85

    
86
/**
87
 * Begin the procedure to charge.
88
 **/
89
void wl_recharge_begin(void)
90
{
91
        state = POLLING;
92
        station = -1;
93
        pollCount = 0;
94
}
95

    
96
/**
97
 * Begin the procedure to stop charging. If we are currently docked,
98
 * we wait for departureDelay before alerting the station of our
99
 * departure. This is so that we have time to leave.
100
 **/
101
void wl_recharge_stop()
102
{
103
        state = NOT_RECHARGING;
104
}
105

    
106
/**
107
 * Call when the robot has docked with the charging station.
108
 * This changes the state to DOCKED.
109
 **/
110
void wl_recharge_dock(void)
111
{
112
        if (state != SEEKING)
113
        {
114
                WL_DEBUG_PRINT("Unexpected docking occurred.\n");
115
                return;
116
        }
117

    
118
        state = DOCKED;
119
}
120

    
121
/**
122
 * Call this when the robot has departed from the charging
123
 * station. This changes the state to DEPARTING.
124
 **/
125
void wl_recharge_depart(void)
126
{
127
        if (state != DOCKED)
128
        {
129
                WL_DEBUG_PRINT("Unexpected departure occurred.\n");
130
                return;
131
        }
132
        
133
        state = DEPARTING;
134
}
135

    
136
/**
137
 * Returns the current state of the robot, as one of the constants
138
 * defined for a state -
139
 * NOT_CHARGING, POLLING, REQUESTING, SEEKING, DOCKED, or DEPARTING.
140
 *
141
 * @return the current state of the robot
142
 **/
143
int wl_recharge_get_state(void)
144
{
145
        return state;
146
}
147

    
148
/**
149
 * Returns the station we are currently homing to, or -1
150
 * if no such station exists.
151
 *
152
 * @return the 16-bit XBee address of the charging station
153
 **/
154
int wl_recharge_get_station(void)
155
{
156
        return station;
157
}
158

    
159

    
160
/**
161
 * Sends a request polling for charging stations.
162
 **/
163
void wl_recharge_send_poll(void)
164
{
165
        wl_send_global_packet(RECHARGE_GROUP, WL_RECHARGE_POLL_STATIONS,
166
                                NULL, 0, 0);
167
}
168

    
169
/**
170
 * Sends a request to seek a specific charging station.
171
 *
172
 * @param dest the charging station to seek
173
 **/
174
void wl_recharge_send_request(int dest)
175
{
176
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_REQUEST,
177
                                NULL, 0, dest, REQUEST_FRAME);
178
}
179

    
180
/**
181
 * Sends a request to verify what the charging station
182
 * believes we are doing.
183
 *
184
 * @param dest the charging station to check
185
 **/
186
void wl_recharge_send_verify(int dest)
187
{
188
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_VERIFY,
189
                                NULL, 0, dest, VERIFY_FRAME);
190
}
191

    
192
/**
193
 * Sends a packet to the charging station that we are
194
 * no longer attempting to charge from it.
195
 **/
196
void wl_recharge_send_cancel(int dest)
197
{
198
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_CANCEL,
199
                                NULL, 0, dest, CANCEL_FRAME);
200
}
201

    
202
/**
203
 * Sends a packet to the charging station that we are
204
 * attempting to dock with it.
205
 * 
206
 * @param dest the charging station
207
 **/
208
void wl_recharge_send_seeking(int dest)
209
{
210
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_SEEKING,
211
                                NULL, 0, dest, SEEKING_FRAME);
212
}
213

    
214
/**
215
 * Sends a packet to the charging station that
216
 * we have docked with it.
217
 *
218
 * @param dest the charging station we have docked with
219
 **/
220
void wl_recharge_send_docked(int dest)
221
{
222
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_DOCKED,
223
                                NULL, 0, dest, DOCKED_FRAME);
224
}
225

    
226
/**
227
 * Called when this packet is unregistered with the wireless library.
228
 **/
229
void wl_recharge_cleanup(void)
230
{
231

    
232
}
233

    
234
/**
235
 * Called when the timer goes off in the wireless library.
236
 **/
237
void wl_recharge_timeout_handler(void)
238
{
239
        switch (state)
240
        {
241
                case POLLING:
242
                        if (pollCount <= 0)
243
                        {
244
                                wl_recharge_send_poll();
245
                                pollCount = POLL_DELAY + 1;
246
                        }
247
                        pollCount--;
248
                        break;
249

    
250
                case REQUESTING:
251
                        if (requestCount <= 0)
252
                        {
253
                                //request failed
254
                                station = -1;
255
                                state = POLLING;
256
                                break;
257
                        }
258
                        requestCount--;
259
                        break;
260

    
261
                case SEEKING:
262
                        if (verifyCount <= 0)
263
                        {
264
                                //station is down
265
                                station = -1;
266
                                state = POLLING;
267
                                break;
268
                        }
269
                        if (verifyCount % VERIFY_FREQUENCY == 0 && verifyCount != VERIFY_DELAY)
270
                                wl_recharge_send_verify(station);
271
                        verifyCount--;
272
                        break;
273
                        
274
                case DEPARTING:
275
                        break;
276
        }
277
}
278

    
279
/**
280
 * Called when a response is received regarding a packet that was sent.
281
 * 
282
 * @param frame the frame number for the packet
283
 * @param received true if the packet was received, false otherwise
284
 **/
285
void wl_recharge_response_handler(int frame, int received)
286
{
287
        if (received)
288
                return;
289
        if (!received)
290
        {
291
                WL_DEBUG_PRINT("Sent packet not recieved.\n");
292
                switch (frame)
293
                {
294
                        case REQUEST_FRAME:
295
                                break;
296
                        case VERIFY_FRAME:
297
                                break;
298
                        case CANCEL_FRAME:
299
                        case SEEKING_FRAME:
300
                        case DOCKED_FRAME:
301
                                break;
302
                }
303
        }
304
}
305

    
306
/**
307
 * Handles receiving an error packet.
308
 *
309
 * @param type the packet type
310
 * @param source the 16-bit address of the packet's sender
311
 * @param packet the packet data
312
 * @param length the length in bytes of the packet
313
 **/
314
void wl_recharge_handle_receive(char type, int source, unsigned char* packet,
315
                                                        int length)
316
{
317
        switch (type)
318
        {
319
                case WL_RECHARGE_POLL_STATIONS:
320
                        //since we aren't a station, we ignore this packet
321
                        break;
322
                case WL_RECHARGE_STATION_AVAILABLE:
323
                        wl_recharge_available_station(source);
324
                        break;
325
                case WL_RECHRAGE_REQUEST:
326
                        WL_DEBUG_PRINT("Only stations should receive WL_RECHARGE_REQUEST.\n");
327
                        break;
328
                case WL_RECHARGE_REQUEST_ACCEPT:
329
                        wl_recharge_request_accepted(source);
330
                        break;
331
                case WL_RECHARGE_VERIFY:
332
                        wl_recharge_verify(source);
333
                        break;
334
                case WL_RECHARGE_CANCEL:
335
                        wl_recharge_cancel(source);
336
                        break;
337
                case WL_RECHARGE_SEEKING:
338
                        wl_recharge_seeking(source);
339
                        break;
340
                case WL_RECHARGE_DOCKED:
341
                        wl_recharge_docked(source);
342
                        break;
343
                default:
344
                        WL_DEBUG_PRINT("Error packet of unknown type received.\n");
345
                        break;
346
        }
347
}
348

    
349
/**
350
 * Called when we receive a packet alerting us that
351
 * a station is available for charging.
352
 *
353
 * @param source the station which has available bays
354
 **/
355
void wl_recharge_available_station(int source)
356
{
357
        if (state != POLLING)
358
                return;
359
        station = source;
360
        state = REQUESTING;
361
        requestCount = REQUEST_DELAY;
362
        wl_recharge_send_request(station);
363
}
364

    
365
/**
366
 * Called when we receive a packet saying our request
367
 * to charge has been accepted.
368
 *
369
 * @param source the station which has accepted our request
370
 **/
371
void wl_recharge_request_accepted(int source)
372
{
373
        if (state != REQUESTING)
374
        {
375
                WL_DEBUG_PRINT("Accepted when we weren't requesting.\n");
376
                return;
377
        }
378
        if (station != source)
379
        {
380
                WL_DEBUG_PRINT("Accepted by a different station.\n");
381
                return;
382
        }
383

    
384
        state = SEEKING;
385
        verifyCount = VERIFY_DELAY;
386
}
387

    
388
/**
389
 * Called when we receive a request to verify our status
390
 * in the docking procedure.
391
 *
392
 * @param source the station verifying our request
393
 **/
394
void wl_recharge_verify(int source)
395
{
396
        if (source != station)
397
        {
398
                WL_DEBUG_PRINT("Received verify from unassociated station.\n");
399
                wl_recharge_send_cancel(source);
400
                return;
401
        }
402
        
403
        switch (state)
404
        {
405
                case SEEKING:
406
                        wl_recharge_send_seeking(station);
407
                        break;
408
                case DOCKED:
409
                        wl_recharge_send_docked(station);
410
                        break;
411
                default:
412
                        WL_DEBUG_PRINT("Cancelled docking procedure.\n");
413
                        wl_recharge_send_cancel(station);
414
                        break;
415
        }
416
}
417

    
418
/**
419
 * Called when we receive a packet cancelling our
420
 * docking procedure.
421
 *
422
 * @param source the station cancelling the procedure
423
 **/
424
void wl_recharge_cancel(int source)
425
{
426
        if (station != source)
427
        {
428
                WL_DEBUG_PRINT("Received cancel from station we weren't docking with.\n");
429
                return;
430
        }
431

    
432
        verifyCount = VERIFY_DELAY;
433
        switch (state)
434
        {
435
                case REQUESTING:
436
                        station = -1;
437
                        state = POLLING;
438
                        break;
439
                case SEEKING:
440
                        station = -1;
441
                        state = POLLING;
442
                        break;
443
                case DOCKED:
444
                        WL_DEBUG_PRINT("Charging station kicked us out.\n");
445
                        wl_recharge_depart();
446
                        break;
447
                case DEPARTING:
448
                        //ignore, since we are already departing
449
                        break;
450
                default:
451
                        WL_DEBUG_PRINT("Received unexpected cancellation.\n");
452
                        break;
453
        }
454
}
455

    
456
/**
457
 * Called when we receive a packet stating that the
458
 * station believes we are seeking them.
459
 *
460
 * @param source the station we are seeking
461
 **/
462
void wl_recharge_seeking(int source)
463
{
464
        if (station != source)
465
        {
466
                WL_DEBUG_PRINT("Received seeking alert from station we aren't seeking.\n");
467
                wl_recharge_send_cancel(source);
468
                return;
469
        }
470
        
471
        verifyCount = VERIFY_DELAY;
472
        switch (state)
473
        {
474
                case SEEKING:
475
                        break;
476
                case DOCKED:
477
                case DEPARTING:
478
                        wl_recharge_send_docked(station);
479
                        break;
480
                default:
481
                        WL_DEBUG_PRINT("Received unexpected seeking confirmation.\n");
482
                        break;
483
        }
484
}
485

    
486
/**
487
 * Called when we receive a packet stating that
488
 * we are docked with a station.
489
 * 
490
 * @param source the station we are docked with
491
 **/
492
void wl_recharge_docked(int source)
493
{
494
        if (station != source)
495
        {
496
                WL_DEBUG_PRINT("Unknown station believes we are docked.\n");
497
                wl_recharge_send_cancel(source);
498
                return;
499
        }
500
        
501
        verifyCount = VERIFY_DELAY;
502
        switch (state)
503
        {
504
                case DOCKED:
505
                case DEPARTING:
506
                        break;
507
                case SEEKING:
508
                        //not good - we can't immediately proceed to seeking again
509
                        //we will leave the station and repoll it
510
                        WL_DEBUG_PRINT("Seeking, but station believes we are docked. ");
511
                        WL_DEBUG_PRINT("Leaving station and repolling.\n");
512
                        wl_recharge_send_cancel(source);
513
                        wl_recharge_begin();
514
                        break;
515
                default:
516
                        WL_DEBUG_PRINT("Unexpected docking verification received.\n");
517
                        break;
518
        }
519
}
520