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 /* define this macro */
30 /* define in CFLAGS */
34 #define WAIT_FOR_START
35 #define COMPETITION_TIME_DEFAULT 90
36 #define TIME_TO_DEPOSITE_DEFAULT 60
39 #define COMPETITION_TIME_DEFAULT 900
40 #define TIME_TO_DEPOSITE_DEFAULT 60
43 /* competition time in seconds */
44 #define COMPETITION_TIME COMPETITION_TIME_DEFAULT
45 #define TIME_TO_DEPOSITE TIME_TO_DEPOSITE_DEFAULT
46 /* competition time in seconds */
48 /************************************************************************
49 * SUBFSM's return values ...
50 ************************************************************************/
59 #define FSM_EVENT_RET_VAL ((SUBFSM_RET_VAL)FSM_EVENT_PTR)
61 /************************************************************************
62 * Trajectory constraints used, are initialized in the init state
63 ************************************************************************/
65 struct TrajectoryConstraints tcFast, tcSlow;
67 /************************************************************************
68 * Trajectory constraints used, are initialized in the init state
69 ************************************************************************/
71 int free_puck_to_get_next = 0; // next free puck number (index of the free_puck_pick_up_sequence array) to pick up
73 /************************************************************************
74 * Definition of particular "free pucks pick up sequences"
75 ************************************************************************/
77 const int free_puck_pick_up_sequence[][6][3] = {
84 {0, 0, 0}, // FIXME: test last two pucks
92 {0, 0, 10}, // FIXME: test last two pucks
100 {0, 0, 0}, // FIXME: test last two pucks
108 {2, 0, 90}, // FIXME: test last two pucks
116 {0, 0, 0}, // FIXME: test last two pucks
124 {0, 0, 0}, // FIXME: test last two pucks
132 {1, 0, 45}, // FIXME: test last two pucks
140 {2, 1, -90}, // FIXME: test last two pucks
148 {2, 1, -90}, // FIXME: test last two pucks
156 {1, 2, -90}, // FIXME: test last two pucks
160 /************************************************************************
161 * NOTES ON DATA WE NEED TO STORE
162 ************************************************************************/
166 - puck (column element) dispensers status (number of pucks)
167 - their max. capacity is 5
168 - lintel dispensers status
169 - free column elements configuration and their positions
170 - free pucks configuration (lot number)
172 - puck stack status (puck count)
173 - lintel holder status
176 /************************************************************************
178 ************************************************************************/
181 * Competition timer. Stop robot when the timer exceeds.
184 void *wait_for_end(void *arg)
186 sleep(COMPETITION_TIME);
187 printf("%d seconds timer exceeded! exiting!\n", COMPETITION_TIME);
193 * Timer to go to tray.
195 * FIXME: rename this function? (F.J.)
197 void *wait_to_deposition(void *arg)
199 sleep(TIME_TO_DEPOSITE);
200 FSM_SIGNAL(MAIN, EV_SHORT_TIME_TO_END, NULL);
205 * Get position of the point when we know the distance and angle to turn.
207 * FIXME (F.J.): - there used to be non-actual parameter documentation
208 * - what was this function good for? (not used anywhere)
210 void get_relative_pos(struct est_pos_type *est, struct ref_pos_type *ref,
211 double l, double phi)
213 ref->x = est->x + l*cos(est->phi + phi);
214 ref->y = est->y + l*sin(est->phi + phi);
215 ref->phi = est->phi + phi;
218 void robot_goto_point(struct ref_pos_type des_pos)
220 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
223 robot_trajectory_new(&tc);
224 robot_trajectory_add_final_point_trans(des_pos.x, des_pos.y, NO_TURN());
227 void robot_go_backward_to_point(struct ref_pos_type des_pos)
229 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
232 robot_trajectory_new_backward(&tc);
233 robot_trajectory_add_final_point_notrans(des_pos.x, des_pos.y, NO_TURN());
236 void robot_goto_puck_in_grid(int nx, int ny, int phi)
238 struct puck_pos pp = free_puck_pos(nx, ny); // puck position
239 robot_trajectory_new(&tcSlow);
240 robot_trajectory_add_point_trans(
241 pp.x + (ROBOT_AXIS_TO_PUCK_M+0.10)*cos(DEG2RAD(phi)),
242 pp.y + (ROBOT_AXIS_TO_PUCK_M+0.10)*sin(DEG2RAD(phi)));
243 robot_trajectory_add_final_point_trans(
244 pp.x + ROBOT_AXIS_TO_PUCK_M*cos(DEG2RAD(phi)),
245 pp.y + ROBOT_AXIS_TO_PUCK_M*sin(DEG2RAD(phi)),
246 TURN(fmod(DEG2RAD(phi+180), 2.0*M_PI)));
247 /* robot_goto_trans( // does not exist
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))); */
253 /************************************************************************
254 * FSM STATES DECLARATION
255 ************************************************************************/
257 /* initial and starting states */
258 FSM_STATE_DECL(init);
259 FSM_STATE_DECL(wait_for_start);
260 /* strategies related states */
261 FSM_STATE_DECL(collect_free_pucks);
262 /* movement states */
263 FSM_STATE_DECL(simple_construction_zone_approach);
264 FSM_STATE_DECL(approach_our_static_dispenser);
265 FSM_STATE_DECL(approach_opponents_static_dispenser);
266 /* States handling ACT's actions (SUBFSMs) */
267 FSM_STATE_DECL(load_the_puck);
268 FSM_STATE_DECL(grasp_the_puck);
269 FSM_STATE_DECL(look_for_puck_ahead);
270 FSM_STATE_DECL(look_around_for_puck);
272 /************************************************************************
273 * INITIAL AND STARTING STATES
274 ************************************************************************/
280 tcFast = trajectoryConstraintsDefault;
282 tcSlow = trajectoryConstraintsDefault;
284 FSM_TRANSITION(wait_for_start);
291 FSM_STATE(wait_for_start)
294 printf("COMPETITION mode set");
297 #ifdef WAIT_FOR_START
301 /* start competition timer */
302 pthread_create(&thid, NULL, wait_for_end, NULL);
303 pthread_create(&thid, NULL, wait_to_deposition, NULL);
308 robot_set_est_pos_trans(0.16,
309 PLAYGROUND_HEIGHT_M - 0.16,
311 /* start to do something */
313 FSM_TRANSITION(collect_free_pucks);
315 /*robot_trajectory_new(&tcSlow);
316 struct puck_pos pp = free_puck_pos(0, 2, 0); // puck position
317 robot_trajectory_add_final_point_trans(
320 TURN(DEG2RAD(0))); */
321 //FSM_TRANSITION(approach_our_static_dispenser);
322 //robot_goto_puck_in_grid(0, 1, 2, 270);
324 FSM_SIGNAL(ACT, EV_GRASP_THE_PUCK, NULL);
330 FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
336 case EV_GOAL_NOT_REACHABLE:
337 case EV_SHORT_TIME_TO_END:
340 case EV_ACTION_ERROR:
341 case EV_PUCK_REACHABLE:
343 DBG_PRINT_EVENT("unhandled event");
350 /************************************************************************
351 * STRATEGIES RELATED STATES
352 ************************************************************************/
354 static void robot_goto_next_puck_in_sequence(int lot, int puck_number)
356 robot_goto_puck_in_grid(
357 free_puck_pick_up_sequence[lot][puck_number][0],
358 free_puck_pick_up_sequence[lot][puck_number][1],
359 free_puck_pick_up_sequence[lot][puck_number][2]);
362 FSM_STATE(collect_free_pucks)
364 static const int lot = 7; // this variable location is temporary...; going to be received from the camera
365 static int puck_approach_attempt_no;
368 puck_approach_attempt_no = 0;
369 FSM_SIGNAL(ACT, EV_PREPARE_FOR_LOAD, NULL);
370 robot_goto_next_puck_in_sequence(lot, free_puck_to_get_next);
372 case EV_MOTION_DONE: {
373 printf("-----arrived where the free puck no. %d should be\n", free_puck_to_get_next);
374 if (PUCK_REACHABLE(robot.puck_distance)) {
375 SUBFSM_TRANSITION(load_the_puck, NULL);
377 switch (puck_approach_attempt_no) {
379 printf("-----moving forward by 5 cm\n");
380 robot_move_by(0.05, NO_TURN(), &tcSlow);
381 puck_approach_attempt_no++;
384 SUBFSM_TRANSITION(look_around_for_puck, NULL);
391 switch(FSM_EVENT_RET_VAL) {
392 case LOOK_AROUND_SUCCESS: // FIXME: test number of pucks loaded!!
393 printf(">>>>>> Look around succeeded\n");
394 SUBFSM_TRANSITION(load_the_puck, NULL);
397 printf(">>>>>> Loading the puck succeeded\n");
398 if(free_puck_to_get_next<4) {
399 free_puck_to_get_next++;
400 robot_goto_next_puck_in_sequence(lot, free_puck_to_get_next);
402 puck_approach_attempt_no = 0;
404 case LOOK_AROUND_FAIL:
405 printf(">>>>>> Looking around for the puck FAILED\n");
406 break; // FIXME: remove the break
408 printf(">>>>>> Loading the puck FAILED\n");
409 if(free_puck_to_get_next<6) { // FIXME: test number of pucks loaded!!
410 free_puck_to_get_next++;
411 robot_goto_next_puck_in_sequence(lot, free_puck_to_get_next);
413 // FIXME (TODO): transition to next strategy state
418 case EV_PUCK_REACHABLE:
420 printf("-----reached some free puck, hopefully no. %d\n", free_puck_to_get_next);
421 SUBFSM_TRANSITION(load_the_puck, NULL);
426 case EV_GOAL_NOT_REACHABLE:
427 case EV_SHORT_TIME_TO_END:
429 case EV_ACTION_ERROR:
431 DBG_PRINT_EVENT("unhandled event");
438 /************************************************************************
440 ************************************************************************/
442 FSM_STATE(simple_construction_zone_approach)
446 robot_trajectory_new(&tcFast);
447 robot_trajectory_add_point_trans(0.9, 1);
448 robot_trajectory_add_final_point_trans(0.9, ROBOT_AXIS_TO_FRONT_M + 0.05, NO_TURN());
451 //FSM_SIGNAL(ACT, EV_UNLOAD_THE_PUCK, NULL);
457 case EV_GOAL_NOT_REACHABLE:
458 case EV_SHORT_TIME_TO_END:
460 case EV_ACTION_ERROR:
461 case EV_PUCK_REACHABLE:
463 DBG_PRINT_EVENT("unhandled event");
470 FSM_STATE(approach_our_static_dispenser)
474 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
476 robot_trajectory_new(&tc);
478 robot_trajectory_add_point_trans(STATIC_DISPENSER_X,
479 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
480 robot_trajectory_add_final_point_trans(STATIC_DISPENSER_X,
481 STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
486 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
487 printf("Arrived to the static dispenser\n");
490 printf("A Puck picked up\n");
495 case EV_GOAL_NOT_REACHABLE:
496 case EV_SHORT_TIME_TO_END:
497 //case EV_PUCK_REACHABLE: // FIXME: handle this
499 case EV_ACTION_ERROR:
500 case EV_PUCK_REACHABLE:
502 DBG_PRINT_EVENT("unhandled event");
509 FSM_STATE(approach_opponents_static_dispenser)
513 struct TrajectoryConstraints tc = trajectoryConstraintsDefault;
515 robot_trajectory_new(&tc);
517 robot_trajectory_add_point_trans(OPPONENTS_STATIC_DISPENSER_X,
518 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M + 0.4);
519 robot_trajectory_add_final_point_trans(OPPONENTS_STATIC_DISPENSER_X,
520 OPPONENTS_STATIC_DISPENSER_Y + ROBOT_AXIS_TO_FRONT_M+0.15,
525 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
526 printf("Arrived to the static dispenser\n");
529 printf("A Puck picked up\n");
534 case EV_GOAL_NOT_REACHABLE:
535 case EV_SHORT_TIME_TO_END:
536 //case EV_PUCK_REACHABLE: // FIXME: handle this
538 case EV_ACTION_ERROR:
539 case EV_PUCK_REACHABLE:
541 DBG_PRINT_EVENT("unhandled event");
548 /************************************************************************
549 * STATES HANDLING ACT's ACTIONS (to be used as SUB FSMs)
550 ************************************************************************/
552 FSM_STATE(load_the_puck)
556 FSM_SIGNAL(ACT, EV_SCRABBLE, NULL);
560 robot_move_by(0.02, NO_TURN(), &tcSlow);
563 FSM_SIGNAL(ACT, EV_LOAD_THE_PUCK, NULL);
566 SUBFSM_RET((void *)LOAD_SUCCESS);
568 case EV_ACTION_ERROR:
569 SUBFSM_RET((void *)LOAD_FAIL);
573 case EV_GOAL_NOT_REACHABLE:
574 case EV_SHORT_TIME_TO_END:
576 case EV_PUCK_REACHABLE:
578 DBG_PRINT_EVENT("unhandled event");
585 FSM_STATE(look_around_for_puck)
587 static int lfp_status = 0;
588 const static int scatter_angle = 20;
589 static struct ref_pos_type orig_position;
593 orig_position = robot.ref_pos;
594 ROBOT_UNLOCK(ref_pos);
595 //printf("original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
596 robot_move_by(0, TURN_CW(DEG2RAD(RAD2DEG(orig_position.phi)-scatter_angle)), &tcSlow);
597 //printf("lfp_status: %d\n", lfp_status);
600 switch (lfp_status) {
602 //printf("2. original angle of rotation of the robot: %f degrees\n", RAD2DEG(orig_position.phi));
603 //printf("robot.fer_pos angle of rotation of the robot: %f degrees\n", RAD2DEG(robot.ref_pos.phi));
604 //printf("--- robot move by ... turn cw\n");
605 robot_move_by(0, TURN_CCW(DEG2RAD(RAD2DEG(orig_position.phi)+scatter_angle)), &tcSlow);
609 robot_move_by(0, TURN(orig_position.phi), &tcSlow);
612 case 2: // puck not found
613 SUBFSM_RET((void *)LOOK_AROUND_FAIL);
616 //printf("lfp_status: %d\n", lfp_status);
618 case EV_PUCK_REACHABLE: // puck found
620 SUBFSM_RET((void *)LOOK_AROUND_SUCCESS);
623 case EV_ACTION_ERROR: // look for puck does not send this event
627 case EV_GOAL_NOT_REACHABLE:
628 case EV_SHORT_TIME_TO_END:
631 DBG_PRINT_EVENT("unhandled event");
649 case EV_OBSTRUCTION_AHEAD:
651 case EV_GOAL_NOT_REACHABLE:
652 case EV_SHORT_TIME_TO_END:
655 case EV_ACTION_ERROR:
656 case EV_PUCK_REACHABLE:
658 DBG_PRINT_EVENT("unhandled event");