Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / lib / colonet_dragonfly / colonet_dragonfly.c @ 443

History | View | Annotate | Download (8.07 KB)

1
/** @file colonet.c
2
 * @brief Colonet library for DRAGONFLY colony robots
3
 *
4
 * @author Eugene Marinelli
5
 * @date 10/10/07
6
 *
7
 * @bug Handler registration not tested
8
 * @bug Request reponding not implemented - only accepts commands.
9
 */
10

    
11
#include <assert.h>
12
#include <dragonfly_lib.h>
13
#include <battery.h>
14
#include <string.h>
15
#include <wireless.h>
16

    
17
#include <colonet_dragonfly.h>
18

    
19
typedef struct {
20
  unsigned char msgId; //is this necessary?
21
  void (*handler)(void);
22
} UserHandler;
23

    
24
/* Globals (internal) */
25
static UserHandler user_handlers[USER_DEFINED_MSG_TOTAL];
26

    
27
static int robot_x, robot_y;
28
static int server_xbee_id; // ID of server xbee; set when a colonet packet is received.
29

    
30
/* Internal function prototypes */
31
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt, unsigned char* pkt_buf);
32
static unsigned int two_bytes_to_int(char high, char low);
33
static void colonet_handle_receive(char type, int source, unsigned char* packet, int length);
34
static void request_abs_position(void);
35
static void move_to_position_routine(int x, int y);
36

    
37
static PacketGroupHandler colonet_pgh;
38

    
39
/* Public functions */
40
int colonet_init() {
41
  colonet_pgh.groupCode = COLONET_PACKET_GROUP_ID;
42
  colonet_pgh.timeout_handler = NULL;
43
  colonet_pgh.handle_response = NULL;
44
  colonet_pgh.handle_receive = colonet_handle_receive;
45
  colonet_pgh.unregister = NULL;
46

    
47
  // TODO this should return an error if wl_init has not been called yet.
48
  wl_register_packet_group(&colonet_pgh);
49

    
50
  robot_x = 0;
51
  robot_y = 0;
52
  server_xbee_id = -1;
53

    
54
  return 0;
55
}
56

    
57
/* colonet_add_message
58
 * Adds a user-defined message
59
 */
60
int colonet_add_message(unsigned char msgId, void (*handler)(void)) {
61
  if(msgId < USER_DEFINED_MSG_ID_START  /* || msgId > USER_DEFINED_MSG_ID_END */){
62
    return -1;
63
  }
64

    
65
  /* Register this function in the array */
66
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].msgId = msgId;
67
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].handler = handler;
68

    
69
  return 0;
70
}
71

    
72
static void request_abs_position() {
73
  if (server_xbee_id != -1) { // if -1, then we don't know the server's xbee id yet.
74
    ColonetRobotServerPacket pkt;
75
    pkt.client_id = -1;
76
    pkt.msg_code = ROBOT_REQUEST_POSITION_FROM_SERVER;
77
    wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, 0, (char*)&pkt, sizeof(pkt), server_xbee_id, 0);
78
  }
79
}
80

    
81
static void move_to_position_routine(int x, int y) {
82
  /* TODO emarinel - control algorithm */
83
  motor1_set(1, 200);
84
  motor2_set(1, 200);
85
}
86

    
87
/* Private functions */
88

    
89
/** @brief Handles colonet packets.  Should be called by parse_buffer
90
 * when it is determined that a colonet message has been received.
91
 *
92
 * @param robot_id The robot id
93
 * @param pkt_buf The packet buffer (e.g. wl_buf)
94
 *
95
 * @return -1 on error (invalid msgId), 0 on success
96
 */
