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>
29 #include <actuators.h>
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 */
46 /************************************************************************
47 * SUBFSM's return values ...
48 ************************************************************************/
55 #define FSM_EVENT_RET_VAL ((subfsm_ret_val)FSM_EVENT_INT)
57 /************************************************************************
58 * Trajectory constraints used, are initialized in the init state
59 ************************************************************************/
61 struct TrajectoryConstraints tcFast, tcSlow, tcVerySlow;
63 /************************************************************************
64 * Variables (short_time_to_end and variables related to puck collecting)
65 ************************************************************************/
67 int free_puck_to_try_to_get_next; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
68 const int pucks_at_once = 4; // number of pucks to load at once (maximum number of pucks we want to have in robot)
69 bool short_time_to_end;
71 /************************************************************************
72 * Definition of particular "free pucks pick up sequences" and related stuff
73 ************************************************************************/
75 // FIXME: has to be redefined and tested
76 const int free_puck_pick_up_sequence[][6][3] = {
77 /* nx, ny, arrival angle */
160 const int preferred_acropolis_approach_angles[][3] = {
164 {130, 160, 200}, // FIXME... fix these
165 {130, 160, 200}, // FIXME... fix these
166 {130, 160, 200}, // FIXME... fix these
167 {130, 160, 200}, // FIXME... fix these
168 {130, 160, 200}, // FIXME... fix these
169 {130, 160, 200}, // FIXME... fix these
170 {130, 160, 200}, // FIXME... fix these
174 const int universal_free_puck_pick_up_sequence[12][3] = {
189 const int preferred_universal_acropolis_approach_angles[][3] = {
192 /************************************************************************
193 * NOTES ON DATA WE NEED TO STORE
194 ************************************************************************/
198 - puck (column element) dispensers status (number of pucks)
199 - their max. capacity is 5
200 - lintel dispensers status
201 - free column elements configuration and their positions
202 - free pucks configuration (lot number)
204 - puck stack status (puck count)
205 - lintel holder status
208 /************************************************************************
210 ************************************************************************/
213 * Competition timer. Stop robot when the timer exceeds.
216 void *timing_thread(void *arg)
218 struct timespec start;
220 clock_gettime(CLOCK_MONOTONIC, &start);
224 t.tv_sec = start.tv_sec+sec; \
225 t.tv_nsec = start.tv_nsec; \
226 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); \
230 robot.use_back_switch = true;
231 printf("Back switch not ignored\n");
233 WAIT(TIME_TO_DEPOSITE);
234 short_time_to_end = true;
236 WAIT(COMPETITION_TIME);
237 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
243 void robot_goto_acropolis(int phi)
246 ACROPOLIS_CENTER_X + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*cos(DEG2RAD(phi)),
247 ACROPOLIS_CENTER_Y + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*sin(DEG2RAD(phi)),
248 ARRIVE_FROM(DEG2RAD(phi+180), 0.07), &tcSlow);
251 void robot_goto_puck_in_grid(int nx, int ny, int phi)
253 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
255 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
256 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
257 ARRIVE_FROM(DEG2RAD(phi+180), 0.1), &tcSlow);
260 void robot_goto_next_puck_in_sequence(int lot, int puck_number)
262 robot_goto_puck_in_grid(
263 free_puck_pick_up_sequence[lot][puck_number][0],
264 free_puck_pick_up_sequence[lot][puck_number][1],
265 free_puck_pick_up_sequence[lot][puck_number][2]);
268 /************************************************************************
269 * FSM STATES DECLARATION
270 ************************************************************************/
272 /* initial and starting states */
273 FSM_STATE_DECL(init);
274 FSM_STATE_DECL(wait_for_start);
275 /* strategies related states */
276 FSM_STATE_DECL(decide_what_next);
277 FSM_STATE_DECL(collect_free_pucks);
278 FSM_STATE_DECL(deposit_at_acropolis);
279 /* movement states */
280 FSM_STATE_DECL(approach_acropolis);
281 FSM_STATE_DECL(simple_construction_zone_approach);
282 FSM_STATE_DECL(approach_our_static_dispenser);
283 FSM_STATE_DECL(approach_opponents_static_dispenser);
284 /* States handling ACT's actions (SUBFSMs) */
285 FSM_STATE_DECL(load_the_puck);
286 FSM_STATE_DECL(look_around_for_puck);
288 /************************************************************************
289 * INITIAL AND STARTING STATES
290 ************************************************************************/
296 short_time_to_end = false;
298 free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
299 tcFast = trajectoryConstraintsDefault;
301 tcSlow = trajectoryConstraintsDefault;
305 tcSlow.maxangacc = 1;
306 tcVerySlow = trajectoryConstraintsDefault;
307 tcVerySlow.maxv = 0.1;
308 tcVerySlow.maxacc = 0.05;
309 tcVerySlow.maxomega = 0.7;
310 tcVerySlow.maxangacc = 1;
311 FSM_TRANSITION(wait_for_start);
318 FSM_STATE(wait_for_start)
322 printf("COMPETITION mode set\n");
325 #ifdef WAIT_FOR_START
334 /* start competition timer */
335 pthread_create(&thid, NULL, timing_thread, NULL);
336 robot_set_est_pos_trans(0.16,
337 PLAYGROUND_HEIGHT_M - 0.16,
339 FSM_TRANSITION(decide_what_next);
344 case EV_GOAL_NOT_REACHABLE: // currently not used
345 //case EV_SHORT_TIME_TO_END:
348 case EV_ACTION_ERROR:
349 case EV_PUCK_REACHABLE:
351 DBG_PRINT_EVENT("unhandled event");
358 /************************************************************************
359 * STRATEGIES RELATED STATES
360 ************************************************************************/
362 FSM_STATE(decide_what_next)
366 if(short_time_to_end) {
367 if(robot.pucks_inside > 0) {
368 FSM_TRANSITION(deposit_at_acropolis);
371 if(robot.pucks_inside == pucks_at_once) {
372 FSM_TRANSITION(deposit_at_acropolis);
374 if(robot.pucks_inside < pucks_at_once && free_puck_to_try_to_get_next < 6) {
375 FSM_TRANSITION(collect_free_pucks);
384 case EV_GOAL_NOT_REACHABLE: // currently not used
385 //case EV_SHORT_TIME_TO_END:
387 case EV_ACTION_ERROR:
388 case EV_PUCK_REACHABLE:
390 DBG_PRINT_EVENT("unhandled event");
397 FSM_STATE(deposit_at_acropolis)
399 static int deposit_status;
403 SUBFSM_TRANSITION(approach_acropolis, NULL);
406 //if ((bool)FSM_EVENT_INT == true) {
408 FSM_SIGNAL(ACT, EV_PREPARE_THE_UNLOAD, (void*)floor);
413 switch(deposit_status) {
415 robot_move_by(0.11, NO_TURN(), &tcSlow);
418 robot_move_by(-0.07, NO_TURN(), &tcSlow);
424 switch(deposit_status) {
426 FSM_SIGNAL(ACT, EV_UNLOAD_PUCKS, NULL);
429 robot_move_by(0.08, NO_TURN(), &tcVerySlow);
433 robot_move_by(-0.15, NO_TURN(), &tcSlow);
437 FSM_SIGNAL(ACT, EV_FREE_SPACE, NULL);
438 FSM_TRANSITION(decide_what_next);
442 // case EV_SHORT_TIME_TO_END:
445 case EV_GOAL_NOT_REACHABLE: // currently not used
447 case EV_ACTION_ERROR:
448 case EV_PUCK_REACHABLE:
450 DBG_PRINT_EVENT("unhandled event");
457 FSM_STATE(collect_free_pucks)
459 // game configuration... detected lot number is stored in robot.game_conf
462 robot_goto_next_puck_in_sequence(robot.game_conf, free_puck_to_try_to_get_next);
464 case EV_MOTION_DONE: {
465 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
466 SUBFSM_TRANSITION(load_the_puck, NULL);
470 switch(FSM_EVENT_RET_VAL) {
472 printf(">>>>>> Loading the puck succeeded\n");
475 printf(">>>>>> Loading the puck FAILED\n");
478 free_puck_to_try_to_get_next++;
479 FSM_TRANSITION(decide_what_next);
481 //case EV_SHORT_TIME_TO_END:
482 case EV_PUCK_REACHABLE:
486 case EV_GOAL_NOT_REACHABLE: // currently not used
488 case EV_ACTION_ERROR:
490 DBG_PRINT_EVENT("unhandled event");
497 /************************************************************************
499 ************************************************************************/
501 FSM_STATE(approach_acropolis)
505 robot_goto_acropolis(preferred_acropolis_approach_angles[(int)robot.game_conf][(free_puck_to_try_to_get_next-1)/2]);
509 // FIXME SUBFSM_RET((void*)true);
511 case EV_GOAL_NOT_REACHABLE: // currently not used
513 //case EV_SHORT_TIME_TO_END:
519 case EV_ACTION_ERROR:
520 case EV_PUCK_REACHABLE:
522 DBG_PRINT_EVENT("unhandled event");
529 FSM_STATE(simple_construction_zone_approach)
533 robot_trajectory_new(&tcFast);
534 robot_trajectory_add_point_trans(0.9, 1);
535 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
538 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
540 //case EV_SHORT_TIME_TO_END:
545 case EV_GOAL_NOT_REACHABLE: // currently not used
547 case EV_ACTION_ERROR:
548 case EV_PUCK_REACHABLE:
550 DBG_PRINT_EVENT("unhandled event");
557 FSM_STATE(approach_our_static_dispenser)
561 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
563 robot_trajectory_new(&tc);
565 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
566 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
567 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
568 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");
579 //case EV_SHORT_TIME_TO_END:
583 case EV_GOAL_NOT_REACHABLE: // currently not used
585 case EV_ACTION_ERROR:
586 case EV_PUCK_REACHABLE:
588 DBG_PRINT_EVENT("unhandled event");
595 FSM_STATE(approach_opponents_static_dispenser)
599 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
601 robot_trajectory_new(&tc);
603 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
604 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
605 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
606 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
611 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
612 printf("Arrived to the static dispenser\n");
615 printf("A Puck picked up\n");
617 //case EV_SHORT_TIME_TO_END:
621 case EV_GOAL_NOT_REACHABLE: // currently not used
623 case EV_ACTION_ERROR:
624 case EV_PUCK_REACHABLE:
626 DBG_PRINT_EVENT("unhandled event");
633 /************************************************************************
634 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
635 ************************************************************************/
637 FSM_STATE(load_the_puck)
639 static int puck_load_attempt_count;
642 puck_load_attempt_count = 0;
643 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
647 robot_move_by(0.02, NO_TURN(), &tcSlow);
650 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
653 SUBFSM_RET((void *)LOAD_SUCCESS);
655 case EV_ACTION_ERROR:
656 puck_load_attempt_count++;
657 if (puck_load_attempt_count > 1) {
658 SUBFSM_RET((void *)LOAD_FAIL);
660 robot_move_by(0.02, NO_TURN(), &tcSlow);
663 //case EV_SHORT_TIME_TO_END:
666 case EV_GOAL_NOT_REACHABLE: // currently not used
668 case EV_PUCK_REACHABLE:
670 DBG_PRINT_EVENT("unhandled event");
682 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
684 robot.fsm.main.debug_states = 1;
685 robot.fsm.motion.debug_states = 1;
686 robot.fsm.act.debug_states = 1;
688 robot.fsm.main.state = &fsm_state_main_init;
691 if (rv) error(1, errno, "robot_start() returned %d\n", rv);