#define ROLLER_REVERSE ROLLER_SPEED
#define FORKROT_DEPLOYED -55000
-#define FORKROT_MID -33000
+#define FORKROT_MID1 -31000
+#define FORKROT_MID2 -27000
+#define FORKROT_EJECT -12000
#define FORKROT_PACKED -4000
void roller_on(void)
cs_set_consign(&ballboard.forkrot.cs, FORKROT_PACKED);
}
-void fork_mid(void)
+void fork_mid1(void)
{
- cs_set_consign(&ballboard.forkrot.cs, FORKROT_MID);
+ cs_set_consign(&ballboard.forkrot.cs, FORKROT_MID1);
+}
+
+void fork_mid2(void)
+{
+ cs_set_consign(&ballboard.forkrot.cs, FORKROT_MID2);
+}
+
+void fork_eject(void)
+{
+ cs_set_consign(&ballboard.forkrot.cs, FORKROT_EJECT);
+}
+
+static uint8_t fork_is_at_pos(int32_t pos)
+{
+ int32_t diff;
+ diff = pos - encoders_spi_get_value(FORKROT_ENCODER);
+ if (diff < 0)
+ diff = -diff;
+ if (diff < 500)
+ return 1;
+ return 0;
+}
+
+uint8_t fork_is_packed(void)
+{
+ return fork_is_at_pos(FORKROT_PACKED);
}
void actuator_init(void)
void fork_deploy(void);
void fork_pack(void);
-void fork_mid(void);
+void fork_mid1(void);
+void fork_mid2(void);
+void fork_eject(void);
+uint8_t fork_is_packed(void);
void actuator_init(void);
fork_deploy();
else if (!strcmp_P(res->arg1, PSTR("pack")))
fork_pack();
- else if (!strcmp_P(res->arg1, PSTR("middle")))
- fork_mid();
+ else if (!strcmp_P(res->arg1, PSTR("mid1")))
+ fork_mid1();
+ else if (!strcmp_P(res->arg1, PSTR("mid2")))
+ fork_mid2();
}
prog_char str_fork_arg0[] = "fork";
parse_pgm_token_string_t cmd_fork_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_fork_result, arg0, str_fork_arg0);
-prog_char str_fork_arg1[] = "deploy#pack#middle";
+prog_char str_fork_arg1[] = "deploy#pack#mid1#mid2";
parse_pgm_token_string_t cmd_fork_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_fork_result, arg1, str_fork_arg1);
prog_char help_fork[] = "move fork";
cs_get_filtered_feedback(&ballboard.roller.cs),
cs_get_out(&ballboard.roller.cs));
+#if 0
/* urgent case: stop power on blocking */
if (ballboard.flags & DO_ERRBLOCKING) {
if (bd_get(&ballboard.forktrans.bd) ||
ballboard.flags &= ~(DO_POWER | DO_ERRBLOCKING);
}
}
+#endif
}
if (ballboard.flags & DO_POWER)
BRAKE_OFF();
/* QUADRAMP */
quadramp_init(&ballboard.forkrot.qr);
- quadramp_set_1st_order_vars(&ballboard.forkrot.qr, 200, 800); /* set speed */
- quadramp_set_2nd_order_vars(&ballboard.forkrot.qr, 20, 20); /* set accel */
+ quadramp_set_1st_order_vars(&ballboard.forkrot.qr, 1000, 500); /* set speed */
+ quadramp_set_2nd_order_vars(&ballboard.forkrot.qr, 100, 20); /* set accel */
/* CS */
cs_init(&ballboard.forkrot.cs);
blocked = 0;
while (1) {
+ /* move fork during ball ejection */
+ if ((us % 600) < 300)
+ fork_eject();
+ else
+ fork_pack();
/* no more balls (sensor is heavily filtered) */
- if (!sensor_get(S_LOW_BARRIER)) {
+ if (!sensor_get(S_LOW_BARRIER) &&
+ !sensor_get(S_HIGH_BARRIER)) {
STMCH_DEBUG("%s(): no more balls", __FUNCTION__);
break;
}
break;
}
}
+ fork_pack();
if (!blocked)
break;
case TAKE_FORK:
roller_off();
- fork_mid();
- time_wait_ms(1300);
+ fork_mid1();
+ time_wait_ms(666);
+ fork_mid2();
+ time_wait_ms(666);
+ while (1) {
+ uint8_t packed;
+
+ fork_pack();
+ packed = WAIT_COND_OR_TIMEOUT(fork_is_packed(),
+ 500);
+ if (packed)
+ break;
+ fork_mid2();
+ time_wait_ms(200);
+ }
state_mode = OFF;
break;
#include "main.h"
#include "actuator.h"
-#define COBROLLER_SPEED 666
+#define COBROLLER_SPEED 850
#define SERVO_DOOR_OPEN 300
#define SERVO_DOOR_CLOSED 525
#define SHOVEL_DOWN 100
#define SHOVEL_MID 4500
#define SHOVEL_UP 11300
-#define SHOVEL_KICKSTAND_UP 12800
-#define SHOVEL_KICKSTAND_DOWN 10000
+#define SHOVEL_KICKSTAND_UP 13400
+#define SHOVEL_KICKSTAND_DOWN 10400
static int32_t shovel_k1 = 1000;
static int32_t shovel_k2 = 20;
{
shovel_current_limit_enable(0);
if (state_get_cob_count() <= 1)
- quadramp_set_1st_order_vars(&cobboard.shovel.qr, 1000, 2500);
+ quadramp_set_1st_order_vars(&cobboard.shovel.qr, 700, 2500);
else
- quadramp_set_1st_order_vars(&cobboard.shovel.qr, 2000, 2500);
+ quadramp_set_1st_order_vars(&cobboard.shovel.qr, 1000, 2500);
quadramp_set_2nd_order_vars(&cobboard.shovel.qr, 80, 15);
cs_set_consign(&cobboard.shovel.cs, SHOVEL_UP);
}
return shovel_is_at_pos(SHOVEL_DOWN);
}
+uint8_t shovel_is_mid(void)
+{
+ return shovel_is_at_pos(SHOVEL_MID);
+}
+
void shovel_init(void)
{
shovel_autopos();
uint8_t shovel_is_up(void);
uint8_t shovel_is_down(void);
+uint8_t shovel_is_mid(void);
#endif /* _SHOVEL_H_ */
#define KICKSTAND_DOWN(mode) ((mode) == I2C_COBBOARD_MODE_KICKSTAND_DOWN)
uint8_t state_debug = 0;
+static uint8_t state_cob_partial = 0;
uint8_t state_get_cob_count(void)
{
!sensor_get(S_COB_INSIDE_R);
}
+static uint8_t state_cob_inside_enhanced(void)
+{
+ if (sensor_get(S_COB_INSIDE_L))
+ state_cob_partial = 1;
+ if (sensor_get(S_COB_INSIDE_R))
+ state_cob_partial = 1;
+ return state_cob_inside();
+}
+
static uint8_t state_spicklemode_deployed(uint8_t side)
{
if (side == I2C_LEFT_SIDE)
/* harvest cobs from area */
static void state_do_harvest(uint8_t side)
{
+ uint8_t i = 0;
+
/* if there is no cob, return */
if (cob_falling_edge(side) == 0)
return;
cobroller_on(side);
/* check that cob is correctly in place */
- if (WAIT_COND_OR_TIMEOUT(state_cob_inside(), 750) == 0) {
- if (state_no_cob_inside()) {
+ state_cob_partial = 0;
+ if (WAIT_COND_OR_TIMEOUT(state_cob_inside_enhanced(), 750) == 0) {
+ if (state_no_cob_inside() && state_cob_partial == 0) {
STMCH_DEBUG("no cob");
return;
}
+ else if (state_no_cob_inside() && state_cob_partial == 1)
+ goto cont;
+
STMCH_DEBUG("bad cob state");
/* while cob is not correctly placed try to extract
time_wait_ms(250);
shovel_down();
time_wait_ms(250);
+
+ if (EJECT(state_mode))
+ return;
}
STMCH_DEBUG("cob removed");
}
}
+ cont:
/* cob is inside, switch off roller */
cobroller_off(side);
cob_count ++;
/* store it */
shovel_up();
+ i = 0;
while (WAIT_COND_OR_TIMEOUT(shovel_is_up(), 600) == 0) {
STMCH_DEBUG("shovel blocked");
shovel_down();
- time_wait_ms(250);
- shovel_up();
+
+ if (i == 4)
+ break;
+
/* if eject command is received, force exit */
if (EJECT(state_mode))
return;
+
+ time_wait_ms(250);
+ shovel_up();
+ i ++;
+ }
+
+ /* bad state, try to eject to cobs */
+ if (i == 4) {
+ servo_door_open();
+ shovel_mid();
+
+ while (WAIT_COND_OR_TIMEOUT(shovel_is_mid(), 600) == 0) {
+ STMCH_DEBUG("ejecting cobs");
+
+ shovel_down();
+ time_wait_ms(250);
+ if (state_no_cob_inside()) {
+ servo_door_close();
+ cob_count = 0;
+ return;
+ }
+ shovel_mid();
+ }
}
state_debug_wait_key_pressed();
#endif
}
+static void remove_cob(uint8_t idx)
+{
+ if (strat_db.corn_table[idx]->corn.color == I2C_COB_BLACK)
+ return;
+
+ if (strat_db.corn_table[idx]->time_removed == -1) {
+ strat_db.corn_table[idx]->time_removed = time_get_s();
+#ifdef HOST_VERSION
+ cobboard.cob_count ++;
+ printf("add cob %d\n", idx);
+#endif
+ }
+}
+
/* mark corn as not present and give correct commands to the cobboard
* for spickles */
static void check_corn(void)
lcob == I2C_COB_WHITE ? "white" : "black", lidx);
corn_set_color(strat_db.corn_table[lidx], lcob);
}
- if (!__y_is_more_than(l_yspickle, 600))
+ if (cur_time > 5 && !__y_is_more_than(l_yspickle, 600))
l_y_too_high_pack = 1;
/* detect cob on right side */
rcob == I2C_COB_WHITE ? "white" : "black", ridx);
corn_set_color(strat_db.corn_table[ridx], rcob);
}
- if (!__y_is_more_than(r_yspickle, 600))
+ if (cur_time > 5 && !__y_is_more_than(r_yspickle, 600))
r_y_too_high_pack = 1;
+ /* re-enable white cob */
+ if (lcob == I2C_COB_WHITE && lcob_near &&
+ strat_db.corn_table[lidx]->present == 0) {
+ strat_db.corn_table[lidx]->present = 1;
+ strat_db.corn_table[lidx]->time_removed = -1;
+ }
+ if (rcob == I2C_COB_WHITE && rcob_near &&
+ strat_db.corn_table[ridx]->present == 0) {
+ strat_db.corn_table[ridx]->present = 1;
+ strat_db.corn_table[ridx]->time_removed = -1;
+ }
+
/* control the cobboard mode for left spickle */
need_lpack = get_cob_count() >= 5 || strat_want_pack ||
strat_lpack60 || strat_opponent_lpack || l_y_too_high_pack;
- if (lcob_near && strat_db.corn_table[lidx]->present) {
+ if (lcob_near &&
+ (strat_db.corn_table[lidx]->present ||
+ strat_db.corn_table[lidx]->time_removed == -1)) {
if (need_lpack) {
/* nothing */
}
else {
/* deploy spickle and harvest white ones */
- if (strat_db.corn_table[lidx]->corn.color == I2C_COB_WHITE) {
+ if (strat_db.corn_table[lidx]->corn.color == I2C_COB_WHITE)
i2c_cobboard_autoharvest_nomove(I2C_LEFT_SIDE);
- if (strat_db.corn_table[lidx]->time_removed == -1
-#ifndef HOST_VERSION
- && cobboard.status == I2C_COBBOARD_STATUS_LBUSY
-#endif
- ) {
- strat_db.corn_table[lidx]->time_removed = time_get_s();
-#ifdef HOST_VERSION
- cobboard.cob_count ++;
- printf("add cob %d\n", lidx);
-#else
- strat_db.corn_table[lidx]->present = 0;
-#endif
- }
- }
else
i2c_cobboard_deploy_nomove(I2C_LEFT_SIDE);
+ remove_cob(lidx);
}
}
else {
/* control the cobboard mode for right spickle */
need_rpack = get_cob_count() >= 5 || strat_want_pack ||
strat_rpack60 || strat_opponent_rpack || r_y_too_high_pack;
- if (rcob_near && strat_db.corn_table[ridx]->present) {
+ if (rcob_near &&
+ (strat_db.corn_table[ridx]->present ||
+ strat_db.corn_table[ridx]->time_removed == -1)) {
if (need_rpack) {
/* nothing */
}
else {
/* deploy spickle and harvest white ones */
- if (strat_db.corn_table[ridx]->corn.color == I2C_COB_WHITE) {
+ if (strat_db.corn_table[ridx]->corn.color == I2C_COB_WHITE)
i2c_cobboard_autoharvest_nomove(I2C_RIGHT_SIDE);
- if (strat_db.corn_table[ridx]->time_removed == -1
-#ifndef HOST_VERSION
- && cobboard.status == I2C_COBBOARD_STATUS_RBUSY
-#endif
- ) {
- strat_db.corn_table[ridx]->time_removed = time_get_s();
-#ifdef HOST_VERSION
- cobboard.cob_count ++;
- printf("add cob %d\n", ridx);
-#else
- strat_db.corn_table[ridx]->present = 0;
-#endif
- }
- }
else
i2c_cobboard_deploy_nomove(I2C_RIGHT_SIDE);
+ remove_cob(ridx);
}
}
else {
#ifdef HOST_VERSION
time_wait_ms(2000);
#else
- WAIT_COND_OR_TIMEOUT(ballboard.status == I2C_BALLBOARD_STATUS_F_BUSY,
- 2000);
WAIT_COND_OR_TIMEOUT(ballboard.status == I2C_BALLBOARD_STATUS_F_READY,
2000);
#endif
time_wait_ms(300);
}
- if (get_cob_count() > 0) {
+ if (get_cob_count() > 0 ||
+ cobboard.status == I2C_COBBOARD_STATUS_LBUSY ||
+ cobboard.status == I2C_COBBOARD_STATUS_RBUSY) {
/* half turn */
trajectory_a_abs(&mainboard.traj, COLOR_A(-110));
err = wait_traj_end(END_INTR|END_TRAJ);
if (do_initturn) {
//strat_set_speed(600, 60);
- strat_set_speed(450, 50);
+ //strat_set_speed(450, 50);
+ strat_set_speed(350, 40);
trajectory_d_a_rel(&mainboard.traj, 1000, COLOR_A(20));
err = WAIT_COND_OR_TRAJ_END(trajectory_angle_finished(&mainboard.traj),
TRAJ_FLAGS_STD);
strat_hardstop();
i2c_ballboard_set_mode(I2C_BALLBOARD_MODE_TAKE_FORK);
- time_wait_ms(1100);
+ time_wait_ms(500);
trajectory_d_rel(&mainboard.traj, 15);
- time_wait_ms(400);
+ time_wait_ms(700);
strat_hardstop();
time_wait_ms(200);
/* reach top, go down */
- trajectory_d_rel(&mainboard.traj, -HILL_LEN);
+ trajectory_d_a_rel(&mainboard.traj, -HILL_LEN, -2);
if (orange_color == our_color)
err = WAIT_COND_OR_TRAJ_END(position_get_x_s16(&mainboard.pos) <
TRAJ_FLAGS_SMALL_DIST);
DEBUG(E_USER_STRAT, "deploy support balls");
- strat_set_acc(ad, aa);
- strat_set_speed(SPEED_DIST_FAST, SPEED_ANGLE_FAST);
support_balls_deploy();
+ if (orange_color == I2C_COLOR_YELLOW) {
+ strat_set_acc(ad, aa);
+ strat_set_speed(SPEED_DIST_FAST, SPEED_ANGLE_FAST);
+ }
+ else {
+ strat_set_acc(ad, 0.4);
+ strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_SLOW);
+ trajectory_d_a_rel(&mainboard.traj, -500, 20);
+ }
+
/* wait to be near the wall */
if (orange_color == our_color)
err = WAIT_COND_OR_TRAJ_END(position_get_x_s16(&mainboard.pos) < 300,
AREA_X - 300,
TRAJ_FLAGS_SMALL_DIST);
+ strat_set_acc(ad, aa);
+ strat_set_speed(SPEED_DIST_FAST, SPEED_ANGLE_FAST);
+
/* restore BD coefs */
bd_set_current_thresholds(&mainboard.distance.bd, 500, 8000, 1000000, 20);
bd_set_current_thresholds(&mainboard.distance.bd, 500, 8000, 1000000, 20);
trajectory_d_rel(&mainboard.traj, -250);
err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
+#if 0
if (orange_color == our_color)
trajectory_a_abs(&mainboard.traj, 180);
else
trajectory_d_rel(&mainboard.traj, -250);
err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
-
+#endif
/* revert acceleration and speed */
pid_set_gains(&mainboard.angle.pid, p, i, d);
pid_set_maximums(&mainboard.distance.pid, max_in, max_i, max_out);
}
/* opponent is in front of us */
- if ((mainboard.speed_d >= 0 && opp_d < 500 && (opp_a > 315 || opp_a < 45)) ||
- (mainboard.speed_d >= 0 && opp_d < 650 && (opp_a > 330 || opp_a < 30))) {
+ if ((mainboard.speed_d >= 0 && opp_d < 600 && (opp_a > 315 || opp_a < 45)) ||
+ (mainboard.speed_d >= 0 && opp_d < 800 && (opp_a > 330 || opp_a < 30))) {
DEBUG(E_USER_STRAT, "opponent front d=%d, a=%d "
"xrel=%d yrel=%d (speed_d=%d)",
opp_d, opp_a, x_rel, y_rel, mainboard.speed_d);
return 1;
}
/* opponent is behind us */
- if ((mainboard.speed_d < 0 && opp_d < 500 && (opp_a < 225 && opp_a > 135)) ||
- (mainboard.speed_d < 0 && opp_d < 650 && (opp_a < 210 && opp_a > 150))) {
+ if ((mainboard.speed_d < 0 && opp_d < 600 && (opp_a < 225 && opp_a > 135)) ||
+ (mainboard.speed_d < 0 && opp_d < 800 && (opp_a < 210 && opp_a > 150))) {
DEBUG(E_USER_STRAT, "opponent behind d=%d, a=%d xrel=%d yrel=%d",
opp_d, opp_a, x_rel, y_rel);
sensor_obstacle_disable();