Project

General

Profile

Revision 644

Added by Greg Tress about 16 years ago

Changed move-to-point colonet behavior. Need to test.

View differences:

trunk/code/projects/colonet/robot/robot_slave/robot_slave.c
12 12
#include <serial.h>
13 13
#include <stdio.h>
14 14

  
15
int behavior_status;
16

  
15 17
int main(void) {
16 18
  dragonfly_init(ALL_ON);
17 19

  
trunk/code/projects/colonet/robot/colonet_dragonfly/colonet_dragonfly.c
17 17
#include <string.h>
18 18
#include <wireless.h>
19 19

  
20
#define TARGET_POSITION_STOP_DISTANCE_THRESHOLD (40.0)
20
#define TARGET_POSITION_STOP_DISTANCE_THRESHOLD (40)
21 21

  
22 22
typedef struct {
23 23
  unsigned char msgId; //is this necessary?
......
28 28
static UserHandler user_handlers[USER_DEFINED_MSG_TOTAL];
29 29

  
30 30
static unsigned robot_x, robot_y;
31
static unsigned last_x, last_y;
31 32
static volatile int updated_robot_pos_ready;
32 33
static volatile int new_movement_command_received;
33 34
#define ERROR_MAG_TO_MOTOR_DIFFENTIAL_CONST (1)
......
36 37
static unsigned two_bytes_to_int(unsigned char high, unsigned char low);
37 38
static void colonet_handle_receive(char type, int source, unsigned char* packet, int length);
38 39
static void move_to_position_routine(unsigned x, unsigned y);
40
static int dist_squared(int x1, int y1, int x2, int y2);
39 41

  
40 42
static PacketGroupHandler colonet_pgh;
41 43

  
......
57 59
  // TODO this should return an error if wl_init has not been called yet.
58 60
  wl_register_packet_group(&colonet_pgh);
59 61

  
60
  robot_x = 0;
61
  robot_y = 0;
62
  robot_x = last_x = 0;
63
  robot_y = last_y = 0;
62 64
  updated_robot_pos_ready = 0;
63 65
  new_movement_command_received = 0;
64 66

  
......
87 89

  
88 90
void request_abs_position() {
89 91
  //usb_puts("requesting_abs_position\n");
90

  
91 92
  ColonetRobotServerPacket pkt;
92 93
  pkt.client_id = -1;
93 94
  pkt.msg_code = ROBOT_REQUEST_POSITION_FROM_SERVER;
94 95
  wl_send_global_packet(colonet_pgh.groupCode, 0, (char*)&pkt, sizeof(ColonetRobotServerPacket), 0);
95 96
}
96 97

  
97
static float sqrt_approx(float x) {
98
  float x2 = x*x;
99
  float x3 = x*x2;
100

  
101
  return 0.00014*x3 - 0.0078*x2 + 0.29*x + 0.84;
98
static int dist_squared(int x1, int y1, int x2, int y2) {
99
  int dx = x1 - x2;
100
  int dy = y1 - y2;
101
  return dx*dx + dy*dy;
102 102
}
103 103

  
104
static float dist(float x1, float y1, float x2, float y2) {
105
  return sqrt_approx((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
106
}
107

  
108
/* cubic approximation of arctan. */
109
/*static void arctan(float t) {
110
  float t3 = t*t*t;
111
  return -0.039 * t3 + 0.74 * t + 0.00011;
112
  }*/
113

  
114 104
/** Differential is the intended left motor speed - right motor speed. */
115 105
static void set_motors_with_differential(int differential) {
116 106
  int ml, mr;
......
149 139
    }
150 140
  }
151 141

  
152
//  usb_puts("got past first loop.\n");
153

  
154
  unsigned last_x = robot_x, last_y = robot_y;
155

  
156
  //  char buf[40];
157
  //sprintf(buf, "cur dist is %f\n", dist((float)robot_x, (float)robot_y, (float)target_x, (float)target_y));
158
  //usb_puts(buf);
159
  //sprintf(buf, "radius squared is %f\n", TARGET_POSITION_STOP_DISTANCE_THRESHOLD);
160
  //usb_puts(buf);
161

  
162 142
  while (!new_movement_command_received &&
163
         dist(robot_x, robot_y, target_x, target_y) > TARGET_POSITION_STOP_DISTANCE_THRESHOLD) {
143
         dist_squared(robot_x, robot_y, target_x, target_y) > TARGET_POSITION_STOP_DISTANCE_THRESHOLD) {
164 144
    updated_robot_pos_ready = 0;
165
    request_abs_position(); // While we're doing this computation, server can be reporting next position.
145
    request_abs_position();   // While we're doing this computation, server can be reporting next position.
166 146

  
167
//    usb_puts("after request_abs_position.\n");
147
    // e is the error vector (where we want to go)
148
    int e_x = target_x - robot_x;
149
    int e_y = target_y - robot_y;
168 150

  
169
    int cur_robot_x = robot_x;
170
    int cur_robot_y = robot_y;
151
    // v is the velocity vector (wehere we just went)
152
    int v_x = robot_x - last_x;
153
    int v_y = robot_y - last_y;
154
    
155
    if (abs(v_x) < 2 && abs(v_x) < 2) {
156
      // if we didn't move since the last check, just go forward.
157
      motor1_set(0, 240);
158
      motor2_set(0, 240);
159
    } else {
160
      // move according to algortihm
161
      int e_mag = e_x*e_x + e_y*e_y;
162
      int motor_differential = e_mag >> 7;   // 128;
171 163

  
172
    //usb_puts("after cur_robot_x/y = robot_x/y.\n");
164
      // p is perpendicular to v, directed to the "left" of the robot.
165
      int p_x = v_y;
166
      int p_y = -v_x;
167
      int dot_product_pe = p_x * e_x + p_y * e_y;
173 168

  
174

  
175
    int e_x = target_x - cur_robot_x;
176
    int e_y = target_y - cur_robot_y;
177

  
178
    int v_x = cur_robot_x - last_x;
179
    int v_y = cur_robot_y - last_y;
180

  
181
    //    sprintf(buf, "vx:%d vy:%d rx:%d ry:%d ex:%d ey:%d\n", v_x, v_y, e_x, e_y, e_x, e_y);
182
    // usb_puts(buf);
183

  
184
    int e_mag = e_x*e_x + e_y*e_y;
185

  
186
    int motor_differential = e_mag >> 7;// / 128;
187

  
188
/*
189
    sprintf(buf, "Current position: %d %d\n", cur_robot_x, cur_robot_y);
190
    usb_puts(buf);
191

  
192
    sprintf(buf, "Target position: %d %d\n", target_x, target_y);
193
    usb_puts(buf);
194

  
195
    float r_x = (float)target_x - cur_robot_x;
196
    float r_y = (float)target_y - cur_robot_y;
197
    float r_mag = sqrt_approx(r_x * r_x + r_y * r_y);
198
    r_x /= r_mag;
199
    r_y /= r_mag;
200

  
201
    float v_x = (float)cur_robot_x - last_x;
202
    float v_y = robot_y - last_y;
203
    float v_mag = sqrt_approx(v_x*v_x + v_y*v_y);
204
    v_x /= v_mag;
205
    v_y /= v_mag;
206

  
207
    float e_x = r_x - v_x;
208
    float e_y = r_y - v_y;
209
    float e_mag = sqrt_approx(e_x * e_x + e_y * e_y);
210

  
211
    sprintf(buf, "Error: <%f,%f>; mag: %f\n", e_x, e_y, e_mag);
212
    usb_puts(buf);
213

  
214
    // Motor differential proportional to magnitude of directional error.
215
  //  int motor_differential = (int)(e_mag * ERROR_MAG_TO_MOTOR_DIFFENTIAL_CONST);
216
*/
217

  
218

  
219
    int p_x = v_y;
220
    int p_y = -v_x;
221

  
222
    int e_trans_x = p_x * e_x + p_y * e_y;
223

  
224
/*
225
    // Determine left or right by transforming error vector to robot axes
226
    // Perpendicular
227
    float p_x = v_y;
228
    float p_y = -v_x;
229

  
230
    // Inverse matrix
231
    float coeff = 1.0 / (p_x * v_y - v_x * p_y);
232
    float mat[2][2];
233
    mat[0][0] = v_y * coeff;
234
    mat[0][1] = -v_x * coeff;
235
    //mat[1][0] = -p_y * coeff;     //Not needed for our purposes.
236
    //mat[1][1] = p_x * coeff;
237

  
238
    float e_trans_x = mat[0][0] * e_x + mat[0][1] * e_y;
239
    //float e_trans_y = mat[1][0] * e_x + mat[1][1] * e_y;  //Not needed for our purposes.
240
*/
241

  
242

  
243
    if (e_trans_x < 0) {
244
      motor_differential = -motor_differential;
169
      // if the dot product of p and e is negative, we should turn right. otherwise turn left.
170
      if (dot_product_pe < 0) {
171
        motor_differential = -motor_differential;
172
      }
173
      set_motors_with_differential(motor_differential);
245 174
    }
246 175

  
247
    // sprintf(buf, "motor_diff: %d\n", motor_differential);
248
    //    usb_puts(buf);
249

  
250
    last_x = cur_robot_x;
251
    last_y = cur_robot_y;
252

  
253
    set_motors_with_differential(motor_differential);
254

  
176
    // once we move, ask for the position again.
255 177
    count = 0;
256
    while (!updated_robot_pos_ready) { // ghetto condition variable
178
    while (!updated_robot_pos_ready) {
257 179
      wl_do();
258 180
      if (count++ == 5000) { // in case the server missed it...
259 181
        request_abs_position();
......
262 184
    }
263 185
  }
264 186

  
265
  //  usb_puts("reached destination!\n");
187
  //  Once this function terminates, the robot be at its destination.
266 188
}
267 189

  
268 190
/* Private functions */
......
332 254

  
333 255
    case BATTERY:
334 256
      sprintf((char*)pkt->data, "%d", (int)battery8());
335

  
336
      usb_puts("battery:");
337
      usb_puts((char*)pkt->data);
338
      usb_puts("\n");
339

  
340 257
      // NOTE: wl_send_robot_to_robot_global_packet does not work here!
341 258
      wl_send_global_packet(COLONET_PACKET_GROUP_ID, 0, (char*)pkt, sizeof(ColonetRobotServerPacket), 0);
342 259
      break;
......
369 286
/*       break; */
370 287

  
371 288
    case SERVER_REPORT_POSITION_TO_ROBOT:
289
      last_x = robot_x;
290
      last_y = robot_y;
372 291
      robot_x = (unsigned)int_args[0];
373 292
      robot_y = (unsigned)int_args[1];
374 293

  
......
447 366
    case MOVE:
448 367
      new_movement_command_received = 1;
449 368
      /* format for move: left direction, left velocity, right direction, right velocity */	  
450
      sprintf(buf, "calling motor1 set with: %d, %d\ncalling motor2 set with: %d %d\n", 
451
        args[0], args[1], args[2], args[3]);
369
      sprintf(buf, "calling move\n");
452 370
      usb_puts(buf);
453 371
	  motor1_set(args[0], args[1]);
454 372
	  motor2_set(args[2], args[3]);  
trunk/code/projects/colonet/client/Colonet.java
129 129
	}
130 130

  
131 131
	private synchronized void createAndShowGUI () {
132
		paintThread = new Thread(this, "PaintThread");
133
		paintThread.start();
132
		//paintThread = new Thread(this, "PaintThread");
133
		//paintThread.start();
134 134
		
135 135
		// Webcam
136 136
		gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();

Also available in: Unified diff