Project

General

Profile

Statistics
| Revision:

root / branches / autonomous_recharging / code / projects / autonomous_recharging / charging_station / wl_charging_station.c @ 98

History | View | Annotate | Download (9.11 KB)

1
#include "wl_charging_station.h"
2

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

    
8
#include "charging_defs.h"
9
#include "charging.h"
10

    
11
//Possible states for the robot
12
/** The robot is not attempting to recharging. **/
13
#define NOT_RECHARGING 0
14
/** Waiting for an available charging station. **/
15
#define POLLING 1
16
/** Requesting to dock with a charging station. **/
17
#define REQUESTING 2
18
/** Traveling to a charging station. **/
19
#define SEEKING 3
20
/** Docked with a charging station. **/
21
#define DOCKED 4
22
/** Leaving a charging station. **/
23
#define DEPARTING 5
24

    
25
// Function prototypes
26
void wl_charging_timeout_handler(void);
27
void wl_charging_response_handler(int frame, int received);
28
void wl_charging_handle_receive(char type, int source, unsigned char* packet,
29
                                                        int length);
30
void wl_charging_cleanup(void);
31

    
32
// messgae handlers
33
void wl_charging_poll(int source);
34
void wl_charging_request(int source);
35
void wl_charging_verify(int source);
36
void wl_charging_cancel(int source);
37
void wl_charging_seeking(int source);
38
void wl_charging_docked(int source);
39

    
40
// sending packets
41
void wl_charging_send_station_available(int dest);
42
void wl_charging_send_request_accept(int dest);
43
void wl_charging_send_verify(int dest);
44
void wl_charging_send_cancel(int dest);
45
void wl_charging_send_seeking(int dest);
46
void wl_charging_send_docked(int dest);
47

    
48
// the handler
49
PacketGroupHandler wl_charging_handler =
50
                {WL_RECHARGE_GROUP, wl_charging_timeout_handler,
51
                wl_charging_response_handler, wl_charging_handle_receive,
52
                wl_charging_cleanup};
53

    
54
//timing
55
//timer ticks between polls
56
#define VERIFY_DELAY 8
57
#define VERIFY_FREQUENCY 4
58

    
59
//frames
60
#define STATION_AVAILABLE_FRAME 1
61
#define REQUEST_ACCEPT_FRAME 2
62
#define VERIFY_FRAME 3
63
#define CANCEL_FRAME 4
64
#define SEEKING_FRAME 5
65
#define DOCKED_FRAME 6
66

    
67
/**
68
 * Register this packet group with the wireless library.
69
 * This function must be called before any other wl_charging
70
 * function. Also, wl_token_ring_register must be called
71
 * before this function, along with wl_token_ring_join.
72
 *
73
 * @see wl_charging_unregister
74
 **/
75
void wl_station_register(void)
76
{
77
        wl_register_packet_group(&wl_charging_handler);
78
}
79

    
80
/**
81
 * Called to unregister this packet group with the wireless
82
 * library.
83
 *
84
 * @see wl_charging_register
85
 **/
86
void wl_station_unregister(void)
87
{
88
        wl_unregister_packet_group(&wl_charging_handler);
89
}
90

    
91
/**
92
 * Sends a packet alerting a specific robot that the station
93
 * is available.
94
 *
95
 * @param dest the robot to tell that the station is available
96
 **/
97
void wl_charging_send_station_available(int dest)
98
{
99
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP,
100
                WL_RECHARGE_STATION_AVAILABLE, NULL, 0, dest,
101
                STATION_AVAILABLE_FRAME);
102
}
103

    
104
/**
105
 * Sends a packet accepting the request of a specific robot.
106
 *
107
 * @param dest the robot to alert of its acceptance
108
 **/
109
void wl_charging_send_request_accept(int dest)
110
{
111
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP,
112
                WL_RECHARGE_REQUEST_ACCEPT, NULL, 0, dest,
113
                REQUEST_ACCEPT_FRAME);
114
}
115

    
116
/**
117
 * Sends a request to verify what the robot
118
 * believes it is doing.
119
 *
120
 * @param dest the robot to check
121
 **/
122
void wl_charging_send_verify(int dest)
123
{
124
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_VERIFY,
125
                                NULL, 0, dest, VERIFY_FRAME);
