Skip to content

Commit 9292c6e

Browse files
committed
Merge branch 'dev'
2 parents 157f8d3 + af2248e commit 9292c6e

1 file changed

Lines changed: 29 additions & 68 deletions

File tree

src/sensor/sensor.c

Lines changed: 29 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,16 @@ static float q3[4] = {SENSOR_QUATERNION_CORRECTION}; // correction quaternion
8080

8181
static float last_lin_a[3] = {0}; // vector to hold last linear accelerometer
8282

83+
static float last_m[3] = {0};
84+
static int64_t last_mag_time = -1000;
85+
static int64_t mag_interval = 0;
86+
8387
static float temp; // sensor temperature
8488
static int64_t last_temp_time = -1000;
8589

8690
static int64_t last_suspend_attempt_time = 0;
8791
static int64_t last_data_time;
8892

89-
static float max_gyro_speed_square;
90-
static bool mag_use_oneshot;
91-
static bool mag_skip_oneshot;
92-
9393
static float accel_actual_time;
9494
static float gyro_actual_time;
9595
static float mag_actual_time;
@@ -680,9 +680,9 @@ int sensor_init(void)
680680
mag_enabled = CONFIG_1_SETTINGS_READ(CONFIG_1_SENSOR_USE_MAG);
681681

682682
// setup sensor, set ODR
683-
float accel_initial_time = 1.0 / CONFIG_2_SETTINGS_READ(CONFIG_2_SENSOR_ACCEL_ODR); // configure with ~1000Hz ODR
684-
float gyro_initial_time = 1.0 / CONFIG_2_SETTINGS_READ(CONFIG_2_SENSOR_GYRO_ODR); // configure with ~1000Hz ODR
685-
float mag_initial_time = sensor_update_time_ms / 1000.0; // configure with ~200Hz ODR
683+
float accel_initial_time = 1.0 / CONFIG_2_SETTINGS_READ(CONFIG_2_SENSOR_ACCEL_ODR);
684+
float gyro_initial_time = 1.0 / CONFIG_2_SETTINGS_READ(CONFIG_2_SENSOR_GYRO_ODR);
685+
float mag_initial_time = 0.1; // configure with 10Hz ODR
686686
err = sensor_imu->init(clock_actual_rate, accel_initial_time, gyro_initial_time, &accel_actual_time, &gyro_actual_time);
687687
sensor_actual_time = MIN(accel_actual_time, gyro_actual_time);
688688
#if SENSOR_IMU_SPI_EXISTS
@@ -697,7 +697,8 @@ int sensor_init(void)
697697
{
698698
// TODO: need to flag passthrough enabled
699699
// sensor_imu->ext_passthrough(true); // reenable passthrough
700-
err = sensor_mag->init(mag_initial_time, &mag_actual_time); // configure with ~200Hz ODR
700+
err = sensor_mag->init(mag_initial_time, &mag_actual_time);
701+
mag_interval = mag_actual_time * 0.9f * 1000; // start attemping magnetometer reads before expected new sample
701702
#if SENSOR_MAG_SPI_EXISTS
702703
LOG_INF("Requested SPI frequency: %.2fMHz", (double)sensor_mag_spi_dev.config.frequency / 1000000.0);
703704
#endif
@@ -724,7 +725,7 @@ int sensor_init(void)
724725
}
725726
else
726727
{
727-
sensor_fusion->init(gyro_actual_time, accel_actual_time, mag_initial_time); // TODO: using initial time since mag are not polled at the actual rate
728+
sensor_fusion->init(gyro_actual_time, accel_actual_time, mag_actual_time);
728729
}
729730

730731
sensor_calibration_update_sensor_ids(sensor_imu_id);
@@ -778,6 +779,7 @@ static uint64_t total_read_packets = 0;
778779
static uint64_t total_processed_packets = 0;
779780
static uint64_t total_gyro_samples = 0;
780781
static uint64_t total_accel_samples = 0;
782+
static uint64_t total_mag_samples = 0;
781783
static uint64_t total_loop_time = 0;
782784
static uint64_t total_loop_iterations = 0;
783785
#endif
@@ -815,11 +817,6 @@ void sensor_loop(void)
815817
// Fusing data will take between 100us (~7 samples, low noise) - 500us (~33 samples, low power) for xiofusion
816818
// TODO: on any errors set main_ok false and skip (make functions return nonzero)
817819

