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);
57 // We set initial position periodically in order for it to be updated
58 // on the display if the team color is changed during waiting for
62 set_initial_position();
63 if (robot.start_state == START_PLUGGED_IN)
69 sem_post(&robot.start);
71 set_initial_position();
76 robot.corns = get_all_corns(robot.corns_conf_side, robot.corns_conf_center);
80 /************************************************************************
81 * Trajectory constraints used; They are initialized in the main() function in competition.cc
82 ************************************************************************/
84 struct TrajectoryConstraints tcJerk, tcFast, tcSlow, tcVerySlow;
86 #define VIDLE_TIMEOUT 2000
88 /************************************************************************
89 * States that form the "collect some oranges" subautomaton. Calling automaton
90 * SHOULD ALWAYS call the "approach_the_slope" state.
91 ************************************************************************/
93 bool inline is_ready_to_climb_the_slope(enum which_side which_slope, double x, double y) {
95 if (which_slope == MINE) {
96 ret = x < 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
97 } else if (which_slope == OPPONENTS) {
98 ret = x > 0.5 && y > PLAYGROUND_HEIGHT_M - 0.5;
100 printf("ERROR: unknown side;");
101 #warning Remove the next line
107 static struct slope_approach_style *slope_approach_style_p;
109 /* assures that the robot is near the slope rim; if outside our starting area, approach the slope first */
110 FSM_STATE(approach_the_slope)
114 slope_approach_style_p = (struct slope_approach_style *) FSM_EVENT_PTR;
115 if (slope_approach_style_p == NULL) {
116 printf("\n\nit is not allowed to call the approach_the_slope state with NULL data!!\n\n");
117 #warning remove the next line
121 robot_get_est_pos_trans(&x, &y, &phi);
123 bool ready_to_climb_the_slope = is_ready_to_climb_the_slope(slope_approach_style_p->which_side, x, y);
124 /* if necessary, approach the slope */
125 if (ready_to_climb_the_slope) {
126 FSM_TRANSITION(climb_the_slope);
129 x_coord(0.3, slope_approach_style_p->which_side),
130 PLAYGROUND_HEIGHT_M - ROBOT_WIDTH_M/2 - 0.03,
131 ARRIVE_FROM(DEG2RAD(0), 0.02),
137 FSM_TRANSITION(climb_the_slope);
143 case EV_MOTION_ERROR:
144 case EV_SWITCH_STRATEGY:
145 DBG_PRINT_EVENT("unhandled event");
151 void inline enable_switches(bool enabled)
153 robot.use_left_switch = enabled;
154 robot.use_right_switch = enabled;
155 robot.use_back_switch = enabled;
158 FSM_STATE(climb_the_slope)
160 struct TrajectoryConstraints tc;
163 // disables using side switches on bumpers when going up
164 enable_switches(false);
165 robot.ignore_hokuyo = true;
166 /* create the trajectory and go */
169 robot_trajectory_new_backward(&tc);
170 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
171 act_vidle(VIDLE_LOAD_PREPARE, 5);
172 robot_trajectory_add_point_trans(
173 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
174 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01);
175 robot_trajectory_add_final_point_trans(
176 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
177 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) +0.01,
179 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
181 robot_trajectory_add_point_trans(
182 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
183 //1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85));
184 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.199);
185 robot_trajectory_add_final_point_trans(
186 x_coord(SLOPE_TO_RIM_M + SLOPE_LENGTH_M - ROBOT_AXIS_TO_BACK_M + 0.07, slope_approach_style_p->which_side),
187 //1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) + 0.01 - 1.85),
188 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.199,
194 SUBFSM_TRANSITION(load_oranges, NULL);
197 FSM_TRANSITION(sledge_down);
200 act_vidle(VIDLE_LOAD_PREPARE, 10);
204 case EV_MOTION_ERROR:
205 case EV_SWITCH_STRATEGY:
206 DBG_PRINT_EVENT("unhandled event");
212 /* subautomaton to load oranges in two stages */
213 FSM_STATE_DECL(load_oranges2);
214 FSM_STATE_DECL(load_oranges3);
215 FSM_STATE(load_oranges)
220 act_vidle(VIDLE_MIDDLE, VIDLE_MEDIUM_SPEED);
226 FSM_TRANSITION(load_oranges2);
231 case EV_MOTION_ERROR:
232 case EV_SWITCH_STRATEGY:
233 DBG_PRINT_EVENT("unhandled event");
239 FSM_STATE(load_oranges2)
243 act_vidle(VIDLE_UP, VIDLE_MEDIUM_SPEED);
247 FSM_TRANSITION(load_oranges3);
251 FSM_TRANSITION(load_oranges3);
257 case EV_MOTION_ERROR:
258 case EV_SWITCH_STRATEGY:
259 DBG_PRINT_EVENT("unhandled event");
261 act_vidle(VIDLE_UP-1, VIDLE_FAST_SPEED);
266 FSM_STATE(load_oranges3)
270 act_vidle(VIDLE_MIDDLE+50, 0);
282 case EV_MOTION_ERROR:
283 case EV_SWITCH_STRATEGY:
284 DBG_PRINT_EVENT("unhandled event");
286 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
291 FSM_STATE(sledge_down)
293 struct TrajectoryConstraints tc;
298 robot_trajectory_new(&tc);
300 if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_BOUNDARY) {
301 robot_trajectory_add_point_trans(
302 x_coord(1.2 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
303 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01);
304 robot_trajectory_add_point_trans(
305 x_coord(1.0 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
306 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.01);
307 robot_trajectory_add_point_trans(
308 x_coord(0.8 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
309 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.05);
310 robot_trajectory_add_point_trans(
311 x_coord(0.6 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
312 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.10);
313 robot_trajectory_add_final_point_trans(
314 x_coord(0.5 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
315 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.19,
317 } else if (slope_approach_style_p->which_oranges == NEAR_PLAYGROUND_CENTER) {
318 robot_trajectory_add_point_trans(
319 x_coord(1 - ROBOT_AXIS_TO_BACK_M, slope_approach_style_p->which_side),
320 //1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85));
321 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.199);
322 robot_trajectory_add_final_point_trans(
323 x_coord(SLOPE_TO_RIM_M - ROBOT_AXIS_TO_BACK_M - 0.2, slope_approach_style_p->which_side),
324 //1.85 - (PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2)+0.01 - 1.85),
325 PLAYGROUND_HEIGHT_M - (ROBOT_WIDTH_M/2) - 0.199,
330 /* just for sure, try to close it one more time */
331 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
333 delete(slope_approach_style_p);
339 case EV_MOTION_ERROR:
340 case EV_SWITCH_STRATEGY:
341 DBG_PRINT_EVENT("unhandled event");
344 // enables using side switches on bumpers
345 enable_switches(true);
346 robot.ignore_hokuyo = false;
347 robot.check_turn_safety = true;
353 /************************************************************************
354 * The "unload our oranges" subautomaton
355 ************************************************************************/
357 FSM_STATE(to_cntainer_and_unld)
361 robot_goto_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, ARRIVE_FROM(DEG2RAD(90),0.05), &tcFast);
364 FSM_TIMER(1000); // FIXME: test this
365 act_vidle(VIDLE_DOWN, VIDLE_FAST_SPEED);
368 FSM_TRANSITION(jerk);
373 case EV_MOTION_ERROR:
374 case EV_SWITCH_STRATEGY:
375 DBG_PRINT_EVENT("unhandled event");
383 static char move_cnt;
387 robot_move_by(-0.05, NO_TURN(), &tcSlow);
391 robot_move_by(0.05, NO_TURN(), &tcJerk);
392 } else if (move_cnt > 0) {
393 FSM_TIMER(1500); // FIXME: test this
398 act_vidle(VIDLE_UP, VIDLE_FAST_SPEED);
404 case EV_MOTION_ERROR:
405 case EV_SWITCH_STRATEGY:
406 DBG_PRINT_EVENT("unhandled event");
412 /************************************************************************
413 * The "collect corns" subautomaton
414 ************************************************************************/
416 static enum where_to_go {
421 } where_to_go = CORN;
423 static struct corn *corn_to_get;
425 FSM_STATE(rush_corns_decider)
429 if (where_to_go == CORN) {
430 FSM_TRANSITION(approach_next_corn);
431 } else if (where_to_go == CONTAINER) {
432 FSM_TRANSITION(rush_the_corn);
433 } else if (where_to_go == TURN_AROUND) {
434 FSM_TRANSITION(turn_around);
435 } else /* NO_MORE_CORN */ {
443 case EV_MOTION_ERROR:
444 case EV_SWITCH_STRATEGY:
445 DBG_PRINT_EVENT("unhandled event");
452 FSM_STATE(approach_next_corn)
457 robot_get_est_pos(&x, &y, &phi);
458 printf("approach_next_corn: puck cnt: %d, est pos %.3f, %.3f, %.3f\n",
461 corn_to_get = choose_next_corn();
463 Pos *p = get_corn_approach_position(corn_to_get);
464 corn_to_get->was_collected = true;
465 robot_goto_trans(p->x, p->y, TURN(p->phi), &tcFast);
467 where_to_go = CONTAINER;
469 where_to_go = NO_MORE_CORN;
475 FSM_TRANSITION(rush_corns_decider);
481 case EV_MOTION_ERROR:
482 case EV_SWITCH_STRATEGY:
483 DBG_PRINT_EVENT("unhandled event");
489 FSM_STATE(rush_the_corn)
494 if (robot.team_color == BLUE) {
495 x = corn_to_get->position.x;
497 x = PLAYGROUND_WIDTH_M - corn_to_get->position.x;
499 remove_wall_around_corn(x, corn_to_get->position.y);
500 robot_goto_trans(PLAYGROUND_WIDTH_M - 0.4, 0.15, ARRIVE_FROM(DEG2RAD(-90), 0.02), &tcSlow);
501 where_to_go = TURN_AROUND;
504 FSM_TRANSITION(rush_corns_decider);
510 case EV_MOTION_ERROR:
511 case EV_SWITCH_STRATEGY:
512 DBG_PRINT_EVENT("unhandled event");
518 // used to perform the maneuvre
519 FSM_STATE(turn_around)
523 robot_trajectory_new_backward(&tcFast);
524 robot_trajectory_add_final_point_trans(PLAYGROUND_WIDTH_M-0.35, 0.45, TURN_CCW(90));
528 FSM_TRANSITION(rush_corns_decider);
534 case EV_MOTION_ERROR:
535 case EV_SWITCH_STRATEGY:
536 DBG_PRINT_EVENT("unhandled event");