Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (11.5 KB)

1
#include "wl_recharge_group.h"
2

    
3
#include <wireless.h>
4
#include <wl_defs.h>
5

    
6
#include <serial.h>
7

    
8
#include "recharge_defs.h"
9

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

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

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

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

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

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

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

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

    
63

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

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

    
88
/**
89
 * Begin the procedure to charge.
90
 **/
91
void wl_recharge_begin(void)
92
{
93
        RECHARGE_DEBUG_PRINT("Beginning to recharge.\n");
94
        recharge_state = POLLING;
95
        station = -1;
96
        pollCount = 0;
97
}
98

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

    
110
/**
111
 * Call when the robot has docked with the charging station.
112
 * This changes the state to DOCKED.
113
 **/
114
void wl_recharge_dock(void)
115
{
116
        if (recharge_state != SEEKING)
117
        {
118
                RECHARGE_DEBUG_PRINT("Unexpected docking occurred.\n");
119
                return;
120
        }
121

    
122
        recharge_state = DOCKED;
123
}
124

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

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

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

    
163

    
164
/**
165
 * Sends a request polling for charging stations.
166
 **/
167
void wl_recharge_send_poll(void)
168
{
169
        wl_send_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_POLL_STATIONS,
170
                                0, 0, 0);
171
}
172

    
173
/**
174
 * Sends a request to seek a specific charging station.
175
 *
176
 * @param dest the charging station to seek
177
 **/
178
void wl_recharge_send_request(int dest)
179
{
180
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_REQUEST,
181
                                0, 0, dest, REQUEST_FRAME);
182
}
183

    
184
/**
185
 * Sends a request to verify what the charging station
186
 * believes we are doing.
187
 *
188
 * @param dest the charging station to check
189
 **/
190
void wl_recharge_send_verify(int dest)
191
{
192
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_VERIFY,
193
                                0, 0, dest, VERIFY_FRAME);
194
}
195

    
196
/**
197
 * Sends a packet to the charging station that we are
198
 * no longer attempting to charge from it.
199
 **/
200
void wl_recharge_send_cancel(int dest)
201
{
202
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_CANCEL,
203
                                0, 0, dest, CANCEL_FRAME);
204
}
205

    
206
/**
207
 * Sends a packet to the charging station that we are
208
 * attempting to dock with it.
209
 * 
210
 * @param dest the charging station
211
 **/
212
void wl_recharge_send_seeking(int dest)
213
{
214
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_SEEKING,
215
                                0, 0, dest, SEEKING_FRAME);
216
}
217

    
218
/**
219
 * Sends a packet to the charging station that
220
 * we have docked with it.
221
 *
222
 * @param dest the charging station we have docked with
223
 **/
224
void wl_recharge_send_docked(int dest)
225
{
226
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_DOCKED,
227
                                0, 0, dest, DOCKED_FRAME);
228
}
229

    
230
/**
231
 * Called when this packet is unregistered with the wireless library.
232
 **/
233
void wl_recharge_cleanup(void)
234
{
235

    
236
}
237

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

    
254
                case REQUESTING:
255
                        if (requestCount <= 0)
256
                        {
257
                                RECHARGE_DEBUG_PRINT("Station timed out ");
258
                                RECHARGE_DEBUG_PRINT("on request.\n");
259
                                //request failed
260
                                station = -1;
261
                                recharge_state = POLLING;
262
                                break;
263
                        }
264
                        requestCount--;
265
                        break;
266

    
267
                case SEEKING:
268
                        if (verifyCount <= 0)
269
                        {
270
                                RECHARGE_DEBUG_PRINT("Station timed out ");
271
                                RECHARGE_DEBUG_PRINT("on seeking verify.\n");
272
                                //station is down
273
                                station = -1;
274
                                recharge_state = POLLING;
275
                                break;
276
                        }
277
                        if (verifyCount % VERIFY_FREQUENCY == 0 && verifyCount != VERIFY_DELAY)
278
                                wl_recharge_send_verify(station);
