2 * Copyright Droids, Microb Technology (2008)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: strat_lintel.c,v 1.5 2009-11-08 17:24:33 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
28 #include <aversive/pgmspace.h>
29 #include <aversive/queue.h>
30 #include <aversive/wait.h>
31 #include <aversive/error.h>
41 #include <control_system_manager.h>
42 #include <trajectory_manager.h>
43 #include <vect_base.h>
46 #include <obstacle_avoidance.h>
47 #include <blocking_detection_manager.h>
48 #include <robot_system.h>
49 #include <position_manager.h>
54 #include "../common/i2c_commands.h"
57 #include "strat_base.h"
58 #include "strat_avoid.h"
59 #include "strat_utils.h"
61 #include "i2c_protocol.h"
63 #define ERROUT(e) do { \
68 #define X_PRE_MARGIN 20
69 #define X_POST_MARGIN 10
72 * goto lintel disp. Return END_TRAJ if success or if there is nothing
73 * to do. Return END_ERROR if dest cannot be reached, else, it may
74 * return END_OBSTACLE or END_BLOCKING.
76 uint8_t strat_goto_lintel_disp(struct lintel_dispenser *disp)
78 uint8_t err, first_try = 1, right_ok, left_ok;
79 uint16_t old_spdd, old_spda;
80 int16_t left_cur, right_cur, a;
85 if (get_lintel_count() == 2)
88 if (disp->last_try_time >= time_get_s())
91 disp->last_try_time = time_get_s();
93 strat_get_speed(&old_spdd, &old_spda);
94 strat_set_speed(SPEED_DIST_FAST, SPEED_ANGLE_FAST);
96 DEBUG(E_USER_STRAT, "%s(): goto %s", __FUNCTION__, disp->name);
97 i2c_mechboard_mode_prepare_pickup(I2C_AUTO_SIDE);
99 err = goto_and_avoid_backward(disp->x, COLOR_Y(400),
100 TRAJ_FLAGS_STD, TRAJ_FLAGS_NO_NEAR);
101 if (!TRAJ_SUCCESS(err))
104 trajectory_a_abs(&mainboard.traj, COLOR_A(-90));
105 err = wait_traj_end(TRAJ_FLAGS_SMALL_DIST);
106 if (!TRAJ_SUCCESS(err))
109 if (time_get_s() > 86) {
110 DEBUG(E_USER_STRAT, "%s() too late...", __FUNCTION__);
114 i2c_mechboard_mode_prepare_get_lintel();
116 strat_set_speed(SPEED_DIST_VERY_SLOW, SPEED_ANGLE_FAST);
117 err = strat_calib(500, TRAJ_FLAGS_SMALL_DIST);
118 if (err == END_BLOCKING) {
119 a = position_get_a_deg_s16(&mainboard.pos);
120 /* only reset pos if angle is not too different */
121 if (ABS(a - COLOR_A(-90)) < 5)
122 strat_reset_pos(DO_NOT_SET_POS,
123 COLOR_Y(ROBOT_LENGTH/2),
126 else if (!TRAJ_SUCCESS(err))
129 i2c_mechboard_mode_get_lintel();
132 left_cur = sensor_get_adc(ADC_CSENSE3);
133 left_ok = (left_cur > I2C_MECHBOARD_CURRENT_COLUMN);
134 right_cur = mechboard.pump_right1_current;
135 right_ok = (right_cur > I2C_MECHBOARD_CURRENT_COLUMN);
137 DEBUG(E_USER_STRAT, "%s left_ok=%d (%d), right_ok=%d (%d)", __FUNCTION__,
138 left_ok, left_cur, right_ok, right_cur);
140 if (!right_ok && !left_ok) {
141 i2c_mechboard_mode_prepare_get_lintel();
144 /* XXX recalib x ? */
145 else if (right_ok && !left_ok) {
146 i2c_mechboard_mode_prepare_get_lintel();
148 strat_set_speed(500, 500);
149 trajectory_d_a_rel(&mainboard.traj, -200, 30);
150 err = wait_traj_end(TRAJ_FLAGS_SMALL_DIST);
151 trajectory_d_a_rel(&mainboard.traj, 190, -30);
152 err = wait_traj_end(TRAJ_FLAGS_SMALL_DIST);
156 else if (!right_ok && left_ok) {
157 i2c_mechboard_mode_prepare_get_lintel();
159 strat_set_speed(500, 500);
160 trajectory_d_a_rel(&mainboard.traj, -200, -30);
161 err = wait_traj_end(TRAJ_FLAGS_SMALL_DIST);
162 trajectory_d_a_rel(&mainboard.traj, 190, 30);
163 err = wait_traj_end(TRAJ_FLAGS_SMALL_DIST);
167 /* else, lintel is ok */
169 strat_infos.taken_lintel ++;
170 i2c_mechboard_mode_put_lintel();
174 if (right_ok && left_ok) {
176 strat_infos.taken_lintel ++;
177 i2c_mechboard_mode_put_lintel();
180 i2c_mechboard_mode_prepare_get_lintel();
186 strat_set_speed(SPEED_DIST_FAST, SPEED_ANGLE_FAST);
187 trajectory_d_rel(&mainboard.traj, -250);
188 err = wait_traj_end(TRAJ_FLAGS_STD);
193 strat_set_speed(old_spdd, old_spda);
197 /* go pickup lintels on dispensers. Return END_TRAJ on success or if
199 * there is nothing to do, else return the error status. */
200 uint8_t strat_pickup_lintels(void)
204 if (get_column_count() != 0)
207 if (strat_infos.l1.count == 0 && strat_infos.l2.count == 0)
210 /* skip if it's too early */
211 if (time_get_s() < strat_infos.conf.lintel_min_time)
214 /* skip next lintel if we want only one */
215 if (strat_infos.conf.flags & STRAT_CONF_TAKE_ONE_LINTEL) {
216 if (strat_infos.taken_lintel)
220 /* don't take lintel now if we already have one and if there
221 * is not much time */
222 if (get_lintel_count() && time_get_s() > 75)
226 err = strat_goto_lintel_disp(&strat_infos.l1);
227 if (!TRAJ_SUCCESS(err) && err != END_ERROR)
230 /* skip next lintel if we want only one */
231 if (strat_infos.conf.flags & STRAT_CONF_TAKE_ONE_LINTEL) {
232 if (strat_infos.taken_lintel)
236 /* don't take lintel now if we already have one and if there
237 * is not much time */
238 if (get_lintel_count() && time_get_s() > 75)
242 err = strat_goto_lintel_disp(&strat_infos.l2);
243 if (!TRAJ_SUCCESS(err) && err != END_ERROR)