4 * Robot's main control program (Eurobot 2008).
6 * Copyright: (c) 2008 CTU Dragons
7 * CTU FEE - Department of Control Engineering
17 #include <robot_eb2008.h>
20 #include <servos_eb2008.h>
23 #include <movehelper_eb2008.h>
28 /* define this macro */
32 #define WAIT_FOR_START
33 #define COMPETITION_TIME_DEFAULT 90
34 #define TIME_TO_DEPOSITE_DEFAULT 60
37 #define COMPETITION_TIME_DEFAULT 900
38 #define TIME_TO_DEPOSITE_DEFAULT 60
41 /* competition time in seconds */
42 #define COMPETITION_TIME COMPETITION_TIME_DEFAULT
43 #define TIME_TO_DEPOSITE TIME_TO_DEPOSITE_DEFAULT
44 /* competition time in seconds */
52 int balls_to_collect = 0;
54 /************************************************************************
56 ************************************************************************/
59 * Convert back sharps' measured values to mm.
63 void get_back_sharp_mm(int *sharp)
66 sharp[LEFT] = (int)(robot.sharps.back_left)*1000;
67 sharp[RIGHT] = (int)(robot.sharps.back_right)*1000;
72 * Convert rear sharps' measured values to mm.
76 void get_rear_sharp_mm(int *sharp)
79 sharp[LEFT] = (int)(robot.sharps.left)*1000;
80 sharp[RIGHT] = (int)(robot.sharps.right)*1000;
85 * Convert front sharps' measured values to mm.
89 void get_front_sharp_mm(int *sharp)
92 sharp[LEFT] = (int)(robot.sharps.front_left)*1000;
93 sharp[RIGHT] = (int)(robot.sharps.front_right)*1000;
98 * Get values from front sharps.
102 void get_front_sharp_m(double *sharp)
105 sharp[LEFT] = robot.sharps.front_left;
106 sharp[RIGHT] = robot.sharps.front_right;
107 ROBOT_UNLOCK(sharps);
111 * Get values from rear sharps.
115 void get_rear_sharp_m(double *sharp)
118 sharp[LEFT] = robot.sharps.left;
119 sharp[RIGHT] = robot.sharps.right;
120 ROBOT_UNLOCK(sharps);
124 * Get values from back sharps.
128 void get_back_sharp_m(double *sharp)
131 sharp[LEFT] = robot.sharps.back_left;
132 sharp[RIGHT] = robot.sharps.back_right;
133 ROBOT_UNLOCK(sharps);
137 * Use bumpers check if we are closed to the dispenser
139 int closed_to_dispenser()
144 rv = robot.bumper.left | robot.bumper.right;
145 ROBOT_UNLOCK(bumper);
150 int closed_to_container()
155 rv = ((robot.sharps.back_left < 0.05)
156 && (robot.sharps.back_right < 0.05));
157 ROBOT_UNLOCK(sharps);
163 int get_ball_number()
165 static int cycle = 0;
188 * Competition timer. Stop robot when the timer exceeds.
191 void *wait_for_end(void *arg)
193 sleep(COMPETITION_TIME);
194 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
200 * Timer to go to tray.
203 void *wait_to_deposition(void *arg)
205 sleep(TIME_TO_DEPOSITE);
206 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
211 * Get position of the point when we know the distance and angle to turn.
213 * @param act actual position
214 * @param pos countered position
216 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
217 double l, double phi)
219 ref->x = est->x + l*cos(est->phi + phi);
220 ref->y = est->y + l*sin(est->phi + phi);
221 ref->phi = est->phi + phi;
224 void robot_goto_point(struct ref_pos_type des_pos)
226 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
229 robot_trajectory_new(&tc);
230 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
233 void robot_go_backward_to_point(struct ref_pos_type des_pos)
235 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
238 robot_trajectory_new_backward(&tc);
239 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
242 void trans_callback(struct robo_fsm *fsm)
244 if(fsm->state_name!=NULL)
245 strncpy(robot.act_fsm_state_name, fsm->state_name, FSM_STATE_NAME_MAX_LEN);
248 /************************************************************************
249 * FSM STATES DECLARATION
250 ************************************************************************/
252 /* initial and starting states */
253 FSM_STATE_DECL(init);
254 FSM_STATE_DECL(wait_for_start);
255 FSM_STATE_DECL(decide_where_now);
256 /* movement states */
257 FSM_STATE_DECL(go_to_our_white_dispenser);
258 FSM_STATE_DECL(go_to_our_red_dispenser);
259 FSM_STATE_DECL(go_to_opponent_white_dispenser);
260 FSM_STATE_DECL(try_to_approach_dispenser);
261 FSM_STATE_DECL(go_to_container);
262 /* ball and carousel states */
263 FSM_STATE_DECL(get_balls);
264 FSM_STATE_DECL(next_carousel_position);
265 FSM_STATE_DECL(deposite_balls);
267 /************************************************************************
268 * INITIAL AND STARTING STATES
269 ************************************************************************/
273 /* start event ocurred */
276 robot_set_est_pos_trans(ROBOT_WIDTH_M/2,
277 PLAYGROUND_HEIGHT_M - ROBOT_AXIS_TO_BACK_M,
284 FSM_TRANSITION(wait_for_start);
285 // FSM_TRANSITION(go_to_container);
286 // FSM_TRANSITION(get_balls);
292 FSM_STATE(wait_for_start)
295 #ifdef WAIT_FOR_START
299 /* start competition timer */
300 pthread_create(&thid, NULL, wait_for_end, NULL);
301 pthread_create(&thid, NULL, wait_to_deposition, NULL);
306 /* start to do something */
307 FSM_TRANSITION(decide_where_now);
313 FSM_STATE(decide_where_now)
315 static int cycle = 0;
323 if (robot.carousel_cnt >= BALL_TO_COLLECT ||
324 robot.carousel_cnt >= CAROUSEL_SIZE) {
325 FSM_TRANSITION(go_to_container);
330 FSM_TRANSITION(go_to_our_white_dispenser);
334 FSM_TRANSITION(go_to_our_red_dispenser);
338 FSM_TRANSITION(go_to_container);
342 FSM_TRANSITION(go_to_opponent_white_dispenser);
346 FSM_TRANSITION(go_to_our_white_dispenser);
348 FSM_TRANSITION(go_to_container);
357 /************************************************************************
359 ************************************************************************/
361 FSM_STATE(go_to_our_white_dispenser)
365 robot_trajectory_new(NULL);
366 robot_trajectory_add_point_trans(0.7,
367 PLAYGROUND_HEIGHT_M - 0.65);
368 robot_trajectory_add_final_point_trans(0.25,
369 PLAYGROUND_HEIGHT_M - 0.65, NO_TURN());
372 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
375 balls_to_collect = get_ball_number();
376 FSM_TRANSITION(get_balls);
382 FSM_STATE(go_to_our_red_dispenser)
386 robot_trajectory_new(NULL);
387 robot_trajectory_add_point_trans(0.7,
388 PLAYGROUND_HEIGHT_M - 0.65);
389 robot_trajectory_add_final_point_trans(0.7,
390 PLAYGROUND_HEIGHT_M - 0.25, NO_TURN());
393 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
396 balls_to_collect = get_ball_number();
397 FSM_TRANSITION(get_balls);
403 FSM_STATE(go_to_opponent_white_dispenser)
407 robot_trajectory_new(NULL);
408 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.7,
409 PLAYGROUND_HEIGHT_M - 0.65);
410 robot_trajectory_add_final_point_trans(
411 PLAYGROUND_WIDTH_M - 0.25,
412 PLAYGROUND_HEIGHT_M - 0.7, NO_TURN());
415 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
418 balls_to_collect = get_ball_number();
419 FSM_TRANSITION(get_balls);
425 #define APPROACHING_ATTEMPS 1
427 FSM_STATE(try_to_approach_dispenser)
429 static int approaching_attempts = 0;
430 static unsigned char backward = 0;
434 if (closed_to_dispenser() ||
435 approaching_attempts++ > APPROACHING_ATTEMPS) {
437 approaching_attempts = 0;
439 robot_move_by(-0.1, NO_TURN(), NULL);
445 robot_move_by(0.1, NO_TURN(), NULL);
448 FSM_TRANSITION(try_to_approach_dispenser);
455 #define GO_TO_CONTAINER_TIMER 10000
457 FSM_STATE(go_to_container)
464 robot_trajectory_new(NULL);
465 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.6, 1.0);
466 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M - 0.4,
468 /*FSM_TIMER(GO_TO_CONTAINER_TIMER);*/
472 if (closed_to_container()) {
473 robot.carousel_pos = 0;
474 FSM_TRANSITION(deposite_balls);
476 DBG("FIXME: go_closer_to_container\n");
483 /************************************************************************
484 * BALLS AND CAROUSEL MANIPULATION STATES
485 ************************************************************************/
487 #define MAX_GET_BALL_ATTEMPS 4
488 #define GET_BALL_TIMER 1500
489 #define WAIT_BALL_INSIDE 5000
490 #define GET_BALL_BAGR_SPEED 120
494 static int get_ball_attemps = 0;
495 static int ball_inside = 0;
496 static int last_get = 0;
502 robot_move_by(-0.2, NO_TURN(), NULL);
505 get_ball_attemps = 0;
506 DBG("balls_to_collect = %d\n", balls_to_collect);
508 set_bagr(GET_BALL_BAGR_SPEED);
518 if (robot.carousel_cnt >= balls_to_collect) {
522 next_carousel_position, NULL);
524 (robot.carousel_pos+2) % CAROUSEL_SIZE;
525 } else if (get_ball_attemps++ < MAX_GET_BALL_ATTEMPS) {
526 FSM_TIMER(GET_BALL_TIMER);
528 robot_move_by(-0.2, NO_TURN(), NULL);
532 /* ball is already inside */
537 robot.carousel[robot.carousel_pos % CAROUSEL_SIZE] =
538 (enum ball_color)robot.cmu.color;
539 robot.carousel_cnt++;
540 DBG("collected balls = %d\n", robot.carousel_cnt);
541 FSM_TIMER(WAIT_BALL_INSIDE);
544 FSM_TRANSITION(decide_where_now);
550 #define MAX_CAROUSEL_ATTEMPTS 3
551 #define CAROUSEL_ATTEMPT_TIMER 1000
553 FSM_STATE(next_carousel_position)
555 static int carousel_attempts;
560 carousel_attempts = 0;
561 DBG("carousel_pos = %d\n", robot.carousel_pos);
562 set_carousel(robot.carousel_pos);
563 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
567 /* check out, if the carousel reached position */
569 rv = (robot.drives.carousel_pos == robot.carousel_pos);
570 ROBOT_UNLOCK(drives);
571 if (!rv && carousel_attempts++ < MAX_CAROUSEL_ATTEMPTS) {
572 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
574 DBG("carousel reached the position.\n");
577 DBG("FIXME: carousel lost.\n");
585 #define WAIT_FOR_DEPOSITION_TIMER 1500
587 FSM_STATE(deposite_balls)
591 if (robot.carousel_pos < CAROUSEL_SIZE) {
593 SUBFSM_TRANSITION(next_carousel_position, NULL);
595 robot.carousel_cnt = 0;
596 robot.carousel_pos = 0;
597 DBG("carousel_cnt = %d\n", robot.carousel_cnt);
598 FSM_TRANSITION(decide_where_now);
603 FSM_TIMER(WAIT_FOR_DEPOSITION_TIMER);
606 robot.carousel_pos++;
608 FSM_TRANSITION(deposite_balls);
617 /* robot initialization */
620 robot.carousel_cnt = 0;
621 robot.carousel_pos = 0;
623 FSM(MAIN)->debug_states = 1;
625 robot.fsm[FSM_ID_MAIN].state = &fsm_state_main_init;
626 robot.fsm[FSM_ID_MAIN].transition_callback = trans_callback;
628 /* start threads and wait */