279
                        verifyCount--;
280
                        break;
281
                        
282
                case DEPARTING:
283
                        break;
284
        }
285
}
286

    
287
/**
288
 * Called when a response is received regarding a packet that was sent.
289
 * 
290
 * @param frame the frame number for the packet
291
 * @param received true if the packet was received, false otherwise
292
 **/
293
void wl_recharge_response_handler(int frame, int received)
294
{
295
        if (received)
296
                return;
297
        if (!received)
298
        {
299
                RECHARGE_DEBUG_PRINT("Sent packet not recieved.\n");
300
                switch (frame)
301
                {
302
                        case REQUEST_FRAME:
303
                                break;
304
                        case VERIFY_FRAME:
305
                                break;
306
                        case CANCEL_FRAME:
307
                        case SEEKING_FRAME:
308
                        case DOCKED_FRAME:
309
                                break;
310
                }
311
        }
312
}
313

    
314
/**
315
 * Handles receiving an error packet.
316
 *
317
 * @param type the packet type
318
 * @param source the 16-bit address of the packet's sender
319
 * @param packet the packet data
320
 * @param length the length in bytes of the packet
321
 **/
322
void wl_recharge_handle_receive(char type, int source, unsigned char* packet,
323
                                                        int length)
324
{
325
        switch (type)
326
        {
327
                case WL_RECHARGE_POLL_STATIONS:
328
                        //since we aren't a station, we ignore this packet
329
                        break;
330
                case WL_RECHARGE_STATION_AVAILABLE:
331
                        wl_recharge_available_station(source);
332
                        break;
333
                case WL_RECHARGE_REQUEST:
334
                        RECHARGE_DEBUG_PRINT("Only stations should receive WL_RECHARGE_REQUEST.\n");
335
                        break;
336
                case WL_RECHARGE_REQUEST_ACCEPT:
337
                        wl_recharge_request_accepted(source);
338
                        break;
339
                case WL_RECHARGE_VERIFY:
340
                        wl_recharge_verify(source);
341
                        break;
342
                case WL_RECHARGE_CANCEL:
343
                        wl_recharge_cancel(source);
344
                        break;
345
                case WL_RECHARGE_SEEKING:
346
                        wl_recharge_seeking(source);
347
                        break;
348
                case WL_RECHARGE_DOCKED:
349
                        wl_recharge_docked(source);
350
                        break;
351
                //TODO: remove this, only for demo purposes
352
                case 9:
353
                        if (recharge_state == NOT_RECHARGING)
354
                                wl_recharge_begin();
355
                        break;
356
                default:
357
                        RECHARGE_DEBUG_PRINT("Error packet of unknown type received.\n");
358
                        break;
359
        }
360
}
361

    
362
/**
363
 * Called when we receive a packet alerting us that
364
 * a station is available for charging.
365
 *
366
 * @param source the station which has available bays
367
 **/
368
void wl_recharge_available_station(int source)
369
{
370
        if (recharge_state != POLLING)
371
                return;
372
        station = source;
373
        recharge_state = REQUESTING;
374
        requestCount = REQUEST_DELAY;
375
        wl_recharge_send_request(station);
376
}
377

    
378
/**
379
 * Called when we receive a packet saying our request
380
 * to charge has been accepted.
381
 *
382
 * @param source the station which has accepted our request
383
 **/
384
void wl_recharge_request_accepted(int source)
385
{
386
        if (recharge_state != REQUESTING)
387
        {
388
                RECHARGE_DEBUG_PRINT("Accepted when we weren't requesting.\n");
389
                return;
390
        }
391
        if (station != source)
392
        {
393
                RECHARGE_DEBUG_PRINT("Accepted by a different station.\n");
394
                return;
395
        }
396

    
397
        recharge_state = SEEKING;
398
        verifyCount = VERIFY_DELAY;
399
}
400

    
401
/**
402
 * Called when we receive a request to verify our status
403
 * in the docking procedure.
404
 *
405
 * @param source the station verifying our request
406
 **/
