Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / diagnostic_station / station / comm_robot.c @ 1219

History | View | Annotate | Download (6.54 KB)

1
#include <dragonfly_lib.h>
2
#include <wireless.h>
3
#include <string.h>
4

    
5
#include "global.h"
6
#include "comm_robot.h"
7
#include "../common/comm_station_robot.h"
8

    
9
//char new_data = 0;
10
//char finished = 0;
11
//char data_received[10];
12

    
13
uint8_t received_buffer[10]; // Maximum length of a packet to be handled
14
uint8_t received_length;
15
bool received_data;
16

    
17

    
18

    
19
// *********************
20
// ** Motor direction **
21
// *********************
22

    
23
/**
24
  * All the functions in this file use these motor settings: a pair (direction/velocity) maps to a pair motor_direction/
25
  * motor_velocity. motor_direction and motor_velocity are the values passed to the library functions and also sent
26
  * to the robot. direction also includes an "off" direction. If the direction is off, the motor_velocity is always 0.\
27
  **/
28

    
29
char *motor_direction_string (uint8_t direction)
30
{
31
        if (direction==motor_direction_forward)
32
                return "forward";
33
        else if (direction==motor_direction_backward)
34
                return "backward";
35
        else if (direction==motor_direction_off)
36
                return "off";
37
        else
38
                return "?";
39
}
40

    
41
static uint8_t motor_direction (uint8_t direction, uint8_t velocity)
42
{
43
        if (direction==motor_direction_backward)
44
                return BACKWARD;
45
        else
46
                return FORWARD;
47
}
48

    
49
static uint8_t motor_velocity (uint8_t direction, uint8_t velocity)
50
{
51
        if (direction==motor_direction_off)
52
                return 0;
53
        else
54
                return velocity;
55
}
56

    
57

    
58
// ***************************
59
// ** Common comm functions        **
60
// ***************************
61

    
62
// A packet that is followed by a "done" packet from the robot.
63
static void send_command_packet (char type, char *data, int len)
64
{
65
        wl_send_global_packet (station_robot_group, type, data, len, 0);
66
        
67
        // TODO: is it guaranteed that the packet will be sent on the next call to wl_do, or
68
        // do we have to call wl_do in a loop?
69

    
70
        // TODO: wait for "done" from robot.
71

    
72
        wl_do ();
73
}
74

    
75
// A packet that is followed by a data packet from the robot
76
static void send_request_packet(char type, char *data, int len)
77
{
78
        received_data=false;
79
        
80
        // Send the request packet
81
        wl_send_global_packet (station_robot_group, type, data, len, 0);
82
        
83
        // When the reply is received, the receive handler will set received_data to the buffer containing the data. Wait
84
        // until this happens, periodically calling the wl_do function to handle incoming messages.
85
        
86
        // FIXME pretend that we received the data right away
87
//        received_data=true;
88
//        received_length=0;
89
        
90
        while(!received_data)
91
        {
92
                wl_do();
93
        }
94
}
95

    
96

    
97
// *************************
98
// ** Individual commands **
99
// *************************
100

    
101
void robot_set_orbs (uint8_t red1, uint8_t green1, uint8_t blue1, uint8_t red2, uint8_t green2, uint8_t blue2)
102
{
103
        char data[6];
104

    
105
        data[0]=red1;
106
        data[1]=green1;
107
        data[2]=blue1;
108
        
109
        data[3]=red2;
110
        data[4]=green2;
111
        data[5]=blue2;
112

    
113
        send_command_packet (station_robot_set_orbs, data, 6);
114
}
115

    
116
/** Direction is motor_direction_off/forward/backward, not FORWARD/BACKWARD */
117
void robot_set_motors (uint8_t direction1, uint8_t speed1, uint8_t direction2, uint8_t speed2)
118
{
119
        char data[4];
120
        
121
        data[0]=motor_direction (direction1, speed1);
122
        data[1]=motor_velocity  (direction1, speed1);
123
        data[2]=motor_direction (direction2, speed2);
124
        data[3]=motor_velocity  (direction2, speed2);
125
        
126
        send_command_packet (station_robot_set_motors, data, 4);
127
}
128

    
129
/** Direction is direction_off/forward/backward, not FORWARD/BACKWARD */
130
void robot_set_motors_time (uint8_t direction1, uint8_t speed1, uint8_t direction2, uint8_t speed2, uint16_t time_ms)
131
{
132
        char data[6];
133
        
134
        data[0]=motor_direction (direction1, speed1);
135
        data[1]=motor_velocity  (direction1, speed1);
136
        data[2]=motor_direction (direction2, speed1);
137
        data[3]=motor_velocity  (direction2, speed2);
138
        data[4]=WORD_BYTE_0(time_ms);
139
        data[5]=WORD_BYTE_1(time_ms);
140
        
141
        send_command_packet (station_robot_set_motors, data, 6);
142
}
143

    
144
void robot_set_motors_off (void)
145
{
146
        send_command_packet (station_robot_set_motors_off, NULL, 0);
147
}
148

    
149
void robot_set_bom (uint16_t bitmask)
150
{
151
        char data[2];
152
        
153
        data[0]=WORD_BYTE_0(bitmask);
154
        data[1]=WORD_BYTE_1(bitmask);
155
        
156
        send_command_packet (station_robot_set_bom, data, 2);
157
}
158

    
159
void robot_reset_encoders (void)
160
{
161
        send_command_packet (station_robot_reset_encoders, NULL, 0);
162
}
163

    
164

    
165
// *************************
166
// ** Individual requests **
167
// *************************
168

    
169
bool robot_read_encoders (int16_t *left, int16_t *right)
170
{
171
        send_request_packet (station_robot_read_encoders, NULL, 0);
172
        
173
        // Now the received data is in received_data/received_length
174
        if (received_length>=4)
175
        {
176
                *left =WORD(received_buffer[0], received_buffer[1]);
177
                *right=WORD(received_buffer[2], received_buffer[3]);
178
                return true;
179
        }
180
        else
181
        {
182
                return false;
183
        }
184
}
185

    
186
uint16_t robot_read_bom (uint8_t num)
187
{
188
        // FIXME implement
189
        return 0;
190
}
191

    
192
uint16_t robot_read_rangefinder (uint8_t num)
193
{
194
        // FIXME implement
195
        return 0;
196
}
197

    
198

    
199
// ***********************
200
// ** Receive callbacks **
201
// ***********************
202

    
203
static void robot_station_receive (char type, int source, unsigned char* packet, int length)
204
{
205
        // Dump the raw packet
206
        //usb_putc ('[');
207
        //for (uint8_t i=0; i<length; ++i)
208
        //{
209
        //        if (i!=0) usb_putc (' ');
210
        //        usb_puti (packet[i]);
211
        //}
212
        //usb_putc (']');
213
        
214
        // We received some data from the robot. It is not handled immediately as some function is waiting for it.
215
        // TODO introduce a separate packet group for done/data/commands (commands are things to be handled immediately).
216
        
217
        // Note the fact that we received some data
218
        received_data=true;
219
        
220
        // The packet buffer might be overwritten after this function returns, so we have to make a copy of the data.
221
        
222
        // First, determine the number of bytes to copy. It is the minimum of the received length and the size of the data
223
        // buffer the data is copied to.
224
        received_length=length;
225
        if (sizeof (received_buffer)<received_length) received_length=sizeof (received_buffer);
226
        
227
        // Now copy the data
228
        memcpy (received_buffer, packet, received_length);
229
}
230

    
231

    
232
// ********************
233
// ** Initialization **
234
// ********************
235

    
236
// Must not be a local variable because the library doesn't make a copy of it.
237
PacketGroupHandler receive_handler={robot_station_group, NULL, NULL, &robot_station_receive, NULL};
238

    
239
void comm_robot_init ()
240
{
241
        received_data=NULL;
242
        received_length=0;
243

    
244
        usb_puts("# Initializing robot communication" NL);
245
        xbee_init ();
246
        wl_init();
247
        usb_puts("# Done" NL);
248
        
249
        //PacketGroupHandler xxx_receive_handler = {robot_station_group, NULL, NULL, &robot_station_receive, NULL};
250
        wl_register_packet_group(&receive_handler);
251
}