818-
// At high speed, use oneshot mode to have synced magnetometer data
819-
// Call before FIFO and get the data after
820-
if (mag_available && mag_enabled && mag_use_oneshot)
821-
sensor_mag->mag_oneshot();
822-
823820
// Read IMU temperature
824821
err = sensor_imu->temp_read(&temp); // TODO: use as calibration data
825822
if (!err)
@@ -853,8 +850,12 @@ void sensor_loop(void)
853850

854851
// Read magnetometer
855852
float raw_m[3];
856-
if (mag_available && mag_enabled)
853+
bool mag_read = false;
854+
if (mag_available && mag_enabled && (k_uptime_get() - last_mag_time > mag_interval)) // some magnetometer do not have int pin // TODO: implement for magnetometer that does, or read status byte
855+
{
856+
mag_read = true;
857857
sensor_mag->mag_read(raw_m); // reading mag last, and it will be processed last
858+
}
858859

859860
int16_t last_sensor_fifo_threshold = sensor_fifo_threshold;
860861

@@ -885,7 +886,6 @@ void sensor_loop(void)
885886
int g_count = 0;
886887
float a_sum[3] = {0};
887888
int a_count = 0;
888-
max_gyro_speed_square = 0;
889889
int processed_packets = 0;
890890
for (uint16_t i = 0; i < packets; i++)
891891
{
@@ -919,11 +919,6 @@ void sensor_loop(void)
919919
sensor_fusion->get_gyro_bias(g_off);
920920
for (int i = 0; i < 3; i++)
921921
g_off[i] = g[i] - g_off[i];
922-
923-
// Get the highest gyro speed
924-
float gyro_speed_square = g_off[0] * g_off[0] + g_off[1] * g_off[1] + g_off[2] * g_off[2];
925-
if (gyro_speed_square > max_gyro_speed_square)
926-
max_gyro_speed_square = gyro_speed_square;
927922
}
928923
}
929924

@@ -961,16 +956,19 @@ void sensor_loop(void)
961956
total_processed_packets += processed_packets;
962957
#endif
963958

