4 * Robot's main control program (Eurobot 2009).
6 * Copyright: (c) 2009 CTU Dragons
7 * CTU FEE - Department of Control Engineering
21 #include <movehelper.h>
31 #define WAIT_FOR_START
32 #define COMPETITION_TIME_DEFAULT 90
33 #define TIME_TO_DEPOSITE_DEFAULT 60
36 #define COMPETITION_TIME_DEFAULT 900
37 #define TIME_TO_DEPOSITE_DEFAULT 60
40 /* competition time in seconds */
41 #define COMPETITION_TIME COMPETITION_TIME_DEFAULT
42 #define TIME_TO_DEPOSITE TIME_TO_DEPOSITE_DEFAULT
43 /* competition time in seconds */
45 /************************************************************************
46 * SUBFSM's return values ...
47 ************************************************************************/
54 #define FSM_EVENT_RET_VAL ((subfsm_ret_val)FSM_EVENT_INT)
56 /************************************************************************
57 * Trajectory constraints used, are initialized in the init state
58 ************************************************************************/
60 struct TrajectoryConstraints tcFast, tcSlow;
62 /************************************************************************
63 * Variables related to puck collecting
64 ************************************************************************/
66 int free_puck_to_try_to_get_next; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
67 int pucks_at_once; // number of pucks to load at once (maximum number of pucks we want to have in robot)
69 /************************************************************************
70 * Definition of particular "free pucks pick up sequences" and related stuff
71 ************************************************************************/
73 // FIXME: has to be redefined and tested
74 const int free_puck_pick_up_sequence[][6][3] = {
75 /* nx, ny, arrival angle */
159 const int prefered_acropolis_approach_angles[][3] = {
163 {130, 170, 210}, // FIXME... fix these
164 {130, 170, 210}, // FIXME... fix these
165 {130, 170, 210}, // FIXME... fix these
166 {130, 170, 210}, // FIXME... fix these
167 {220, 130, 190}, // FIXME... fix these
168 {130, 220, 180}, // FIXME... fix these
169 {130, 220, 180}, // FIXME... fix these
172 /************************************************************************
173 * NOTES ON DATA WE NEED TO STORE
174 ************************************************************************/
178 - puck (column element) dispensers status (number of pucks)
179 - their max. capacity is 5
180 - lintel dispensers status
181 - free column elements configuration and their positions
182 - free pucks configuration (lot number)
184 - puck stack status (puck count)
185 - lintel holder status
188 /************************************************************************
190 ************************************************************************/
193 * Competition timer. Stop robot when the timer exceeds.
196 void *timing_thread(void *arg)
198 struct timespec start;
200 clock_gettime(CLOCK_MONOTONIC, &start);
204 t.tv_sec = start.tv_sec+sec; \
205 t.tv_nsec = start.tv_nsec; \
206 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); \
210 robot.use_back_switch = true;
211 printf("Back switch not ignored\n");
213 WAIT(TIME_TO_DEPOSITE);
214 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
216 WAIT(COMPETITION_TIME);
217 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
224 * Get position of the point when we know the distance and angle to turn.
226 * FIXME (F.J.): - there used to be non-actual parameter documentation
227 * - what was this function good for? (not used anywhere)
229 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
230 double l, double phi)
232 ref->x = est->x + l*cos(est->phi + phi);
233 ref->y = est->y + l*sin(est->phi + phi);
234 ref->phi = est->phi + phi;
237 void robot_goto_point(struct ref_pos_type des_pos)
239 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
242 robot_trajectory_new(&tc);
243 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
246 void robot_go_backward_to_point(struct ref_pos_type des_pos)
248 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
251 robot_trajectory_new_backward(&tc);
252 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
255 void robot_goto_acropolis(int phi)
258 ACROPOLIS_CENTER_X + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*cos(DEG2RAD(phi)),
259 ACROPOLIS_CENTER_Y + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*sin(DEG2RAD(phi)),
260 ARRIVE_FROM(DEG2RAD(phi+180), 0.07), &tcSlow);
263 void robot_goto_puck_in_grid(int nx, int ny, int phi)
265 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
267 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
268 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
269 ARRIVE_FROM(DEG2RAD(phi+180), 0.1), &tcSlow);
272 void robot_goto_next_puck_in_sequence(int lot, int puck_number)
274 robot_goto_puck_in_grid(
275 free_puck_pick_up_sequence[lot][puck_number][0],
276 free_puck_pick_up_sequence[lot][puck_number][1],
277 free_puck_pick_up_sequence[lot][puck_number][2]);
280 /************************************************************************
281 * FSM STATES DECLARATION
282 ************************************************************************/
284 /* initial and starting states */
285 FSM_STATE_DECL(init);
286 FSM_STATE_DECL(wait_for_start);
287 /* strategies related states */
288 FSM_STATE_DECL(decide_what_next);
289 FSM_STATE_DECL(collect_free_pucks);
290 FSM_STATE_DECL(deposit_at_acropolis);
291 /* movement states */
292 FSM_STATE_DECL(approach_acropolis);
293 FSM_STATE_DECL(simple_construction_zone_approach);
294 FSM_STATE_DECL(approach_our_static_dispenser);
295 FSM_STATE_DECL(approach_opponents_static_dispenser);
296 /* States handling ACT's actions (SUBFSMs) */
297 FSM_STATE_DECL(load_the_puck);
298 FSM_STATE_DECL(grasp_the_puck);
299 FSM_STATE_DECL(look_for_puck_ahead);
300 FSM_STATE_DECL(look_around_for_puck);
302 /************************************************************************
303 * INITIAL AND STARTING STATES
304 ************************************************************************/
310 free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
311 pucks_at_once = 2; // number of pucks to load at once (maximum number of pucks we want to have in robot)
312 tcFast = trajectoryConstraintsDefault;
314 tcSlow = trajectoryConstraintsDefault;
316 FSM_TRANSITION(wait_for_start);
323 FSM_STATE(wait_for_start)
327 printf("COMPETITION mode set\n");
330 #ifdef WAIT_FOR_START
338 /* start competition timer */
339 pthread_create(&thid, NULL, timing_thread, NULL);
340 robot_set_est_pos_trans(0.16,
341 PLAYGROUND_HEIGHT_M - 0.16,
343 FSM_TRANSITION(decide_what_next);
348 case EV_GOAL_NOT_REACHABLE:
349 case EV_SHORT_TIME_TO_END:
352 case EV_ACTION_ERROR:
353 case EV_PUCK_REACHABLE:
355 DBG_PRINT_EVENT("unhandled event");
362 /************************************************************************
363 * STRATEGIES RELATED STATES
364 ************************************************************************/
366 FSM_STATE(decide_what_next)
370 if(robot.pucks_inside == pucks_at_once) {
371 FSM_TRANSITION(deposit_at_acropolis);
373 if(robot.pucks_inside < pucks_at_once && free_puck_to_try_to_get_next < 6) {
374 FSM_TRANSITION(collect_free_pucks);
383 case EV_GOAL_NOT_REACHABLE:
384 case EV_SHORT_TIME_TO_END:
386 case EV_ACTION_ERROR:
387 case EV_PUCK_REACHABLE:
389 DBG_PRINT_EVENT("unhandled event");
396 FSM_STATE(deposit_at_acropolis)
400 FSM_TRANSITION(approach_acropolis);
407 case EV_GOAL_NOT_REACHABLE:
408 case EV_SHORT_TIME_TO_END:
410 case EV_ACTION_ERROR:
411 case EV_PUCK_REACHABLE:
413 DBG_PRINT_EVENT("unhandled event");
420 FSM_STATE(collect_free_pucks)
422 // game configuration... detected lot number is stored in robot.game_conf
425 robot_goto_next_puck_in_sequence(robot.game_conf, free_puck_to_try_to_get_next);
427 case EV_MOTION_DONE: {
428 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
429 SUBFSM_TRANSITION(load_the_puck, NULL);
433 switch(FSM_EVENT_RET_VAL) {
435 printf(">>>>>> Loading the puck succeeded\n");
438 printf(">>>>>> Loading the puck FAILED\n");
441 free_puck_to_try_to_get_next++;
442 FSM_TRANSITION(decide_what_next);
444 case EV_PUCK_REACHABLE:
448 case EV_GOAL_NOT_REACHABLE:
449 case EV_SHORT_TIME_TO_END:
451 case EV_ACTION_ERROR:
453 DBG_PRINT_EVENT("unhandled event");
460 /************************************************************************
462 ************************************************************************/
464 FSM_STATE(approach_acropolis)
468 robot_goto_acropolis(prefered_acropolis_approach_angles[(int)robot.game_conf]
470 //[free_puck_to_try_to_get_next]);
477 case EV_GOAL_NOT_REACHABLE:
478 case EV_SHORT_TIME_TO_END:
480 case EV_ACTION_ERROR:
481 case EV_PUCK_REACHABLE:
483 DBG_PRINT_EVENT("unhandled event");
490 FSM_STATE(simple_construction_zone_approach)
494 robot_trajectory_new(&tcFast);
495 robot_trajectory_add_point_trans(0.9, 1);
496 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
499 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
505 case EV_GOAL_NOT_REACHABLE:
506 case EV_SHORT_TIME_TO_END:
508 case EV_ACTION_ERROR:
509 case EV_PUCK_REACHABLE:
511 DBG_PRINT_EVENT("unhandled event");
518 FSM_STATE(approach_our_static_dispenser)
522 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
524 robot_trajectory_new(&tc);
526 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
527 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
528 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
529 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
534 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
535 printf("Arrived to the static dispenser\n");
538 printf("A Puck picked up\n");
543 case EV_GOAL_NOT_REACHABLE:
544 case EV_SHORT_TIME_TO_END:
545 //case EV_PUCK_REACHABLE: // FIXME: handle this
547 case EV_ACTION_ERROR:
548 case EV_PUCK_REACHABLE:
550 DBG_PRINT_EVENT("unhandled event");
557 FSM_STATE(approach_opponents_static_dispenser)
561 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
563 robot_trajectory_new(&tc);
565 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
566 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
567 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
568 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
573 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
574 printf("Arrived to the static dispenser\n");
577 printf("A Puck picked up\n");
582 case EV_GOAL_NOT_REACHABLE:
583 case EV_SHORT_TIME_TO_END:
584 //case EV_PUCK_REACHABLE: // FIXME: handle this
586 case EV_ACTION_ERROR:
587 case EV_PUCK_REACHABLE:
589 DBG_PRINT_EVENT("unhandled event");
596 /************************************************************************
597 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
598 ************************************************************************/
600 FSM_STATE(load_the_puck)
602 static int puck_load_attempt_count;
605 puck_load_attempt_count = 0;
606 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
610 robot_move_by(0.02, NO_TURN(), &tcSlow);
613 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
616 SUBFSM_RET((void *)LOAD_SUCCESS);
618 case EV_ACTION_ERROR:
619 puck_load_attempt_count++;
620 if (puck_load_attempt_count > 2) {
621 SUBFSM_RET((void *)LOAD_FAIL);
623 robot_move_by(0.02, NO_TURN(), &tcSlow);
628 case EV_GOAL_NOT_REACHABLE:
629 case EV_SHORT_TIME_TO_END:
631 case EV_PUCK_REACHABLE:
633 DBG_PRINT_EVENT("unhandled event");
640 /* of no use without the sharp sensor measuring "puck distance"
641 FSM_STATE(look_around_for_puck)
643 static int lfp_status = 0;
644 const static int scatter_angle = 20;
645 static struct ref_pos_type orig_position;
649 orig_position = robot.ref_pos;
650 ROBOT_UNLOCK(ref_pos);
651 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
652 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
653 //printf("lfp_status: %d\n", lfp_status);
656 switch (lfp_status) {
658 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
659 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
660 //printf("--- robot move by ... turn cw\n");
661 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
665 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
668 case 2: // puck not found
669 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
672 //printf("lfp_status: %d\n", lfp_status);
674 case EV_PUCK_REACHABLE: // puck found
676 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
679 case EV_ACTION_ERROR: // look for puck does not send this event
683 case EV_GOAL_NOT_REACHABLE:
684 case EV_SHORT_TIME_TO_END:
687 DBG_PRINT_EVENT("unhandled event");
707 case EV_GOAL_NOT_REACHABLE:
708 case EV_SHORT_TIME_TO_END:
710 case EV_ACTION_ERROR:
711 case EV_PUCK_REACHABLE:
713 DBG_PRINT_EVENT("unhandled event");
727 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
729 robot.fsm.main.debug_states = 1;
730 robot.fsm.motion.debug_states = 1;
731 robot.fsm.act.debug_states = 1;
733 robot.fsm.main.state = &fsm_state_main_init;
736 if (rv) error(1, errno, "robot_start() returned %d\n", rv);