root / branches / encoders / code / behaviors / spline / server / server.c @ 1344
History | View | Annotate | Download (6.67 KB)
1 | 1197 | ayeager | #include <termios.h> |
---|---|---|---|
2 | #include <stdio.h> |
||
3 | #include <stdlib.h> |
||
4 | #include <sys/types.h> |
||
5 | #include <sys/stat.h> |
||
6 | #include <fcntl.h> |
||
7 | 1301 | ayeager | #include "internals.h" |
8 | 1241 | ayeager | #include <math.h> |
9 | 1342 | ayeager | #include "speed_map.h" |
10 | 1197 | ayeager | |
11 | 1342 | ayeager | #include <time.h> |
12 | 1216 | chihsiuh | |
13 | 1342 | ayeager | #define PG 8 |
14 | #define DG .1 |
||
15 | #define IG .1 |
||
16 | 1237 | ayeager | |
17 | 1342 | ayeager | int VEL_S = 1; |
18 | |||
19 | |||
20 | #define TICKS_PER_CM 48.03 |
||
21 | #define TIME_INTERVAL 1520 |
||
22 | |||
23 | #define LEN 30000 |
||
24 | |||
25 | |||
26 | 1301 | ayeager | state robot; |
27 | double vel_l_i;
|
||
28 | double vel_r_i;
|
||
29 | double vel_l_old;
|
||
30 | double vel_r_old;
|
||
31 | 1241 | ayeager | |
32 | |||
33 | 1301 | ayeager | void init(double x, double y, double theta) |
34 | { |
||
35 | robot.x = x; |
||
36 | robot.y = y; |
||
37 | robot.theta = theta; |
||
38 | |||
39 | robot.vl = 0;
|
||
40 | 1342 | ayeager | robot.vr = 0;
|
41 | 1301 | ayeager | robot.vl_ref = 0;
|
42 | robot.vr_ref = 0;
|
||
43 | } |
||
44 | |||
45 | 1224 | chihsiuh | void setAttrib(int file) |
46 | 1197 | ayeager | { |
47 | 1216 | chihsiuh | struct termios attributes;
|
48 | 1224 | chihsiuh | tcgetattr(file, &attributes); |
49 | 1197 | ayeager | |
50 | 1216 | chihsiuh | cfsetispeed(&attributes, B115200); |
51 | cfsetospeed(&attributes, B115200); |
||
52 | attributes.c_cflag &= ~PARENB; |
||
53 | attributes.c_cflag &= ~CSTOPB; |
||
54 | attributes.c_cflag &= ~CSIZE; |
||
55 | 1342 | ayeager | attributes.c_cflag |= CS8; |
56 | 1216 | chihsiuh | |
57 | 1237 | ayeager | attributes.c_cflag &= ~ICRNL; |
58 | attributes.c_cflag &= ~OCRNL; |
||
59 | attributes.c_cflag |= (CLOCAL | CREAD); |
||
60 | attributes.c_lflag &= ~ICANON; |
||
61 | 1216 | chihsiuh | |
62 | |||
63 | 1224 | chihsiuh | if (tcsetattr(file, TCSANOW, &attributes) < 0){ |
64 | 1216 | chihsiuh | perror("tcsetattr failed");
|
65 | exit(-1);
|
||
66 | } |
||
67 | 1224 | chihsiuh | } |
68 | |||
69 | 1344 | ayeager | //#define FORWARD
|
70 | |||
71 | #ifdef FORWARD
|
||
72 | #undef LEFT
|
||
73 | #undef RIGHT
|
||
74 | #define LEFT 0 |
||
75 | #define RIGHT 1 |
||
76 | #endif
|
||
77 | |||
78 | #define CIRCLE
|
||
79 | //#define SINE
|
||
80 | //#define COSINE
|
||
81 | //#define LINE45
|
||
82 | //#define LINE
|
||
83 | |||
84 | #define RADIUS 70 |
||
85 | #define AMP 70 |
||
86 | |||
87 | 1342 | ayeager | int main(int argc, char** args) |
88 | 1224 | chihsiuh | { |
89 | 1344 | ayeager | #ifdef CIRCLE
|
90 | init(20, 30, 0); |
||
91 | #endif
|
||
92 | #ifdef SINE
|
||
93 | init(0, 0, M_PI/4); |
||
94 | #endif
|
||
95 | #ifdef COSINE
|
||
96 | init(0, AMP, 0); |
||
97 | #endif
|
||
98 | #ifdef LINE45
|
||
99 | init(0,0,0); |
||
100 | #endif
|
||
101 | #ifdef LINE
|
||
102 | init(0,0,0); |
||
103 | #endif
|
||
104 | 1342 | ayeager | double x_ref[LEN];
|
105 | double y_ref[LEN];
|
||
106 | int i;
|
||
107 | for (i = 0; i < LEN; i++) { |
||
108 | 1344 | ayeager | #ifdef CIRCLE
|
109 | x_ref[i] = RADIUS * cos((double)(i) / LEN * 2.0 * M_PI); |
||
110 | y_ref[i] = RADIUS * sin((double)(i) / LEN * 2.0 * M_PI); |
||
111 | #endif
|
||
112 | #ifdef SINE
|
||
113 | 1343 | ayeager | x_ref[i] = ((double)(i+1) / LEN * 2.0 * M_PI) * 100; |
114 | 1344 | ayeager | y_ref[i] = AMP *sin (x_ref[i] / 50);
|
115 | #endif
|
||
116 | #ifdef COSINE
|
||
117 | x_ref[i] = ((double)(i+1) / LEN * 2.0 * M_PI) * 100; |
||
118 | y_ref[i] = AMP *cos (x_ref[i] / 50);
|
||
119 | #endif
|
||
120 | #ifdef LINE45
|
||
121 | x_ref[i] = (double)i / LEN * 1000; |
||
122 | y_ref[i] = (double)i / LEN * 1000; |
||
123 | #endif
|
||
124 | #ifdef LINE
|
||
125 | x_ref[i] = (double)i / LEN * 1000; |
||
126 | y_ref[i] = 0;
|
||
127 | #endif
|
||
128 | |||
129 | 1343 | ayeager | //printf("%g \t%g\n", x_ref[i], y_ref[i]);
|
130 | 1342 | ayeager | //getchar();
|
131 | } |
||
132 | 1343 | ayeager | |
133 | //printf("aaaaaaa\n");
|
||
134 | 1342 | ayeager | |
135 | curv_t ref; |
||
136 | ref.x = x_ref; |
||
137 | ref.y = y_ref; |
||
138 | |||
139 | 1224 | chihsiuh | int serialFileIn = open("/dev/ttyUSB0", O_RDWR); |
140 | int serialFileOut = open("/dev/ttyUSB1", O_RDWR); |
||
141 | if(serialFileIn < 1 || serialFileOut < 1) |
||
142 | { |
||
143 | printf("Error opening serial\n");
|
||
144 | return -1; |
||
145 | } |
||
146 | |||
147 | setAttrib(serialFileOut); |
||
148 | setAttrib(serialFileIn); |
||
149 | 1342 | ayeager | |
150 | //unsigned char encoders[4] = {0,0,0,0};
|
||
151 | char ref_vels[2] = {0,0}; |
||
152 | |||
153 | 1224 | chihsiuh | char senderNum = SENDER;
|
154 | char receiverNum = RECEIVER;
|
||
155 | |||
156 | write(serialFileIn, &receiverNum, 1);
|
||
157 | sleep(1);
|
||
158 | write(serialFileOut, &senderNum, 1);
|
||
159 | |||
160 | 1216 | chihsiuh | //Sending velocity as LS LD RS RD
|
161 | 1342 | ayeager | int tempCount = 0; |
162 | 1237 | ayeager | |
163 | 1342 | ayeager | int dx;
|
164 | 1301 | ayeager | double Ul, Ur;
|
165 | |||
166 | 1342 | ayeager | while(1) { |
167 | 1301 | ayeager | |
168 | 1342 | ayeager | pos_control_curve(&ref, LEN); |
169 | |||
170 | 1343 | ayeager | // ref_vels[LEFT] = 20;
|
171 | // ref_vels[RIGHT] = 20;
|
||
172 | 1301 | ayeager | |
173 | 1344 | ayeager | |
174 | 1342 | ayeager | ref_vels[LEFT] = -(char)robot_velocity(1, robot.vl_ref); |
175 | ref_vels[RIGHT] = -(char)robot_velocity(1, robot.vr_ref); |
||
176 | 1344 | ayeager | #ifdef FORWARD
|
177 | ref_vels[LEFT] = -ref_vels[LEFT]; |
||
178 | ref_vels[RIGHT] = -ref_vels[RIGHT]; |
||
179 | #endif
|
||
180 | |||
181 | 1343 | ayeager | //printf("Ref Vs: \t\t%d\t%d\n", ref_vels[LEFT], ref_vels[RIGHT]);
|
182 | 1342 | ayeager | // printf("Left Speed: %d \t Right Speed: %d\n", encoders[LS], encoders[RS]);
|
183 | 1301 | ayeager | |
184 | 1342 | ayeager | //tempCount++;
|
185 | //printf("RECEIVED %d\n", tempCount);
|
||
186 | 1216 | chihsiuh | int temp = 0; |
187 | int count = 0; |
||
188 | do
|
||
189 | { |
||
190 | 1342 | ayeager | temp = write(serialFileOut, ref_vels + count, 1);
|
191 | 1216 | chihsiuh | if(temp < 0) |
192 | perror("Write Error");
|
||
193 | count += temp; |
||
194 | 1342 | ayeager | //printf("sent: %d\n", count);
|
195 | usleep(10000);
|
||
196 | // sleep(1);
|
||
197 | } while(count < 2); |
||
198 | |||
199 | 1216 | chihsiuh | count = 0;
|
200 | 1342 | ayeager | //printf("READING DATA\n");
|
201 | 1216 | chihsiuh | do
|
202 | { |
||
203 | 1342 | ayeager | count += read(serialFileIn, ref_vels, 2);
|
204 | }while(count < 2); |
||
205 | 1216 | chihsiuh | |
206 | 1301 | ayeager | |
207 | 1344 | ayeager | #ifndef FORWARD
|
208 | 1342 | ayeager | robot.vl = real_velocity(1, -ref_vels[LEFT]);
|
209 | robot.vr = real_velocity(1, -ref_vels[RIGHT]);
|
||
210 | 1344 | ayeager | #else
|
211 | robot.vl = real_velocity(1, ref_vels[LEFT]);
|
||
212 | robot.vr = real_velocity(1, ref_vels[RIGHT]);
|
||
213 | #endif
|
||
214 | |||
215 | //printf("ACTUAL V \t\t%g\t%g\n", robot.vl, robot.vr);
|
||
216 | 1237 | ayeager | |
217 | 1301 | ayeager | updatePosition(); |
218 | 1342 | ayeager | //printf("Raw Location is x: %g \t y: %g \t o: %g\n", robot.x,robot.y, robot.theta);
|
219 | printf("%g\t%g\n", robot.x, robot.y);
|
||
220 | 1241 | ayeager | } |
221 | } |
||
222 | 1237 | ayeager | |
223 | 1342 | ayeager | //Todo: This makes no sense, 4am
|
224 | 1301 | ayeager | void updatePosition()
|
225 | { |
||
226 | double wdt = (robot.vr - robot.vl)*DT/L;
|
||
227 | 1241 | ayeager | double R;
|
228 | 1237 | ayeager | |
229 | 1342 | ayeager | if(robot.vr - robot.vl != 0) |
230 | 1301 | ayeager | R = (L/2)*(robot.vr + robot.vl)/(robot.vr - robot.vl);
|
231 | 1241 | ayeager | |
232 | if(wdt != 0) |
||
233 | { |
||
234 | 1301 | ayeager | double ICC[2] = {robot.x - R * sin(robot.theta), robot.y + R*cos(robot.theta)}; |
235 | 1342 | ayeager | robot.x = (cos(wdt)*(robot.x-ICC[0]) - sin(wdt)*(robot.y-ICC[1]) + ICC[0]); |
236 | robot.y = (sin(wdt)*(robot.x-ICC[0]) + cos(wdt)*(robot.y-ICC[1]) + ICC[1]); |
||
237 | 1301 | ayeager | robot.theta = robot.theta + wdt; |
238 | 1197 | ayeager | } |
239 | 1241 | ayeager | else
|
240 | { |
||
241 | 1342 | ayeager | robot.x += cos(robot.theta)*robot.vr*DT; |
242 | robot.y += sin(robot.theta)*robot.vr*DT; |
||
243 | 1241 | ayeager | } |
244 | 1342 | ayeager | if (robot.theta > 2*M_PI) |
245 | robot.theta -= 2*M_PI;
|
||
246 | if (robot.theta < -2*M_PI) |
||
247 | robot.theta += 2*M_PI;
|
||
248 | 1197 | ayeager | } |
249 | 1301 | ayeager | |
250 | |||
251 | static int find_goal(curv_t *ref, int len); |
||
252 | 1342 | ayeager | |
253 | void pos_control_curve(curv_t *ref, int len) { |
||
254 | 1301 | ayeager | int goal_idx = find_goal(ref, len);
|
255 | 1344 | ayeager | //printf("\tGOAL: x: %g, y: %g\n", ref->x[goal_idx], ref->y[goal_idx]);
|
256 | 1301 | ayeager | //did a transformation here.
|
257 | double goal_y = cos(robot.theta)*(ref->y[goal_idx]-robot.y)
|
||
258 | - sin(robot.theta)*(ref->x[goal_idx]-robot.x); |
||
259 | double goal_rad = 2*goal_y / LOOK_AHEAD; |
||
260 | |||
261 | 1342 | ayeager | |
262 | robot.vl_ref = real_velocity(1, VELOCITY)*(1-0.5*goal_rad); |
||
263 | robot.vr_ref = real_velocity(1, VELOCITY)*(1+0.5*goal_rad); |
||
264 | /*
|
||
265 | if(robot.vl_ref > 127)
|
||
266 | robot.vl_ref = 127;
|
||
267 | else if(robot.vl_ref < -128)
|
||
268 | robot.vl_ref = -128;
|
||
269 | if(robot.vr_ref > 127)
|
||
270 | robot.vr_ref = 127;
|
||
271 | else if(robot.vr_ref < -128)
|
||
272 | robot.vr_ref = -128;
|
||
273 | */
|
||
274 | |||
275 | 1301 | ayeager | } |
276 | |||
277 | static int find_goal(curv_t *ref, int len) { |
||
278 | int i, goal_idx;
|
||
279 | double min_dist = 100000000; |
||
280 | 1343 | ayeager | double temp, err;
|
281 | 1301 | ayeager | int min_idx;
|
282 | 1343 | ayeager | int ctr = 0; |
283 | 1301 | ayeager | for (i = 0; i < len; i++) { |
284 | temp = DIST(ref->x[i], ref->y[i], robot.x, robot.y); |
||
285 | if (temp < min_dist) {
|
||
286 | min_dist = temp; |
||
287 | min_idx = i; |
||
288 | } |
||
289 | } |
||
290 | 1344 | ayeager | /*
|
291 | if (min_dist > LOOK_AHEAD) {
|
||
292 | printf("toooooo far away \n");
|
||
293 | return min_idx;
|
||
294 | }
|
||
295 | */
|
||
296 | 1342 | ayeager | //printf("%d min %f\n", min_idx, min_dist);
|
297 | //getchar();
|
||
298 | 1301 | ayeager | goal_idx = -1;
|
299 | 1343 | ayeager | err = LOOK_AHEAD_ERR_THRES; |
300 | 1344 | ayeager | while(ctr < 3) { |
301 | 1343 | ayeager | for (i = min_idx; i < len; i++) {
|
302 | 1344 | ayeager | #ifdef CIRCLE
|
303 | if (i == len-1) |
||
304 | i = 0;
|
||
305 | #endif
|
||
306 | 1343 | ayeager | temp = DIST(ref->x[i], ref->y[i], robot.x, robot.y); |
307 | if (abs(temp - LOOK_AHEAD) < err) {
|
||
308 | goal_idx = i; |
||
309 | return goal_idx;
|
||
310 | } |
||
311 | } |
||
312 | err += 5;
|
||
313 | ctr++; |
||
314 | } |
||
315 | 1342 | ayeager | while(1) { |
316 | 1344 | ayeager | printf("eol\n");
|
317 | 1342 | ayeager | exit(0);
|
318 | } |
||
319 | 1301 | ayeager | return goal_idx;
|
320 | 1342 | ayeager | } |