97
static void colonet_handle_receive(char type, int wl_source, unsigned char* packet, int length) {
98
  ColonetRobotServerPacket pkt;
99
  unsigned char* args; //up to 7 char args
100
  unsigned int int_args[3]; //up to 3 int (2-byte) args
101

    
102
  /* Globally store this id. */
103
  server_xbee_id = wl_source;
104

    
105
  usb_puts("Packet received.\n");
106
  char buf[40];
107
  sprintf(buf, "length=%d\n", length);
108

    
109
  int i;
110
  for (i = 0; i < length; i++) {
111
    sprintf(buf, "%d: %d ", i, packet[i]);
112
    usb_puts(buf);
113
  }
114
  usb_puts("\n");
115

    
116
  //printf("received message from %d of length %d\n", source, length);
117

    
118
  ///assert(length == sizeof(ColonetRobotServerPacket));
119
  packet_string_to_struct(&pkt, packet);
120

    
121
  char buf2[40];
122
  sprintf(buf2, "client_id:%d, msg_code:%d\n", pkt.client_id, pkt.msg_code);
123
  usb_puts(buf2);
124

    
125
  args = pkt.data;
126

    
127
  int_args[0] = two_bytes_to_int(args[0], args[1]);
128
  int_args[1] = two_bytes_to_int(args[2], args[3]);
129
  int_args[2] = two_bytes_to_int(args[4], args[5]);
130

    
131
  if (type == COLONET_REQUEST) {
132
    usb_puts("type is colonet request\n");
133

    
134
    /* TODO - send back data! */
135

    
136
    switch (pkt.msg_code) {
137
      //Sharp
138
    case READ_DISTANCE:
139
      break;
140
    case LINEARIZE_DISTANCE:
141
      break;
142
    case LOG_DISTANCE:
143
      break;
144

    
145
      //Analog
146
    case CALL_ANALOG8:
147
      break;
148
    case CALL_ANALOG10:
149
      break;
150
    case WHEEL:
151
      break;
152

    
153
    case BATTERY:
154
      sprintf((char*)pkt.data, "%d", (int)battery8());
155
      wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, 0, (char*)&pkt, sizeof(pkt), wl_source, 0);
156
      break;
157

    
158
      //BOM
159
    case GETMAXBOM:
160
      break;
161

    
162
      //Dio
163
    case DIGITAL_INPUT:
164
      break;
165
    case BUTTON1_READ:
166
      break;
167
    case BUTTON2_READ:
168
      break;
169

    
170
      //Bumper
171
    case DETECT_BUMP:
172
      break;
173
    }
174
  } else if (type == COLONET_COMMAND) {
175
    usb_puts("type is colonet command...\n");
176

    
177
/* TODO uncomment this stuff */
178
/*     if (pkt.msg_code >= USER_DEFINED_MSG_ID_START && */
179
/*         pkt.msg_code <= USER_DEFINED_MSG_ID_END) { */
180
/*       if (user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler) { */
181
/*         /\* Call the user's handler function if it the function's address */
182
/*          * is non-zero (has been set) *\/ */
183
/*         user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler(); */
184
/*       } */
185
/*     } */
186

    
187
    switch (pkt.msg_code) {
188
/*     default: */
189
/*       printf("%s: Error - message code %d not implemented\n", __FUNCTION__, */
190
/*              pkt.msg_code); */
191
/*       break; */
192

    
193
    case SERVER_REPORT_POSITION_TO_ROBOT:
194
      robot_x = int_args[0];
195
      robot_y = int_args[1];
196
      break;
197

    
198
    case MOVE_TO_ABSOLUTE_POSITION:
199
      move_to_position_routine(int_args[0], int_args[1]);
200
      break;
201

    
202
      //Buzzer
203
    case BUZZER_INIT:
204
      buzzer_init();
205
      break;
206
    case BUZZER_SET_VAL:
207
      buzzer_set_val(args[0]);
208
      break;
209
    case BUZZER_SET_FREQ:
210
      buzzer_set_freq(args[0]);
211
      break;
212
    case BUZZER_CHIRP:
213
      buzzer_chirp(int_args[0], int_args[1]);
214
      break;
215
    case BUZZER_OFF:
216
      buzzer_off();
217
      break;
218
    case ORB_INIT:
219
      orb_init();
220
      break;
221
    //Orb
222
    case ORB_SET:
223
      orb_set(args[0], args[1], args[2]);
224
      break;
225
    case ORB_SET_COLOR:
226
      orb_set_color(int_args[0]);
227
      break;
228
    case ORB_DISABLE:
229
      orb_disable();
230
      break;
231
    case ORB_ENABLE:
232
      orb_enable();
233
      break;
234
    case LED_INIT:
235
      break;
236
    case LED_USER:
237
      break;
238
    case ORB_SEND:
239
      //orb_send();
240
      break;
241
      //Motors
242
    case MOTORS_INIT:
243
      usb_puts("calling motors_init\n");
244
      motors_init();
245
      break;
246
    case MOTOR1_SET:
247
      sprintf(buf, "calling motor1_set [%i] [%i]\n", args[0], args[1]);
248
      usb_puts(buf);
249
      motor1_set(args[0], args[1]);
250
      break;
251
    case MOTOR2_SET:
252
      sprintf(buf, "calling motor2_set [%i] [%i]\n", args[0], args[1]);
253
      usb_puts(buf);
254
      motor2_set(args[0], args[1]);
255
      break;
256
    case MOTORS_OFF:
257
      usb_puts("calling motors_off\n");
258
      motors_off();
259
      break;
260
    case MOVE:
261
      sprintf(buf, "calling move with: %d, %d\n", args[0], args[1]);
262
      usb_puts(buf);
263
      move(args[0], args[1]);
264
      break;
265
    case XBEE_INIT:
266
      xbee_init();
267
      break;
268

    
269
    case XBEE_PUTC:
270
      xbee_putc((char)args[0]);
271
      break;
272

    
273
    case USB_INIT:
274
      usb_init();
275
      break;
276

    
277
    case USB_PUTC:
278
      usb_putc((char)args[0]);
279
      break;
280

    
281
    case PRINTF:
282
      printf("%s", pkt.data);
283
      break;
284
    case KILL_ROBOT:
285
      motors_off();
286
      buzzer_off();
287
      exit(0); //kill the robot
288
      break;
289
      //Time
290
    case DELAY_MS:
291
      delay_ms(int_args[0]);
292
      break;
293

    
294
      //Analog
295
    case ANALOG_INIT:
296
      //TODO: how do we really init the analog? this doesn't work:
297
      //analog_init();
298
      break;
299

    
300
      //BOM
301
    case BOM_ON:
302
      bom_on();
303
      break;
304
    case BOM_OFF:
305
      bom_off();
306
      break;
307

    
308
    //Dio
309
    case DIGITAL_OUTPUT:
310
      digital_output(int_args[0], int_args[1]);
311
      break;
312
    }
313
  } else {
314
    sprintf(buf, "%s: Error: Invalid colonet message type", __FUNCTION__);
315
    usb_puts(buf);
316
  }
317
}
318

    
319
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt, unsigned char* pkt_buf) {
320
  memcpy(dest_pkt, pkt_buf, sizeof(ColonetRobotServerPacket));
321
}
322

    
323
/* two_bytes_to_int(char a, char b)
324
 * Returns int of form [high][low]
325
 */
326
static unsigned int two_bytes_to_int(char high, char low) {
327
  return (((unsigned int)high)<<8) + (unsigned int)low;
328
}