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(collect_free_pucks);
266 /* movement states */
267 FSM_STATE_DECL(simple_construction_zone_approach);
268 FSM_STATE_DECL(approach_our_static_dispenser);
269 FSM_STATE_DECL(approach_opponents_static_dispenser);
270 /* States handling ACT's actions (SUBFSMs) */
271 FSM_STATE_DECL(load_the_puck);
272 FSM_STATE_DECL(grasp_the_puck);
273 FSM_STATE_DECL(look_for_puck_ahead);
274 FSM_STATE_DECL(look_around_for_puck);
276 /************************************************************************
277 * INITIAL AND STARTING STATES
278 ************************************************************************/
284 free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
285 pucks_at_once = 2; // number of pucks to load at once (maximum number of pucks we want to have in robot)
286 tcFast = trajectoryConstraintsDefault;
288 tcSlow = trajectoryConstraintsDefault;
290 FSM_TRANSITION(wait_for_start);
297 FSM_STATE(wait_for_start)
301 printf("COMPETITION mode set");
304 #ifdef WAIT_FOR_START
312 /* start competition timer */
313 pthread_create(&thid, NULL, timing_thread, NULL);
314 robot_set_est_pos_trans(0.16,
315 PLAYGROUND_HEIGHT_M - 0.16,
318 FSM_TRANSITION(collect_free_pucks);
320 /*robot_trajectory_new(&tcSlow);
321 struct puck_pos pp = free_puck_pos(0, 2, 0); // puck position
322 robot_trajectory_add_final_point_trans(
325 TURN(DEG2RAD(0))); */
326 //FSM_TRANSITION(approach_our_static_dispenser);
327 //robot_goto_puck_in_grid(0, 1, 2, 270);
329 FSM_SIGNAL(ACT, EV_GRASP_THE_PUCK, NULL);
335 FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
341 case EV_GOAL_NOT_REACHABLE:
342 case EV_SHORT_TIME_TO_END:
345 case EV_ACTION_ERROR:
346 case EV_PUCK_REACHABLE:
348 DBG_PRINT_EVENT("unhandled event");
355 /************************************************************************
356 * STRATEGIES RELATED STATES
357 ************************************************************************/
359 static void robot_goto_next_puck_in_sequence(int lot, int puck_number)
361 robot_goto_puck_in_grid(
362 free_puck_pick_up_sequence[lot][puck_number][0],
363 free_puck_pick_up_sequence[lot][puck_number][1],
364 free_puck_pick_up_sequence[lot][puck_number][2]);
367 FSM_STATE(collect_free_pucks)
369 static const int lot = 7; // this variable location is temporary...; going to be received from the camera
372 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
374 case EV_MOTION_DONE: {
375 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
376 SUBFSM_TRANSITION(load_the_puck, NULL);
380 switch(FSM_EVENT_RET_VAL) {
382 printf(">>>>>> Loading the puck succeeded\n");
383 if(free_puck_to_try_to_get_next<4) {
384 free_puck_to_try_to_get_next++;
385 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
389 printf(">>>>>> Loading the puck FAILED\n");
390 if(free_puck_to_try_to_get_next<6) { // FIXME: test number of pucks loaded!!
391 free_puck_to_try_to_get_next++;
392 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
394 // FIXME (TODO): transition to next strategy state
399 case EV_PUCK_REACHABLE:
401 printf("-----reached some free puck, hopefully no. %d\n", free_puck_to_try_to_get_next);
402 SUBFSM_TRANSITION(load_the_puck, NULL);
407 case EV_GOAL_NOT_REACHABLE:
408 case EV_SHORT_TIME_TO_END:
410 case EV_ACTION_ERROR:
412 DBG_PRINT_EVENT("unhandled event");
419 /************************************************************************
421 ************************************************************************/
423 FSM_STATE(simple_construction_zone_approach)
427 robot_trajectory_new(&tcFast);
428 robot_trajectory_add_point_trans(0.9, 1);
429 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
432 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
438 case EV_GOAL_NOT_REACHABLE:
439 case EV_SHORT_TIME_TO_END:
441 case EV_ACTION_ERROR:
442 case EV_PUCK_REACHABLE:
444 DBG_PRINT_EVENT("unhandled event");
451 FSM_STATE(approach_our_static_dispenser)
455 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
457 robot_trajectory_new(&tc);
459 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
460 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
461 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
462 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
467 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
468 printf("Arrived to the static dispenser\n");
471 printf("A Puck picked up\n");
476 case EV_GOAL_NOT_REACHABLE:
477 case EV_SHORT_TIME_TO_END:
478 //case EV_PUCK_REACHABLE: // FIXME: handle this
480 case EV_ACTION_ERROR:
481 case EV_PUCK_REACHABLE:
483 DBG_PRINT_EVENT("unhandled event");
490 FSM_STATE(approach_opponents_static_dispenser)
494 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
496 robot_trajectory_new(&tc);
498 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
499 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
500 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
501 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
506 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
507 printf("Arrived to the static dispenser\n");
510 printf("A Puck picked up\n");
515 case EV_GOAL_NOT_REACHABLE:
516 case EV_SHORT_TIME_TO_END:
517 //case EV_PUCK_REACHABLE: // FIXME: handle this
519 case EV_ACTION_ERROR:
520 case EV_PUCK_REACHABLE:
522 DBG_PRINT_EVENT("unhandled event");
529 /************************************************************************
530 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
531 ************************************************************************/
533 FSM_STATE(load_the_puck)
535 static int puck_load_attempt_count;
538 puck_load_attempt_count = 0;
539 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
543 robot_move_by(0.02, NO_TURN(), &tcSlow);
546 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
549 SUBFSM_RET((void *)LOAD_SUCCESS);
551 case EV_ACTION_ERROR:
552 puck_load_attempt_count++;
553 if (puck_load_attempt_count > 2) {
554 SUBFSM_RET((void *)LOAD_FAIL);
556 robot_move_by(0.02, NO_TURN(), &tcSlow);
561 case EV_GOAL_NOT_REACHABLE:
562 case EV_SHORT_TIME_TO_END:
564 case EV_PUCK_REACHABLE:
566 DBG_PRINT_EVENT("unhandled event");
573 /* of no use without the sharp sensor measuring "puck distance"
574 FSM_STATE(look_around_for_puck)
576 static int lfp_status = 0;
577 const static int scatter_angle = 20;
578 static struct ref_pos_type orig_position;
582 orig_position = robot.ref_pos;
583 ROBOT_UNLOCK(ref_pos);
584 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
585 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
586 //printf("lfp_status: %d\n", lfp_status);
589 switch (lfp_status) {
591 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
592 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
593 //printf("--- robot move by ... turn cw\n");
594 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
598 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
601 case 2: // puck not found
602 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
605 //printf("lfp_status: %d\n", lfp_status);
607 case EV_PUCK_REACHABLE: // puck found
609 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
612 case EV_ACTION_ERROR: // look for puck does not send this event
616 case EV_GOAL_NOT_REACHABLE:
617 case EV_SHORT_TIME_TO_END:
620 DBG_PRINT_EVENT("unhandled event");
639 case EV_OBSTRUCTION_AHEAD:
641 case EV_GOAL_NOT_REACHABLE:
642 case EV_SHORT_TIME_TO_END:
645 case EV_ACTION_ERROR:
646 case EV_PUCK_REACHABLE:
648 DBG_PRINT_EVENT("unhandled event");
662 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
664 robot.fsm.main.debug_states = 1;
665 robot.fsm.motion.debug_states = 1;
666 robot.fsm.act.debug_states = 1;
668 robot.fsm.main.state = &fsm_state_main_init;
671 if (rv) error(1, errno, "robot_start() returned %d\n", rv);