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 ************************************************************************/
28 static void set_initial_position()
30 robot_set_est_pos_trans(ROBOT_AXIS_TO_FRONT_M,
31 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2),
35 static void actuators_home()
38 act_vidle(VIDLE_UP - tmp, VIDLE_FAST_SPEED);
39 tmp = 1 - tmp; // Force movement (we need to change the target position)
45 robot.check_turn_safety = false;
46 pthread_create(&thid, NULL, timing_thread, NULL);
50 // We set initial position periodically in order for it to be updated
51 // on the display if the team color is changed during waiting for
55 set_initial_position();
56 if (robot.start_state == START_PLUGGED_IN)
62 sem_post(&robot.start);
64 set_initial_position();
69 robot.corns = get_all_corns(robot.corns_conf_side, robot.corns_conf_center);
73 /************************************************************************
74 * Trajectory constraints used; They are initialized in the main() function in competition.cc
75 ************************************************************************/
77 struct TrajectoryConstraints tcFast, tcSlow, tcVerySlow;
79 #define VIDLE_TIMEOUT 2000
81 /************************************************************************
82 * States that form the "collect some oranges" subautomaton. Calling automaton
83 * SHOULD ALWAYS call the "approach_the_slope" state.
84 ************************************************************************/
86 bool inline is_ready_to_climb_the_slope(enum which_side which_slope, double x, double y) {
88 if (which_slope == MINE) {
89 ret = x < 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
90 } else if (which_slope == OPPONENTS) {
91 ret = x > 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
93 printf("ERROR: unknown side;");
94 #warning Remove the next line
100 static struct slope_approach_style *slope_approach_style_p;
102 /* assures that the robot is near the slope rim; if outside our starting area, approach the slope first */
103 FSM_STATE(approach_the_slope)
107 slope_approach_style_p = (struct slope_approach_style *) FSM_EVENT_PTR;
108 if (slope_approach_style_p == NULL) {
109 printf("\n\nit is not allowed to call the approach_the_slope state with NULL data!!\n\n");
110 #warning remove the next line
114 robot_get_est_pos_trans(&x, &y, &phi);
116 bool ready_to_climb_the_slope = is_ready_to_climb_the_slope(slope_approach_style_p->which_side, x, y);
117 /* if necessary, approach the slope */
118 if (ready_to_climb_the_slope) {
119 FSM_TRANSITION(climb_the_slope);
123 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.3, slope_approach_style_p->which_side),
124 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.05,
125 ARRIVE_FROM(DEG2RAD(0),0.05),
127 x_coord(0.3, slope_approach_style_p->which_side),
128 PLAYGROUND_HEIGHT_M - ROBOT_WIDTH_M/2 - 0.03,
129 ARRIVE_FROM(DEG2RAD(0), 0.02),
135 FSM_TRANSITION(climb_the_slope);
141 case EV_MOTION_ERROR:
142 case EV_SWITCH_STRATEGY:
143 DBG_PRINT_EVENT("unhandled event");
149 void inline enable_switches(bool enabled)
151 robot.use_left_switch = enabled;
152 robot.use_right_switch = enabled;
153 robot.use_back_switch = enabled;
156 FSM_STATE(climb_the_slope)
160 // disables using side switches on bumpers when going up
161 enable_switches(false);
162 act_vidle(VIDLE_LOAD_PREPARE, 5);
163 robot.ignore_hokuyo = true;
164 /* create the trajectory and go */
165 robot_trajectory_new_backward(&tcSlow);
166 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
167 robot_trajectory_add_point_trans(
168 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
169 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01);
170 robot_trajectory_add_final_point_trans(
171 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
172 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01,
174 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
175 robot_trajectory_add_point_trans(
176 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
177 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85));
178 robot_trajectory_add_final_point_trans(
179 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
180 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85),
186 SUBFSM_TRANSITION(load_oranges, NULL);
189 FSM_TRANSITION(sledge_down);
194 case EV_MOTION_ERROR:
195 case EV_SWITCH_STRATEGY:
196 DBG_PRINT_EVENT("unhandled event");
202 /* subautomaton to load oranges in two stages */
203 FSM_STATE_DECL(load_oranges2);
204 FSM_STATE(load_oranges)
209 act_vidle(VIDLE_MIDDLE, VIDLE_MEDIUM_SPEED);
215 FSM_TRANSITION(load_oranges2);
220 case EV_MOTION_ERROR:
221 case EV_SWITCH_STRATEGY:
222 DBG_PRINT_EVENT("unhandled event");
228 FSM_STATE(load_oranges2)
232 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
244 case EV_MOTION_ERROR:
245 case EV_SWITCH_STRATEGY:
246 DBG_PRINT_EVENT("unhandled event");
252 FSM_STATE(sledge_down)
254 struct TrajectoryConstraints tc;
259 robot_trajectory_new(&tc);
261 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
262 robot_trajectory_add_point_trans(
263 x_coord(1.2 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
264 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01);
265 robot_trajectory_add_point_trans(
266 x_coord(1.0 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
267 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.01);
268 robot_trajectory_add_point_trans(
269 x_coord(0.8 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
270 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.05);
271 robot_trajectory_add_point_trans(
272 x_coord(0.6 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
273 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.10);
274 robot_trajectory_add_final_point_trans(
275 x_coord(0.5 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
276 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.17,
278 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
279 robot_trajectory_add_point_trans(
280 x_coord(1 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
281 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85));
282 robot_trajectory_add_final_point_trans(
283 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.2, slope_approach_style_p->which_side),
284 1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85),
287 /* robot_trajectory_add_point_trans(
288 x_coord(1 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
289 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01, slope_approach_style_p->which_oranges));
290 robot_trajectory_add_point_trans(
291 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.20, slope_approach_style_p->which_side),
292 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.08, slope_approach_style_p->which_oranges));
293 robot_trajectory_add_final_point_trans(
294 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.26, slope_approach_style_p->which_side),
295 y_coord(PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.14, slope_approach_style_p->which_oranges),
299 /* just for sure, try to close it one more time */
300 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
302 delete(slope_approach_style_p);
308 case EV_MOTION_ERROR:
309 case EV_SWITCH_STRATEGY:
310 DBG_PRINT_EVENT("unhandled event");
313 // enables using side switches on bumpers
314 enable_switches(true);
315 robot.ignore_hokuyo = false;
316 robot.check_turn_safety = true;
322 /************************************************************************
323 * The "unload our oranges" subautomaton
324 ************************************************************************/
326 FSM_STATE(to_cntainer_and_unld)
331 if (slope_approach_style_p->which_side == MINE) {
332 robot_trajectory_new(&tcFast);
333 // face the rim with front of the robot
334 //robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.12, ARRIVE_FROM(DEG2RAD(-90), 0.10));
335 // face the rim with back of the robot
336 robot_trajectory_add_point_trans(PLAYGROUND_WIDTH_M-0.6, 0.35);
337 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, ARRIVE_FROM(DEG2RAD(90),0.05));
339 robot_goto_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, ARRIVE_FROM(DEG2RAD(90),0.05), &tcFast);
343 FSM_TIMER(3000); // FIXME: test this
344 act_vidle(VIDLE_DOWN, VIDLE_FAST_SPEED);
347 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
353 case EV_MOTION_ERROR:
354 case EV_SWITCH_STRATEGY:
355 DBG_PRINT_EVENT("unhandled event");
361 /************************************************************************
362 * The "collect corns" subautomaton
363 ************************************************************************/
365 static enum where_to_go {
370 } where_to_go = CORN;
372 static struct corn *corn_to_get;
374 FSM_STATE(rush_corns_decider)
378 if (where_to_go == CORN) {
379 FSM_TRANSITION(approach_next_corn);
380 } else if (where_to_go == CONTAINER) {
381 FSM_TRANSITION(rush_the_corn);
382 } else if (where_to_go == TURN_AROUND) {
383 FSM_TRANSITION(turn_around);
384 } else /* NO_MORE_CORN */ {
392 case EV_MOTION_ERROR:
393 case EV_SWITCH_STRATEGY:
394 DBG_PRINT_EVENT("unhandled event");
401 FSM_STATE(approach_next_corn)
406 robot_get_est_pos(&x, &y, &phi);
407 printf("approach_next_corn: puck cnt: %d, est pos %.3f, %.3f, %.3f\n",
410 corn_to_get = choose_next_corn();
412 Pos *p = get_corn_approach_position(corn_to_get);
413 corn_to_get->was_collected = true;
414 //robot_trajectory_new(&tcFast);
415 //robot_trajectory_add_final_point_trans(robot_trajectory_add_final_point_trans(p->x, p->y, TURN(p->phi));
416 robot_goto_trans(p->x, p->y, TURN(p->phi), &tcFast);
418 where_to_go = CONTAINER;
420 where_to_go = NO_MORE_CORN;
426 FSM_TRANSITION(rush_corns_decider);
432 case EV_MOTION_ERROR:
433 case EV_SWITCH_STRATEGY:
434 DBG_PRINT_EVENT("unhandled event");
440 FSM_STATE(rush_the_corn)
445 if (robot.team_color == BLUE) {
446 x = corn_to_get->position.x;
448 x = PLAYGROUND_WIDTH_M - corn_to_get->position.x;
450 remove_wall_around_corn(x, corn_to_get->position.y);
451 robot_goto_trans(PLAYGROUND_WIDTH_M - 0.4, 0.15, ARRIVE_FROM(DEG2RAD(-90), 0.02), &tcFast);
452 where_to_go = TURN_AROUND;
455 FSM_TRANSITION(rush_corns_decider);
461 case EV_MOTION_ERROR:
462 case EV_SWITCH_STRATEGY:
463 DBG_PRINT_EVENT("unhandled event");
469 // used to perform the maneuvre
470 FSM_STATE(turn_around)
474 robot_trajectory_new_backward(&tcFast);
475 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, TURN_CCW(90));
479 FSM_TRANSITION(rush_corns_decider);
485 case EV_MOTION_ERROR:
486 case EV_SWITCH_STRATEGY:
487 DBG_PRINT_EVENT("unhandled event");