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 */
29 /* define in CFLAGS */
30 // #define COMPETITION
33 #define WAIT_FOR_START
34 #define COMPETITION_TIME_DEFAULT 90
35 #define TIME_TO_DEPOSITE_DEFAULT 60
38 #define COMPETITION_TIME_DEFAULT 900
39 #define TIME_TO_DEPOSITE_DEFAULT 60
42 /* competition time in seconds */
43 #define COMPETITION_TIME COMPETITION_TIME_DEFAULT
44 #define TIME_TO_DEPOSITE TIME_TO_DEPOSITE_DEFAULT
45 /* competition time in seconds */
53 int balls_to_collect = 0;
55 /************************************************************************
57 ************************************************************************/
60 * Convert back sharps' measured values to mm.
64 void get_back_sharp_mm(int *sharp)
67 sharp[LEFT] = (int)(robot.sharps.back_left)*1000;
68 sharp[RIGHT] = (int)(robot.sharps.back_right)*1000;
73 * Convert rear sharps' measured values to mm.
77 void get_rear_sharp_mm(int *sharp)
80 sharp[LEFT] = (int)(robot.sharps.left)*1000;
81 sharp[RIGHT] = (int)(robot.sharps.right)*1000;
86 * Convert front sharps' measured values to mm.
90 void get_front_sharp_mm(int *sharp)
93 sharp[LEFT] = (int)(robot.sharps.front_left)*1000;
94 sharp[RIGHT] = (int)(robot.sharps.front_right)*1000;
99 * Get values from front sharps.
103 void get_front_sharp_m(double *sharp)
106 sharp[LEFT] = robot.sharps.front_left;
107 sharp[RIGHT] = robot.sharps.front_right;
108 ROBOT_UNLOCK(sharps);
112 * Get values from rear sharps.
116 void get_rear_sharp_m(double *sharp)
119 sharp[LEFT] = robot.sharps.left;
120 sharp[RIGHT] = robot.sharps.right;
121 ROBOT_UNLOCK(sharps);
125 * Get values from back sharps.
129 void get_back_sharp_m(double *sharp)
132 sharp[LEFT] = robot.sharps.back_left;
133 sharp[RIGHT] = robot.sharps.back_right;
134 ROBOT_UNLOCK(sharps);
138 * Use bumpers check if we are closed to the dispenser
140 int closed_to_dispenser()
145 rv = robot.bumper.left | robot.bumper.right;
146 ROBOT_UNLOCK(bumper);
151 int closed_to_container()
156 rv = ((robot.sharps.back_left < 0.05)
157 && (robot.sharps.back_right < 0.05));
158 ROBOT_UNLOCK(sharps);
164 int get_ball_number()
166 static int cycle = 0;
189 * Competition timer. Stop robot when the timer exceeds.
192 void *wait_for_end(void *arg)
194 sleep(COMPETITION_TIME);
195 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
201 * Timer to go to tray.
204 void *wait_to_deposition(void *arg)
206 sleep(TIME_TO_DEPOSITE);
207 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
212 * Get position of the point when we know the distance and angle to turn.
214 * @param act actual position
215 * @param pos countered position
217 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
218 double l, double phi)
220 ref->x = est->x + l*cos(est->phi + phi);
221 ref->y = est->y + l*sin(est->phi + phi);
222 ref->phi = est->phi + phi;
225 void robot_goto_point(struct ref_pos_type des_pos)
227 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
230 robot_trajectory_new(&tc);
231 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
234 void robot_go_backward_to_point(struct ref_pos_type des_pos)
236 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
239 robot_trajectory_new_backward(&tc);
240 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
243 void trans_callback(struct robo_fsm *fsm)
245 if(fsm->state_name!=NULL)
246 strncpy(robot.act_fsm_state_name, fsm->state_name, FSM_STATE_NAME_MAX_LEN);
250 void move_trans_callback(struct robo_fsm *fsm)
252 if(fsm->state_name!=NULL)
253 strncpy(robot.move_fsm_state_name, fsm->state_name, FSM_STATE_NAME_MAX_LEN);
256 /************************************************************************
257 * FSM STATES DECLARATION
258 ************************************************************************/
260 /* initial and starting states */
261 FSM_STATE_DECL(init);
262 FSM_STATE_DECL(wait_for_deposit);
263 FSM_STATE_DECL(wait_for_laser);
264 FSM_STATE_DECL(wait_for_start);
265 FSM_STATE_DECL(decide_where_now);
266 /* movement states */
267 FSM_STATE_DECL(go_to_our_white_dispenser);
268 FSM_STATE_DECL(go_to_our_red_dispenser);
269 FSM_STATE_DECL(go_to_opponent_white_dispenser);
270 FSM_STATE_DECL(try_to_approach_dispenser);
271 FSM_STATE_DECL(go_to_container);
272 FSM_STATE_DECL(go_back_to_edge);
273 /* ball and carousel states */
274 FSM_STATE_DECL(get_balls);
275 FSM_STATE_DECL(next_carousel_position);
276 FSM_STATE_DECL(deposite_balls);
278 /************************************************************************
279 * INITIAL AND STARTING STATES
280 ************************************************************************/
286 robot_set_est_pos_trans(ROBOT_WIDTH_M/2,
287 PLAYGROUND_HEIGHT_M - ROBOT_AXIS_TO_BACK_M,
289 FSM_TRANSITION(wait_for_start);
296 FSM_STATE(wait_for_laser)
299 #ifdef WAIT_FOR_START
304 robot_set_est_pos_trans(ROBOT_WIDTH_M/2,
305 PLAYGROUND_HEIGHT_M - ROBOT_AXIS_TO_BACK_M,
312 robot_set_est_pos_trans(ROBOT_WIDTH_M/2,
313 PLAYGROUND_HEIGHT_M - ROBOT_AXIS_TO_BACK_M,
318 #ifdef WAIT_FOR_START
319 FSM_TRANSITION(wait_for_deposit);
321 FSM_TRANSITION(wait_for_start);
329 FSM_STATE(wait_for_deposit)
331 /* start event ocurred */
337 // If start is given in two seconds
338 SUBFSM_TRANSITION(deposite_balls, NULL);
341 FSM_TRANSITION(wait_for_deposit);
344 FSM_TRANSITION(wait_for_start);
351 FSM_STATE(wait_for_start)
354 #ifdef WAIT_FOR_START
358 /* start competition timer */
359 pthread_create(&thid, NULL, wait_for_end, NULL);
360 pthread_create(&thid, NULL, wait_to_deposition, NULL);
367 /* start to do something */
368 FSM_TRANSITION(decide_where_now);
370 case EV_DEPOSITE_BALLS:
371 FSM_TRANSITION(wait_for_deposit);
377 FSM_STATE(decide_where_now)
379 static int cycle = 0;
387 if (robot.carousel_cnt >= BALL_TO_COLLECT ||
388 robot.carousel_cnt >= CAROUSEL_SIZE) {
389 FSM_TRANSITION(go_to_container);
394 FSM_TRANSITION(go_to_our_white_dispenser);
398 FSM_TRANSITION(go_to_our_red_dispenser);
402 FSM_TRANSITION(go_to_container);
406 FSM_TRANSITION(go_to_opponent_white_dispenser);
410 FSM_TRANSITION(go_to_our_white_dispenser);
412 FSM_TRANSITION(go_to_container);
421 /************************************************************************
423 ************************************************************************/
425 FSM_STATE(go_to_our_white_dispenser)
429 robot_trajectory_new(NULL);
430 robot_trajectory_add_point_trans(0.7,
431 PLAYGROUND_HEIGHT_M - 0.65);
432 robot_trajectory_add_final_point_trans(0.25,
433 PLAYGROUND_HEIGHT_M - 0.65, NO_TURN());
436 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
439 balls_to_collect = get_ball_number();
440 FSM_TRANSITION(get_balls);
446 FSM_STATE(go_to_our_red_dispenser)
450 robot_trajectory_new(NULL);
451 robot_trajectory_add_point_trans(0.7,
452 PLAYGROUND_HEIGHT_M - 0.45);
453 robot_trajectory_add_final_point_trans(0.7,
454 PLAYGROUND_HEIGHT_M - 0.25, NO_TURN());
457 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
460 balls_to_collect = get_ball_number();
461 FSM_TRANSITION(get_balls);
467 FSM_STATE(go_to_opponent_white_dispenser)
471 robot_trajectory_new(NULL);
472 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.7,
473 PLAYGROUND_HEIGHT_M - 0.65);
474 robot_trajectory_add_final_point_trans(
475 PLAYGROUND_WIDTH_M - 0.25,
476 PLAYGROUND_HEIGHT_M - 0.7, NO_TURN());
479 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
482 balls_to_collect = get_ball_number();
483 FSM_TRANSITION(get_balls);
489 #define APPROACHING_ATTEMPS 1
491 FSM_STATE(try_to_approach_dispenser)
493 static int approaching_attempts = 0;
494 static unsigned char backward = 1;
498 if (closed_to_dispenser()) {
500 approaching_attempts = 0;
502 robot_move_by(0.04, NO_TURN(), NULL);
507 if (closed_to_dispenser() || (approaching_attempts++ > APPROACHING_ATTEMPS)) {
511 FSM_TRANSITION(try_to_approach_dispenser);
513 robot_move_by(-0.02, NO_TURN(), NULL);
522 #define GO_TO_CONTAINER_TIMER 10000
524 FSM_STATE(go_to_container)
531 robot_trajectory_new(NULL);
532 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.8, 1.0);
533 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M - 0.6,
534 0.4, TURN(DEG2RAD(90)));
535 /*FSM_TIMER(GO_TO_CONTAINER_TIMER);*/
539 FSM_TRANSITION(go_back_to_edge);
545 FSM_STATE(go_back_to_edge)
549 robot_move_by(-0.4, NO_TURN(), NULL);
553 if (closed_to_container()) {
554 robot.carousel_pos = 0;
555 SUBFSM_TRANSITION(deposite_balls, NULL);
557 DBG("FIXME: go_closer_to_container\n");
561 FSM_TRANSITION(decide_where_now);
567 /************************************************************************
568 * BALLS AND CAROUSEL MANIPULATION STATES
569 ************************************************************************/
571 #define MAX_GET_BALL_ATTEMPS 4
572 #define GET_BALL_TIMER 1500
573 #define WAIT_BALL_INSIDE 5000
574 #define GET_BALL_BAGR_SPEED 120
578 static int get_ball_attemps = 0;
579 static int ball_inside = 0;
580 static int last_get = 0;
586 robot_move_by(-0.2, NO_TURN(), NULL);
589 get_ball_attemps = 0;
590 DBG("balls_to_collect = %d\n", balls_to_collect);
592 set_bagr(GET_BALL_BAGR_SPEED);
602 if (robot.carousel_cnt >= balls_to_collect) {
606 next_carousel_position, NULL);
608 (robot.carousel_pos+2) % CAROUSEL_SIZE;
609 } else if (get_ball_attemps++ < MAX_GET_BALL_ATTEMPS) {
610 FSM_TIMER(GET_BALL_TIMER);
612 robot_move_by(-0.2, NO_TURN(), NULL);
616 /* ball is already inside */
621 robot.carousel[robot.carousel_pos % CAROUSEL_SIZE] =
622 (enum ball_color)robot.cmu.color;
623 robot.carousel_cnt++;
624 DBG("collected balls = %d\n", robot.carousel_cnt);
625 FSM_TIMER(WAIT_BALL_INSIDE);
628 FSM_TRANSITION(decide_where_now);
634 #define MAX_CAROUSEL_ATTEMPTS 3
635 #define CAROUSEL_ATTEMPT_TIMER 1000
637 FSM_STATE(next_carousel_position)
639 static int carousel_attempts;
644 carousel_attempts = 0;
645 DBG("carousel_pos = %d\n", robot.carousel_pos);
646 set_carousel(robot.carousel_pos);
647 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
651 /* check out, if the carousel reached position */
653 rv = (robot.drives.carousel_pos == robot.carousel_pos);
654 ROBOT_UNLOCK(drives);
655 if (!rv && carousel_attempts++ < MAX_CAROUSEL_ATTEMPTS) {
656 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
658 DBG("carousel reached the position.\n");
661 DBG("FIXME: carousel lost.\n");
669 #define WAIT_FOR_DEPOSITION_TIMER 1500
671 FSM_STATE(deposite_balls)
675 if (robot.carousel_pos < CAROUSEL_SIZE) {
677 SUBFSM_TRANSITION(next_carousel_position, NULL);
679 robot.carousel_cnt = 0;
680 robot.carousel_pos = 0;
681 DBG("carousel_cnt = %d\n", robot.carousel_cnt);
687 FSM_TIMER(WAIT_FOR_DEPOSITION_TIMER);
690 robot.carousel_pos++;
692 FSM_TRANSITION(deposite_balls);
701 /* robot initialization */
704 robot.carousel_cnt = 0;
705 robot.carousel_pos = 0;
707 robot.obstacle_avoidance_enabled = false;
709 FSM(MAIN)->debug_states = 1;
710 FSM(MOTION)->debug_states = 1;
712 robot.fsm[FSM_ID_MAIN].state = &fsm_state_main_init;
713 robot.fsm[FSM_ID_MAIN].transition_callback = trans_callback;
714 robot.fsm[FSM_ID_MOTION].transition_callback = move_trans_callback;
716 /* start threads and wait */