X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=projects%2Fmicrob2010%2Fballboard%2Fbeacon.c;fp=projects%2Fmicrob2010%2Fballboard%2Fbeacon.c;h=147a2a90e8070002890bb0dad9c1cb4164fa4c95;hp=0000000000000000000000000000000000000000;hb=ad466314d3aff8f661654d4701b9d12fdeb7811f;hpb=d78a81c0df6dfe318d873a6f877e53cfb957ad8e diff --git a/projects/microb2010/ballboard/beacon.c b/projects/microb2010/ballboard/beacon.c new file mode 100644 index 0000000..147a2a9 --- /dev/null +++ b/projects/microb2010/ballboard/beacon.c @@ -0,0 +1,396 @@ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sensor.h" + +#include "../common/i2c_commands.h" +#include "main.h" +#include "beacon.h" + +struct beacon beacon; + +#define BEACON_PWM_VALUE 1000 +#define IR_SENSOR() (!!(PINK&(1<<5))) +#define MODULO_TIMER (1023L) +#define COEFF_TIMER (2) +#define COEFF_MULT (100L) +#define COEFF_MULT2 (1000L) +#define BEACON_SIZE (9) +#define BEACON_MAX_SAMPLE (3) + +#define OPPONENT_POS_X (11) +#define OPPONENT_POS_Y (22) + +#define BEACON_DEBUG(args...) DEBUG(E_USER_BEACON, args) +#define BEACON_NOTICE(args...) NOTICE(E_USER_BEACON, args) +#define BEACON_ERROR(args...) ERROR(E_USER_BEACON, args) + +static volatile int32_t rising = -1; +static volatile int32_t falling = -1; + +static int32_t get_dist(float size); +static int32_t get_angle(int32_t middle, int32_t ref); + +static int32_t pos_ref = 0; +static int32_t invalid_count = 0; + +static volatile int32_t beacon_speed; +static volatile int32_t beacon_save_count = 0; +static volatile int32_t beacon_prev_save_count = 0; +static volatile int32_t count = 0; +static volatile int32_t count_diff_rising = 0; +static volatile int32_t count_diff_falling = 0; +static int32_t beacon_coeff = 0; + +static volatile int8_t valid_beacon = 0; + +static volatile int32_t beacon_pos; + +//static int32_t beacon_sample_size[BEACON_MAX_SAMPLE]; + +int32_t encoders_spi_get_value_beacon(void *number) +{ + int32_t ret; + + ret = encoders_spi_get_value(number); + return ret*4; +} + +void encoders_spi_set_value_beacon(void * number, int32_t v) +{ + encoders_spi_set_value(number, v/4); +} + +int32_t encoders_spi_update_beacon_speed(void * number) +{ + int32_t ret; + uint8_t flags; + + IRQ_LOCK(flags); + ret = encoders_spi_get_value_beacon(number); + beacon_speed = ret - beacon_pos; + beacon_pos = ret; + beacon_prev_save_count = beacon_save_count; + beacon_save_count = TCNT3; + IRQ_UNLOCK(flags); + + beacon_coeff = COEFF_TIMER * COEFF_MULT;//beacon_speed * COEFF_MULT / ((beacon_prev_save_count - beacon_save_count + MODULO_TIMER + 1)&MODULO_TIMER); + + return beacon_speed; +} + + +void beacon_init(void) +{ + //int8_t i; + + beacon_reset_pos(); + pos_ref = encoders_spi_get_value_beacon(BEACON_ENCODER); + + memset(&beacon, 0, sizeof(struct beacon)); + beacon.opponent_x = I2C_OPPONENT_NOT_THERE; + + beacon_speed = 0; + + /*for(i=0;i falling, so invert both and recalculate size and middle */ + if(local_falling < local_rising){ + temp = local_rising; + local_rising = local_falling; + local_falling = temp; + size = BEACON_STEP_TOUR - local_falling + local_rising; + middle = (local_falling + ((int32_t)(size)/2) + BEACON_STEP_TOUR) %(BEACON_STEP_TOUR); + edge = local_falling; + } + /* else rising > falling */ + else{ + size = local_falling - local_rising; + middle = local_rising + (size / 2); + edge = local_rising; + } + + //for(i=BEACON_MAX_SAMPLE-1;i>0;i--){ + // beacon_sample_size[i] = beacon_sample_size[i-1]; + // total_size += beacon_sample_size[i]; + //} + //beacon_sample_size[0] = size; + //total_size += size; + //total_size /= BEACON_MAX_SAMPLE; + + //BEACON_DEBUG("rising2= %ld\t",local_rising); + //BEACON_DEBUG("falling2= %ld\r\n",local_falling); + /* BEACON_DEBUG("size= %ld %ld\t",size, total_size); */ + BEACON_DEBUG("size= %f\r\n",size); + //BEACON_DEBUG("middle= %ld\r\n",middle); + + local_angle = get_angle(middle,0); + BEACON_NOTICE("opponent angle= %ld\t",local_angle); + + local_dist = get_dist(size); + BEACON_NOTICE("opponent dist= %ld\r\n",local_dist); + + beacon_angle_dist_to_x_y(local_angle, local_dist, &result_x, &result_y); + + IRQ_LOCK(flags); + beacon.opponent_x = result_x; + beacon.opponent_y = result_y; + beacon.opponent_angle = local_angle; + beacon.opponent_dist = local_dist; + /* for I2C test */ + //beacon.opponent_x = OPPONENT_POS_X; + //beacon.opponent_y = OPPONENT_POS_Y; + IRQ_UNLOCK(flags); + + BEACON_NOTICE("opponent x= %ld\t",beacon.opponent_x); + BEACON_NOTICE("opponent y= %ld\r\n\n",beacon.opponent_y); + } + else { + BEACON_NOTICE("non valid\r\n\n"); + } + + falling = -1; +} + +static int32_t get_dist(float size) +{ + int32_t dist=0; + //int32_t alpha=0; + + //alpha = (size*2*M_PI*COEFF_MULT2); + //dist = ((2*BEACON_SIZE*BEACON_STEP_TOUR*COEFF_MULT2)/alpha)/2; + + /* function found by measuring points up to 80cm */ + //dist = ((size - 600)*(size - 600)) / 2400 +28; + + /* new function */ + /* dist = a0 + a1*x + a2*x² + a3x³ */ + dist = 1157.3 + (1.4146*size) + (-0.013508*size*size) + (0.00001488*size*size*size); + + return dist; + +} + +static int32_t get_angle(int32_t middle, int32_t ref) +{ + int32_t ret_angle; + + ret_angle = (middle - ref) * 360 / BEACON_STEP_TOUR; + + if(ret_angle > 360) + ret_angle -= 360; + + return ret_angle; +} + +void beacon_angle_dist_to_x_y(int32_t angle, int32_t dist, int32_t *x, int32_t *y) +{ + uint8_t flags; + + int32_t local_x; + int32_t local_y; + int32_t x_opponent; + int32_t y_opponent; + int32_t local_robot_angle; + + IRQ_LOCK(flags); + local_x = beacon.robot_x; + local_y = beacon.robot_y; + local_robot_angle = beacon.robot_angle; + IRQ_UNLOCK(flags); + + if (local_robot_angle < 0) + local_robot_angle += 360; + + x_opponent = cos((local_robot_angle + angle)* 2 * M_PI / 360)* dist; + y_opponent = sin((local_robot_angle + angle)* 2 * M_PI / 360)* dist; + + //BEACON_DEBUG("x_op= %ld\t",x_opponent); + //BEACON_DEBUG("y_op= %ld\r\n",y_opponent); + //BEACON_NOTICE("robot_x= %ld\t",local_x); + //BEACON_NOTICE("robot_y= %ld\t",local_y); + //BEACON_NOTICE("robot_angle= %ld\r\n",local_robot_angle); + + *x = local_x + x_opponent; + *y = local_y + y_opponent; + +}