Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (12.9 KB)

1
#include "wl_recharge_group.h"
2

    
3
#include <wireless.h>
4
#include <wl_defs.h>
5
#include <battery.h>
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
void wl_recharge_battery_request(int source);
25

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

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

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

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

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

    
60
//counter variables
61
int pollCount = 0;
62
int requestCount = 0;
63
int verifyCount = 0;
64

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

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

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

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

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

    
123
        recharge_state = DOCKED;
124
}
125

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

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

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

    
164

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

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

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

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

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

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

    
231
/**
232
 * Sends a packet to the charging station telling
233
 * it the robot's battery life remaining.
234
 *
235
 * @param dest the charging station we have docked with
236
 **/
237
void wl_recharge_send_battery(int dest)
238
{
239
        char c[1];
240
        c[0]=(char)battery8();
241
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_BATTERY_REQUEST,
242
                                c, 1, dest, 0);
243
}
244

    
245
/**
246
 * Called when this packet is unregistered with the wireless library.
247
 **/
248
void wl_recharge_cleanup(void)
249
{
250

    
251
}
252

    
253
/**
254
 * Called when the timer goes off in the wireless library.
255
 **/
256
void wl_recharge_timeout_handler(void)
257
{
258
        switch (recharge_state)
259
        {
260
                case POLLING:
261
                        if (pollCount <= 0)
262
                        {
263
                                wl_recharge_send_poll();
264
                                pollCount = POLL_DELAY + 1;
265
                        }
266
                        pollCount--;
267
                        break;
268

    
269
                case REQUESTING:
270
                        if (requestCount <= 0)
271
                        {
272
                                RECHARGE_DEBUG_PRINT("Station timed out ");
273
                                RECHARGE_DEBUG_PRINT("on request.\n");
274
                                //request failed
275
                                station = -1;
276
                                recharge_state = POLLING;
277
                                break;
278
                        }
279
                        requestCount--;
280
                        break;
281

    
282
                case SEEKING:
283
                        if (verifyCount <= 0)
284
                        {
285
                                RECHARGE_DEBUG_PRINT("Station timed out ");
286
                                RECHARGE_DEBUG_PRINT("on seeking verify.\n");
287
                                //station is down
288
                                station = -1;
289
                                recharge_state = POLLING;
290
                                break;
291
                        }
292
                        if (verifyCount % VERIFY_FREQUENCY == 0 && verifyCount != VERIFY_DELAY)
293
                                wl_recharge_send_verify(station);
294
                        verifyCount--;
295
                        break;
296
                        
297
                case DEPARTING:
298
                        break;
299
        }
300
}
301

    
302
/**
303
 * Called when a response is received regarding a packet that was sent.
304
 * 
305
 * @param frame the frame number for the packet
306
 * @param received true if the packet was received, false otherwise
307
 **/
308
void wl_recharge_response_handler(int frame, int received)
309
{
310
        if (received)
311
                return;
312
        if (!received)
313
        {
314
                RECHARGE_DEBUG_PRINT("Sent packet not recieved.\n");
315
                switch (frame)
316
                {
317
                        case REQUEST_FRAME:
318
                                break;
319
                        case VERIFY_FRAME:
320
                                break;
321
                        case CANCEL_FRAME:
322
                        case SEEKING_FRAME:
323
                        case DOCKED_FRAME:
324
                                break;
325
                }
326
        }
327
}
328

    
329
/**
330
 * Handles receiving an error packet.
331
 *
332
 * @param type the packet type
333
 * @param source the 16-bit address of the packet's sender
334
 * @param packet the packet data
335
 * @param length the length in bytes of the packet
336
 **/
337
void wl_recharge_handle_receive(char type, int source, unsigned char* packet,
338
                                                        int length)
339
{
340
        switch (type)
341
        {
342
                case WL_RECHARGE_POLL_STATIONS:
343
                        //since we aren't a station, we ignore this packet
344
                        break;
345
                case WL_RECHARGE_STATION_AVAILABLE:
346
                        wl_recharge_available_station(source);
347
                        break;
348
                case WL_RECHARGE_REQUEST:
349
                        RECHARGE_DEBUG_PRINT("Only stations should receive WL_RECHARGE_REQUEST.\n");
350
                        break;
351
                case WL_RECHARGE_REQUEST_ACCEPT:
352
                        wl_recharge_request_accepted(source);
353
                        break;
354
                case WL_RECHARGE_VERIFY:
355
                        wl_recharge_verify(source);
356
                        break;
357
                case WL_RECHARGE_CANCEL:
358
                        wl_recharge_cancel(source);
359
                        break;
360
                case WL_RECHARGE_SEEKING:
361
                        wl_recharge_seeking(source);
362
                        break;
363
                case WL_RECHARGE_DOCKED:
364
                        wl_recharge_docked(source);
365
                        break;
366
                //TODO: remove this, only for demo purposes
367
                case 9:
368
                        if (recharge_state == NOT_RECHARGING)
369
                                wl_recharge_begin();
370
                        break;
371
                case 10:
372
                        if (recharge_state == DOCKED)
373
                                wl_recharge_depart();
374
                        break;
375
                case WL_BATTERY_REQUEST:
376
                        wl_recharge_battery_request(source);
377
                        break;
378
                default:
379
                        RECHARGE_DEBUG_PRINT("Error packet of unknown type received.\n");
380
                        break;
381
        }
382
}
383

    
384
/**
385
 * Called when we receive a packet alerting us that
386
 * a station is available for charging.
387
 *
388
 * @param source the station which has available bays
389
 **/
