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 ************************************************************************/
52 //LOOK_AROUND_SUCCESS, // obsolete, no sharp sensor
53 //LOOK_AROUND_FAIL // obsolete, no sharp sensor
56 #define FSM_EVENT_RET_VAL ((SUBFSM_RET_VAL)FSM_EVENT_INT)
58 /************************************************************************
59 * Trajectory constraints used, are initialized in the init state
60 ************************************************************************/
62 struct TrajectoryConstraints tcFast, tcSlow;
64 /************************************************************************
65 * Variables related to puck collecting
66 ************************************************************************/
68 int free_puck_to_try_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
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 tcFast = trajectoryConstraintsDefault;
286 tcSlow = trajectoryConstraintsDefault;
288 FSM_TRANSITION(wait_for_start);
295 FSM_STATE(wait_for_start)
299 printf("COMPETITION mode set\n");
302 #ifdef WAIT_FOR_START
310 /* start competition timer */
311 pthread_create(&thid, NULL, timing_thread, NULL);
312 robot_set_est_pos_trans(0.16,
313 PLAYGROUND_HEIGHT_M - 0.16,
316 FSM_TRANSITION(collect_free_pucks);
318 /*robot_trajectory_new(&tcSlow);
319 struct puck_pos pp = free_puck_pos(0, 2, 0); // puck position
320 robot_trajectory_add_final_point_trans(
323 TURN(DEG2RAD(0))); */
324 //FSM_TRANSITION(approach_our_static_dispenser);
325 //robot_goto_puck_in_grid(0, 1, 2, 270);
327 FSM_SIGNAL(ACT, EV_GRASP_THE_PUCK, NULL);
333 FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
339 case EV_GOAL_NOT_REACHABLE:
340 case EV_SHORT_TIME_TO_END:
343 case EV_ACTION_ERROR:
344 case EV_PUCK_REACHABLE:
346 DBG_PRINT_EVENT("unhandled event");
353 /************************************************************************
354 * STRATEGIES RELATED STATES
355 ************************************************************************/
357 static void robot_goto_next_puck_in_sequence(int lot, int puck_number)
359 robot_goto_puck_in_grid(
360 free_puck_pick_up_sequence[lot][puck_number][0],
361 free_puck_pick_up_sequence[lot][puck_number][1],
362 free_puck_pick_up_sequence[lot][puck_number][2]);
365 FSM_STATE(collect_free_pucks)
367 static const int lot = 7; // this variable location is temporary...; going to be received from the camera
368 // static const int lot = robot.game_conf; // +1?? game_conf is 0..9
371 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
373 case EV_MOTION_DONE: {
374 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
375 SUBFSM_TRANSITION(load_the_puck, NULL);
379 switch(FSM_EVENT_RET_VAL) {
380 /* obsolete, no sharp sensor present
381 case LOOK_AROUND_SUCCESS: // FIXME: test number of pucks loaded!!
382 printf(">>>>>> Look around succeeded\n");
383 SUBFSM_TRANSITION(load_the_puck, NULL);
386 printf(">>>>>> Loading the puck succeeded\n");
387 if(free_puck_to_try_to_get_next<4) {
388 free_puck_to_try_to_get_next++;
389 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
392 /* obsolete, no sharp sensor present
393 case LOOK_AROUND_FAIL:
394 printf(">>>>>> Looking around for the puck FAILED\n");
395 break; // FIXME: remove the break
398 printf(">>>>>> Loading the puck FAILED\n");
399 if(free_puck_to_try_to_get_next<6) { // FIXME: test number of pucks loaded!!
400 free_puck_to_try_to_get_next++;
401 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
403 // FIXME (TODO): transition to next strategy state
408 case EV_PUCK_REACHABLE:
410 printf("-----reached some free puck, hopefully no. %d\n", free_puck_to_try_to_get_next);
411 SUBFSM_TRANSITION(load_the_puck, NULL);
416 case EV_GOAL_NOT_REACHABLE:
417 case EV_SHORT_TIME_TO_END:
419 case EV_ACTION_ERROR:
421 DBG_PRINT_EVENT("unhandled event");
428 /************************************************************************
430 ************************************************************************/
432 FSM_STATE(simple_construction_zone_approach)
436 robot_trajectory_new(&tcFast);
437 robot_trajectory_add_point_trans(0.9, 1);
438 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
441 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
447 case EV_GOAL_NOT_REACHABLE:
448 case EV_SHORT_TIME_TO_END:
450 case EV_ACTION_ERROR:
451 case EV_PUCK_REACHABLE:
453 DBG_PRINT_EVENT("unhandled event");
460 FSM_STATE(approach_our_static_dispenser)
464 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
466 robot_trajectory_new(&tc);
468 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
469 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
470 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
471 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
476 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
477 printf("Arrived to the static dispenser\n");
480 printf("A Puck picked up\n");
485 case EV_GOAL_NOT_REACHABLE:
486 case EV_SHORT_TIME_TO_END:
487 //case EV_PUCK_REACHABLE: // FIXME: handle this
489 case EV_ACTION_ERROR:
490 case EV_PUCK_REACHABLE:
492 DBG_PRINT_EVENT("unhandled event");
499 FSM_STATE(approach_opponents_static_dispenser)
503 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
505 robot_trajectory_new(&tc);
507 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
508 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
509 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
510 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
515 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
516 printf("Arrived to the static dispenser\n");
519 printf("A Puck picked up\n");
524 case EV_GOAL_NOT_REACHABLE:
525 case EV_SHORT_TIME_TO_END:
526 //case EV_PUCK_REACHABLE: // FIXME: handle this
528 case EV_ACTION_ERROR:
529 case EV_PUCK_REACHABLE:
531 DBG_PRINT_EVENT("unhandled event");
538 /************************************************************************
539 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
540 ************************************************************************/
542 FSM_STATE(load_the_puck)
544 static int puck_load_attempt_count;
547 puck_load_attempt_count = 0;
548 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
552 robot_move_by(0.02, NO_TURN(), &tcSlow);
555 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
558 SUBFSM_RET((void *)LOAD_SUCCESS);
560 case EV_ACTION_ERROR:
561 puck_load_attempt_count++;
562 if (puck_load_attempt_count > 2) {
563 SUBFSM_RET((void *)LOAD_FAIL);
565 robot_move_by(0.02, NO_TURN(), &tcSlow);
570 case EV_GOAL_NOT_REACHABLE:
571 case EV_SHORT_TIME_TO_END:
573 case EV_PUCK_REACHABLE:
575 DBG_PRINT_EVENT("unhandled event");
582 /* of no use without the sharp sensor measuring "puck distance"
583 FSM_STATE(look_around_for_puck)
585 static int lfp_status = 0;
586 const static int scatter_angle = 20;
587 static struct ref_pos_type orig_position;
591 orig_position = robot.ref_pos;
592 ROBOT_UNLOCK(ref_pos);
593 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
594 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
595 //printf("lfp_status: %d\n", lfp_status);
598 switch (lfp_status) {
600 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
601 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
602 //printf("--- robot move by ... turn cw\n");
603 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
607 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
610 case 2: // puck not found
611 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
614 //printf("lfp_status: %d\n", lfp_status);
616 case EV_PUCK_REACHABLE: // puck found
618 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
621 case EV_ACTION_ERROR: // look for puck does not send this event
625 case EV_GOAL_NOT_REACHABLE:
626 case EV_SHORT_TIME_TO_END:
629 DBG_PRINT_EVENT("unhandled event");
648 case EV_OBSTRUCTION_AHEAD:
650 case EV_GOAL_NOT_REACHABLE:
651 case EV_SHORT_TIME_TO_END:
654 case EV_ACTION_ERROR:
655 case EV_PUCK_REACHABLE:
657 DBG_PRINT_EVENT("unhandled event");
671 if (rv) error(1, errno, "robot_init() returned %d\n", rv);
673 robot.fsm.main.debug_states = 1;
674 robot.fsm.motion.debug_states = 1;
675 robot.fsm.act.debug_states = 1;
677 robot.fsm.main.state = &fsm_state_main_init;
680 if (rv) error(1, errno, "robot_start() returned %d\n", rv);