Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / robot / colonet_dragonfly / colonet_dragonfly.c @ 519

History | View | Annotate | Download (8.09 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 move_to_position_routine(int x, int y);
35

    
36
static PacketGroupHandler colonet_pgh;
37

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

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

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

    
53
  return 0;
54
}
55

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

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

    
68
  return 0;
69
}
70

    
71
void get_absolute_position(int* x, int* y) {
72
  *x = robot_x;
73
  *y = robot_y;
74
}
75

    
76
void request_abs_position() {
77
  //usb_puts("requesting_abs_position\n");
78

    
79
  ColonetRobotServerPacket pkt;
80
  pkt.client_id = -1;
81
  pkt.msg_code = ROBOT_REQUEST_POSITION_FROM_SERVER;
82
  wl_send_global_packet(colonet_pgh.groupCode, 0, (char*)&pkt, sizeof(pkt), 0);
83
}
84

    
85
static void move_to_position_routine(int x, int y) {
86
  /* TODO emarinel - control algorithm */
87
  motor1_set(1, 200);
88
  motor2_set(1, 200);
89
}
90

    
91
/* Private functions */
92

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

    
106
  /* Globally store this id. */
107
  server_xbee_id = wl_source;
108

    
109
  usb_puts("Packet received.\n");
110
  char buf[40];
111
  sprintf(buf, "length=%d\n", length);
112

    
113
  int i;
114
  for (i = 0; i < length; i++) {
115
    sprintf(buf, "%d: %d ", i, packet[i]);
116
    usb_puts(buf);
117
  }
118
  usb_puts("\n");
119

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

    
122
  ///assert(length == sizeof(ColonetRobotServerPacket));
123
  packet_string_to_struct(&pkt, packet);
124

    
125
  char buf2[40];
126
  sprintf(buf2, "client_id:%d, msg_code:%d\n", pkt.client_id, pkt.msg_code);
127
  usb_puts(buf2);
128

    
129
  args = pkt.data;
130

    
131
  int_args[0] = two_bytes_to_int(args[0], args[1]);
132
  int_args[1] = two_bytes_to_int(args[2], args[3]);
133
  int_args[2] = two_bytes_to_int(args[4], args[5]);
134

    
135
  if (type == COLONET_REQUEST) {
136
    usb_puts("type is colonet request\n");
137

    
138
    /* TODO - send back data! */
139

    
140
    switch (pkt.msg_code) {
141
      //Sharp
142
    case READ_DISTANCE:
143
      break;
144
    case LINEARIZE_DISTANCE:
145
      break;
146
    case LOG_DISTANCE:
147
      break;
148

    
149
      //Analog
150
    case CALL_ANALOG8:
151
      break;
152
    case CALL_ANALOG10:
153
      break;
154
    case WHEEL:
155
      break;
156

    
157
    case BATTERY:
158
      sprintf((char*)pkt.data, "%d", (int)battery8());
159
      wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, 0, (char*)&pkt, sizeof(pkt), wl_source, 0);
160
      break;
161

    
162
      //BOM
163
    case GETMAXBOM:
164
      break;
165

    
166
      //Dio
167
    case DIGITAL_INPUT:
168
      break;
169
    case BUTTON1_READ:
170
      break;
171
    case BUTTON2_READ:
172
      break;
173

    
174
      //Bumper
175
    case DETECT_BUMP:
176
      break;
177
    }
178
  } else if (type == COLONET_COMMAND) {
179
    usb_puts("colonet command...\n");
180

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

    
191
    switch (pkt.msg_code) {
192
/*     default: */
193
/*       printf("%s: Error - message code %d not implemented\n", __FUNCTION__, */
194
/*              pkt.msg_code); */
195
/*       break; */
196

    
197
    case SERVER_REPORT_POSITION_TO_ROBOT:
198
      robot_x = int_args[0];
199
      robot_y = int_args[1];
200

    
201
      sprintf(buf, "pos is: %d %d\n", robot_x, robot_y);
202
      usb_puts(buf);
203
      break;
204

    
205
    case MOVE_TO_ABSOLUTE_POSITION:
206
      move_to_position_routine(int_args[0], int_args[1]);
207
      break;
208

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

    
276
    case XBEE_PUTC:
277
      xbee_putc((char)args[0]);
278
      break;
279

    
280
    case USB_INIT:
281
      usb_init();
282
      break;
283

    
284
    case USB_PUTC:
285
      usb_putc((char)args[0]);
286
      break;
287

    
288
    case PRINTF:
289
      printf("%s", pkt.data);
290
      break;
291
    case KILL_ROBOT:
292
      motors_off();
293
      buzzer_off();
294
      exit(0); //kill the robot
295
      break;
296
      //Time
297
    case DELAY_MS:
298
      delay_ms(int_args[0]);
299
      break;
300

    
301
      //Analog
302
    case ANALOG_INIT:
303
      //TODO: how do we really init the analog? this doesn't work:
304
      //analog_init();
305
      break;
306

    
307
      //BOM
308
    case BOM_ON:
309
      bom_on();
310
      break;
311
    case BOM_OFF:
312
      bom_off();
313
      break;
314

    
315
    //Dio
316
    case DIGITAL_OUTPUT:
317
      digital_output(int_args[0], int_args[1]);
318
      break;
319
    }
320
  } else {
321
    sprintf(buf, "%s: Error: Invalid colonet message type", __FUNCTION__);
322
    usb_puts(buf);
323
  }
324
}
325

    
326
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt, unsigned char* pkt_buf) {
327
  memcpy(dest_pkt, pkt_buf, sizeof(ColonetRobotServerPacket));
328
}
329

    
330
/* two_bytes_to_int(char a, char b)
331
 * Returns int of form [high][low]
332
 */
333
static unsigned int two_bytes_to_int(char high, char low) {
334
  return (((unsigned int)high)<<8) + (unsigned int)low;
335
}