126
}
127

    
128
/**
129
 * Sends a packet to the robot that we are
130
 * no longer allowing it to charge.
131
 *
132
 * @param dest the robot to tell that it cannot charge
133
 **/
134
void wl_charging_send_cancel(int dest)
135
{
136
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_CANCEL,
137
                                NULL, 0, dest, CANCEL_FRAME);
138
}
139

    
140
/**
141
 * Sends a packet to the robot that it may
142
 * attempt to dock with us.
143
 * 
144
 * @param dest the robot attempting to dock
145
 **/
146
void wl_charging_send_seeking(int dest)
147
{
148
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_SEEKING,
149
                                NULL, 0, dest, SEEKING_FRAME);
150
}
151

    
152
/**
153
 * Sends a packet to the robot that
154
 * we believe it is docked with us.
155
 *
156
 * @param dest the robot that has docked with us
157
 **/
158
void wl_charging_send_docked(int dest)
159
{
160
        wl_send_robot_to_robot_global_packet(WL_RECHARGE_GROUP, WL_RECHARGE_DOCKED,
161
                                NULL, 0, dest, DOCKED_FRAME);
162
}
163

    
164
/**
165
 * Called when this packet is unregistered with the wireless library.
166
 **/
167
void wl_charging_cleanup(void)
168
{
169

    
170
}
171

    
172
/**
173
 * Called when the timer goes off in the wireless library.
174
 **/
175
void wl_charging_timeout_handler(void)
176
{
177
        charging_robot_iterator_init();
178
        
179
        while (charging_robot_iterator_has_next())
180
        {
181
                int robot = charging_robot_iterator_next();
182

    
183
                int c = charging_get_verify_count(robot);
184
                if (c <= 0)
185
                {
186
                        charging_cancel(robot);
187
                        continue;
188
                }
189
        
190
                if (c % VERIFY_FREQUENCY == 0 && c != VERIFY_DELAY)
191
                        wl_charging_send_verify(robot);
192
                
193
                charging_set_verify_count(robot, c - 1);
194
        }
195
}
196

    
197
/**
198
 * Called when a response is received regarding a packet that was sent.
199
 * 
200
 * @param frame the frame number for the packet
201
 * @param received true if the packet was received, false otherwise
202
 **/
203
void wl_charging_response_handler(int frame, int received)
204
{
205
        if (received)
206
                return;
207
        if (!received)
208
        {
209
                STATION_DEBUG_PRINT("Sent packet not recieved.\n");
210
                switch (frame)
211
                {
212
                        case STATION_AVAILABLE_FRAME:
213
                                break;
214
                        case REQUEST_ACCEPT_FRAME:
215
                                break;
216
                        case VERIFY_FRAME:
217
                                break;
218
                        case CANCEL_FRAME:
219
                        case SEEKING_FRAME:
220
                        case DOCKED_FRAME:
221
                                break;
222
                }
223
        }
224
}
225

    
226
/**
227
 * Handles receiving an error packet.
228
 *
229
 * @param type the packet type
230
 * @param source the 16-bit address of the packet's sender
231
 * @param packet the packet data
232
 * @param length the length in bytes of the packet
233
 **/
234
void wl_charging_handle_receive(char type, int source, unsigned char* packet,
235
                                                        int length)
236
{
237
        switch (type)
238
        {
239
                case WL_RECHARGE_POLL_STATIONS:
240
                        wl_charging_poll(source);
241
                        break;
242
                case WL_RECHARGE_STATION_AVAILABLE:
243
                        STATION_DEBUG_PRINT("Stations should not receive ");
244
                        STATION_DEBUG_PRINT("station available packets.\n");
245
                        break;
246
                case WL_RECHARGE_REQUEST:
247
                        wl_charging_request(source);
248
                        break;
249
                case WL_RECHARGE_REQUEST_ACCEPT:
250
                        STATION_DEBUG_PRINT("Stations should not receive ");
251
                        STATION_DEBUG_PRINT("request accept packets.\n");
252
                        break;
253
                case WL_RECHARGE_VERIFY:
254
                        wl_charging_verify(source);
255
                        break;
256
                case WL_RECHARGE_CANCEL:
257
                        wl_charging_cancel(source);
258
                        break;
259
                case WL_RECHARGE_SEEKING:
260
                        wl_charging_seeking(source);
261
                        break;
262
                case WL_RECHARGE_DOCKED:
263
                        wl_charging_docked(source);
264
                        break;
265
                default:
266
                        STATION_DEBUG_PRINT("Error packet of unknown type received.\n");
267
                        break;
268
        }
269
}
270

    
271
/**
272
 * Called when we receive a packet alerting us that
273
 * a robot is looking for stations.
274
 *
275
 * @param source the robot requesting a station
276
 **/
