avant la coupe de belgique
[aversive.git] / projects / microb2010 / mainboard / strat_corn.c
index 72029b3..4262e34 100644 (file)
 #include <aversive.h>
 #include <aversive/pgmspace.h>
 
+#include <ax12.h>
+#include <uart.h>
+#include <pwm_ng.h>
+#include <clock_time.h>
+#include <spi.h>
+
+#include <pid.h>
+#include <quadramp.h>
+#include <control_system_manager.h>
+#include <trajectory_manager.h>
+#include <trajectory_manager_utils.h>
+#include <trajectory_manager_core.h>
 #include <vect_base.h>
+#include <lines.h>
+#include <polygon.h>
+#include <obstacle_avoidance.h>
+#include <blocking_detection_manager.h>
+#include <robot_system.h>
+#include <position_manager.h>
+
+#include <diagnostic.h>
+
+#include <rdline.h>
+#include <parse.h>
+
+#include "../common/i2c_commands.h"
+#include "i2c_protocol.h"
+#include "main.h"
+#include "strat.h"
+#include "strat_base.h"
+#include "strat_corn.h"
+#include "strat_utils.h"
+#include "sensor.h"
+#include "actuator.h"
 
 /* XXX TODO
 static
@@ -525,6 +558,187 @@ int get_path(struct djpoint *start, struct djpoint *end)
        return 0; /* XXX */
 }
 