407
void wl_recharge_verify(int source)
408
{
409
        if (source != station)
410
        {
411
                RECHARGE_DEBUG_PRINT("Received verify from unassociated station.\n");
412
                wl_recharge_send_cancel(source);
413
                return;
414
        }
415
        
416
        switch (recharge_state)
417
        {
418
                case SEEKING:
419
                        wl_recharge_send_seeking(station);
420
                        break;
421
                case DOCKED:
422
                        wl_recharge_send_docked(station);
423
                        break;
424
                default:
425
                        RECHARGE_DEBUG_PRINT("Cancelled docking procedure.\n");
426
                        wl_recharge_send_cancel(station);
427
                        break;
428
        }
429
}
430

    
431
/**
432
 * Called when we receive a packet cancelling our
433
 * docking procedure.
434
 *
435
 * @param source the station cancelling the procedure
436
 **/
437
void wl_recharge_cancel(int source)
438
{
439
        if (station != source)
440
        {
441
                RECHARGE_DEBUG_PRINT("Received cancel from station we weren't docking with.\n");
442
                return;
443
        }
444

    
445
        RECHARGE_DEBUG_PRINT("Received cancellation from the charging station.\n");
446

    
447
        verifyCount = VERIFY_DELAY;
448
        switch (recharge_state)
449
        {
450
                case REQUESTING:
451
                        station = -1;
452
                        recharge_state = POLLING;
453
                        break;
454
                case SEEKING:
455
                        station = -1;
456
                        recharge_state = POLLING;
457
                        break;
458
                case DOCKED:
459
                        RECHARGE_DEBUG_PRINT("Charging station kicked us out.\n");
460
                        wl_recharge_depart();
461
                        break;
462
                case DEPARTING:
463
                        //ignore, since we are already departing
464
                        break;
465
                default:
466
                        RECHARGE_DEBUG_PRINT("Received unexpected cancellation.\n");
467
                        break;
468
        }
469
}
470

    
471
/**
472
 * Called when we receive a packet stating that the
473
 * station believes we are seeking them.
474
 *
475
 * @param source the station we are seeking
476
 **/
477
void wl_recharge_seeking(int source)
478
{
479
        if (station != source)
480
        {
481
                RECHARGE_DEBUG_PRINT("Received seeking alert from station we aren't seeking.\n");
482
                wl_recharge_send_cancel(source);
483
                return;
484
        }
485
        
486
        verifyCount = VERIFY_DELAY;
487
        switch (recharge_state)
488
        {
489
                case SEEKING:
490
                        break;
491
                case DOCKED:
492
                case DEPARTING:
493
                        wl_recharge_send_docked(station);
494
                        break;
495
                default:
496
                        RECHARGE_DEBUG_PRINT("Received unexpected seeking confirmation.\n");
497
                        break;
498
        }
499
}
500

    
501
/**
502
 * Called when we receive a packet stating that
503
 * we are docked with a station.
504
 * 
505
 * @param source the station we are docked with
506
 **/
507
void wl_recharge_docked(int source)
508
{
509
        if (station != source)
510
        {
511
                RECHARGE_DEBUG_PRINT("Unknown station believes we are docked.\n");
512
                wl_recharge_send_cancel(source);
513
                return;
514
        }
515
        
516
        verifyCount = VERIFY_DELAY;
517
        switch (recharge_state)
518
        {
519
                case DOCKED:
520
                case DEPARTING:
521
                        break;
522
                case SEEKING:
523
                        //not good - we can't immediately proceed to seeking again
524
                        //we will leave the station and repoll it
525
                        RECHARGE_DEBUG_PRINT("Seeking, but station believes we are docked. ");
526
                        RECHARGE_DEBUG_PRINT("Leaving station and repolling.\n");
527
                        wl_recharge_send_cancel(source);
528
                        wl_recharge_begin();
529
                        break;
530
                default:
531
                        RECHARGE_DEBUG_PRINT("Unexpected docking verification received.\n");
532
                        break;
533
        }
534
}
535