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 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 int pucks_at_once; // number of pucks to load at once (maximum number of pucks we want to have in robot)
70 /************************************************************************
71 * Definition of particular "free pucks pick up sequences" and related stuff
72 ************************************************************************/
74 // FIXME: has to be redefined and tested
75 const int free_puck_pick_up_sequence[][6][3] = {
76 /* nx, ny, arrival angle */
159 const int prefered_acropolis_approach_angles[][3] = {
163 {130, 160, 200}, // FIXME... fix these
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
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);
223 void robot_goto_acropolis(int phi)
226 ACROPOLIS_CENTER_X + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*cos(DEG2RAD(phi)),
227 ACROPOLIS_CENTER_Y + (ACROPOLIS_RADIUS + ROBOT_AXIS_TO_PUCK_M + 0.07)*sin(DEG2RAD(phi)),
228 ARRIVE_FROM(DEG2RAD(phi+180), 0.07), &tcSlow);
231 void robot_goto_puck_in_grid(int nx, int ny, int phi)
233 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
235 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
236 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
237 ARRIVE_FROM(DEG2RAD(phi+180), 0.1), &tcSlow);
240 void robot_goto_next_puck_in_sequence(int lot, int puck_number)
242 robot_goto_puck_in_grid(
243 free_puck_pick_up_sequence[lot][puck_number][0],
244 free_puck_pick_up_sequence[lot][puck_number][1],
245 free_puck_pick_up_sequence[lot][puck_number][2]);
248 /************************************************************************
249 * FSM STATES DECLARATION
250 ************************************************************************/
252 /* initial and starting states */
253 FSM_STATE_DECL(init);
254 FSM_STATE_DECL(wait_for_start);
255 /* strategies related states */
256 FSM_STATE_DECL(decide_what_next);
257 FSM_STATE_DECL(collect_free_pucks);
258 FSM_STATE_DECL(deposit_at_acropolis);
259 /* movement states */
260 FSM_STATE_DECL(approach_acropolis);
261 FSM_STATE_DECL(simple_construction_zone_approach);
262 FSM_STATE_DECL(approach_our_static_dispenser);
263 FSM_STATE_DECL(approach_opponents_static_dispenser);
264 /* States handling ACT's actions (SUBFSMs) */
265 FSM_STATE_DECL(load_the_puck);
266 FSM_STATE_DECL(grasp_the_puck);
267 FSM_STATE_DECL(look_for_puck_ahead);
268 FSM_STATE_DECL(look_around_for_puck);
270 /************************************************************************
271 * INITIAL AND STARTING STATES
272 ************************************************************************/
279 free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
280 pucks_at_once = 4; // number of pucks to load at once (maximum number of pucks we want to have in robot)
281 tcFast = trajectoryConstraintsDefault;
283 tcSlow = trajectoryConstraintsDefault;
287 tcSlow.maxangacc = 1;
288 tcVerySlow = trajectoryConstraintsDefault;
289 tcVerySlow.maxv = 0.1;
290 tcVerySlow.maxacc = 0.05;
291 tcVerySlow.maxomega = 0.7;
292 tcVerySlow.maxangacc = 1;
293 FSM_TRANSITION(wait_for_start);
300 FSM_STATE(wait_for_start)
304 printf("COMPETITION mode set\n");
307 #ifdef WAIT_FOR_START
316 /* start competition timer */
317 pthread_create(&thid, NULL, timing_thread, NULL);
318 robot_set_est_pos_trans(0.16,
319 PLAYGROUND_HEIGHT_M - 0.16,
321 FSM_TRANSITION(decide_what_next);
326 case EV_GOAL_NOT_REACHABLE: // currently not used
327 case EV_SHORT_TIME_TO_END:
330 case EV_ACTION_ERROR:
331 case EV_PUCK_REACHABLE:
333 DBG_PRINT_EVENT("unhandled event");
340 /************************************************************************
341 * STRATEGIES RELATED STATES
342 ************************************************************************/
344 FSM_STATE(decide_what_next)
348 if(robot.pucks_inside == pucks_at_once) {
349 FSM_TRANSITION(deposit_at_acropolis);
351 if(robot.pucks_inside < pucks_at_once && free_puck_to_try_to_get_next < 6) {
352 FSM_TRANSITION(collect_free_pucks);
361 case EV_GOAL_NOT_REACHABLE: // currently not used
362 case EV_SHORT_TIME_TO_END:
363 FSM_TRANSITION(deposit_at_acropolis); //FIXME fsm transition to decide_what_next
364 break; // everywhere and ...
366 case EV_ACTION_ERROR:
367 case EV_PUCK_REACHABLE:
369 DBG_PRINT_EVENT("unhandled event");
376 FSM_STATE(deposit_at_acropolis)
378 static int deposit_status;
382 SUBFSM_TRANSITION(approach_acropolis, NULL);
385 //if ((bool)FSM_EVENT_INT == true) {
387 FSM_SIGNAL(ACT, EV_PREPARE_THE_UNLOAD, (void*)floor);
392 switch(deposit_status) {
394 robot_move_by(0.11, NO_TURN(), &tcSlow);
397 robot_move_by(-0.07, NO_TURN(), &tcSlow);
403 switch(deposit_status) {
405 FSM_SIGNAL(ACT, EV_UNLOAD_PUCKS, NULL);
408 robot_move_by(0.08, NO_TURN(), &tcVerySlow);
412 robot_move_by(-0.15, NO_TURN(), &tcSlow);
416 FSM_TRANSITION(decide_what_next);
417 FSM_SIGNAL(ACT, EV_FREE_SPACE, NULL);
421 case EV_SHORT_TIME_TO_END:
422 //FSM_TRANSITION(deposit_at_acropolis);
426 case EV_GOAL_NOT_REACHABLE: // currently not used
428 case EV_ACTION_ERROR:
429 case EV_PUCK_REACHABLE:
431 DBG_PRINT_EVENT("unhandled event");
438 FSM_STATE(collect_free_pucks)
440 // game configuration... detected lot number is stored in robot.game_conf
443 robot_goto_next_puck_in_sequence(robot.game_conf, free_puck_to_try_to_get_next);
445 case EV_MOTION_DONE: {
446 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
447 SUBFSM_TRANSITION(load_the_puck, NULL);
451 switch(FSM_EVENT_RET_VAL) {
453 printf(">>>>>> Loading the puck succeeded\n");
456 printf(">>>>>> Loading the puck FAILED\n");
459 free_puck_to_try_to_get_next++;
460 FSM_TRANSITION(decide_what_next);
462 case EV_SHORT_TIME_TO_END:
463 FSM_TRANSITION(deposit_at_acropolis);
465 case EV_PUCK_REACHABLE:
469 case EV_GOAL_NOT_REACHABLE: // currently not used
471 case EV_ACTION_ERROR:
473 DBG_PRINT_EVENT("unhandled event");
480 /************************************************************************
482 ************************************************************************/
484 FSM_STATE(approach_acropolis)
488 robot_goto_acropolis(prefered_acropolis_approach_angles[(int)robot.game_conf][(free_puck_to_try_to_get_next-1)/2]);
492 // FIXME SUBFSM_RET((void*)true);
494 case EV_GOAL_NOT_REACHABLE: // currently not used
496 case EV_SHORT_TIME_TO_END:
503 case EV_ACTION_ERROR:
504 case EV_PUCK_REACHABLE:
506 DBG_PRINT_EVENT("unhandled event");
513 FSM_STATE(simple_construction_zone_approach)
517 robot_trajectory_new(&tcFast);
518 robot_trajectory_add_point_trans(0.9, 1);
519 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
522 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
524 case EV_SHORT_TIME_TO_END:
525 FSM_TRANSITION(deposit_at_acropolis);
531 case EV_GOAL_NOT_REACHABLE: // currently not used
533 case EV_ACTION_ERROR:
534 case EV_PUCK_REACHABLE:
536 DBG_PRINT_EVENT("unhandled event");
543 FSM_STATE(approach_our_static_dispenser)
547 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
549 robot_trajectory_new(&tc);
551 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
552 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
553 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
554 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
559 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
560 printf("Arrived to the static dispenser\n");
563 printf("A Puck picked up\n");
565 case EV_SHORT_TIME_TO_END:
566 FSM_TRANSITION(deposit_at_acropolis);
571 case EV_GOAL_NOT_REACHABLE: // currently not used
573 case EV_ACTION_ERROR:
574 case EV_PUCK_REACHABLE:
576 DBG_PRINT_EVENT("unhandled event");
583 FSM_STATE(approach_opponents_static_dispenser)
587 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
589 robot_trajectory_new(&tc);
591 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
592 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
593 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
594 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
599 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
600 printf("Arrived to the static dispenser\n");
603 printf("A Puck picked up\n");
605 case EV_SHORT_TIME_TO_END:
606 FSM_TRANSITION(deposit_at_acropolis);
611 case EV_GOAL_NOT_REACHABLE: // currently not used
613 case EV_ACTION_ERROR:
614 case EV_PUCK_REACHABLE:
616 DBG_PRINT_EVENT("unhandled event");
623 /************************************************************************
624 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
625 ************************************************************************/
627 FSM_STATE(load_the_puck)
629 static int puck_load_attempt_count;
632 puck_load_attempt_count = 0;
633 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
637 robot_move_by(0.02, NO_TURN(), &tcSlow);
640 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
643 SUBFSM_RET((void *)LOAD_SUCCESS);
645 case EV_ACTION_ERROR:
646 puck_load_attempt_count++;
647 if (puck_load_attempt_count > 2) {
648 SUBFSM_RET((void *)LOAD_FAIL);
650 robot_move_by(0.02, NO_TURN(), &tcSlow);
653 case EV_SHORT_TIME_TO_END:
654 FSM_TRANSITION(deposit_at_acropolis);
658 case EV_GOAL_NOT_REACHABLE: // currently not used
660 case EV_PUCK_REACHABLE:
662 DBG_PRINT_EVENT("unhandled event");
669 /* of no use without the sharp sensor measuring "puck distance"
670 FSM_STATE(look_around_for_puck)
672 static int lfp_status = 0;
673 const static int scatter_angle = 20;
674 static struct robot_pos_type orig_position;
678 orig_position = robot.ref_pos;
679 ROBOT_UNLOCK(ref_pos);
680 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
681 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
682 //printf("lfp_status: %d\n", lfp_status);
685 switch (lfp_status) {
687 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
688 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
689 //printf("--- robot move by ... turn cw\n");
690 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
694 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
697 case 2: // puck not found
698 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
701 //printf("lfp_status: %d\n", lfp_status);
703 case EV_PUCK_REACHABLE: // puck found
705 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
708 case EV_ACTION_ERROR: // look for puck does not send this event
712 case EV_GOAL_NOT_REACHABLE: // currently not used
713 case EV_SHORT_TIME_TO_END:
716 DBG_PRINT_EVENT("unhandled event");
731 case EV_SHORT_TIME_TO_END:
737 case EV_GOAL_NOT_REACHABLE: // currently not used
739 case EV_ACTION_ERROR:
740 case EV_PUCK_REACHABLE:
742 DBG_PRINT_EVENT("unhandled event");
756 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
758 robot.fsm.main.debug_states = 1;
759 robot.fsm.motion.debug_states = 1;
760 robot.fsm.act.debug_states = 1;
762 robot.fsm.main.state = &fsm_state_main_init;
765 if (rv) error(1, errno, "robot_start() returned %d\n", rv);