2026-03-18 21:43:28 +00:00
|
|
|
#include "imu.h"
|
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
#include "esp_timer.h"
|
2026-03-30 22:09:23 +01:00
|
|
|
#include "hal/spi_types.h"
|
2026-04-03 17:52:02 +01:00
|
|
|
#include "sens_fus.h"
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-03-30 22:09:23 +01:00
|
|
|
#ifdef PS
|
|
|
|
|
#undef PS
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef F
|
|
|
|
|
#undef F
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <Eigen/Dense>
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-04-06 03:39:08 +01:00
|
|
|
#include "freertos/idf_additions.h"
|
|
|
|
|
|
2026-03-30 22:09:23 +01:00
|
|
|
static const char *TAG = "IMU";
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-04-03 19:13:39 +01:00
|
|
|
void setup_imu() {
|
|
|
|
|
imu_state *local_state = new imu_state;
|
2026-04-06 03:39:08 +01:00
|
|
|
imu_state_mutex = xSemaphoreCreateMutex();
|
2026-04-03 19:13:39 +01:00
|
|
|
|
2026-03-30 22:09:23 +01:00
|
|
|
BNO08x *imu = new BNO08x(
|
|
|
|
|
bno08x_config_t(SPI2_HOST, GPIO_NUM_26, GPIO_NUM_27, GPIO_NUM_25,
|
|
|
|
|
GPIO_NUM_33, GPIO_NUM_36, GPIO_NUM_32, 2000000, false));
|
2026-03-18 21:43:28 +00:00
|
|
|
|
|
|
|
|
if (!imu->initialize()) {
|
|
|
|
|
ESP_LOGE(TAG, "BNO08x Init failure.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imu->dynamic_calibration_autosave_enable();
|
|
|
|
|
imu->dynamic_calibration_enable(BNO08xCalSel::all);
|
|
|
|
|
|
|
|
|
|
imu->rpt.rv_game.enable(2500UL);
|
|
|
|
|
imu->rpt.linear_accelerometer.enable(2500UL);
|
2026-04-06 03:39:08 +01:00
|
|
|
imu->rpt.cal_gyro.enable(2500UL);
|
2026-04-03 19:13:39 +01:00
|
|
|
|
|
|
|
|
imu->register_cb([imu, local_state]() {
|
|
|
|
|
bool needs_updating = false;
|
2026-04-06 03:39:08 +01:00
|
|
|
if (sens_fus_mutex == NULL || imu_state_mutex == NULL)
|
|
|
|
|
return;
|
2026-03-18 21:43:28 +00:00
|
|
|
|
|
|
|
|
if (imu->rpt.rv_game.has_new_data()) {
|
2026-04-03 19:13:39 +01:00
|
|
|
|
|
|
|
|
needs_updating = true;
|
|
|
|
|
|
2026-03-18 21:43:28 +00:00
|
|
|
auto sens_rot = imu->rpt.rv_game.get_quat();
|
2026-04-03 19:13:39 +01:00
|
|
|
auto sens_euler = imu->rpt.rv_game.get_euler();
|
|
|
|
|
local_state->rot = {sens_rot.i, sens_rot.j, sens_rot.k, sens_rot.real};
|
|
|
|
|
local_state->rot_euler = {sens_euler.x, sens_euler.y, sens_euler.z};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (imu->rpt.cal_gyro.has_new_data()) {
|
|
|
|
|
|
|
|
|
|
needs_updating = true;
|
|
|
|
|
|
|
|
|
|
auto cal_gyro = imu->rpt.cal_gyro.get();
|
|
|
|
|
local_state->angvel = {cal_gyro.x, cal_gyro.y, cal_gyro.z};
|
2026-03-18 21:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (imu->rpt.linear_accelerometer.has_new_data()) {
|
|
|
|
|
|
2026-04-03 19:13:39 +01:00
|
|
|
needs_updating = true;
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-04-03 19:13:39 +01:00
|
|
|
auto sens_accel = imu->rpt.linear_accelerometer.get();
|
|
|
|
|
local_state->accel = {sens_accel.x, sens_accel.y, sens_accel.z};
|
2026-03-30 22:09:23 +01:00
|
|
|
int64_t current_time = esp_timer_get_time();
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-04-03 19:13:39 +01:00
|
|
|
if (local_state->last_time != -1) {
|
|
|
|
|
|
|
|
|
|
float dt =
|
|
|
|
|
((float)(current_time - local_state->last_time)) / 1000000.0f;
|
2026-04-04 02:39:41 +01:00
|
|
|
dcont::Vec3C accel_global =
|
|
|
|
|
dcont::apply_rot(&local_state->accel, &local_state->rot);
|
2026-03-18 21:43:28 +00:00
|
|
|
|
2026-04-06 03:39:08 +01:00
|
|
|
if (xSemaphoreTake(sens_fus_mutex, (TickType_t)0) == pdTRUE) {
|
|
|
|
|
|
|
|
|
|
ESP_LOGE(TAG, "accel: (%f, %f, %f), dt: %f", accel_global.x,
|
|
|
|
|
accel_global.y, accel_global.z, dt);
|
|
|
|
|
|
2026-04-03 17:52:02 +01:00
|
|
|
sens_fus.predict(dt, Eigen::Vector3f(accel_global.x, accel_global.y,
|
|
|
|
|
accel_global.z));
|
2026-04-06 03:39:08 +01:00
|
|
|
|
|
|
|
|
ESP_LOGE(TAG, "vel: (%f, %f, %f)", sens_fus.velocity.x(),
|
|
|
|
|
sens_fus.velocity.z(), sens_fus.velocity.y());
|
2026-04-03 17:52:02 +01:00
|
|
|
xSemaphoreGive(sens_fus_mutex);
|
2026-03-30 22:09:23 +01:00
|
|
|
} else {
|
2026-04-03 19:13:39 +01:00
|
|
|
ESP_LOGE(TAG, "Failed to get sens_fus mutex.");
|
2026-03-18 21:43:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
2026-04-03 19:13:39 +01:00
|
|
|
local_state->last_time = current_time;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needs_updating) {
|
2026-04-06 03:39:08 +01:00
|
|
|
if (xSemaphoreTake(imu_state_mutex, 0)) {
|
2026-04-03 19:13:39 +01:00
|
|
|
imu_state_var = *local_state;
|
|
|
|
|
xSemaphoreGive(imu_state_mutex);
|
|
|
|
|
}
|
2026-03-18 21:43:28 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "IMU Setup Success.");
|
|
|
|
|
}
|