new report management system

This commit is contained in:
myles-parfeniuk 2024-11-22 17:05:03 -08:00
parent 19beed4492
commit 936fab897b
26 changed files with 878 additions and 1081 deletions

View File

@ -1,3 +1,3 @@
idf_component_register(SRC_DIRS "source" "SH2" idf_component_register(SRC_DIRS "source" "source/report" "SH2"
INCLUDE_DIRS "include" "SH2" INCLUDE_DIRS "include" "include/report" "SH2"
REQUIRES driver esp_timer cmock) REQUIRES driver esp_timer cmock)

View File

@ -99,12 +99,12 @@ menu "esp32_BNO08x"
menu "Callbacks" menu "Callbacks"
config ESP32_BNO08X_DATA_PROC_TASK_SZ config ESP32_BNO08X_CB_TASK_SZ
int "Callback task size, (data_proc_task())" int "Callback task size, (cb_task())"
range 1024 20480 range 1024 20480
default 4096 default 4096
help help
Stack size of task responsible for parsing packets and executing callbacks. Stack size of task responsible for executing callbacks.
Note that callbacks should remain as short as possible, pass the data out of Note that callbacks should remain as short as possible, pass the data out of
the callback with a queue or save it to different variables for longer operations. the callback with a queue or save it to different variables for longer operations.

View File

