/* sensors.c */ #include "mpu6050.h" #include "dcm.h" #include "fisqrt.h" #include "watchdog.h" #include "status.h" #include "abs.h" #include "panic.h" #include "uart.h" #include "log.h" #include "stick.h" bool (*sensor_start_fns[])(void) = { mpu6050_start_sample, }; #define SENSOR_START_FNS (sizeof(sensor_start_fns)/sizeof(sensor_start_fns[0])) static unsigned int next_sensor; static bool sensors_zero; static bool sensors_update; static unsigned int sensors_discard; static unsigned int sensors_generation; float sensors_gyro_roll; float sensors_gyro_pitch; float sensors_gyro_yaw; float sensors_temp; float sensors_accel_x; float sensors_accel_y; float sensors_accel_z; float gyro_yaw_zero; float gyro_pitch_zero; float gyro_roll_zero; void sensors_write_log(void); void sensors_process(void); #define TWO_PI 6.28318531f #define DEG_TO_RAD (TWO_PI/360.0f) /* The gyro has to stay within this limit in each axis in order to arm */ #define GYRO_RATE_THRESHOLD (0.01 / DEG_TO_RAD) #define GYRO_ZERO_COUNT 1000 void sensors_dump(void); bool sensors_init(void) { next_sensor = 0; if (!mpu6050_init()) return FALSE; return TRUE; } bool sensors_next_sample(void) { bool result; result = (sensor_start_fns[next_sensor])(); if (next_sensor >= SENSOR_START_FNS) next_sensor = 0; return result; } void sensors_sample_done(void) { if (next_sensor == 0) { sensors_write_log(); return; } if (!sensors_next_sample()) panic(PANIC_SENSOR_FAIL); } bool sensors_start_sample(void) { next_sensor = 0; return sensors_next_sample(); } void sensors_write_gyro_data(float roll, float pitch, float yaw) { #if 0 sensors_gyro_roll = roll - gyro_roll_zero; sensors_gyro_pitch = pitch - gyro_pitch_zero; sensors_gyro_yaw = yaw - gyro_yaw_zero; #else sensors_gyro_roll = roll; sensors_gyro_pitch = pitch; sensors_gyro_yaw = yaw; #endif } void sensors_write_accel_data(float x, float y, float z) { sensors_accel_x = x; sensors_accel_y = y; sensors_accel_z = z; } void sensors_write_temp_data(float temp) { sensors_temp = temp; /* XXX HACK find a better place for this call */ sensors_process(); } #define LOG_SIGNATURE_SENSORS 0xDA7ADA7A #define LOG_SIGNATURE_SENSORS2 0xDA7AF173 void sensors_write_log(void) { #if 0 log_put_uint(LOG_SIGNATURE_SENSORS); log_put_float(sensors_accel_x); log_put_float(sensors_accel_y); log_put_float(sensors_accel_z); log_put_float(sensors_gyro_roll); log_put_float(sensors_gyro_pitch); log_put_float(sensors_gyro_yaw); log_put_float(sensors_temp); #else /* XXX this just about comes out in the right place, but by luck */ log_put_uint(LOG_SIGNATURE_SENSORS2); #endif } void sensors_start_zero(void) { sensors_zero = TRUE; sensors_update = FALSE; sensors_discard = 100; sensors_generation = 0; putstr("Starting zero\r\n"); mpu6050_start_zero(); } void sensors_process(void) { if (sensors_update) { #if 1 dcm_update(-sensors_gyro_pitch, -sensors_gyro_roll, -sensors_gyro_yaw); #else dcm_update(0.0, 0.0, 0.0); #endif if (!status_armed()) { if ( (abs(sensors_gyro_roll) < GYRO_RATE_THRESHOLD) && (abs(sensors_gyro_pitch) < GYRO_RATE_THRESHOLD) && (abs(sensors_gyro_yaw) < GYRO_RATE_THRESHOLD)) { status_set_ready(STATUS_MODULE_GYRO_RATE, TRUE); } else { status_set_ready(STATUS_MODULE_GYRO_RATE, FALSE); } } sensors_generation++; #if SEND_DCM if ((sensors_generation % 40) == 0) { dcm_send_packet(); sensors_dump(); } #endif } else if (sensors_zero) { if (sensors_discard) { sensors_discard--; } else { gyro_yaw_zero += sensors_gyro_yaw; gyro_pitch_zero += sensors_gyro_pitch; gyro_roll_zero += sensors_gyro_roll; sensors_generation++; if (sensors_generation >= GYRO_ZERO_COUNT) { sensors_zero = FALSE; sensors_update = TRUE; sensors_generation = 0; gyro_yaw_zero /= GYRO_ZERO_COUNT; gyro_pitch_zero /= GYRO_ZERO_COUNT; gyro_roll_zero /= GYRO_ZERO_COUNT; putstr("Zero finished\r\n"); status_set_ready(STATUS_MODULE_GYRO_ZERO, TRUE); } } } watchdog_kick(WATCHDOG_GYRO); #if 1 dcm_drift_correction(-sensors_accel_y, -sensors_accel_x, -sensors_accel_z); #endif #if 0 dcm_drift_correction(sensors_accel_x, sensors_accel_y, sensors_accel_z); #endif watchdog_kick(WATCHDOG_ACCEL); stick_input(); } void sensors_dump(void) { putstr("("); putint_s((int)(sensors_accel_x * 1000.0)); putstr(","); putint_s((int)(sensors_accel_y * 1000.0)); putstr(","); putint_s((int)(sensors_accel_z * 1000.0)); putstr(")"); putstr("("); putint_s((int)(sensors_gyro_roll * 1000.0)); putstr(","); putint_s((int)(sensors_gyro_pitch * 1000.0)); putstr(","); putint_s((int)(sensors_gyro_yaw * 1000.0)); putstr(")"); putstr("("); putint_s((int)(sensors_temp * 1000.0)); putstr(")\r\n"); }