Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (10.5 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
 * Sends a request polling for charging stations.
150
 **/
151
void wl_recharge_send_poll(void)
152
{
153
        wl_send_global_packet(RECHARGE_GROUP, WL_RECHARGE_POLL_STATIONS,
154
                                NULL, 0, 0);
155
}
156

    
157
/**
158
 * Sends a request to seek a specific charging station.
159
 *
160
 * @param dest the charging station to seek
161
 **/
162
void wl_recharge_send_request(int dest)
163
{
164
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_REQUEST,
165
                                NULL, 0, dest, REQUEST_FRAME);
166
}
167

    
168
/**
169
 * Sends a request to verify what the charging station
170
 * believes we are doing.
171
 *
172
 * @param dest the charging station to check
173
 **/
174
void wl_recharge_send_verify(int dest)
175
{
176
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_VERIFY,
177
                                NULL, 0, dest, VERIFY_FRAME);
178
}
179

    
180
/**
181
 * Sends a packet to the charging station that we are
182
 * no longer attempting to charge from it.
183
 **/
184
void wl_recharge_send_cancel(int dest)
185
{
186
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_CANCEL,
187
                                NULL, 0, dest, CANCEL_FRAME);
188
}
189

    
190
/**
191
 * Sends a packet to the charging station that we are
192
 * attempting to dock with it.
193
 * 
194
 * @param dest the charging station
195
 **/
196
void wl_recharge_send_seeking(int dest)
197
{
198
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_SEEKING,
199
                                NULL, 0, dest, SEEKING_FRAME);
200
}
201

    
202
/**
203
 * Sends a packet to the charging station that
204
 * we have docked with it.
205
 *
206
 * @param dest the charging station we have docked with
207
 **/
208
void wl_recharge_send_docked(int dest)
209
{
210
        wl_send_robot_to_robot_global_packet(RECHARGE_GROUP, WL_RECHARGE_DOCKED,
211
                                NULL, 0, dest, DOCKED_FRAME);
212
}
213

    
214
/**
215
 * Called when this packet is unregistered with the wireless library.
216
 **/
217
void wl_recharge_cleanup(void)
218
{
219

    
220
}
221

    
222
/**
223
 * Called when the timer goes off in the wireless library.
224
 **/
225
void wl_recharge_timeout_handler(void)
226
{
227
        switch (state)
228
        {
229
                case POLLING:
230
                        if (pollCount <= 0)
231
                        {
232
                                wl_recharge_send_poll();
233
                                pollCount = POLL_DELAY + 1;
234
                        }
235
                        pollCount--;
236
                        break;
237

    
238
                case REQUESTING:
239
                        if (requestCount <= 0)
240
                        {
241
                                //request failed
242
                                station = -1;
243
                                state = POLLING;
244
                                break;
245
                        }
246
                        requestCount--;
247
                        break;
248

    
249
                case SEEKING:
250
                        if (verifyCount <= 0)
251
                        {
252
                                //station is down
253
                                station = -1;
254
                                state = POLLING;
255
                                break;
256
                        }
257
                        if (verifyCount % VERIFY_FREQUENCY == 0 && verifyCount != VERIFY_DELAY)
258
                                wl_recharge_send_verify(station);
259
                        verifyCount--;
260
                        break;
261
                        
262
                case DEPARTING:
263
                        break;
264
        }
265
}
266

    
267
/**
268
 * Called when a response is received regarding a packet that was sent.
269
 * 
270
 * @param frame the frame number for the packet
271
 * @param received true if the packet was received, false otherwise
272
 **/
273
void wl_recharge_response_handler(int frame, int received)
274
{
275
        if (received)
276
                return;
277
        if (!received)
278
        {
279
                WL_DEBUG_PRINT("Sent packet not recieved.\n");
280
                switch (frame)
281
                {
282
                        case REQUEST_FRAME:
283
                                break;
284
                        case VERIFY_FRAME:
285
                                break;
286
                        case CANCEL_FRAME:
287
                        case SEEKING_FRAME:
288
                        case DOCKED_FRAME:
289
                                break;
290
                }
291
        }
292
}
293

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

    
337
/**
338
 * Called when we receive a packet alerting us that
339
 * a station is available for charging.
340
 *
341
 * @param source the station which has available bays
342
 **/