+/* return 1 if there is a corn near, and fill the index ptr */
+static uint8_t corn_is_near(int8_t *corn_idx, uint8_t side)
+{
+#define SENSOR_CORN_DIST  225
+#define SENSOR_CORN_ANGLE 90
+       double x = position_get_x_double(&mainboard.pos);
+       double y = position_get_y_double(&mainboard.pos);
+       double a_rad = position_get_a_rad_double(&mainboard.pos);
+       double x_corn, y_corn;
+       int16_t x_corn_int, y_corn_int;
+
+       if (side == I2C_LEFT_SIDE) {
+               x_corn = x + cos(a_rad + RAD(SENSOR_CORN_ANGLE)) * SENSOR_CORN_DIST;
+               y_corn = y + sin(a_rad + RAD(SENSOR_CORN_ANGLE)) * SENSOR_CORN_DIST;
+       }
+       else {
+               x_corn = x + cos(a_rad + RAD(-SENSOR_CORN_ANGLE)) * SENSOR_CORN_DIST;
+               y_corn = y + sin(a_rad + RAD(-SENSOR_CORN_ANGLE)) * SENSOR_CORN_DIST;
+       }
+       x_corn_int = x_corn;
+       y_corn_int = y_corn;
+
+       *corn_idx = xycoord_to_corn_idx(&x_corn_int, &y_corn_int);
+       if (*corn_idx < 0)
+               return 0;
+       return 1;
+}
+
+/*
+ * - send the correct commands to the spickles
+ * - return 1 if we need to stop (cobboard is stucked)
+*/
+static uint8_t handle_spickles(void)
+{
+       int8_t corn_idx;
+
+       return 0;
+
+       if (!corn_is_near(&corn_idx, I2C_LEFT_SIDE))
+               i2c_cobboard_mode_deploy(I2C_LEFT_SIDE);
+       else {
+               if (corn_table[corn_idx] == TYPE_WHITE_CORN)
+                       i2c_cobboard_mode_harvest(I2C_LEFT_SIDE);
+               else
+                       i2c_cobboard_mode_pack(I2C_LEFT_SIDE);
+       }
+/*     printf("%d %d\n", corn_idx, corn_table[corn_idx]); */
+/*     time_wait_ms(100); */
+
+       if (!corn_is_near(&corn_idx, I2C_RIGHT_SIDE))
+               i2c_cobboard_mode_deploy(I2C_RIGHT_SIDE);
+       else {
+               if (corn_table[corn_idx] == TYPE_WHITE_CORN)
+                       i2c_cobboard_mode_harvest(I2C_RIGHT_SIDE);
+               else
+                       i2c_cobboard_mode_pack(I2C_RIGHT_SIDE);
+       }
+
+       return 0;
+}
+
+uint8_t line2line(uint8_t dir1, uint8_t num1,
+                 uint8_t dir2, uint8_t num2)
+{
+       double line1_a_rad, line1_a_deg, line2_a_rad;
+       double diff_a_deg, diff_a_deg_abs, beta_deg;
+       double radius;
+       struct line_2pts l1, l2;
+       line_t ll1, ll2;
+       point_t p;
+       uint8_t err;
+
+       /* convert to 2 points */
+       num2line(&l1, dir1, num1);
+       num2line(&l2, dir2, num2);
+
+       printf_P(PSTR("A2 (%2.2f, %2.2f) -> (%2.2f, %2.2f)\r\n"),
+                l1.p1.x, l1.p1.y, l1.p2.x, l1.p2.y);
+       printf_P(PSTR("B2 (%2.2f, %2.2f) -> (%2.2f, %2.2f)\r\n"),
+                l2.p1.x, l2.p1.y, l2.p2.x, l2.p2.y);
+
+       /* convert to line eq and find intersection */
+       pts2line(&l1.p1, &l1.p2, &ll1);
+       pts2line(&l2.p1, &l2.p2, &ll2);
+       intersect_line(&ll1, &ll2, &p);
+
+       line1_a_rad = atan2(l1.p2.y - l1.p1.y,
+                           l1.p2.x - l1.p1.x);
+       line1_a_deg = DEG(line1_a_rad);
+       line2_a_rad = atan2(l2.p2.y - l2.p1.y,
+                           l2.p2.x - l2.p1.x);
+       diff_a_deg = DEG(line2_a_rad - line1_a_rad);
+       diff_a_deg_abs = fabs(diff_a_deg);
+
+       if (diff_a_deg_abs < 70.) {
+               radius = 200;
+               if (diff_a_deg > 0)
+                       beta_deg = 40;
+               else
+                       beta_deg = -40;
+       }
+       else if (diff_a_deg_abs < 100.) {
+               radius = 100;
+               if (diff_a_deg > 0)
+                       beta_deg = 40;
+               else
+                       beta_deg = -40;
+       }
+       else {
+               radius = 120;
+               if (diff_a_deg > 0)
+                       beta_deg = 60;
+               else
+                       beta_deg = -60;
+       }
+
+       trajectory_clitoid(&mainboard.traj, l1.p1.x, l1.p1.y,
+                          line1_a_deg, 150., diff_a_deg, beta_deg,
+                          radius, xy_norm(l1.p1.x, l1.p1.y,
+                                          p.x, p.y));
+       err = 0;
+       while (err == 0) {
+               err = WAIT_COND_OR_TRAJ_END(handle_spickles(), 0xFF);
+               if (err == 0) {
+                       /* cobboard is stucked */
+                       trajectory_hardstop(&mainboard.traj);
+                       return err; /* XXX do something */
+               }
+               err = test_traj_end(0xFF);
+       }
+       return err;
+}
+
+void num2line(struct line_2pts *l, uint8_t dir, uint8_t num)
+{
+       float n = num;
+
+       switch (dir) {
+
+       case LINE_UP:
+               l->p1.x = n * 450 + 375;
+               l->p1.y = COLOR_Y(0);
+               l->p2.x = n * 450 + 375;
+               l->p2.y = COLOR_Y(2100);
+               break;
+       case LINE_DOWN:
+               l->p1.x = n * 450 + 375;
+               l->p1.y = COLOR_Y(2100);
+               l->p2.x = n * 450 + 375;
+               l->p2.y = COLOR_Y(0);
+               break;
+       case LINE_R_UP:
+               l->p1.x = 150;
+               l->p1.y = COLOR_Y(-n * 500 + 1472);
+               l->p2.x = 2850;
+               l->p2.y = COLOR_Y((-n + 4) * 500 + 972);
+               break;
+       case LINE_L_DOWN:
+               l->p1.x = 2850;
+               l->p1.y = COLOR_Y((-n + 4) * 500 + 972);
+               l->p2.x = 150;
+               l->p2.y = COLOR_Y(-n * 500 + 1472);
+               break;
+       case LINE_L_UP:
+               l->p1.x = 2850;
+               l->p1.y = COLOR_Y(-n * 500 + 1472);
+               l->p2.x = 150;
+               l->p2.y = COLOR_Y((-n + 4) * 500 + 972);
+               break;
+       case LINE_R_DOWN:
+               l->p1.x = 150;
+               l->p1.y = COLOR_Y((-n + 4) * 500 + 972);
+               l->p2.x = 2850;
+               l->p2.y = COLOR_Y(-n * 500 + 1472);
+               break;
+       default:
+               break;
+       }
+}
+
+
 #if 0
 int main(void)
 {