You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
4.8 KiB
238 lines
4.8 KiB
/* sensors.c */ |
|
|
|
#include "mpu6050.h" |
|
#include "hmc5883l.h" |
|
#include "mpl3115a2.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_init_fns[])(void) = { |
|
mpu6050_init, |
|
hmc5883l_init, |
|
mpl3115a2_init, |
|
}; |
|
|
|
bool (*sensor_start_fns[])(void) = { |
|
mpu6050_start_sample, |
|
hmc5883l_start_sample, |
|
mpl3115a2_start_sample, |
|
}; |
|
|
|
#define SENSOR_INIT_FNS (sizeof(sensor_init_fns)/sizeof(sensor_init_fns[0])) |
|
#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; |
|
|
|
/* x = roll |
|
y = pitch |
|
z = yaw |
|
*/ |
|
vec3f sensors_gyro; |
|
vec3f gyro_zero; |
|
|
|
float sensors_temp; |
|
|
|
vec3f sensors_accel; |
|
|
|
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) |
|
{ |
|
unsigned int i; |
|
|
|
next_sensor = 0; |
|
|
|
for (i = 0; i < SENSOR_INIT_FNS; i++) |
|
if (!(sensor_init_fns[i])()) |
|
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(vec3f gyro) |
|
{ |
|
#if 0 |
|
sensors_gyro.x = gyro.x - gyro_zero.x; |
|
sensors_gyro.y = gyro.y - gyro_zero.y; |
|
sensors_gyro.z = gyro.z - gyro_zero.z; |
|
#else |
|
sensors_gyro = gyro; |
|
#endif |
|
} |
|
|
|
void sensors_write_accel_data(vec3f accel) |
|
{ |
|
sensors_accel = accel; |
|
} |
|
|
|
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.x); |
|
log_put_float(sensors_gyro.y); |
|
log_put_float(sensors_gyro.z); |
|
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 |
|
vec3f dcm_gyro = {-sensors_gyro.y, -sensors_gyro.x, -sensors_gyro.z}; |
|
#else |
|
vec3f dcm_gyro = {0.0, 0.0, 0.0}; |
|
#endif |
|
dcm_update(dcm_gyro); |
|
if (!status_armed()) { |
|
if ( (abs(sensors_gyro.x) < GYRO_RATE_THRESHOLD) && |
|
(abs(sensors_gyro.y) < GYRO_RATE_THRESHOLD) && |
|
(abs(sensors_gyro.z) < 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_zero.z += sensors_gyro.z; |
|
gyro_zero.y += sensors_gyro.y; |
|
gyro_zero.x += sensors_gyro.x; |
|
sensors_generation++; |
|
if (sensors_generation >= GYRO_ZERO_COUNT) { |
|
sensors_zero = FALSE; |
|
sensors_update = TRUE; |
|
sensors_generation = 0; |
|
gyro_zero.z /= GYRO_ZERO_COUNT; |
|
gyro_zero.y /= GYRO_ZERO_COUNT; |
|
gyro_zero.x /= GYRO_ZERO_COUNT; |
|
putstr("Zero finished\r\n"); |
|
status_set_ready(STATUS_MODULE_GYRO_ZERO, TRUE); |
|
} |
|
} |
|
} |
|
watchdog_kick(WATCHDOG_GYRO); |
|
|
|
#if 1 |
|
vec3f dcm_accel = {-sensors_accel.y, -sensors_accel.x, -sensors_accel.z}; |
|
#endif |
|
#if 0 |
|
vec3f dcm_accel = {sensors_accel.x, sensors_accel.y, sensors_accel.z}; |
|
#endif |
|
dcm_drift_correction(dcm_accel); |
|
|
|
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.x * 1000.0)); |
|
putstr(","); |
|
putint_s((int)(sensors_gyro.y * 1000.0)); |
|
putstr(","); |
|
putint_s((int)(sensors_gyro.z * 1000.0)); |
|
putstr(")"); |
|
|
|
putstr("("); |
|
putint_s((int)(sensors_temp * 1000.0)); |
|
putstr(")\r\n"); |
|
}
|
|
|