390
void wl_recharge_available_station(int source)
391
{
392
        if (recharge_state != POLLING)
393
                return;
394
        station = source;
395
        recharge_state = REQUESTING;
396
        requestCount = REQUEST_DELAY;
397
        wl_recharge_send_request(station);
398
}
399

    
400
/**
401
 * Called when we receive a packet saying our request
402
 * to charge has been accepted.
403
 *
404
 * @param source the station which has accepted our request
405
 **/
406
void wl_recharge_request_accepted(int source)
407
{
408
        if (recharge_state != REQUESTING)
409
        {
410
                RECHARGE_DEBUG_PRINT("Accepted when we weren't requesting.\n");
411
                return;
412
        }
413
        if (station != source)
414
        {
415
                RECHARGE_DEBUG_PRINT("Accepted by a different station.\n");
416
                return;
417
        }
418

    
419
        recharge_state = SEEKING;
420
        verifyCount = VERIFY_DELAY;
421
}
422

    
423
/**
424
 * Called when we receive a request to verify our status
425
 * in the docking procedure.
426
 *
427
 * @param source the station verifying our request
428
 **/
429
void wl_recharge_verify(int source)
430
{
431
        if (source != station)
432
        {
433
                RECHARGE_DEBUG_PRINT("Received verify from unassociated station.\n");
434
                wl_recharge_send_cancel(source);
435
                return;
436
        }
437
        
438
        switch (recharge_state)
439
        {
440
                case SEEKING:
441
                        wl_recharge_send_seeking(station);
442
                        break;
443
                case DOCKED:
444
                        wl_recharge_send_docked(station);
445
                        break;
446
                default:
447
                        RECHARGE_DEBUG_PRINT("Cancelled docking procedure.\n");
448
                        wl_recharge_send_cancel(station);
449
                        break;
450
        }
451
}
452

    
453
/**
454
 * Called when we receive a packet cancelling our
455
 * docking procedure.
456
 *
457
 * @param source the station cancelling the procedure
458
 **/
459
void wl_recharge_cancel(int source)
460
{
461
        if (station != source)
462
        {
463
                RECHARGE_DEBUG_PRINT("Received cancel from station we weren't docking with.\n");
464
                return;
465
        }
466

    
467
        RECHARGE_DEBUG_PRINT("Received cancellation from the charging station.\n");
468

    
469
        verifyCount = VERIFY_DELAY;
470
        switch (recharge_state)
471
        {
472
                case REQUESTING:
473
                        station = -1;
474
                        recharge_state = POLLING;
475
                        break;
476
                case SEEKING:
477
                        station = -1;
478
                        recharge_state = DEPARTING;
479
                        //recharge_state = POLLING;
480
                        break;
481
                case DOCKED:
482
                        RECHARGE_DEBUG_PRINT("Charging station kicked us out.\n");
483
                        wl_recharge_depart();
484
                        break;
485
                case DEPARTING:
486
                        //ignore, since we are already departing
487
                        break;
488
                default:
489
                        RECHARGE_DEBUG_PRINT("Received unexpected cancellation.\n");
490
                        break;
491
        }
492
}
493

    
494
/**
495
 * Called when we receive a packet stating that the
496
 * station believes we are seeking them.
497
 *
498
 * @param source the station we are seeking
499
 **/
500
void wl_recharge_seeking(int source)
501
{
502
        if (station != source)
503
        {
504
                RECHARGE_DEBUG_PRINT("Received seeking alert from station we aren't seeking.\n");
505
                wl_recharge_send_cancel(source);
506
                return;
507
        }
508
        
509
        verifyCount = VERIFY_DELAY;
510
        switch (recharge_state)
511
        {
512
                case SEEKING:
513
                        break;
514
                case DOCKED:
515
                case DEPARTING:
516
                        wl_recharge_send_docked(station);
517
                        break;
518
                default:
519
                        RECHARGE_DEBUG_PRINT("Received unexpected seeking confirmation.\n");
520
                        break;
521
        }
522
}
523

    
524
/**
525
 * Called when we receive a packet stating that
526
 * we are docked with a station.
527
 * 
528
 * @param source the station we are docked with
529
 **/
530
void wl_recharge_docked(int source)
531
{
532
        if (station != source)
533
        {
534
                RECHARGE_DEBUG_PRINT("Unknown station believes we are docked.\n");
535
                wl_recharge_send_cancel(source);
536
                return;
537
        }
538
        
539
        verifyCount = VERIFY_DELAY;
540
        switch (recharge_state)
541
        {
542
                case DOCKED:
543
                case DEPARTING:
544
                        break;
545
                case SEEKING:
546
                        //not good - we can't immediately proceed to seeking again
547
                        //we will leave the station and repoll it
548
                        RECHARGE_DEBUG_PRINT("Seeking, but station believes we are docked. ");
549
                        RECHARGE_DEBUG_PRINT("Leaving station and repolling.\n");
550
                        wl_recharge_send_cancel(source);
551
                        wl_recharge_begin();
552
                        break;
553
                default:
554
                        RECHARGE_DEBUG_PRINT("Unexpected docking verification received.\n");
555
                        break;
556
        }
557
}
558

    
559
/**
560
 * Called when we receive a packet requesting
561
 * battery level.
562
 * 
563
 * @param source the station that sent the request
564
 **/
565
void wl_recharge_battery_request(int source){
566
        wl_recharge_send_battery(source);
567
        return;
568
}