277
void wl_charging_poll(int source)
278
{
279
        if (charging_is_space_available() && !charging_is_robot_seeking())
280
                wl_charging_send_station_available(source);
281
}
282

    
283
/**
284
 * Called when we receive a request to charge.
285
 *
286
 * @param source the robot requesting to charge
287
 **/
288
void wl_charging_request(int source)
289
{
290
        if (charging_is_space_available() && !charging_is_robot_seeking())
291
        {
292
                charging_begin_seeking(source);
293
                wl_charging_send_request_accept(source);
294
        }
295
        else
296
                wl_charging_send_cancel(source);
297
}
298

    
299
/**
300
 * Called when we receive a request to verify our status
301
 * in the docking procedure.
302
 *
303
 * @param source the robot verifying our status
304
 **/
305
void wl_charging_verify(int source)
306
{
307
        int state = charging_get_robot_state(source);
308

    
309
        switch (state)
310
        {
311
                case STATE_SEEKING:
312
                        wl_charging_send_seeking(source);
313
                        break;
314
                case STATE_DOCKED:
315
                        wl_charging_send_docked(source);
316
                        break;
317
                case STATE_NOT_CHARGING:
318
                        STATION_DEBUG_PRINT("Received verify from unknown robot.\n");
319
                        wl_charging_send_cancel(source);
320
                        break;
321
                default:
322
                        STATION_DEBUG_PRINT("Unknown robot state.\n");
323
                        break;
324
        }
325
}
326

    
327
/**
328
 * Called when we receive a packet cancelling our
329
 * docking procedure.
330
 *
331
 * @param source the robot cancelling the procedure
332
 **/
333
void wl_charging_cancel(int source)
334
{
335
        int state = charging_get_robot_state(source);
336

    
337
        if (state == STATE_NOT_CHARGING)
338
        {
339
                STATION_DEBUG_PRINT("Received cancel from unknown robot.\n");
340
                return;
341
        }
342

    
343
        charging_set_verify_count(source, VERIFY_DELAY);
344

    
345
        charging_cancel(source);
346
}
347

    
348
/**
349
 * Called when we receive a packet stating that the
350
 * robot is seeking us.
351
 *
352
 * @param source the robot seeking us
353
 **/
354
void wl_charging_seeking(int source)
355
{
356
        int state = charging_get_robot_state(source);
357

    
358
        if (state == STATE_NOT_CHARGING)
359
        {
360
                STATION_DEBUG_PRINT("Received seeking from unknown robot.\n");
361
                wl_charging_send_cancel(source);
362
                return;
363
        }
364
        
365
        charging_set_verify_count(source, VERIFY_DELAY);
366

    
367
        if (state == STATE_DOCKED)
368
        {
369
                STATION_DEBUG_PRINT("Should not have revert from docked to seeking.\n");
370
                if (charging_is_robot_seeking())
371
                {
372
                        charging_cancel(source);
373
                        wl_charging_send_cancel(source);
374
                }
375
                else
376
                        charging_begin_seeking(source);
377
        }
378
}
379

    
380
/**
381
 * Called when we receive a packet stating that
382
 * a robot is docked with us.
383
 * 
384
 * @param source the robot that is docked with us
385
 **/
386
void wl_charging_docked(int source)
387
{
388
        int state = charging_get_robot_state(source);
389
        if (state == STATE_NOT_CHARGING)
390
        {
391
                STATION_DEBUG_PRINT("Received docked from unknown robot.\n");
392
                return;
393
        }
394
        
395
        charging_set_verify_count(source, VERIFY_DELAY);
396

    
397
        //seeking has ended
398
        if (state == STATE_SEEKING)
399
                charging_dock(source);
400
}
401