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)
70 /************************************************************************
71 * Definition of particular "free pucks pick up sequences"
72 ************************************************************************/
74 const int free_puck_pick_up_sequence[][6][3] = {
81 {0, 0, 0}, // FIXME: test last two pucks
89 {0, 0, 10}, // FIXME: test last two pucks
97 {0, 0, 0}, // FIXME: test last two pucks
105 {2, 0, 90}, // FIXME: test last two pucks
113 {0, 0, 0}, // FIXME: test last two pucks
121 {0, 0, 0}, // FIXME: test last two pucks
129 {1, 0, 45}, // FIXME: test last two pucks
137 {2, 1, -90}, // FIXME: test last two pucks
145 {2, 1, -90}, // FIXME: test last two pucks
153 {1, 2, -90}, // FIXME: test last two pucks
157 /************************************************************************
158 * NOTES ON DATA WE NEED TO STORE
159 ************************************************************************/
163 - puck (column element) dispensers status (number of pucks)
164 - their max. capacity is 5
165 - lintel dispensers status
166 - free column elements configuration and their positions
167 - free pucks configuration (lot number)
169 - puck stack status (puck count)
170 - lintel holder status
173 /************************************************************************
175 ************************************************************************/
178 * Competition timer. Stop robot when the timer exceeds.
181 void *timing_thread(void *arg)
183 struct timespec start;
185 clock_gettime(CLOCK_MONOTONIC, &start);
189 t.tv_sec = start.tv_sec+sec; \
190 t.tv_nsec = start.tv_nsec; \
191 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); \
195 robot.use_back_switch = true;
196 printf("Back switch not ignored\n");
198 WAIT(TIME_TO_DEPOSITE);
199 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
201 WAIT(COMPETITION_TIME);
202 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
209 * Get position of the point when we know the distance and angle to turn.
211 * FIXME (F.J.): - there used to be non-actual parameter documentation
212 * - what was this function good for? (not used anywhere)
214 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
215 double l, double phi)
217 ref->x = est->x + l*cos(est->phi + phi);
218 ref->y = est->y + l*sin(est->phi + phi);
219 ref->phi = est->phi + phi;
222 void robot_goto_point(struct ref_pos_type des_pos)
224 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
227 robot_trajectory_new(&tc);
228 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
231 void robot_go_backward_to_point(struct ref_pos_type des_pos)
233 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
236 robot_trajectory_new_backward(&tc);
237 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
240 void robot_goto_puck_in_grid(int nx, int ny, int phi)
242 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
243 robot_trajectory_new(&tcSlow);
244 robot_trajectory_add_point_trans(
245 pp.x + (ROBOT_AXIS_TO_PUCK_M+0.10)*cos(DEG2RAD(phi)),
246 pp.y + (ROBOT_AXIS_TO_PUCK_M+0.10)*sin(DEG2RAD(phi)));
247 robot_trajectory_add_final_point_trans(
248 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
249 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
250 TURN(fmod(DEG2RAD(phi+180), 2.0*M_PI)));
251 /* robot_goto_trans( // does not exist
252 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
253 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
254 TURN(fmod(DEG2RAD(phi+180), 2.0*M_PI))); */
257 /************************************************************************
258 * FSM STATES DECLARATION
259 ************************************************************************/
261 /* initial and starting states */
262 FSM_STATE_DECL(init);
263 FSM_STATE_DECL(wait_for_start);
264 /* strategies related states */
265 FSM_STATE_DECL(decide_what_next);
266 FSM_STATE_DECL(collect_free_pucks);
267 FSM_STATE_DECL(deposit_at_acropolis);
268 /* movement states */
269 FSM_STATE_DECL(simple_construction_zone_approach);
270 FSM_STATE_DECL(approach_our_static_dispenser);
271 FSM_STATE_DECL(approach_opponents_static_dispenser);
272 /* States handling ACT's actions (SUBFSMs) */
273 FSM_STATE_DECL(load_the_puck);
274 FSM_STATE_DECL(grasp_the_puck);
275 FSM_STATE_DECL(look_for_puck_ahead);
276 FSM_STATE_DECL(look_around_for_puck);
278 /************************************************************************
279 * INITIAL AND STARTING STATES
280 ************************************************************************/
286 free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
287 pucks_at_once = 2; // number of pucks to load at once (maximum number of pucks we want to have in robot)
288 tcFast = trajectoryConstraintsDefault;
290 tcSlow = trajectoryConstraintsDefault;
292 FSM_TRANSITION(wait_for_start);
299 FSM_STATE(wait_for_start)
303 printf("COMPETITION mode set");
306 #ifdef WAIT_FOR_START
314 /* start competition timer */
315 pthread_create(&thid, NULL, timing_thread, NULL);
316 robot_set_est_pos_trans(0.16,
317 PLAYGROUND_HEIGHT_M - 0.16,
320 FSM_TRANSITION(collect_free_pucks);
322 /*robot_trajectory_new(&tcSlow);
323 struct puck_pos pp = free_puck_pos(0, 2, 0); // puck position
324 robot_trajectory_add_final_point_trans(
327 TURN(DEG2RAD(0))); */
328 //FSM_TRANSITION(approach_our_static_dispenser);
329 //robot_goto_puck_in_grid(0, 1, 2, 270);
331 FSM_SIGNAL(ACT, EV_GRASP_THE_PUCK, NULL);
337 FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
343 case EV_GOAL_NOT_REACHABLE:
344 case EV_SHORT_TIME_TO_END:
347 case EV_ACTION_ERROR:
348 case EV_PUCK_REACHABLE:
350 DBG_PRINT_EVENT("unhandled event");
357 /************************************************************************
358 * STRATEGIES RELATED STATES
359 ************************************************************************/
361 FSM_STATE(decide_what_next)
365 if(robot.pucks_inside == pucks_at_once) {
368 if(robot.pucks_inside < pucks_at_once && free_puck_to_try_to_get_next < 6) {
369 FSM_TRANSITION(collect_free_pucks);
378 case EV_GOAL_NOT_REACHABLE:
379 case EV_SHORT_TIME_TO_END:
381 case EV_ACTION_ERROR:
382 case EV_PUCK_REACHABLE:
384 DBG_PRINT_EVENT("unhandled event");
391 FSM_STATE(deposit_at_acropolis)
401 case EV_GOAL_NOT_REACHABLE:
402 case EV_SHORT_TIME_TO_END:
404 case EV_ACTION_ERROR:
405 case EV_PUCK_REACHABLE:
407 DBG_PRINT_EVENT("unhandled event");
414 static void robot_goto_next_puck_in_sequence(int lot, int puck_number)
416 robot_goto_puck_in_grid(
417 free_puck_pick_up_sequence[lot][puck_number][0],
418 free_puck_pick_up_sequence[lot][puck_number][1],
419 free_puck_pick_up_sequence[lot][puck_number][2]);
422 FSM_STATE(collect_free_pucks)
424 static const int lot = 7; // this variable location is temporary...; going to be received from the camera
427 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
429 case EV_MOTION_DONE: {
430 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
431 SUBFSM_TRANSITION(load_the_puck, NULL);
435 switch(FSM_EVENT_RET_VAL) {
437 free_puck_to_try_to_get_next++;
438 printf(">>>>>> Loading the puck succeeded\n");
441 printf(">>>>>> Loading the puck FAILED\n");
445 case EV_PUCK_REACHABLE:
449 case EV_GOAL_NOT_REACHABLE:
450 case EV_SHORT_TIME_TO_END:
452 case EV_ACTION_ERROR:
454 DBG_PRINT_EVENT("unhandled event");
461 /************************************************************************
463 ************************************************************************/
465 FSM_STATE(simple_construction_zone_approach)
469 robot_trajectory_new(&tcFast);
470 robot_trajectory_add_point_trans(0.9, 1);
471 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
474 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
480 case EV_GOAL_NOT_REACHABLE:
481 case EV_SHORT_TIME_TO_END:
483 case EV_ACTION_ERROR:
484 case EV_PUCK_REACHABLE:
486 DBG_PRINT_EVENT("unhandled event");
493 FSM_STATE(approach_our_static_dispenser)
497 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
499 robot_trajectory_new(&tc);
501 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
502 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
503 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
504 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
509 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
510 printf("Arrived to the static dispenser\n");
513 printf("A Puck picked up\n");
518 case EV_GOAL_NOT_REACHABLE:
519 case EV_SHORT_TIME_TO_END:
520 //case EV_PUCK_REACHABLE: // FIXME: handle this
522 case EV_ACTION_ERROR:
523 case EV_PUCK_REACHABLE:
525 DBG_PRINT_EVENT("unhandled event");
532 FSM_STATE(approach_opponents_static_dispenser)
536 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
538 robot_trajectory_new(&tc);
540 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
541 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
542 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
543 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
548 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
549 printf("Arrived to the static dispenser\n");
552 printf("A Puck picked up\n");
557 case EV_GOAL_NOT_REACHABLE:
558 case EV_SHORT_TIME_TO_END:
559 //case EV_PUCK_REACHABLE: // FIXME: handle this
561 case EV_ACTION_ERROR:
562 case EV_PUCK_REACHABLE:
564 DBG_PRINT_EVENT("unhandled event");
571 /************************************************************************
572 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
573 ************************************************************************/
575 FSM_STATE(load_the_puck)
577 static int puck_load_attempt_count;
580 puck_load_attempt_count = 0;
581 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
585 robot_move_by(0.02, NO_TURN(), &tcSlow);
588 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
591 SUBFSM_RET((void *)LOAD_SUCCESS);
593 case EV_ACTION_ERROR:
594 puck_load_attempt_count++;
595 if (puck_load_attempt_count > 2) {
596 SUBFSM_RET((void *)LOAD_FAIL);
598 robot_move_by(0.02, NO_TURN(), &tcSlow);
603 case EV_GOAL_NOT_REACHABLE:
604 case EV_SHORT_TIME_TO_END:
606 case EV_PUCK_REACHABLE:
608 DBG_PRINT_EVENT("unhandled event");
615 /* of no use without the sharp sensor measuring "puck distance"
616 FSM_STATE(look_around_for_puck)
618 static int lfp_status = 0;
619 const static int scatter_angle = 20;
620 static struct ref_pos_type orig_position;
624 orig_position = robot.ref_pos;
625 ROBOT_UNLOCK(ref_pos);
626 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
627 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
628 //printf("lfp_status: %d\n", lfp_status);
631 switch (lfp_status) {
633 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
634 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
635 //printf("--- robot move by ... turn cw\n");
636 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
640 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
643 case 2: // puck not found
644 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
647 //printf("lfp_status: %d\n", lfp_status);
649 case EV_PUCK_REACHABLE: // puck found
651 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
654 case EV_ACTION_ERROR: // look for puck does not send this event
658 case EV_GOAL_NOT_REACHABLE:
659 case EV_SHORT_TIME_TO_END:
662 DBG_PRINT_EVENT("unhandled event");
682 case EV_GOAL_NOT_REACHABLE:
683 case EV_SHORT_TIME_TO_END:
685 case EV_ACTION_ERROR:
686 case EV_PUCK_REACHABLE:
688 DBG_PRINT_EVENT("unhandled event");
702 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
704 robot.fsm.main.debug_states = 1;
705 robot.fsm.motion.debug_states = 1;
706 robot.fsm.act.debug_states = 1;
708 robot.fsm.main.state = &fsm_state_main_init;
711 if (rv) error(1, errno, "robot_start() returned %d\n", rv);