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>
30 #define WAIT_FOR_START
31 #define COMPETITION_TIME_DEFAULT 90
32 #define TIME_TO_DEPOSITE_DEFAULT 60
35 #define COMPETITION_TIME_DEFAULT 900
36 #define TIME_TO_DEPOSITE_DEFAULT 60
39 /* competition time in seconds */
40 #define COMPETITION_TIME COMPETITION_TIME_DEFAULT
41 #define TIME_TO_DEPOSITE TIME_TO_DEPOSITE_DEFAULT
42 /* competition time in seconds */
44 /************************************************************************
45 * SUBFSM's return values ...
46 ************************************************************************/
51 //LOOK_AROUND_SUCCESS, // obsolete, no sharp sensor
52 //LOOK_AROUND_FAIL // obsolete, no sharp sensor
55 #define FSM_EVENT_RET_VAL ((SUBFSM_RET_VAL)FSM_EVENT_PTR)
57 /************************************************************************
58 * Trajectory constraints used, are initialized in the init state
59 ************************************************************************/
61 struct TrajectoryConstraints tcFast, tcSlow;
63 /************************************************************************
64 * Variables related to puck collecting
65 ************************************************************************/
67 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
69 /************************************************************************
70 * Definition of particular "free pucks pick up sequences"
71 ************************************************************************/
73 const int free_puck_pick_up_sequence[][6][3] = {
80 {0, 0, 0}, // FIXME: test last two pucks
88 {0, 0, 10}, // FIXME: test last two pucks
96 {0, 0, 0}, // FIXME: test last two pucks
104 {2, 0, 90}, // FIXME: test last two pucks
112 {0, 0, 0}, // FIXME: test last two pucks
120 {0, 0, 0}, // FIXME: test last two pucks
128 {1, 0, 45}, // FIXME: test last two pucks
136 {2, 1, -90}, // FIXME: test last two pucks
144 {2, 1, -90}, // FIXME: test last two pucks
152 {1, 2, -90}, // FIXME: test last two pucks
156 /************************************************************************
157 * NOTES ON DATA WE NEED TO STORE
158 ************************************************************************/
162 - puck (column element) dispensers status (number of pucks)
163 - their max. capacity is 5
164 - lintel dispensers status
165 - free column elements configuration and their positions
166 - free pucks configuration (lot number)
168 - puck stack status (puck count)
169 - lintel holder status
172 /************************************************************************
174 ************************************************************************/
177 * Competition timer. Stop robot when the timer exceeds.
180 void *timing_thread(void *arg)
182 struct timespec start;
184 clock_gettime(CLOCK_MONOTONIC, &start);
188 t.tv_sec = start.tv_sec+sec; \
189 t.tv_nsec = start.tv_nsec; \
190 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); \
194 robot.use_back_switch = true;
195 printf("Back switch not ignored\n");
197 WAIT(TIME_TO_DEPOSITE);
198 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
200 WAIT(COMPETITION_TIME);
201 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
208 * Get position of the point when we know the distance and angle to turn.
210 * FIXME (F.J.): - there used to be non-actual parameter documentation
211 * - what was this function good for? (not used anywhere)
213 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
214 double l, double phi)
216 ref->x = est->x + l*cos(est->phi + phi);
217 ref->y = est->y + l*sin(est->phi + phi);
218 ref->phi = est->phi + phi;
221 void robot_goto_point(struct ref_pos_type des_pos)
223 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
226 robot_trajectory_new(&tc);
227 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
230 void robot_go_backward_to_point(struct ref_pos_type des_pos)
232 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
235 robot_trajectory_new_backward(&tc);
236 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
239 void robot_goto_puck_in_grid(int nx, int ny, int phi)
241 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
242 robot_trajectory_new(&tcSlow);
243 robot_trajectory_add_point_trans(
244 pp.x + (ROBOT_AXIS_TO_PUCK_M+0.10)*cos(DEG2RAD(phi)),
245 pp.y + (ROBOT_AXIS_TO_PUCK_M+0.10)*sin(DEG2RAD(phi)));
246 robot_trajectory_add_final_point_trans(
247 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
248 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
249 TURN(fmod(DEG2RAD(phi+180), 2.0*M_PI)));
250 /* robot_goto_trans( // does not exist
251 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
252 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
253 TURN(fmod(DEG2RAD(phi+180), 2.0*M_PI))); */
256 /************************************************************************
257 * FSM STATES DECLARATION
258 ************************************************************************/
260 /* initial and starting states */
261 FSM_STATE_DECL(init);
262 FSM_STATE_DECL(wait_for_start);
263 /* strategies related states */
264 FSM_STATE_DECL(collect_free_pucks);
265 /* movement states */
266 FSM_STATE_DECL(simple_construction_zone_approach);
267 FSM_STATE_DECL(approach_our_static_dispenser);
268 FSM_STATE_DECL(approach_opponents_static_dispenser);
269 /* States handling ACT's actions (SUBFSMs) */
270 FSM_STATE_DECL(load_the_puck);
271 FSM_STATE_DECL(grasp_the_puck);
272 FSM_STATE_DECL(look_for_puck_ahead);
273 FSM_STATE_DECL(look_around_for_puck);
275 /************************************************************************
276 * INITIAL AND STARTING STATES
277 ************************************************************************/
283 tcFast = trajectoryConstraintsDefault;
285 tcSlow = trajectoryConstraintsDefault;
287 FSM_TRANSITION(wait_for_start);
294 FSM_STATE(wait_for_start)
298 printf("COMPETITION mode set");
301 #ifdef WAIT_FOR_START
309 /* start competition timer */
310 pthread_create(&thid, NULL, timing_thread, NULL);
311 robot_set_est_pos_trans(0.16,
312 PLAYGROUND_HEIGHT_M - 0.16,
315 FSM_TRANSITION(collect_free_pucks);
317 /*robot_trajectory_new(&tcSlow);
318 struct puck_pos pp = free_puck_pos(0, 2, 0); // puck position
319 robot_trajectory_add_final_point_trans(
322 TURN(DEG2RAD(0))); */
323 //FSM_TRANSITION(approach_our_static_dispenser);
324 //robot_goto_puck_in_grid(0, 1, 2, 270);
326 FSM_SIGNAL(ACT, EV_GRASP_THE_PUCK, NULL);
332 FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
338 case EV_GOAL_NOT_REACHABLE:
339 case EV_SHORT_TIME_TO_END:
342 case EV_ACTION_ERROR:
343 case EV_PUCK_REACHABLE:
345 DBG_PRINT_EVENT("unhandled event");
352 /************************************************************************
353 * STRATEGIES RELATED STATES
354 ************************************************************************/
356 static void robot_goto_next_puck_in_sequence(int lot, int puck_number)
358 robot_goto_puck_in_grid(
359 free_puck_pick_up_sequence[lot][puck_number][0],
360 free_puck_pick_up_sequence[lot][puck_number][1],
361 free_puck_pick_up_sequence[lot][puck_number][2]);
364 FSM_STATE(collect_free_pucks)
366 static const int lot = 7; // this variable location is temporary...; going to be received from the camera
369 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
371 case EV_MOTION_DONE: {
372 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_try_to_get_next);
373 SUBFSM_TRANSITION(load_the_puck, NULL);
377 switch(FSM_EVENT_RET_VAL) {
378 /* obsolete, no sharp sensor present
379 case LOOK_AROUND_SUCCESS: // FIXME: test number of pucks loaded!!
380 printf(">>>>>> Look around succeeded\n");
381 SUBFSM_TRANSITION(load_the_puck, NULL);
384 printf(">>>>>> Loading the puck succeeded\n");
385 if(free_puck_to_try_to_get_next<4) {
386 free_puck_to_try_to_get_next++;
387 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
390 /* obsolete, no sharp sensor present
391 case LOOK_AROUND_FAIL:
392 printf(">>>>>> Looking around for the puck FAILED\n");
393 break; // FIXME: remove the break
396 printf(">>>>>> Loading the puck FAILED\n");
397 if(free_puck_to_try_to_get_next<6) { // FIXME: test number of pucks loaded!!
398 free_puck_to_try_to_get_next++;
399 robot_goto_next_puck_in_sequence(lot, free_puck_to_try_to_get_next);
401 // FIXME (TODO): transition to next strategy state
406 case EV_PUCK_REACHABLE:
408 printf("-----reached some free puck, hopefully no. %d\n", free_puck_to_try_to_get_next);
409 SUBFSM_TRANSITION(load_the_puck, NULL);
414 case EV_GOAL_NOT_REACHABLE:
415 case EV_SHORT_TIME_TO_END:
417 case EV_ACTION_ERROR:
419 DBG_PRINT_EVENT("unhandled event");
426 /************************************************************************
428 ************************************************************************/
430 FSM_STATE(simple_construction_zone_approach)
434 robot_trajectory_new(&tcFast);
435 robot_trajectory_add_point_trans(0.9, 1);
436 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
439 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
445 case EV_GOAL_NOT_REACHABLE:
446 case EV_SHORT_TIME_TO_END:
448 case EV_ACTION_ERROR:
449 case EV_PUCK_REACHABLE:
451 DBG_PRINT_EVENT("unhandled event");
458 FSM_STATE(approach_our_static_dispenser)
462 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
464 robot_trajectory_new(&tc);
466 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
467 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
468 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
469 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
474 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
475 printf("Arrived to the static dispenser\n");
478 printf("A Puck picked up\n");
483 case EV_GOAL_NOT_REACHABLE:
484 case EV_SHORT_TIME_TO_END:
485 //case EV_PUCK_REACHABLE: // FIXME: handle this
487 case EV_ACTION_ERROR:
488 case EV_PUCK_REACHABLE:
490 DBG_PRINT_EVENT("unhandled event");
497 FSM_STATE(approach_opponents_static_dispenser)
501 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
503 robot_trajectory_new(&tc);
505 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
506 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
507 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
508 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
513 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
514 printf("Arrived to the static dispenser\n");
517 printf("A Puck picked up\n");
522 case EV_GOAL_NOT_REACHABLE:
523 case EV_SHORT_TIME_TO_END:
524 //case EV_PUCK_REACHABLE: // FIXME: handle this
526 case EV_ACTION_ERROR:
527 case EV_PUCK_REACHABLE:
529 DBG_PRINT_EVENT("unhandled event");
536 /************************************************************************
537 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
538 ************************************************************************/
540 FSM_STATE(load_the_puck)
542 static int puck_load_attempt_count;
545 puck_load_attempt_count = 0;
546 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
550 robot_move_by(0.02, NO_TURN(), &tcSlow);
553 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
556 SUBFSM_RET((void *)LOAD_SUCCESS);
558 case EV_ACTION_ERROR:
559 puck_load_attempt_count++;
560 if (puck_load_attempt_count > 2) {
561 SUBFSM_RET((void *)LOAD_FAIL);
563 robot_move_by(0.02, NO_TURN(), &tcSlow);
568 case EV_GOAL_NOT_REACHABLE:
569 case EV_SHORT_TIME_TO_END:
571 case EV_PUCK_REACHABLE:
573 DBG_PRINT_EVENT("unhandled event");
580 /* of no use without the sharp sensor measuring "puck distance"
581 FSM_STATE(look_around_for_puck)
583 static int lfp_status = 0;
584 const static int scatter_angle = 20;
585 static struct ref_pos_type orig_position;
589 orig_position = robot.ref_pos;
590 ROBOT_UNLOCK(ref_pos);
591 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
592 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
593 //printf("lfp_status: %d\n", lfp_status);
596 switch (lfp_status) {
598 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
599 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
600 //printf("--- robot move by ... turn cw\n");
601 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
605 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
608 case 2: // puck not found
609 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
612 //printf("lfp_status: %d\n", lfp_status);
614 case EV_PUCK_REACHABLE: // puck found
616 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
619 case EV_ACTION_ERROR: // look for puck does not send this event
623 case EV_GOAL_NOT_REACHABLE:
624 case EV_SHORT_TIME_TO_END:
627 DBG_PRINT_EVENT("unhandled event");
646 case EV_OBSTRUCTION_AHEAD:
648 case EV_GOAL_NOT_REACHABLE:
649 case EV_SHORT_TIME_TO_END:
652 case EV_ACTION_ERROR:
653 case EV_PUCK_REACHABLE:
655 DBG_PRINT_EVENT("unhandled event");