343
void wl_recharge_available_station(int source)
344
{
345
        if (state != POLLING)
346
                return;
347
        station = source;
348
        state = REQUESTING;
349
        requestCount = REQUEST_DELAY;
350
        wl_recharge_send_request(station);
351
}
352

    
353
/**
354
 * Called when we receive a packet saying our request
355
 * to charge has been accepted.
356
 *
357
 * @param source the station which has accepted our request
358
 **/
359
void wl_recharge_request_accepted(int source)
360
{
361
        if (state != REQUESTING)
362
        {
363
                WL_DEBUG_PRINT("Accepted when we weren't requesting.\n");
364
                return;
365
        }
366
        if (station != source)
367
        {
368
                WL_DEBUG_PRINT("Accepted by a different station.\n");
369
                return;
370
        }
371

    
372
        state = SEEKING;
373
        verifyCount = VERIFY_DELAY;
374
}
375

    
376
/**
377
 * Called when we receive a request to verify our status
378
 * in the docking procedure.
379
 *
380
 * @param source the station verifying our request
381
 **/
382
void wl_recharge_verify(int source)
383
{
384
        if (source != station)
385
        {
386
                WL_DEBUG_PRINT("Received verify from unassociated station.\n");
387
                wl_recharge_send_cancel(source);
388
                return;
389
        }
390
        
391
        switch (state)
392
        {
393
                case SEEKING:
394
                        wl_recharge_send_seeking(station);
395
                        break;
396
                case DOCKED:
397
                        wl_recharge_send_docked(station);
398
                        break;
399
                default:
400
                        WL_DEBUG_PRINT("Cancelled docking procedure.\n");
401
                        wl_recharge_send_cancel(station);
402
                        break;
403
        }
404
}
405

    
406
/**
407
 * Called when we receive a packet cancelling our
408
 * docking procedure.
409
 *
410
 * @param source the station cancelling the procedure
411
 **/
412
void wl_recharge_cancel(int source)
413
{
414
        if (station != source)
415
        {
416
                WL_DEBUG_PRINT("Received cancel from station we weren't docking with.\n");
417
                return;
418
        }
419

    
420
        verifyCount = VERIFY_DELAY;
421
        switch (state)
422
        {
423
                case REQUESTING:
424
                        station = -1;
425
                        state = POLLING;
426
                        break;
427
                case SEEKING:
428
                        station = -1;
429
                        state = POLLING;
430
                        break;
431
                case DOCKED:
432
                        WL_DEBUG_PRINT("Charging station kicked us out.\n");
433
                        wl_recharge_depart();
434
                        break;
435
                case DEPARTING:
436
                        //ignore, since we are already departing
437
                        break;
438
                default:
439
                        WL_DEBUG_PRINT("Received unexpected cancellation.\n");
440
                        break;
441
        }
442
}
443

    
444
/**
445
 * Called when we receive a packet stating that the
446
 * station believes we are seeking them.
447
 *
448
 * @param source the station we are seeking
449
 **/
450
void wl_recharge_seeking(int source)
451
{
452
        if (station != source)
453
        {
454
                WL_DEBUG_PRINT("Received seeking alert from station we aren't seeking.\n");
455
                wl_recharge_send_cancel(source);
456
                return;
457
        }
458
        
459
        verifyCount = VERIFY_DELAY;
460
        switch (state)
461
        {
462
                case SEEKING:
463
                        break;
464
                case DOCKED:
465
                case DEPARTING:
466
                        wl_recharge_send_docked(station);
467
                        break;
468
                default:
469
                        WL_DEBUG_PRINT("Received unexpected seeking confirmation.\n");
470
                        break;
471
        }
472
}
473

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