@ -8,7 +8,9 @@
#include <stdio.h> #include <stdio.h>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <variant>
#include <vector> #include <vector>
#include <map>
// esp-idf includes // esp-idf includes
#include <esp_rom_gpio.h> #include <esp_rom_gpio.h>
@ -22,6 +24,14 @@
// in-house includes // in-house includes
#include "BNO08x_global_types.hpp" #include "BNO08x_global_types.hpp"
#include "BNO08xSH2HAL.hpp" #include "BNO08xSH2HAL.hpp"
#include "BNO08xRptAcceleration.hpp"
#include "BNO08xRptLinearAcceleration.hpp"
#include "BNO08xRptGravity.hpp"
#include "BNO08xRptCalMagnetometer.hpp"
#include "BNO08xRptRV.hpp"
#include "BNO08xRptGameRV.hpp"
#include "BNO08xRptARVRStabilizedRV.hpp"
#include "BNO08xRptARVRStabilizedGameRV.hpp"
/** /**
* @class BNO08x * @class BNO08x
@ -42,47 +52,27 @@ class BNO08x
BNO08x(bno08x_config_t imu_config = bno08x_config_t()); BNO08x(bno08x_config_t imu_config = bno08x_config_t());
~BNO08x(); ~BNO08x();
bool initialize();
bool initialize();
void hard_reset(); void hard_reset();
bool enable_rotation_vector(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg); bool data_available();
bool enable_game_rotation_vector(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg); bool data_available(uint8_t& report_ID);
bool enable_ARVR_stabilized_rotation_vector(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg); void register_cb(std::function<void(void)> cb_fxn);
bool enable_ARVR_stabilized_game_rotation_vector(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg); void register_cb(std::function<void(uint8_t report_ID)> cb_fxn);
bool enable_gravity(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg); void register_report_cb(uint8_t report_ID, std::function<void(void)> cb_fxn);
bool enable_linear_accelerometer(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_accelerometer(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_calibrated_magnetometer(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_step_counter(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_activity_classifier(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_calibrated_gyro(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_raw_mems_gyro(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_raw_mems_accelerometer(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool enable_raw_mems_magnetometer(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bno08x_quat_t get_rotation_vector_quat();
bno08x_euler_angle_t get_rotation_vector_euler(bool in_degrees = true);
bno08x_quat_t get_game_rotation_vector_quat();
bno08x_euler_angle_t get_game_rotation_vector_euler(bool in_degrees = true);
bno08x_quat_t get_ARVR_stabilized_rotation_vector_quat();
bno08x_euler_angle_t get_ARVR_stabilized_rotation_vector_euler(bool in_degrees = true);
bno08x_quat_t get_ARVR_stabilized_game_rotation_vector_quat();
bno08x_euler_angle_t get_ARVR_stabilized_game_rotation_vector_euler(bool in_degrees = true);
bno08x_accel_data_t get_gravity();
bno08x_accel_data_t get_linear_accel();
bno08x_accel_data_t get_accel();
bno08x_magf_data_t get_calibrated_magnetometer();
bno08x_gyro_data_t get_calibrated_gyro();
bno08x_raw_gyro_data_t get_raw_mems_gyro();
bno08x_raw_accel_data_t get_raw_mems_accelerometer();
bno08x_raw_magf_data_t get_raw_mems_magnetometer();
bno08x_step_counter_data_t get_step_counter();
void register_cb(std::function<void()> cb_fxn);
void print_product_ids(); void print_product_ids();
BNO08xRptAcceleration accelerometer;
BNO08xRptLinearAcceleration linear_accelerometer;
BNO08xRptGravity gravity;
BNO08xRptCalMagnetometer calibrated_magnetometer;
BNO08xRptRV rotation_vector;
BNO08xRptGameRV game_rotation_vector;
BNO08xRptARVRStabilizedRV ARVR_stabilized_rotation_vector;
BNO08xRptARVRStabilizedGameRV ARVR_stabilized_game_rotation_vector;
private: private:
/// @brief Holds info about which functionality has been successfully initialized (used by deconstructor during cleanup). /// @brief Holds info about which functionality has been successfully initialized (used by deconstructor during cleanup).
typedef struct bno08x_init_status_t typedef struct bno08x_init_status_t
@ -96,6 +86,7 @@ class BNO08x
bool sh2_HAL; ///< True if sh2_open() has been called successfully. bool sh2_HAL; ///< True if sh2_open() has been called successfully.
bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task. bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task.
bool sh2_HAL_service_task; ///< True if xTaskCreate has been called successfully for sh2_HAL_service_task. bool sh2_HAL_service_task; ///< True if xTaskCreate has been called successfully for sh2_HAL_service_task.
bool cb_task; ///< True if xTaskCreate has been called successfully for cb_task.
uint8_t task_init_cnt; ///< Amount of tasks that have been successfully initialized. uint8_t task_init_cnt; ///< Amount of tasks that have been successfully initialized.
bno08x_init_status_t() bno08x_init_status_t()
@ -107,6 +98,7 @@ class BNO08x
, spi_device(false) , spi_device(false)
, data_proc_task(false) , data_proc_task(false)
, sh2_HAL_service_task(false) , sh2_HAL_service_task(false)
, cb_task(false)
, task_init_cnt(0) , task_init_cnt(0)
{ {
} }
@ -115,89 +107,60 @@ class BNO08x
/// @brief Holds data returned from sensor reports. /// @brief Holds data returned from sensor reports.
typedef struct bno08x_data_t typedef struct bno08x_data_t
{ {
bno08x_accel_data_t gravity;
bno08x_accel_data_t linear_acceleration;
bno08x_accel_data_t acceleration;
bno08x_magf_data_t cal_magnetometer;
bno08x_step_counter_data_t step_counter; bno08x_step_counter_data_t step_counter;
bno08x_activity_classifier_data_t activity_classifier; bno08x_activity_classifier_data_t activity_classifier;
bno08x_gyro_data_t cal_gyro; bno08x_gyro_data_t cal_gyro;
bno08x_raw_gyro_data_t mems_raw_gyro; bno08x_raw_gyro_data_t mems_raw_gyro;
bno08x_raw_accel_data_t mems_raw_accel; bno08x_raw_accel_data_t mems_raw_accel;
bno08x_raw_magf_data_t mems_raw_magnetometer; bno08x_raw_magf_data_t mems_raw_magnetometer;
bno08x_quat_t rotation_vector; bno08x_quat_t rv;
bno08x_quat_t game_rotation_vector; bno08x_quat_t game_rv;
bno08x_quat_t arvr_s_rotation_vector; bno08x_quat_t arvr_s_rv;
bno08x_quat_t arvr_s_game_rotation_vector; bno08x_quat_t arvr_s_game_rv;
bno08x_data_t() bno08x_data_t()
: gravity({0.0f, 0.0f, 0.0f}) : step_counter({0UL, 0U})
, linear_acceleration({0.0f, 0.0f, 0.0f})
, acceleration({0.0f, 0.0f, 0.0f})
, cal_magnetometer({0.0f, 0.0f, 0.0f})
, step_counter({0UL, 0U})
, activity_classifier(bno08x_activity_classifier_data_t()) , activity_classifier(bno08x_activity_classifier_data_t())
, cal_gyro({0.0f, 0.0f, 0.0f}) , cal_gyro({0.0f, 0.0f, 0.0f})
, mems_raw_gyro({0, 0, 0, 0, 0UL}) , mems_raw_gyro({0, 0, 0, 0, 0UL})
, mems_raw_accel({0, 0, 0, 0UL}) , mems_raw_accel({0, 0, 0, 0UL})
, mems_raw_magnetometer({0, 0, 0, 0UL}) , mems_raw_magnetometer({0, 0, 0, 0UL})
, rotation_vector(bno08x_quat_t()) , rv(bno08x_quat_t())
, game_rotation_vector(bno08x_quat_t()) , game_rv(bno08x_quat_t())
, arvr_s_rv(bno08x_quat_t())
, arvr_s_game_rv(bno08x_quat_t())
{ {
} }
} bno08x_data_t; } bno08x_data_t;
typedef struct bno08x_usr_report_periods_t using bno08x_cb_t = std::variant<std::function<void()>, std::function<void(uint8_t)>>;
/// @brief Holds registered callback info.
typedef struct bno08x_cb_data_t
{ {
uint32_t gravity; uint8_t report_ID; ///< Report this callback is registered to (0 if to execute on any new report).
uint32_t linear_accelerometer; bno08x_cb_t cb; ///< Callback function pointer.
uint32_t accelerometer; } bno08x_cb_data_t;
uint32_t cal_magnetometer;
uint32_t step_counter;
uint32_t activity_classifier;
uint32_t cal_gyro;
uint32_t raw_mems_gyro;
uint32_t raw_mems_accelerometer;
uint32_t raw_mems_magnetometer;
uint32_t rotation_vector;
uint32_t game_rotation_vector;
uint32_t arvr_s_rotation_vector;
uint32_t arvr_s_game_rotation_vector;
bno08x_usr_report_periods_t()
: gravity(0UL)
, linear_accelerometer(0UL)
, accelerometer(0UL)
, cal_magnetometer(0UL)
, step_counter(0UL)
, activity_classifier(0UL)
, cal_gyro(0UL)
, raw_mems_gyro(0UL)
, raw_mems_accelerometer(0UL)
, raw_mems_magnetometer(0UL)
, rotation_vector(0UL)
, game_rotation_vector(0UL)
, arvr_s_rotation_vector(0UL)
, arvr_s_game_rotation_vector(0UL)
{
}
} bno08x_usr_report_periods_t;
bno08x_data_t data; ///< Holds all data returned from enabled reports.
bno08x_usr_report_periods_t user_report_periods; ///< Holds periods for reports enabled by user (0 == disabled report)
// data processing task // data processing task
static const constexpr configSTACK_DEPTH_TYPE DATA_PROC_TASK_SZ = 2048; ///< Size of data_proc_task() stack in bytes
TaskHandle_t data_proc_task_hdl; ///<data_proc_task() task handle TaskHandle_t data_proc_task_hdl; ///<data_proc_task() task handle
static void data_proc_task_trampoline(void* arg); static void data_proc_task_trampoline(void* arg);
void data_proc_task(); void data_proc_task();
// sh2 service task // sh2 service task
static const constexpr configSTACK_DEPTH_TYPE SH2_HAL_SERVICE_TASK_SZ = 2048; ///< Size of sh2_HAL_service_task() stack in bytes
TaskHandle_t sh2_HAL_service_task_hdl; ///<sh2_HAL_service_task() task handle TaskHandle_t sh2_HAL_service_task_hdl; ///<sh2_HAL_service_task() task handle
static void sh2_HAL_service_task_trampoline(void* arg); static void sh2_HAL_service_task_trampoline(void* arg);
void sh2_HAL_service_task(); void sh2_HAL_service_task();
// callback task
static const constexpr configSTACK_DEPTH_TYPE CB_TASK_SZ = CONFIG_ESP32_BNO08X_CB_TASK_SZ; ///< Size of sh2_HAL_service_task() stack in bytes
TaskHandle_t cb_task_hdl; ///<sh2_HAL_service_task() task handle
static void cb_task_trampoline(void* arg);
void cb_task();
SemaphoreHandle_t sh2_HAL_lock; ///<Mutex to prevent sh2 HAL lib functions from being accessed at same time. SemaphoreHandle_t sh2_HAL_lock; ///<Mutex to prevent sh2 HAL lib functions from being accessed at same time.
SemaphoreHandle_t data_lock; ///<Mutex to prevent user from reading data while data_proc_task() updates it, and vice versa. SemaphoreHandle_t data_lock; ///<Mutex to prevent user from reading data while data_proc_task() updates it, and vice versa.
SemaphoreHandle_t sem_kill_tasks; ///<Counting Semaphore to count amount of killed tasks. SemaphoreHandle_t sem_kill_tasks; ///<Counting Semaphore to count amount of killed tasks.
@ -208,20 +171,6 @@ class BNO08x
void unlock_user_data(); void unlock_user_data();
void handle_sensor_report(sh2_SensorValue_t* sensor_val); void handle_sensor_report(sh2_SensorValue_t* sensor_val);
void update_rotation_vector_data(sh2_SensorValue_t* sensor_val);
void update_game_rotation_vector_data(sh2_SensorValue_t* sensor_val);
void update_arvr_s_rotation_vector_data(sh2_SensorValue_t* sensor_val);
void update_arvr_s_game_rotation_vector_data(sh2_SensorValue_t* sensor_val);
void update_gravity_data(sh2_SensorValue_t* sensor_val);
void update_linear_accelerometer_data(sh2_SensorValue_t* sensor_val);
void update_accelerometer_data(sh2_SensorValue_t* sensor_val);
void update_calibrated_magnetometer_data(sh2_SensorValue_t* sensor_val);
void update_step_counter_data(sh2_SensorValue_t* sensor_val);
void update_activity_classifier_data(sh2_SensorValue_t* sensor_val);
void update_calibrated_gyro_data(sh2_SensorValue_t* sensor_val);
void update_raw_mems_gyro_data(sh2_SensorValue_t* sensor_val);
void update_raw_mems_accel_data(sh2_SensorValue_t* sensor_val);
void update_raw_mems_magnetometer_data(sh2_SensorValue_t* sensor_val);
esp_err_t init_config_args(); esp_err_t init_config_args();
esp_err_t init_gpio(); esp_err_t init_gpio();
@ -245,14 +194,17 @@ class BNO08x
esp_err_t enable_report(sh2_SensorId_t sensor_ID, uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg); esp_err_t enable_report(sh2_SensorId_t sensor_ID, uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg);
esp_err_t re_enable_reports(); esp_err_t re_enable_reports();
sh2_Hal_t sh2_HAL; ///< SH2 hardware abstraction layer struct for use with SH2 lib. sh2_Hal_t sh2_HAL; ///< sh2 hardware abstraction layer struct for use with sh2 HAL lib.
EventGroupHandle_t evt_grp_bno08x_task; ///<Event group for indicating various BNO08x related events between tasks. EventGroupHandle_t evt_grp_bno08x_task; ///<Event group for indicating various BNO08x related events between tasks.
EventGroupHandle_t evt_grp_report_en; ///<Event group for indicating which reports are currently enabled. EventGroupHandle_t evt_grp_report_en; ///<Event group for indicating which reports are currently enabled.
QueueHandle_t queue_rx_sensor_event; ///< TODO QueueHandle_t
queue_rx_sensor_event; ///< Queue to send sensor events from sh2 HAL sensor event callback (BNO08xSH2HAL::sensor_event_cb()) to data_proc_task()
std::vector<std::function<void()>> cb_list; // Vector for storing any call-back functions added with register_cb() QueueHandle_t queue_cb_report_id; ///< Queue to send report ID of most recent report to cb_task()
std::vector<bno08x_cb_data_t> cb_list; // Vector for storing any call-back functions added with register_cb()
bno08x_config_t imu_config{}; ///<IMU configuration settings bno08x_config_t imu_config{}; ///<IMU configuration settings
spi_bus_config_t bus_config{}; ///<SPI bus GPIO configuration settings spi_bus_config_t bus_config{}; ///<SPI bus GPIO configuration settings
@ -262,7 +214,14 @@ class BNO08x
bno08x_init_status_t bno08x_init_status_t
init_status; ///<Initialization status of various functionality, used by deconstructor during cleanup, set during initialization. init_status; ///<Initialization status of various functionality, used by deconstructor during cleanup, set during initialization.
sh2_ProductIds_t product_IDs; ///< TODO sh2_ProductIds_t product_IDs; ///< Product ID info returned IMU at initialization, can be viewed with print_product_ids()
uint8_t most_recent_rpt = 0U;
std::map<uint8_t, BNO08xRpt*> usr_reports = {{SH2_ACCELEROMETER, &accelerometer}, {SH2_LINEAR_ACCELERATION, &linear_accelerometer},
{SH2_GRAVITY, &gravity}, {SH2_MAGNETIC_FIELD_CALIBRATED, &calibrated_magnetometer}, {SH2_ROTATION_VECTOR, &rotation_vector},
{SH2_GAME_ROTATION_VECTOR, &game_rotation_vector}, {SH2_ARVR_STABILIZED_RV, &ARVR_stabilized_rotation_vector},
{SH2_ARVR_STABILIZED_GRV, &ARVR_stabilized_game_rotation_vector}};
static void IRAM_ATTR hint_handler(void* arg); static void IRAM_ATTR hint_handler(void* arg);
@ -272,14 +231,14 @@ class BNO08x
500UL / 500UL /
portTICK_PERIOD_MS; ///<Max wait between HINT being asserted by BNO08x before transaction is considered failed (in miliseconds), when no reports are enabled (ie during reset) portTICK_PERIOD_MS; ///<Max wait between HINT being asserted by BNO08x before transaction is considered failed (in miliseconds), when no reports are enabled (ie during reset)
static const constexpr TickType_t DATA_AVAILABLE_TIMEOUT_MS =
3000UL / portTICK_PERIOD_MS; ///<Max wait between data_available() being called and no new data/report being detected.
static const constexpr TickType_t HARD_RESET_DELAY_MS = static const constexpr TickType_t HARD_RESET_DELAY_MS =
100UL / 100UL /
portTICK_PERIOD_MS; ///<How long RST pin is held low during hard reset (min 10ns according to datasheet, but should be longer for stable operation) portTICK_PERIOD_MS; ///<How long RST pin is held low during hard reset (min 10ns according to datasheet, but should be longer for stable operation)
static const constexpr uint32_t SCLK_MAX_SPEED = 3000000UL; ///<Max SPI SCLK speed BNO08x is capable of static const constexpr uint32_t SCLK_MAX_SPEED = 3000000UL; ///<Max SPI SCLK speed BNO08x is capable of.
static const constexpr float RAD_2_DEG =
(180.0f / M_PI); ///< Constant for radian to degree conversions, sed in quaternion to euler function conversions.
// evt_grp_bno08x_task bits // evt_grp_bno08x_task bits
static const constexpr EventBits_t EVT_GRP_BNO08x_TASKS_RUNNING = static const constexpr EventBits_t EVT_GRP_BNO08x_TASKS_RUNNING =
@ -288,34 +247,49 @@ class BNO08x
(1U << 1U); ///<When this bit is set it indicates the BNO08x has asserted its host interrupt pin, thus an SPI transaction should commence. (1U << 1U); ///<When this bit is set it indicates the BNO08x has asserted its host interrupt pin, thus an SPI transaction should commence.
static const constexpr EventBits_t EVT_GRP_BNO08x_TASK_RESET_OCCURRED = static const constexpr EventBits_t EVT_GRP_BNO08x_TASK_RESET_OCCURRED =
(1U << 2U); ///<When this bit is set it indicates the SH2 HAL lib has reset the IMU, any reports enabled by the user must be re-enabled. (1U << 2U); ///<When this bit is set it indicates the SH2 HAL lib has reset the IMU, any reports enabled by the user must be re-enabled.
static const constexpr EventBits_t EVT_GRP_BNO08x_TASK_DATA_AVAILABLE =
(1U << 3U); ///<When this bit is set it indicates a report has been received for the user to read, cleared in data_available() set/cleared in handle_sensor_report()
// evt_grp_report_en bits // evt_grp_report_en bits
static const constexpr EventBits_t EVT_GRP_RPT_ROTATION_VECTOR_BIT_EN = (1 << 0); ///< When set, rotation vector reports are active. static const constexpr EventBits_t EVT_GRP_RPT_RV_BIT = (1 << 0); ///< When set, rotation vector reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_GAME_ROTATION_VECTOR_BIT_EN = (1 << 1); ///< When set, game rotation vector reports are active. static const constexpr EventBits_t EVT_GRP_RPT_GAME_RV_BIT = (1 << 1); ///< When set, game rotation vector reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_ARVR_S_ROTATION_VECTOR_BIT_EN = static const constexpr EventBits_t EVT_GRP_RPT_ARVR_S_RV_BIT = (1U << 2U); ///< When set, ARVR stabilized rotation vector reports are active.
(1U << 2U); ///< When set, ARVR stabilized rotation vector reports are active. static const constexpr EventBits_t EVT_GRP_RPT_ARVR_S_GAME_RV_BIT =
static const constexpr EventBits_t EVT_GRP_RPT_ARVR_S_GAME_ROTATION_VECTOR_BIT_EN =
(1U << 3U); ///< When set, ARVR stabilized game rotation vector reports are active. (1U << 3U); ///< When set, ARVR stabilized game rotation vector reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_GYRO_ROTATION_VECTOR_BIT_EN = static const constexpr EventBits_t EVT_GRP_RPT_GYRO_RV_BIT = (1U << 4U); ///< When set, gyro integrator rotation vector reports are active.
(1U << 4U); ///< When set, gyro integrator rotation vector reports are active. static const constexpr EventBits_t EVT_GRP_RPT_ACCELEROMETER_BIT = (1U << 5U); ///< When set, accelerometer reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_ACCELEROMETER_BIT_EN = (1U << 5U); ///< When set, accelerometer reports are active. static const constexpr EventBits_t EVT_GRP_RPT_LINEAR_ACCELEROMETER_BIT = (1U << 6U); ///< When set, linear accelerometer reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_LINEAR_ACCELEROMETER_BIT_EN = static const constexpr EventBits_t EVT_GRP_RPT_GRAVITY_BIT = (1U << 7U); ///< When set, gravity reports are active.
(1U << 6U); ///< When set, linear accelerometer reports are active. static const constexpr EventBits_t EVT_GRP_RPT_CAL_GYRO_BIT = (1U << 8U); ///< When set, gyro reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_GRAVITY_BIT_EN = (1U << 7U); ///< When set, gravity reports are active. static const constexpr EventBits_t EVT_GRP_RPT_GYRO_UNCALIBRATED_BIT = (1U << 9U); ///< When set, uncalibrated gyro reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_CAL_GYRO_BIT_EN = (1U << 8U); ///< When set, gyro reports are active. static const constexpr EventBits_t EVT_GRP_RPT_CAL_MAGNETOMETER_BIT = (1U << 10U); ///< When set, magnetometer reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_GYRO_UNCALIBRATED_BIT_EN = (1U << 9U); ///< When set, uncalibrated gyro reports are active. static const constexpr EventBits_t EVT_GRP_RPT_TAP_DETECTOR_BIT = (1U << 11U); ///< When set, tap detector reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_CAL_MAGNETOMETER_BIT_EN = (1U << 10U); ///< When set, magnetometer reports are active. static const constexpr EventBits_t EVT_GRP_RPT_STEP_COUNTER_BIT = (1U << 12U); ///< When set, step counter reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_TAP_DETECTOR_BIT_EN = (1U << 11U); ///< When set, tap detector reports are active. static const constexpr EventBits_t EVT_GRP_RPT_STABILITY_CLASSIFIER_BIT = (1U << 13U); ///< When set, stability classifier reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_STEP_COUNTER_BIT_EN = (1U << 12U); ///< When set, step counter reports are active. static const constexpr EventBits_t EVT_GRP_RPT_ACTIVITY_CLASSIFIER_BIT = (1U << 14U); ///< When set, activity classifier reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_STABILITY_CLASSIFIER_BIT_EN = static const constexpr EventBits_t EVT_GRP_RPT_RAW_ACCELEROMETER_BIT = (1U << 15U); ///< When set, raw accelerometer reports are active.
(1U << 13U); ///< When set, stability classifier reports are active. static const constexpr EventBits_t EVT_GRP_RPT_RAW_GYRO_BIT = (1U << 16U); ///< When set, raw gyro reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_ACTIVITY_CLASSIFIER_BIT_EN = static const constexpr EventBits_t EVT_GRP_RPT_RAW_MAGNETOMETER_BIT = (1U << 17U); ///< When set, raw magnetometer reports are active.
(1U << 14U); ///< When set, activity classifier reports are active.
static const constexpr EventBits_t EVT_GRP_RPT_RAW_ACCELEROMETER_BIT_EN = (1U << 15U); ///< When set, raw accelerometer reports are active. static const constexpr EventBits_t EVT_GRP_RPT_ALL =
static const constexpr EventBits_t EVT_GRP_RPT_RAW_GYRO_BIT_EN = (1U << 16U); ///< When set, raw gyro reports are active. EVT_GRP_RPT_RV_BIT | EVT_GRP_RPT_GAME_RV_BIT | EVT_GRP_RPT_ARVR_S_RV_BIT | EVT_GRP_RPT_ARVR_S_GAME_RV_BIT | EVT_GRP_RPT_GYRO_RV_BIT |
static const constexpr EventBits_t EVT_GRP_RPT_RAW_MAGNETOMETER_BIT_EN = (1U << 17U); ///< When set, raw magnetometer reports are active. EVT_GRP_RPT_ACCELEROMETER_BIT | EVT_GRP_RPT_LINEAR_ACCELEROMETER_BIT | EVT_GRP_RPT_GRAVITY_BIT | EVT_GRP_RPT_CAL_GYRO_BIT |
EVT_GRP_RPT_GYRO_UNCALIBRATED_BIT | EVT_GRP_RPT_CAL_MAGNETOMETER_BIT | EVT_GRP_RPT_TAP_DETECTOR_BIT | EVT_GRP_RPT_STEP_COUNTER_BIT |
EVT_GRP_RPT_STABILITY_CLASSIFIER_BIT | EVT_GRP_RPT_ACTIVITY_CLASSIFIER_BIT | EVT_GRP_RPT_RAW_ACCELEROMETER_BIT |
EVT_GRP_RPT_RAW_GYRO_BIT | EVT_GRP_RPT_RAW_MAGNETOMETER_BIT;
static const constexpr char* TAG = "BNO08x"; ///< Class tag used for serial print statements static const constexpr char* TAG = "BNO08x"; ///< Class tag used for serial print statements
// we have a lot of friends
friend class BNO08xSH2HAL; friend class BNO08xSH2HAL;
friend class BNO08xRpt;
friend class BNO08xRptRVGeneric;
friend class BNO08xRptRV;
friend class BNO08xRptGameRV;
friend class BNO08xRptARVRStabilizedRV;
friend class BNO08xRptARVRStabilizedGameRV;
friend class BNO08xRptAcceleration;
friend class BNO08xRptLinearAcceleration;
friend class BNO08xRptGravity;
friend class BNO08xRptCalMagnetometer;
}; };

64
include/BNO08xRpt.hpp Normal file
View File

@ -0,0 +1,64 @@
#pragma once
#include <stdint.h>
#include "BNO08x_global_types.hpp"
// forward dec to prevent compile errors
class BNO08x;
/**
* @brief Class to represent and manage reports returned from BNO08x.
*
* @return ESP_OK if report was successfully enabled.
*/
class BNO08xRpt
{
public:
inline static sh2_SensorConfig default_sensor_cfg = {.changeSensitivityEnabled = false, ///<TODO
.changeSensitivityRelative = false,
.wakeupEnabled = false,
.alwaysOnEnabled = false,
.changeSensitivity = 0,
.reportInterval_us = 0,
.batchInterval_us = 0,
.sensorSpecific = 0};
bool enable(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
bool disable(sh2_SensorConfig_t sensor_cfg = default_sensor_cfg);
virtual void update_data(sh2_SensorValue_t* sensor_val) = 0;
protected:
BNO08x* imu; ///< Pointer to BNO08x object for enable ,disable, and update operations.
uint8_t ID; ///< Report ID, ex. SH2_ACCELERATION.
uint32_t rpt_bit; ///< Respective enable and data bit for report in BNO08x::evt_grp_report_en and BNO08x::evt_grp_report_data
uint32_t period_us; ///< The period/interval of the report in microseconds.
/**
* @brief BNO08xRpt report constructor.
*
* Construct a BNO08xRpt object for managing a BNO08x sensor report.
*
* @param imu Pointer to BNO08x imu object.
* @param report_ID Report ID, ex. SH2_ACCELERATION.
* @param rpt_bit Respective enable bit for report in BNO08x::evt_grp_report_en.
* @param period_us The period/interval of the report in microseconds.
*
* @return void, nothing to return
*/
BNO08xRpt(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: imu(imu)
, ID(report_ID)
, rpt_bit(rpt_bit)
, period_us(period_us)
{
}
static const constexpr float RAD_2_DEG =
(180.0f / M_PI); ///< Constant for radian to degree conversions, sed in quaternion to euler function conversions.
static const constexpr char* TAG = "BNO08xRpt";
friend class BNO08x;
};

View File

@ -10,28 +10,6 @@
#include <driver/spi_master.h> #include <driver/spi_master.h>
#include "sh2_SensorValue.h" #include "sh2_SensorValue.h"
/// @brief Sensor accuracy returned during sensor calibration
enum class BNO08xAccuracy
{
LOW = 1,
MED,
HIGH,
UNDEFINED
};
using IMUAccuracy = BNO08xAccuracy; // legacy version compatibility
/// @brief Reason for previous IMU reset (returned by get_reset_reason())
enum class BNO08xResetReason
{
UNDEFINED, ///< Undefined reset reason, this should never occur and is an error.
POR, ///< Previous reset was due to power on reset.
INT_RST, ///< Previous reset was due to internal reset.
WTD, ///< Previous reset was due to watchdog timer.
EXT_RST, ///< Previous reset was due to external reset.
OTHER ///< Previous reset was due to power other reason.
};
using IMUResetReason = BNO08xResetReason; // legacy version compatibility
/// @brief BNO08xActivity states returned from get_activity_classifier() /// @brief BNO08xActivity states returned from get_activity_classifier()
enum class BNO08xActivity enum class BNO08xActivity
{ {
@ -190,6 +168,7 @@ typedef struct bno08x_euler_angle_t
{ {
} }
// overloaded = operator for quat to euler conversion
bno08x_euler_angle_t& operator=(const bno08x_quat_t& source) bno08x_euler_angle_t& operator=(const bno08x_quat_t& source)
{ {
this->x = atan2(2.0f * (source.real * source.i + source.j * source.k), 1.0f - 2.0f * (source.i * source.i + source.j * source.j)); this->x = atan2(2.0f * (source.real * source.i + source.j * source.k), 1.0f - 2.0f * (source.i * source.i + source.j * source.j));

View File

@ -0,0 +1,20 @@
#pragma once
#include "BNO08xRptRVGeneric.hpp" // Include the base class header
/**
* @brief Class to represent ARVR stabilized rotation vector reports. (See Ref. Manual 6.5.43)
*/
class BNO08xRptARVRStabilizedGameRV : public BNO08xRptRVGeneric
{
public:
// Constructor declaration
BNO08xRptARVRStabilizedGameRV(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRptRVGeneric(imu, report_ID, period_us, rpt_bit)
{
}
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
static const constexpr char* TAG = "BNO08xRptARVRStabilizedGameRV";
};

View File

@ -0,0 +1,20 @@
#pragma once
#include "BNO08xRptRVGeneric.hpp" // Include the base class header
/**
* @brief Class to represent ARVR stabilized rotation vector reports. (See Ref. Manual 6.5.42)
*/
class BNO08xRptARVRStabilizedRV : public BNO08xRptRVGeneric
{
public:
// Constructor declaration
BNO08xRptARVRStabilizedRV(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRptRVGeneric(imu, report_ID, period_us, rpt_bit)
{
}
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
static const constexpr char* TAG = "BNO08xRptARVRStabilizedRV";
};

View File

@ -0,0 +1,23 @@
#pragma once
#include "BNO08xRpt.hpp" // Include the base class header
/**
* @brief Class to represent accelerometer reports. (See Ref. Manual 6.5.9)
*/
class BNO08xRptAcceleration : public BNO08xRpt
{
public:
// Constructor declaration
BNO08xRptAcceleration(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRpt(imu, report_ID, period_us, rpt_bit)
{
}
bno08x_accel_data_t get();
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
bno08x_accel_data_t data;
static const constexpr char* TAG = "BNO08xRptAcceleration";
};

View File

@ -0,0 +1,23 @@
#pragma once
#include "BNO08xRpt.hpp" // Include the base class header
/**
* @brief Class to represent calibrated magnetometer reports. (See Ref. Manual 6.5.16)
*/
class BNO08xRptCalMagnetometer : public BNO08xRpt
{
public:
// Constructor declaration
BNO08xRptCalMagnetometer(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRpt(imu, report_ID, period_us, rpt_bit)
{
}
bno08x_magf_data_t get();
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
bno08x_magf_data_t data;
static const constexpr char* TAG = "BNO08xRptCalMagnetometer";
};

View File

@ -0,0 +1,20 @@
#pragma once
#include "BNO08xRptRVGeneric.hpp" // Include the base class header
/**
* @brief Class to represent game rotation vector reports. (See Ref. Manual 6.5.19)
*/
class BNO08xRptGameRV : public BNO08xRptRVGeneric
{
public:
// Constructor declaration
BNO08xRptGameRV(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRptRVGeneric(imu, report_ID, period_us, rpt_bit)
{
}
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
static const constexpr char* TAG = "BNO08xRptGameRV";
};

View File

@ -0,0 +1,23 @@
#pragma once
#include "BNO08xRpt.hpp" // Include the base class header
/**
* @brief Class to represent gravity reports. (See Ref. Manual 6.5.11)
*/
class BNO08xRptGravity : public BNO08xRpt
{
public:
// Constructor declaration
BNO08xRptGravity(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRpt(imu, report_ID, period_us, rpt_bit)
{
}
bno08x_accel_data_t get();
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
bno08x_accel_data_t data;
static const constexpr char* TAG = "BNO08xRptGravity";
};

View File

@ -0,0 +1,23 @@
#pragma once
#include "BNO08xRpt.hpp" // Include the base class header
/**
* @brief Class to represent linear accelerometer reports. (See Ref. Manual 6.5.10)
*/
class BNO08xRptLinearAcceleration : public BNO08xRpt
{
public:
// Constructor declaration
BNO08xRptLinearAcceleration(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRpt(imu, report_ID, period_us, rpt_bit)
{
}
bno08x_accel_data_t get();
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
bno08x_accel_data_t data;
static const constexpr char* TAG = "BNO08xRptLinearAcceleration";
};

View File

@ -0,0 +1,20 @@
#pragma once
#include "BNO08xRptRVGeneric.hpp" // Include the base class header
/**
* @brief Class to represent rotation vector reports. (See Ref. Manual 6.5.18)
*/
class BNO08xRptRV : public BNO08xRptRVGeneric
{
public:
// Constructor declaration
BNO08xRptRV(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRptRVGeneric(imu, report_ID, period_us, rpt_bit)
{
}
private:
void update_data(sh2_SensorValue_t* sensor_val) override;
static const constexpr char* TAG = "BNO08xRptRV";
};

View File

@ -0,0 +1,22 @@
#pragma once
#include "BNO08xRpt.hpp" // Include the base class header
/**
* @brief Class to represent rotation vector reports.
*/
class BNO08xRptRVGeneric : public BNO08xRpt
{
public:
bno08x_quat_t get_quat();
bno08x_euler_angle_t get_euler(bool in_degrees = true);
protected:
// Constructor declaration
BNO08xRptRVGeneric(BNO08x* imu, uint8_t report_ID, uint32_t period_us, uint32_t rpt_bit)
: BNO08xRpt(imu, report_ID, period_us, rpt_bit)
{
}
bno08x_quat_t data;
static const constexpr char* TAG = "BNO08xRptRVGeneric";
};

File diff suppressed because it is too large Load Diff

55
source/BNO08xRpt.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "BNO08xRpt.hpp"
#include "BNO08x.hpp"
/**
* @brief Enables a sensor report such that the BNO08x begins sending it.
*
* @param sensor_ID The ID of the sensor for the respective report to be enabled.
* @param report_period_us The period/interval of the report in microseconds.
* @param sensor_cfg Sensor special configuration.
*
* @return ESP_OK if report was successfully enabled.
*/
bool BNO08xRpt::enable(uint32_t time_between_reports, sh2_SensorConfig_t sensor_cfg)
{
EventBits_t evt_grp_report_en_bits = xEventGroupGetBits(imu->evt_grp_report_en);
// already enabled
if (!(evt_grp_report_en_bits & rpt_bit))
{
if (imu->enable_report(ID, time_between_reports, sensor_cfg) != ESP_OK)
{
return false; // Return false if enable_report fails
}
else
{
period_us = time_between_reports; // Update the period
xEventGroupSetBits(imu->evt_grp_report_en, rpt_bit); // Set the event group bit
}
}
return true;
}
/**
* @brief Disables a sensor report by setting its period to 0us such that the BNO08x stops sending it.
*
* @param sensor_ID The ID of the sensor for the respective report to be disabled.
* @param sensor_cfg Sensor special configuration.
*
* @return ESP_OK if report was successfully disabled.
*/
bool BNO08xRpt::disable(sh2_SensorConfig_t sensor_cfg)
{
EventBits_t evt_grp_report_en_bits = xEventGroupGetBits(imu->evt_grp_report_en);
if (evt_grp_report_en_bits & rpt_bit)
{
if (imu->enable_report(ID, 0UL, sensor_cfg) != ESP_OK)
return false;
else
xEventGroupClearBits(imu->evt_grp_report_en, rpt_bit); // Set the event group bit
}
return true;
}

View File

@ -0,0 +1,16 @@
#include "BNO08xRptARVRStabilizedGameRV.hpp"
#include "BNO08x.hpp"
/**
* @brief Updates ARVR stabilized game rotation vector data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptARVRStabilizedGameRV::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.arvrStabilizedGRV;
imu->unlock_user_data();
}

View File

@ -0,0 +1,16 @@
#include "BNO08xRptARVRStabilizedRV.hpp"
#include "BNO08x.hpp"
/**
* @brief Updates ARVR stabilized rotation vector data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptARVRStabilizedRV::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.arvrStabilizedRV;
imu->unlock_user_data();
}

View File

@ -0,0 +1,29 @@
#include "BNO08xRptAcceleration.hpp" // Include the header file for the class
#include "BNO08x.hpp"
/**
* @brief Updates accelerometer data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptAcceleration::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.accelerometer;
imu->unlock_user_data();
}
/**
* @brief Grabs most recent acceleration data (including gravity), units are in m/s^2.
*
* @return Struct containing requested data.
*/
bno08x_accel_data_t BNO08xRptAcceleration::get()
{
imu->lock_user_data();
bno08x_accel_data_t rqdata = data;
imu->unlock_user_data();
return rqdata;
}

View File

@ -0,0 +1,29 @@
#include "BNO08xRptCalMagnetometer.hpp" // Include the header file for the class
#include "BNO08x.hpp"
/**
* @brief Updates accelerometer data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptCalMagnetometer::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.magneticField;
imu->unlock_user_data();
}
/**
* @brief Grabs most recent calibrated magnetometer data, units are in uTesla.
*
* @return Struct containing requested data.
*/
bno08x_magf_data_t BNO08xRptCalMagnetometer::get()
{
imu->lock_user_data();
bno08x_magf_data_t rqdata = data;
imu->unlock_user_data();
return rqdata;
}

View File

@ -0,0 +1,16 @@
#include "BNO08xRptRV.hpp"
#include "BNO08x.hpp"
/**
* @brief Updates game rotation vector data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptGameRV::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.gameRotationVector;
imu->unlock_user_data();
}

View File

@ -0,0 +1,29 @@
#include "BNO08xRptGravity.hpp" // Include the header file for the class
#include "BNO08x.hpp"
/**
* @brief Updates gravity data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptGravity::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.gravity;
imu->unlock_user_data();
}
/**
* @brief Grabs most recent gravity data, units are in m/s^2.
*
* @return Struct containing requested data.
*/
bno08x_accel_data_t BNO08xRptGravity::get()
{
imu->lock_user_data();
bno08x_accel_data_t rqdata = data;
imu->unlock_user_data();
return rqdata;
}

View File

@ -0,0 +1,29 @@
#include "BNO08xRptLinearAcceleration.hpp" // Include the header file for the class
#include "BNO08x.hpp"
/**
* @brief Updates accelerometer data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptLinearAcceleration::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.linearAcceleration;
imu->unlock_user_data();
}
/**
* @brief Grabs most recent acceleration data (including gravity), units are in m/s^2.
*
* @return Struct containing requested data.
*/
bno08x_accel_data_t BNO08xRptLinearAcceleration::get()
{
imu->lock_user_data();
bno08x_accel_data_t rqdata = data;
imu->unlock_user_data();
return rqdata;
}

View File

@ -0,0 +1,16 @@
#include "BNO08xRptRV.hpp"
#include "BNO08x.hpp"
/**
* @brief Updates rotation vector data from decoded sensor event.
*
* @param sensor_val The sh2_SensorValue_t struct used in sh2_decodeSensorEvent() call.
*
* @return void, nothing to return
*/
void BNO08xRptRV::update_data(sh2_SensorValue_t* sensor_val)
{
imu->lock_user_data();
data = sensor_val->un.rotationVector;
imu->unlock_user_data();
}

View File

@ -0,0 +1,41 @@
#include "BNO08xRptRVGeneric.hpp"
#include "BNO08x.hpp"
/**
* @brief Grabs most recent rotation vector data in form of unit quaternion, accuracy units in radians (if available).
*
* The following RV reports have accuracy data:
*
* - rotation vector
*
*
* @return Struct containing requested data.
*/
bno08x_quat_t BNO08xRptRVGeneric::get_quat()
{
imu->lock_user_data();
bno08x_quat_t rqdata = data;
imu->unlock_user_data();
return rqdata;
}
/**
* @brief Grabs most recent rotation vector data in form of an euler angle, units are in degrees or rads.
*
* @param in_degrees If true returned euler angle is in degrees, if false in radians
*
* @return Struct containing requested data.
*/
bno08x_euler_angle_t BNO08xRptRVGeneric::get_euler(bool in_degrees)
{
bno08x_euler_angle_t rqdata;
bno08x_quat_t quat = get_quat();
rqdata = quat; // conversion handled by overloaded operator
// convert to degrees if requested
if (in_degrees)
rqdata *= RAD_2_DEG;
return rqdata;
}

View File

@ -1,5 +1,5 @@
idf_component_register(SRC_DIRS "." idf_component_register(SRC_DIRS "source" "SH2"
INCLUDE_DIRS "." INCLUDE_DIRS "include" "include/report" "SH2"
REQUIRES cmock esp32_BNO08x) REQUIRES cmock esp32_BNO08x)
# supress unused var warnings from test_imu # supress unused var warnings from test_imu