Project

General

Profile

Statistics
| Revision:

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

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
                                recharge_i2c_set_battery_full(0);
370
                                wl_recharge_begin();
371
                                move(0,0);
372
                        }
373
                        break;
374
                case 10:
375
                        if (recharge_state == DOCKED)
376
                                wl_recharge_depart();
377
                        break;
378
                case WL_BATTERY_REQUEST:
379
                        wl_recharge_battery_request(source);
380
                        break;
381
                default:
382
                        RECHARGE_DEBUG_PRINT("Error packet of unknown type received.\n");
383
                        break;
384
        }
385
}
386

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

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

    
422
        recharge_state = SEEKING;
423
        verifyCount = VERIFY_DELAY;
424
}
425

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

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

    
470
        RECHARGE_DEBUG_PRINT("Received cancellation from the charging station.\n");
471

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

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

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

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