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);
249 void move_trans_callback(struct robo_fsm *fsm)
251 if(fsm->state_name!=NULL)
252 strncpy(robot.move_fsm_state_name, fsm->state_name, FSM_STATE_NAME_MAX_LEN);
255 /************************************************************************
256 * FSM STATES DECLARATION
257 ************************************************************************/
259 /* initial and starting states */
260 FSM_STATE_DECL(init);
261 FSM_STATE_DECL(wait_for_start);
262 FSM_STATE_DECL(decide_where_now);
263 /* movement states */
264 FSM_STATE_DECL(go_to_our_white_dispenser);
265 FSM_STATE_DECL(go_to_our_red_dispenser);
266 FSM_STATE_DECL(go_to_opponent_white_dispenser);
267 FSM_STATE_DECL(try_to_approach_dispenser);
268 FSM_STATE_DECL(go_to_container);
269 FSM_STATE_DECL(go_back_to_edge);
270 /* ball and carousel states */
271 FSM_STATE_DECL(get_balls);
272 FSM_STATE_DECL(next_carousel_position);
273 FSM_STATE_DECL(deposite_balls);
275 /************************************************************************
276 * INITIAL AND STARTING STATES
277 ************************************************************************/
281 /* start event ocurred */
284 robot_set_est_pos_trans(ROBOT_WIDTH_M/2,
285 PLAYGROUND_HEIGHT_M - ROBOT_AXIS_TO_BACK_M,
292 FSM_TRANSITION(wait_for_start);
293 // FSM_TRANSITION(go_to_container);
294 // FSM_TRANSITION(get_balls);
300 FSM_STATE(wait_for_start)
303 #ifdef WAIT_FOR_START
307 /* start competition timer */
308 pthread_create(&thid, NULL, wait_for_end, NULL);
309 pthread_create(&thid, NULL, wait_to_deposition, NULL);
314 /* start to do something */
315 FSM_TRANSITION(decide_where_now);
321 FSM_STATE(decide_where_now)
323 static int cycle = 0;
331 if (robot.carousel_cnt >= BALL_TO_COLLECT ||
332 robot.carousel_cnt >= CAROUSEL_SIZE) {
333 FSM_TRANSITION(go_to_container);
338 FSM_TRANSITION(go_to_our_white_dispenser);
342 FSM_TRANSITION(go_to_our_red_dispenser);
346 FSM_TRANSITION(go_to_container);
350 FSM_TRANSITION(go_to_opponent_white_dispenser);
354 FSM_TRANSITION(go_to_our_white_dispenser);
356 FSM_TRANSITION(go_to_container);
365 /************************************************************************
367 ************************************************************************/
369 FSM_STATE(go_to_our_white_dispenser)
373 robot_trajectory_new(NULL);
374 robot_trajectory_add_point_trans(0.7,
375 PLAYGROUND_HEIGHT_M - 0.65);
376 robot_trajectory_add_final_point_trans(0.25,
377 PLAYGROUND_HEIGHT_M - 0.65, NO_TURN());
380 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
383 balls_to_collect = get_ball_number();
384 FSM_TRANSITION(get_balls);
390 FSM_STATE(go_to_our_red_dispenser)
394 robot_trajectory_new(NULL);
395 robot_trajectory_add_point_trans(0.7,
396 PLAYGROUND_HEIGHT_M - 0.45);
397 robot_trajectory_add_final_point_trans(0.7,
398 PLAYGROUND_HEIGHT_M - 0.25, NO_TURN());
401 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
404 balls_to_collect = get_ball_number();
405 FSM_TRANSITION(get_balls);
411 FSM_STATE(go_to_opponent_white_dispenser)
415 robot_trajectory_new(NULL);
416 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.7,
417 PLAYGROUND_HEIGHT_M - 0.65);
418 robot_trajectory_add_final_point_trans(
419 PLAYGROUND_WIDTH_M - 0.25,
420 PLAYGROUND_HEIGHT_M - 0.7, NO_TURN());
423 SUBFSM_TRANSITION(try_to_approach_dispenser, NULL);
426 balls_to_collect = get_ball_number();
427 FSM_TRANSITION(get_balls);
433 #define APPROACHING_ATTEMPS 1
435 FSM_STATE(try_to_approach_dispenser)
437 static int approaching_attempts = 0;
438 static unsigned char backward = 1;
442 if (closed_to_dispenser()) {
444 approaching_attempts = 0;
446 robot_move_by(0.1, NO_TURN(), NULL);
451 if (closed_to_dispenser() || (approaching_attempts++ > APPROACHING_ATTEMPS)) {
455 FSM_TRANSITION(try_to_approach_dispenser);
457 robot_move_by(-0.1, NO_TURN(), NULL);
466 #define GO_TO_CONTAINER_TIMER 10000
468 FSM_STATE(go_to_container)
475 robot_trajectory_new(NULL);
476 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M - 0.8, 1.0);
477 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M - 0.6,
478 0.4, TURN(DEG2RAD(90)));
479 /*FSM_TIMER(GO_TO_CONTAINER_TIMER);*/
483 FSM_TRANSITION(go_back_to_edge);
489 FSM_STATE(go_back_to_edge)
493 robot_move_by(-0.4, NO_TURN(), NULL);
497 if (closed_to_container()) {
498 robot.carousel_pos = 0;
499 FSM_TRANSITION(deposite_balls);
501 DBG("FIXME: go_closer_to_container\n");
508 /************************************************************************
509 * BALLS AND CAROUSEL MANIPULATION STATES
510 ************************************************************************/
512 #define MAX_GET_BALL_ATTEMPS 4
513 #define GET_BALL_TIMER 1500
514 #define WAIT_BALL_INSIDE 5000
515 #define GET_BALL_BAGR_SPEED 120
519 static int get_ball_attemps = 0;
520 static int ball_inside = 0;
521 static int last_get = 0;
527 robot_move_by(-0.2, NO_TURN(), NULL);
530 get_ball_attemps = 0;
531 DBG("balls_to_collect = %d\n", balls_to_collect);
533 set_bagr(GET_BALL_BAGR_SPEED);
543 if (robot.carousel_cnt >= balls_to_collect) {
547 next_carousel_position, NULL);
549 (robot.carousel_pos+2) % CAROUSEL_SIZE;
550 } else if (get_ball_attemps++ < MAX_GET_BALL_ATTEMPS) {
551 FSM_TIMER(GET_BALL_TIMER);
553 robot_move_by(-0.2, NO_TURN(), NULL);
557 /* ball is already inside */
562 robot.carousel[robot.carousel_pos % CAROUSEL_SIZE] =
563 (enum ball_color)robot.cmu.color;
564 robot.carousel_cnt++;
565 DBG("collected balls = %d\n", robot.carousel_cnt);
566 FSM_TIMER(WAIT_BALL_INSIDE);
569 FSM_TRANSITION(decide_where_now);
575 #define MAX_CAROUSEL_ATTEMPTS 3
576 #define CAROUSEL_ATTEMPT_TIMER 1000
578 FSM_STATE(next_carousel_position)
580 static int carousel_attempts;
585 carousel_attempts = 0;
586 DBG("carousel_pos = %d\n", robot.carousel_pos);
587 set_carousel(robot.carousel_pos);
588 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
592 /* check out, if the carousel reached position */
594 rv = (robot.drives.carousel_pos == robot.carousel_pos);
595 ROBOT_UNLOCK(drives);
596 if (!rv && carousel_attempts++ < MAX_CAROUSEL_ATTEMPTS) {
597 FSM_TIMER(CAROUSEL_ATTEMPT_TIMER);
599 DBG("carousel reached the position.\n");
602 DBG("FIXME: carousel lost.\n");
610 #define WAIT_FOR_DEPOSITION_TIMER 1500
612 FSM_STATE(deposite_balls)
616 if (robot.carousel_pos < CAROUSEL_SIZE) {
618 SUBFSM_TRANSITION(next_carousel_position, NULL);
620 robot.carousel_cnt = 0;
621 robot.carousel_pos = 0;
622 DBG("carousel_cnt = %d\n", robot.carousel_cnt);
623 FSM_TRANSITION(decide_where_now);
628 FSM_TIMER(WAIT_FOR_DEPOSITION_TIMER);
631 robot.carousel_pos++;
633 FSM_TRANSITION(deposite_balls);
642 /* robot initialization */
645 robot.carousel_cnt = 0;
646 robot.carousel_pos = 0;
648 FSM(MAIN)->debug_states = 1;
650 robot.fsm[FSM_ID_MAIN].state = &fsm_state_main_init;
651 robot.fsm[FSM_ID_MAIN].transition_callback = trans_callback;
652 robot.fsm[FSM_ID_MOTION].transition_callback = move_trans_callback;
654 /* start threads and wait */