964-
if (mag_available && mag_enabled)
959+
if (mag_available && mag_enabled && mag_read && memcmp(raw_m, last_m, sizeof(last_m))) // check data has changed from last acquisition
965960
{
961+
#if DEBUG
962+
total_mag_samples++;
963+
#endif
964+
last_mag_time = k_uptime_get();
966965
bool mag_calibrated = true;
967-
float uncalibrated_m[3] = {0};
968-
memcpy(uncalibrated_m, raw_m, sizeof(uncalibrated_m)); // copy raw magnetometer data
966+
memcpy(last_m, raw_m, sizeof(last_m)); // copy raw magnetometer data
969967
sensor_calibration_process_mag(raw_m);
970968
float zero_m[3] = {0};
971969
if (v_epsilon(raw_m, zero_m, 1e-6)) // if the magnetometer is not calibrated, skip and send raw data
972970
{
973-
memcpy(raw_m, uncalibrated_m, sizeof(uncalibrated_m));
971+
memcpy(raw_m, last_m, sizeof(last_m));
974972
mag_calibrated = false;
975973
}
976974
float mx = raw_m[0];
@@ -980,7 +978,7 @@ void sensor_loop(void)
980978

981979
// Process fusion
982980
if (mag_calibrated)
983-
sensor_fusion->update_mag(m, sensor_update_time_ms / 1000.0); // TODO: use actual time?
981+
sensor_fusion->update_mag(m, mag_actual_time);
984982

985983
v_rotate(m, q3, m); // magnetic field in local device frame, no other transformation will be done
986984
connection_update_sensor_mag(m);
@@ -1035,43 +1033,6 @@ void sensor_loop(void)
10351033

10361034
sensor_update_sensor_state();
10371035

1038-
// Update magnetometer mode
1039-
if (mag_available && mag_enabled)
1040-
{
1041-
// TODO: magnetometer might be better to limit to a lower (fixed) rate
1042-
float gyro_speed = sqrtf(max_gyro_speed_square);
1043-
float mag_target_time = 1.0f / (4 * gyro_speed); // target mag ODR for ~0.25 deg error
1044-
if (mag_target_time < 0.005f && mag_skip_oneshot) // only use continuous modes if oneshot is not available
1045-
mag_target_time = 0.005;
1046-
if (mag_target_time > 0.1f) // limit to 0.1 (minimum 10Hz)
1047-
mag_target_time = 0.1;
1048-
sys_interface_resume();
1049-
if (mag_target_time < 0.005f) // cap at 0.005 (200Hz), above this the sensor will use oneshot mode instead
1050-
{
1051-
int err = sensor_mag->update_odr(INFINITY, &mag_actual_time);
1052-
if (mag_actual_time == INFINITY)
1053-
{
1054-
if (!err)
1055-
LOG_DBG("Switching magnetometer to oneshot");
1056-
mag_use_oneshot = true;
1057-
}
1058-
else // magnetometer did not have a oneshot mode, try 200Hz
1059-
{
1060-
if (!err)
1061-
mag_skip_oneshot = true;
1062-
mag_target_time = 0.005;
1063-
}
1064-
}
1065-
if (mag_target_time >= 0.005f || mag_actual_time != INFINITY) // under 200Hz or magnetometer did not have a oneshot mode
1066-
{
1067-
int err = sensor_mag->update_odr(mag_target_time, &mag_actual_time);
1068-
if (!err)
1069-
LOG_DBG("Switching magnetometer ODR to %.2fHz", 1.0 / (double)mag_actual_time);
1070-
mag_use_oneshot = false;
1071-
}
1072-
sys_interface_suspend();
1073-
}
1074-
10751036
// Update orientation
10761037
bool send_quat_data = !q_epsilon(q, last_q, 0.001);
10771038
bool send_lin_accel_data = !v_epsilon(lin_a, last_lin_a, 0.05);
@@ -1109,13 +1070,13 @@ void sensor_loop(void)
11091070
last_status_time = k_uptime_get();
11101071
if (max_loop_time > 0)
11111072
{
1112-
LOG_WRN("Last update steps took up to %lld ms", time_delta);
1073+
LOG_WRN("Last update steps took up to %lld ms", max_loop_time);
11131074
max_loop_time = 0;
11141075
}
11151076
#if DEBUG
1116-
LOG_DBG("loop iterations: %llu, packets read: %llu, processed: %llu, gyro samples: %llu, accel samples: %llu, total acquisition time: %lld us, total loop time: %lld us", total_loop_iterations, total_read_packets, total_processed_packets, total_gyro_samples, total_accel_samples, k_ticks_to_us_near64(total_acquisition_time), k_ticks_to_us_near64(total_loop_time));
1077+
LOG_DBG("loop iterations: %llu, packets read: %llu, processed: %llu, gyro samples: %llu, accel samples: %llu, mag samples: %llu, total acquisition time: %lld us, total loop time: %lld us", total_loop_iterations, total_read_packets, total_processed_packets, total_gyro_samples, total_accel_samples, total_mag_samples, k_ticks_to_us_near64(total_acquisition_time), k_ticks_to_us_near64(total_loop_time));
11171078
LOG_DBG("sensor loop rate: %.2fHz, processing time: %.2f/%.2f us -> %.2f%%", (double)total_loop_iterations / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0, (double)k_ticks_to_us_near64(total_loop_time) / (double)total_loop_iterations, (double)k_ticks_to_us_near64(total_acquisition_time) / (double)total_loop_iterations, (double)total_loop_time / (double)total_acquisition_time * 100.0);
1118-
LOG_DBG("reported gyro rate: %.2fHz, actual: %.2fHz, reported accel rate: %.2fHz, actual: %.2fHz", 1.0 / (double)gyro_actual_time, (double)total_gyro_samples / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0, 1.0 / (double)accel_actual_time, (double)total_accel_samples / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0);
1079+
LOG_DBG("reported gyro rate: %.2fHz, actual: %.2fHz, reported accel rate: %.2fHz, actual: %.2fHz, reported mag rate: %.2fHz, actual: %.2fHz", 1.0 / (double)gyro_actual_time, (double)total_gyro_samples / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0, 1.0 / (double)accel_actual_time, (double)total_accel_samples / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0, 1.0 / (double)mag_actual_time, (double)total_mag_samples / (double)k_ticks_to_us_near64(total_acquisition_time) * 1000000.0);
11191080
#endif
11201081
}
11211082

@@ -1131,9 +1092,9 @@ void sensor_loop(void)
11311092
main_wfi = false;
11321093
}
11331094
}
1134-
else // if signal was sent during processing, loop immediately to catch up
1095+
else // if signal was sent during processing, loop immediately to catch up (I2C could cause this to happen constantly)
11351096
{
1136-
LOG_INF("FIFO THS/WM/WTM triggered during loop");
1097+
LOG_DBG("FIFO THS/WM/WTM triggered during loop");
11371098
k_yield();
11381099
main_wfi = false;
11391100
}

0 commit comments

Comments
 (0)