#pragma once // esp-idf includes #include #include #include #include #include #include #include #include #include #include #include #include // standard library includes #include #include #include #include #include #include // macros #define CHECK_TASKS_RUNNING(evt_grp_task_flow, running_bit) ((xEventGroupGetBits(evt_grp_task_flow) & (running_bit)) != 0) /// @brief SHTP protocol channels enum channels_t { CHANNEL_COMMAND, CHANNEL_EXECUTABLE, CHANNEL_CONTROL, CHANNEL_REPORTS, CHANNEL_WAKE_REPORTS, CHANNEL_GYRO }; /// @brief Sensor accuracy returned during sensor calibration enum class IMUAccuracy { LOW = 1, MED, HIGH }; /// @brief Reason for previous IMU reset (returned by get_reset_reason()) enum class IMUResetReason { 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. }; /// @brief IMU configuration settings passed into constructor typedef struct bno08x_config_t { spi_host_device_t spi_peripheral; ///GPIO Configuration. /// Alternatively, edit the default values in "Kconfig.projbuild" bno08x_config_t(bool install_isr_service = true) : spi_peripheral((spi_host_device_t) CONFIG_ESP32_BNO08x_SPI_HOST) , io_mosi(static_cast(CONFIG_ESP32_BNO08X_GPIO_DI)) // default: 23 , io_miso(static_cast(CONFIG_ESP32_BNO08X_GPIO_SDA)) // default: 19 , io_sclk(static_cast(CONFIG_ESP32_BNO08X_GPIO_SCL)) // default: 18 , io_cs(static_cast(CONFIG_ESP32_BNO08X_GPIO_CS)) // default: 33 , io_int(static_cast(CONFIG_ESP32_BNO08X_GPIO_HINT)) // default: 26 , io_rst(static_cast(CONFIG_ESP32_BNO08X_GPIO_RST)) // default: 32 , io_wake(static_cast(CONFIG_ESP32_BNO08X_GPIO_WAKE)) // default: -1 (unused) , sclk_speed(static_cast(CONFIG_ESP32_BNO08X_SCL_SPEED_HZ)) // default: 2MHz , install_isr_service(install_isr_service) // default: true { } /// @brief Overloaded IMU configuration settings constructor for custom pin settings bno08x_config_t(spi_host_device_t spi_peripheral, gpio_num_t io_mosi, gpio_num_t io_miso, gpio_num_t io_sclk, gpio_num_t io_cs, gpio_num_t io_int, gpio_num_t io_rst, gpio_num_t io_wake, uint32_t sclk_speed, bool install_isr_service = true) : spi_peripheral(spi_peripheral) , io_mosi(io_mosi) , io_miso(io_miso) , io_sclk(io_sclk) , io_cs(io_cs) , io_int(io_int) , io_rst(io_rst) , io_wake(io_wake) , sclk_speed(sclk_speed) , install_isr_service(install_isr_service) { } } bno08x_config_t; class BNO08x { public: BNO08x(bno08x_config_t imu_config = bno08x_config_t()); ~BNO08x(); bool initialize(); bool hard_reset(); bool soft_reset(); IMUResetReason get_reset_reason(); bool mode_sleep(); bool mode_on(); float q_to_float(int16_t fixed_point_value, uint8_t q_point); bool run_full_calibration_routine(); void calibrate_all(); void calibrate_accelerometer(); void calibrate_gyro(); void calibrate_magnetometer(); void calibrate_planar_accelerometer(); void request_calibration_status(); bool calibration_complete(); void end_calibration(); void save_calibration(); void enable_rotation_vector(uint32_t time_between_reports); void enable_game_rotation_vector(uint32_t time_between_reports); void enable_ARVR_stabilized_rotation_vector(uint32_t time_between_reports); void enable_ARVR_stabilized_game_rotation_vector(uint32_t time_between_reports); void enable_gyro_integrated_rotation_vector(uint32_t time_between_reports); void enable_accelerometer(uint32_t time_between_reports); void enable_linear_accelerometer(uint32_t time_between_reports); void enable_gravity(uint32_t time_between_reports); void enable_gyro(uint32_t time_between_reports); void enable_uncalibrated_gyro(uint32_t time_between_reports); void enable_magnetometer(uint32_t time_between_reports); void enable_tap_detector(uint32_t time_between_reports); void enable_step_counter(uint32_t time_between_reports); void enable_stability_classifier(uint32_t time_between_reports); void enable_activity_classifier(uint32_t time_between_reports, uint32_t activities_to_enable, uint8_t (&activity_confidence_vals)[9]); void enable_raw_accelerometer(uint32_t time_between_reports); void enable_raw_gyro(uint32_t time_between_reports); void enable_raw_magnetometer(uint32_t time_between_reports); void disable_rotation_vector(); void disable_game_rotation_vector(); void disable_ARVR_stabilized_rotation_vector(); void disable_ARVR_stabilized_game_rotation_vector(); void disable_gyro_integrated_rotation_vector(); void disable_accelerometer(); void disable_linear_accelerometer(); void disable_gravity(); void disable_gyro(); void disable_uncalibrated_gyro(); void disable_magnetometer(); void disable_tap_detector(); void disable_step_counter(); void disable_stability_classifier(); void disable_activity_classifier(); void disable_raw_accelerometer(); void disable_raw_gyro(); void disable_raw_magnetometer(); void tare_now(uint8_t axis_sel = TARE_AXIS_ALL, uint8_t rotation_vector_basis = TARE_ROTATION_VECTOR); void save_tare(); void clear_tare(); bool data_available(); void register_cb(std::function cb_fxn); uint32_t get_time_stamp(); void get_magf(float& x, float& y, float& z, uint8_t& accuracy); float get_magf_X(); float get_magf_Y(); float get_magf_Z(); uint8_t get_magf_accuracy(); void get_gravity(float& x, float& y, float& z, uint8_t& accuracy); float get_gravity_X(); float get_gravity_Y(); float get_gravity_Z(); uint8_t get_gravity_accuracy(); float get_roll(); float get_pitch(); float get_yaw(); float get_roll_deg(); float get_pitch_deg(); float get_yaw_deg(); void get_quat(float& i, float& j, float& k, float& real, float& rad_accuracy, uint8_t& accuracy); float get_quat_I(); float get_quat_J(); float get_quat_K(); float get_quat_real(); float get_quat_radian_accuracy(); uint8_t get_quat_accuracy(); void get_accel(float& x, float& y, float& z, uint8_t& accuracy); float get_accel_X(); float get_accel_Y(); float get_accel_Z(); uint8_t get_accel_accuracy(); void get_linear_accel(float& x, float& y, float& z, uint8_t& accuracy); float get_linear_accel_X(); float get_linear_accel_Y(); float get_linear_accel_Z(); uint8_t get_linear_accel_accuracy(); int16_t get_raw_accel_X(); int16_t get_raw_accel_Y(); int16_t get_raw_accel_Z(); int16_t get_raw_gyro_X(); int16_t get_raw_gyro_Y(); int16_t get_raw_gyro_Z(); int16_t get_raw_magf_X(); int16_t get_raw_magf_Y(); int16_t get_raw_magf_Z(); void get_gyro_calibrated_velocity(float& x, float& y, float& z, uint8_t& accuracy); float get_gyro_calibrated_velocity_X(); float get_gyro_calibrated_velocity_Y(); float get_gyro_calibrated_velocity_Z(); uint8_t get_gyro_accuracy(); void get_uncalibrated_gyro(float& x, float& y, float& z, float& bx, float& by, float& bz, uint8_t& accuracy); float get_uncalibrated_gyro_X(); float get_uncalibrated_gyro_Y(); float get_uncalibrated_gyro_Z(); float get_uncalibrated_gyro_bias_X(); float get_uncalibrated_gyro_bias_Y(); float get_uncalibrated_gyro_bias_Z(); uint8_t get_uncalibrated_gyro_accuracy(); void get_gyro_velocity(float& x, float& y, float& z); float get_gyro_velocity_X(); float get_gyro_velocity_Y(); float get_gyro_velocity_Z(); uint8_t get_tap_detector(); uint16_t get_step_count(); int8_t get_stability_classifier(); uint8_t get_activity_classifier(); // Metadata functions int16_t get_Q1(uint16_t record_ID); int16_t get_Q2(uint16_t record_ID); int16_t get_Q3(uint16_t record_ID); float get_resolution(uint16_t record_ID); float get_range(uint16_t record_ID); uint32_t FRS_read_word(uint16_t record_ID, uint8_t word_number); bool FRS_read_request(uint16_t record_ID, uint16_t read_offset, uint16_t block_size); bool FRS_read_data(uint16_t record_ID, uint8_t start_location, uint8_t words_to_read); // Record IDs from figure 29, page 29 reference manual // These are used to read the metadata for each sensor type static const constexpr uint16_t FRS_RECORD_ID_ACCELEROMETER = 0xE302U; ///< Accelerometer record ID, to be passed in metadata functions like get_Q1() static const constexpr uint16_t FRS_RECORD_ID_GYROSCOPE_CALIBRATED = 0xE306U; ///< Calirated gyroscope record ID, to be passed in metadata functions like get_Q1() static const constexpr uint16_t FRS_RECORD_ID_MAGNETIC_FIELD_CALIBRATED = 0xE309U; ///< Calibrated magnetometer record ID, to be passed in metadata functions like get_Q1() static const constexpr uint16_t FRS_RECORD_ID_ROTATION_VECTOR = 0xE30BU; ///< Rotation vector record ID, to be passed in metadata functions like get_Q1() // Activity classifier bits static const constexpr uint16_t ACTIVITY_CLASSIFIER_UNKNOWN_EN = (1U << 0U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_IN_VEHICLE_EN = (1U << 1U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_ON_BICYCLE_EN = (1U << 2U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_ON_FOOT_EN = (1U << 3U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_STILL_EN = (1U << 4U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_TILTING_EN = (1U << 5U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_WALKING_EN = (1U << 6U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_RUNNING_EN = (1U << 7U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_ON_STAIRS_EN = (1U << 8U); static const constexpr uint16_t ACTIVITY_CLASSIFIER_ALL_EN = 0x1FU; static const constexpr uint8_t TARE_AXIS_ALL = 0x07U; ///< Tare all axes (used with tare now command) static const constexpr uint8_t TARE_AXIS_Z = 0x04U; ///< Tar yaw axis only (used with tare now command) // Which rotation vector to tare, BNO08x saves them seperately static const constexpr uint8_t TARE_ROTATION_VECTOR = 0U; ///> cb_list; // Vector for storing any call-back functions added with register_cb() uint32_t meta_data[9]; ///