7 #include <movehelper.h>
14 #include "corns_configs.h"
15 #include "actuators.h"
17 #include "match-timing.h"
18 #include "eb2010misc.h"
21 #include "common-states.h"
23 /************************************************************************
24 * Functions used in and called from all the (almost identical)
25 * "wait for start" states in particular strategies.
26 ************************************************************************/
29 #define DBG_FSM_STATE(name) do { if (fsm->debug_states) printf("fsm %s %.1f: %s(%s)\n", \
30 fsm->debug_name, robot_current_time(), \
31 name, fsm_event_str(fsm->events[fsm->ev_head])); } while(0)
34 static void set_initial_position()
36 robot_set_est_pos_trans(ROBOT_AXIS_TO_FRONT_M,
37 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2),
41 static void actuators_home()
44 act_vidle(VIDLE_UP - tmp, VIDLE_FAST_SPEED);
45 tmp = 1 - tmp; // Force movement (we need to change the target position)
51 robot.check_turn_safety = false;
52 pthread_create(&thid, NULL, timing_thread, NULL);
56 // We set initial position periodically in order for it to be updated
57 // on the display if the team color is changed during waiting for
61 set_initial_position();
62 if (robot.start_state == START_PLUGGED_IN)
68 sem_post(&robot.start);
70 set_initial_position();
75 robot.corns = get_all_corns(robot.corns_conf_side, robot.corns_conf_center);
79 /************************************************************************
80 * Trajectory constraints used; They are initialized in the main() function in competition.cc
81 ************************************************************************/
83 struct TrajectoryConstraints tcFast, tcSlow, tcVerySlow;
85 #define VIDLE_TIMEOUT 2000
87 /************************************************************************
88 * States that form the "collect some oranges" subautomaton. Calling automaton
89 * SHOULD ALWAYS call the "approach_the_slope" state.
90 ************************************************************************/
92 bool inline is_ready_to_climb_the_slope(enum which_side which_slope, double x, double y) {
94 if (which_slope == MINE) {
95 ret = x < 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
96 } else if (which_slope == OPPONENTS) {
97 ret = x > 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
99 printf("ERROR: unknown side;");
100 #warning Remove the next line
106 static struct slope_approach_style *slope_approach_style_p;
108 /* assures that the robot is near the slope rim; if outside our starting area, approach the slope first */
109 FSM_STATE(approach_the_slope)
113 slope_approach_style_p = (struct slope_approach_style *) FSM_EVENT_PTR;
114 if (slope_approach_style_p == NULL) {
115 printf("\n\nit is not allowed to call the approach_the_slope state with NULL data!!\n\n");
116 #warning remove the next line
120 robot_get_est_pos_trans(&x, &y, &phi);
122 bool ready_to_climb_the_slope = is_ready_to_climb_the_slope(slope_approach_style_p->which_side, x, y);
123 /* if necessary, approach the slope */
124 if (ready_to_climb_the_slope) {
125 FSM_TRANSITION(climb_the_slope);
129 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.3, slope_approach_style_p->which_side),
130 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.05,
131 ARRIVE_FROM(DEG2RAD(0),0.05),
133 x_coord(0.3, slope_approach_style_p->which_side),
134 PLAYGROUND_HEIGHT_M - ROBOT_WIDTH_M/2 - 0.03,
135 ARRIVE_FROM(DEG2RAD(0), 0.02),
141 FSM_TRANSITION(climb_the_slope);
147 case EV_MOTION_ERROR:
148 case EV_SWITCH_STRATEGY:
149 DBG_PRINT_EVENT("unhandled event");
155 void inline enable_switches(bool enabled)
157 robot.use_left_switch = enabled;
158 robot.use_right_switch = enabled;
159 robot.use_back_switch = enabled;
162 FSM_STATE(climb_the_slope)
164 struct TrajectoryConstraints tc;
167 // disables using side switches on bumpers when going up
168 enable_switches(false);
169 robot.ignore_hokuyo = true;
170 /* create the trajectory and go */
173 robot_trajectory_new_backward(&tc);
174 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
175 act_vidle(VIDLE_LOAD_PREPARE, 5);
176 robot_trajectory_add_point_trans(
177 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
178 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01);
179 robot_trajectory_add_final_point_trans(
180 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
181 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01,
183 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
185 robot_trajectory_add_point_trans(
186 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
187 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85));
188 robot_trajectory_add_final_point_trans(
189 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
190 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85),
196 SUBFSM_TRANSITION(load_oranges, NULL);
199 FSM_TRANSITION(sledge_down);
202 act_vidle(VIDLE_LOAD_PREPARE, 10);
206 case EV_MOTION_ERROR:
207 case EV_SWITCH_STRATEGY:
208 DBG_PRINT_EVENT("unhandled event");
214 /* subautomaton to load oranges in two stages */
215 FSM_STATE_DECL(load_oranges2);
216 FSM_STATE_DECL(load_oranges3);
217 FSM_STATE(load_oranges)
222 act_vidle(VIDLE_MIDDLE, VIDLE_MEDIUM_SPEED);
228 FSM_TRANSITION(load_oranges2);
233 case EV_MOTION_ERROR:
234 case EV_SWITCH_STRATEGY:
235 DBG_PRINT_EVENT("unhandled event");
241 FSM_STATE(load_oranges2)
245 act_vidle(VIDLE_UP, VIDLE_MEDIUM_SPEED);
249 FSM_TRANSITION(load_oranges3);
253 FSM_TRANSITION(load_oranges3);
259 case EV_MOTION_ERROR:
260 case EV_SWITCH_STRATEGY:
261 DBG_PRINT_EVENT("unhandled event");
263 act_vidle(VIDLE_UP-1, VIDLE_FAST_SPEED);
268 FSM_STATE(load_oranges3)
272 act_vidle(VIDLE_MIDDLE+50, 0);
284 case EV_MOTION_ERROR:
285 case EV_SWITCH_STRATEGY:
286 DBG_PRINT_EVENT("unhandled event");
288 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
293 FSM_STATE(sledge_down)
295 struct TrajectoryConstraints tc;
300 robot_trajectory_new(&tc);
302 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
303 robot_trajectory_add_point_trans(
304 x_coord(1.2 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
305 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01);
306 robot_trajectory_add_point_trans(
307 x_coord(1.0 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
308 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.01);
309 robot_trajectory_add_point_trans(
310 x_coord(0.8 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
311 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.05);
312 robot_trajectory_add_point_trans(
313 x_coord(0.6 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
314 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.10);
315 robot_trajectory_add_final_point_trans(
316 x_coord(0.5 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
317 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.17,
319 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
320 robot_trajectory_add_point_trans(
321 x_coord(1 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
322 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85));
323 robot_trajectory_add_final_point_trans(
324 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.2, slope_approach_style_p->which_side),
325 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85),
328 /* robot_trajectory_add_point_trans(
329 x_coord(1 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
330 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01, slope_approach_style_p->which_oranges));
331 robot_trajectory_add_point_trans(
332 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.20, slope_approach_style_p->which_side),
333 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.08, slope_approach_style_p->which_oranges));
334 robot_trajectory_add_final_point_trans(
335 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.26, slope_approach_style_p->which_side),
336 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.14, slope_approach_style_p->which_oranges),
340 /* just for sure, try to close it one more time */
341 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
343 delete(slope_approach_style_p);
349 case EV_MOTION_ERROR:
350 case EV_SWITCH_STRATEGY:
351 DBG_PRINT_EVENT("unhandled event");
354 // enables using side switches on bumpers
355 enable_switches(true);
356 robot.ignore_hokuyo = false;
357 robot.check_turn_safety = true;
363 /************************************************************************
364 * The "unload our oranges" subautomaton
365 ************************************************************************/
367 FSM_STATE(to_cntainer_and_unld)
372 if (slope_approach_style_p->which_side == MINE) {
373 robot_trajectory_new(&tcFast);
374 // face the rim with front of the robot
375 //robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.12, ARRIVE_FROM(DEG2RAD(-90), 0.10));
376 // face the rim with back of the robot
377 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M-0.6, 0.35);
378 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, ARRIVE_FROM(DEG2RAD(90),0.05));
380 robot_goto_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, ARRIVE_FROM(DEG2RAD(90),0.05), &tcFast);
384 FSM_TIMER(3000); // FIXME: test this
385 act_vidle(VIDLE_DOWN, VIDLE_FAST_SPEED);
388 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
394 case EV_MOTION_ERROR:
395 case EV_SWITCH_STRATEGY:
396 DBG_PRINT_EVENT("unhandled event");
402 /************************************************************************
403 * The "collect corns" subautomaton
404 ************************************************************************/
406 static enum where_to_go {
411 } where_to_go = CORN;
413 static struct corn *corn_to_get;
415 FSM_STATE(rush_corns_decider)
419 if (where_to_go == CORN) {
420 FSM_TRANSITION(approach_next_corn);
421 } else if (where_to_go == CONTAINER) {
422 FSM_TRANSITION(rush_the_corn);
423 } else if (where_to_go == TURN_AROUND) {
424 FSM_TRANSITION(turn_around);
425 } else /* NO_MORE_CORN */ {
433 case EV_MOTION_ERROR:
434 case EV_SWITCH_STRATEGY:
435 DBG_PRINT_EVENT("unhandled event");
442 FSM_STATE(approach_next_corn)
447 robot_get_est_pos(&x, &y, &phi);
448 printf("approach_next_corn: puck cnt: %d, est pos %.3f, %.3f, %.3f\n",
451 corn_to_get = choose_next_corn();
453 Pos *p = get_corn_approach_position(corn_to_get);
454 corn_to_get->was_collected = true;
455 //robot_trajectory_new(&tcFast);
456 //robot_trajectory_add_final_point_trans(robot_trajectory_add_final_point_trans(p->x, p->y, TURN(p->phi));
457 robot_goto_trans(p->x, p->y, TURN(p->phi), &tcFast);
459 where_to_go = CONTAINER;
461 where_to_go = NO_MORE_CORN;
467 FSM_TRANSITION(rush_corns_decider);
473 case EV_MOTION_ERROR:
474 case EV_SWITCH_STRATEGY:
475 DBG_PRINT_EVENT("unhandled event");
481 FSM_STATE(rush_the_corn)
486 if (robot.team_color == BLUE) {
487 x = corn_to_get->position.x;
489 x = PLAYGROUND_WIDTH_M - corn_to_get->position.x;
491 remove_wall_around_corn(x, corn_to_get->position.y);
492 robot_goto_trans(PLAYGROUND_WIDTH_M - 0.4, 0.15, ARRIVE_FROM(DEG2RAD(-90), 0.02), &tcSlow);
493 where_to_go = TURN_AROUND;
496 FSM_TRANSITION(rush_corns_decider);
502 case EV_MOTION_ERROR:
503 case EV_SWITCH_STRATEGY:
504 DBG_PRINT_EVENT("unhandled event");
510 // used to perform the maneuvre
511 FSM_STATE(turn_around)
515 robot_trajectory_new_backward(&tcFast);
516 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, TURN_CCW(90));
520 FSM_TRANSITION(rush_corns_decider);
526 case EV_MOTION_ERROR:
527 case EV_SWITCH_STRATEGY:
528 DBG_PRINT_EVENT("unhandled event");