+ err = END_TRAJ;
+
+ fail:
+ strat_want_pack = 0;
+ return err;
+}
+
+/* list of waypoints when we are not on a circuit */
+const struct xy_point unblock_pts[] = {
+ { .x = 375, .y = 597 }, /* 1,1 */
+ { .x = 2625, .y = 597 }, /* 11,1 */
+ { .x = 1500, .y = 722 }, /* 6,2 */
+ { .x = 375, .y = 1097 }, /* 1,3 */
+ { .x = 375, .y = 1597 }, /* 1,5 */
+ { .x = 2625, .y = 1097 }, /* 11,3 */
+ { .x = 2625, .y = 1597 }, /* 11,5 */
+ { .x = 1500, .y = 1722 }, /* 6,6 */
+};
+
+
+/* try to unblock in any situation */
+uint8_t strat_unblock(void)
+{
+ int16_t x, y, posx, posy;
+ uint8_t i, j, k;
+ uint16_t old_dspeed, old_aspeed;
+ uint8_t err;
+ uint16_t d_min = 0x7FFF, d;
+ const struct xy_point *pt;
+
+ DEBUG(E_USER_STRAT, "%s()", __FUNCTION__);
+
+ strat_want_pack = 1;
+ strat_get_speed(&old_dspeed, &old_aspeed);
+
+ strat_hardstop();
+ strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_SLOW);
+ posx = position_get_x_s16(&mainboard.pos);
+ posy = position_get_y_s16(&mainboard.pos);
+ x = posx;
+ y = posy;
+
+ if (xycoord_to_ijcoord_not_corn(&x, &y, &i, &j) < 0)
+ x = -1;
+ else if (strat_db.wp_table[i][j].on_circuit == 0)
+ x = -1;
+
+ /* find the nearest unblock point */
+ if (x == -1) {
+
+ /* browse all points and find the nearest */
+ for (k = 0; k < sizeof(unblock_pts)/sizeof(*unblock_pts); k++) {
+ pt = &unblock_pts[k];
+ d = distance_between(posx, posy, pt->x, COLOR_Y(pt->y));
+ if (d < d_min) {
+ d_min = d;
+ x = pt->x;
+ y = COLOR_Y(pt->y);
+ }
+ }
+ }
+ DEBUG(E_USER_STRAT, "%s() unblock point is %d,%d",
+ __FUNCTION__, x, y);
+
+ /* XXX if opponent is too close, go back, or wait ? */
+
+ /* go to nearest waypoint */
+ trajectory_goto_xy_abs(&mainboard.traj, x, y);
+ err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
+ if (err == END_TIMER)
+ return err;
+
+ if (!TRAJ_SUCCESS(err))
+ return err;
+
+ strat_set_speed(old_dspeed, old_aspeed);
+ return END_TRAJ;
+}
+
+void strat_avoid_init(void)
+{
+ init_all_circuits();
+
+#ifdef TEST_STRAT_AVOID
+ uint8_t i, j;
+ const struct circuit *selected_circuit;
+ int8_t selected_face;
+ struct wp_line circuit_wpline[MAX_CIRCUIT_WPLINE];
+ int8_t ret;
+
+ i = 1; j = 1;
+ printf_P(PSTR("========= i=%d, j=%d\r\n"), i, j);
+
+ ts = 0; bc = 0; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 3; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 4; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 3; cc = 5;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 4; cc = 5;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 80; bc = 0; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ i = 4; j = 3;
+ printf_P(PSTR("========= i=%d, j=%d\r\n"), i, j);
+
+ ts = 0; bc = 0; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 3; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 80; bc = 0; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ i = 11; j = 6;
+ printf_P(PSTR("========= i=%d, j=%d\r\n"), i, j);
+
+ ts = 0; bc = 0; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);
+
+ ts = 0; bc = 3; cc = 0;
+ printf_P(PSTR("=== time=%"PRIu32", ball=%d, corn=%d\r\n"), ts, bc, cc);
+ find_best_circuit(i, j, &selected_circuit, &selected_face);
+ ret = get_path(selected_circuit, i, j, selected_face, circuit_wpline);
+ dump_circuit_wp(circuit_wpline, ret);