1 /* 2 * Copyright (c) 2015, Freescale Semiconductor, Inc. 3 * Copyright 2016-2017 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 // Sensor fusion requires a fairly extensive set of data structures, which are 10 // defined in this file. The top level structure is shown near the bottom. The 11 // size of this structure (SensorFusionGlobals) varies dramatically as a function 12 // of which fusion variations have been selected in build.h. 13 14 /*! \file sensor_fusion.h 15 \brief The sensor_fusion.h file implements the top level programming interface 16 */ 17 18 #ifndef SENSOR_FUSION_TYPES_H 19 #define SENSOR_FUSION_TYPES_H 20 21 // Standard includes that everyone needs 22 #include "math.h" 23 #include "stdbool.h" 24 #include "stdio.h" 25 #include "stdint.h" 26 27 28 #include "issdk_hal.h" // Hardware Abstraction Layer board dependencies beyond those generated in board.h by PEX 29 #include "build.h" // This is where the build parameters are defined 30 #include "magnetic.h" // Magnetic calibration functions/structures 31 #include "precisionAccelerometer.h" // Accel calibration functions/structures 32 #include "orientation.h" // Functions for manipulating orientations 33 #include "register_io_spi.h" 34 35 /// @name Integer Typedefs 36 /// Typedefs to map common integer types to standard form 37 ///@{ 38 typedef unsigned char byte; 39 typedef int8_t int8; 40 typedef int16_t int16; 41 typedef int32_t int32; 42 typedef uint8_t uint8; 43 typedef uint16_t uint16; 44 typedef uint32_t uint32; 45 ///@} 46 47 /// the quaternion type to be transmitted 48 typedef enum quaternion { 49 Q3, ///< Quaternion derived from 3-axis accel (tilt) 50 Q3M, ///< Quaternion derived from 3-axis mag only (auto compass algorithm) 51 Q3G, ///< Quaternion derived from 3-axis gyro only (rotation) 52 Q6MA, ///< Quaternion derived from 3-axis accel + 3 axis mag (eCompass) 53 Q6AG, ///< Quaternion derived from 3-axis accel + 3-axis gyro (gaming) 54 Q9 ///< Quaternion derived from full 9-axis sensor fusion 55 } quaternion_type; 56 57 /// @name Vector Components 58 /// Index values for accessing vector terms 59 ///@{ 60 #define CHX 0 ///< Used to access X-channel entries in various data data structures 61 #define CHY 1 ///< Used to access Y-channel entries in various data data structures 62 #define CHZ 2 ///< Used to access Z-channel entries in various data data structures 63 ///@} 64 65 // booleans 66 #define true 1 ///< Boolean TRUE 67 #define false 0 ///< Boolean FALSE 68 69 /// @name Generic bit-field values 70 /// Generic bit-field values 71 ///@{ 72 #define B0 (1 << 0) 73 #define B1 (1 << 1) 74 #define B2 (1 << 2) 75 #define B3 (1 << 3) 76 ///@} 77 78 /// @name Math Constants 79 /// useful multiplicative conversion constants 80 ///@{ 81 #define PI 3.141592654F ///< pi 82 #define PIOVER2 1.570796327F ///< pi / 2 83 #define FPIOVER180 0.01745329251994F ///< degrees to radians conversion = pi / 180 84 #define F180OVERPI 57.2957795130823F ///< radians to degrees conversion = 180 / pi 85 #define F180OVERPISQ 3282.8063500117F ///< square of F180OVERPI 86 #define ONETHIRD 0.33333333F ///< one third 87 #define ONESIXTH 0.166666667F ///< one sixth 88 #define ONESIXTEENTH 0.0625F ///< one sixteenth 89 #define ONEOVER12 0.083333333F ///< 1 / 12 90 #define ONEOVER48 0.02083333333F ///< 1 / 48 91 #define ONEOVER120 0.0083333333F ///< 1 / 120 92 #define ONEOVER3840 0.0002604166667F ///< 1 / 3840 93 #define ONEOVERSQRT2 0.707106781F ///< 1/sqrt(2) 94 #define SQRT15OVER4 0.968245837F ///< sqrt(15)/4 95 #define GTOMSEC2 9.80665 ///< standard gravity in m/s2 96 ///@} 97 98 // Placeholder structures (redefined later, but needed now for pointer definitions) 99 struct SensorFusionGlobals; ///< Top level structure has pointers to everything else 100 struct StatusSubsystem; ///< Application-specific status subsystem 101 struct PhysicalSensor; ///< We'll have one of these for each physical sensor (FXOS8700 = 1 physical sensor) 102 struct ControlSubsystem; ///< Application-specific serial communications system 103 104 typedef enum { /// These are the state definitions for the status subsystem 105 OFF, ///< Application hasn't started 106 INITIALIZING, ///< Initializing sensors and algorithms 107 LOWPOWER, ///< Running in reduced power mode 108 NORMAL, ///< Operation is Nominal 109 RECEIVING_WIRED, ///< Receiving commands over wired interface (momentary) 110 RECEIVING_WIRELESS, ///< Receiving commands over wireless interface (momentary) 111 HARD_FAULT, ///< Non-recoverable FAULT = something went very wrong 112 SOFT_FAULT ///< Recoverable FAULT = something went wrong, but we can keep going 113 } fusion_status_t; 114 115 // declare typedefs for function prototypes that need to be installed 116 typedef int8_t (initializeSensor_t) ( 117 struct PhysicalSensor *sensor, 118 struct SensorFusionGlobals *sfg 119 ) ; 120 typedef int8_t (readSensor_t) ( 121 struct PhysicalSensor *sensor, 122 struct SensorFusionGlobals *sfg 123 ) ; 124 typedef int8_t (readSensors_t) ( 125 struct SensorFusionGlobals *sfg, 126 uint16_t read_loop_counter 127 ) ; 128 typedef int8_t (installSensor_t) ( 129 struct SensorFusionGlobals *sfg, ///< Global data structure pointer 130 struct PhysicalSensor *sensor, ///< SF Structure to store sensor configuration 131 uint16_t addr, ///< I2C address or SPI_ADDR 132 uint16_t schedule, ///< Specifies sampling interval 133 void *bus_driver, ///< I2C or SPI handle 134 registerDeviceInfo_t *busInfo, ///< information required for bus power management 135 initializeSensor_t *initialize, ///< SF Sensor Initialization Function pointer 136 readSensor_t *read ///< SF Sensor Read Function pointer 137 ); 138 #define SPI_ADDR 0x00 // Use SPI_ADDR as the address parameter to the installSensor function for SPI-based sensors. 139 // 0x00 is reserved for I2C General Call, and will therefore never occur for any sensor type 140 141 typedef void (initializeFusionEngine_t) (struct SensorFusionGlobals *sfg); 142 typedef void (runFusion_t) (struct SensorFusionGlobals *sfg); 143 typedef void (clearFIFOs_t) (struct SensorFusionGlobals *sfg); 144 typedef void (conditionSensorReadings_t) (struct SensorFusionGlobals *sfg); 145 typedef void (applyPerturbation_t) (struct SensorFusionGlobals *sfg) ; 146 typedef void (setStatus_t) (struct SensorFusionGlobals *sfg, fusion_status_t status); 147 typedef void (updateStatus_t) (struct SensorFusionGlobals *sfg); 148 typedef void (ssSetStatus_t) (struct StatusSubsystem *pStatus, fusion_status_t status); 149 typedef void (ssUpdateStatus_t) (struct StatusSubsystem *pStatus); 150 151 /// \brief An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo devices = 1) 152 /// 153 /// These structures sit 'on-top-of' the pre-7.0 sensor fusion structures and give us the ability to do run 154 /// time driver installation. 155 struct PhysicalSensor { 156 registerDeviceInfo_t deviceInfo; ///< I2C device context 157 void *bus_driver; ///< should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) 158 registerDeviceInfo_t *busInfo; ///< information required for bus power management 159 uint16_t addr; ///< I2C address if applicable 160 uint16_t isInitialized; ///< Bitfields to indicate sensor is active (use SensorBitFields from build.h) 161 spiSlaveSpecificParams_t slaveParams; ///< SPI specific parameters. Not used for I2C. 162 struct PhysicalSensor *next; ///< pointer to next sensor in this linked list 163 uint16_t schedule; ///< Parameter to control sensor sampling rate 164 initializeSensor_t *initialize; ///< pointer to function to initialize sensor using the supplied drivers 165 readSensor_t *read; ///< pointer to function to read sensor using the supplied drivers 166 }; 167 168 // Now start "standard" sensor fusion structure definitions 169 170 /// \brief The PressureSensor structure stores raw and processed measurements for an altimeter. 171 /// 172 /// The PressureSensor structure stores raw and processed measurements, as well as 173 /// metadata for a pressure sensor/altimeter. 174 struct PressureSensor 175 { 176 uint8_t iWhoAmI; ///< sensor whoami 177 bool isEnabled; ///< true if the device is sampling 178 int32_t iH; ///< most recent unaveraged height (counts) 179 int32_t iP; ///< most recent unaveraged pressure (counts) 180 float fH; ///< most recent unaveraged height (m) 181 float fT; ///< most recent unaveraged temperature (C) 182 float fmPerCount; ///< meters per count 183 float fCPerCount; ///< degrees Celsius per count 184 int16_t iT; ///< most recent unaveraged temperature (counts) 185 }; 186 187 /// \brief The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer. 188 /// 189 /// The AccelSensor structure stores raw and processed measurements, as well as metadata 190 /// for a single 3-axis accelerometer. This structure is 191 /// normally "fed" by the sensor driver and "consumed" by the fusion routines. 192 struct AccelSensor 193 { 194 uint8_t iWhoAmI; ///< sensor whoami 195 bool isEnabled; ///< true if the device is sampling 196 uint8_t iFIFOCount; ///< number of measurements read from FIFO 197 uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size 198 int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]; ///< FIFO measurements (counts) 199 // End of common fields which can be referenced via FifoSensor union type 200 float fGs[3]; ///< averaged measurement (g) 201 float fGc[3]; ///< averaged precision calibrated measurement (g) 202 float fgPerCount; ///< g per count 203 float fCountsPerg; ///< counts per g 204 int16_t iGs[3]; ///< averaged measurement (counts) 205 int16_t iGc[3]; ///< averaged precision calibrated measurement (counts) 206 int16_t iCountsPerg; ///< counts per g 207 }; 208 209 /// \brief The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor. 210 /// 211 /// The MagSensor structure stores raw and processed measurements, as well as metadata 212 /// for a single 3-axis magnetometer. This structure is 213 /// normally "fed" by the sensor driver and "consumed" by the fusion routines. 214 struct MagSensor 215 { 216 uint8_t iWhoAmI; ///< sensor whoami 217 bool isEnabled; ///< true if the device is sampling 218 uint8_t iFIFOCount; ///< number of measurements read from FIFO 219 uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size 220 int16_t iBsFIFO[MAG_FIFO_SIZE][3]; ///< FIFO measurements (counts) 221 // End of common fields which can be referenced via FifoSensor union type 222 float fBs[3]; ///< averaged un-calibrated measurement (uT) 223 float fBc[3]; ///< averaged calibrated measurement (uT) 224 float fuTPerCount; ///< uT per count 225 float fCountsPeruT; ///< counts per uT 226 int16_t iBs[3]; ///< averaged uncalibrated measurement (counts) 227 int16_t iBc[3]; ///< averaged calibrated measurement (counts) 228 int16_t iCountsPeruT; ///< counts per uT 229 }; 230 231 /// \brief The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope. 232 /// 233 /// The GyroSensor structure stores raw and processed measurements, as well as metadata 234 /// for a single 3-axis gyroscope. This structure is 235 /// normally "fed" by the sensor driver and "consumed" by the fusion routines. 236 struct GyroSensor 237 { 238 uint8_t iWhoAmI; ///< sensor whoami 239 bool isEnabled; ///< true if the device is sampling 240 uint8_t iFIFOCount; ///< number of measurements read from FIFO 241 uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size 242 int16_t iYsFIFO[GYRO_FIFO_SIZE][3]; ///< FIFO measurements (counts) 243 // End of common fields which can be referenced via FifoSensor union type 244 float fYs[3]; ///< averaged measurement (deg/s) 245 float fDegPerSecPerCount; ///< deg/s per count 246 int16_t iCountsPerDegPerSec; ///< counts per deg/s 247 int16_t iYs[3]; ///< average measurement (counts) 248 }; 249 250 /// \brief The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures. 251 /// 252 /// Common elements include: iWhoAmI, isEnabled, iFIFOCount, iFIFOExceeded and the FIFO itself. 253 union FifoSensor { 254 struct GyroSensor Gyro; 255 struct MagSensor Mag; 256 struct AccelSensor Accel; 257 }; 258 259 /// The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter. 260 struct SV_1DOF_P_BASIC 261 { 262 float fLPH; ///< low pass filtered height (m) 263 float fLPT; ///< low pass filtered temperature (C) 264 float fdeltat; ///< fusion time interval (s) 265 float flpf; ///< low pass filter coefficient 266 int32_t systick; ///< systick timer 267 int8_t resetflag; ///< flag to request re-initialization on next pass 268 }; 269 270 /// This is the 3DOF basic accelerometer state vector structure. 271 struct SV_3DOF_G_BASIC 272 { 273 // start: elements common to all motion state vectors 274 float fLPPhi; ///< low pass roll (deg) 275 float fLPThe; ///< low pass pitch (deg) 276 float fLPPsi; ///< low pass yaw (deg) 277 float fLPRho; ///< low pass compass (deg) 278 float fLPChi; ///< low pass tilt from vertical (deg) 279 float fLPR[3][3]; ///< low pass filtered orientation matrix 280 Quaternion fLPq; ///< low pass filtered orientation quaternion 281 float fLPRVec[3]; ///< rotation vector 282 float fOmega[3]; ///< angular velocity (deg/s) 283 int32_t systick; ///< systick timer 284 // end: elements common to all motion state vectors 285 float fR[3][3]; ///< unfiltered orientation matrix 286 Quaternion fq; ///< unfiltered orientation quaternion 287 float fdeltat; ///< fusion time interval (s) 288 float flpf; ///< low pass filter coefficient 289 int8_t resetflag; ///< flag to request re-initialization on next pass 290 }; 291 292 /// This is the 3DOF basic magnetometer state vector structure/ 293 struct SV_3DOF_B_BASIC 294 { 295 // start: elements common to all motion state vectors 296 float fLPPhi; ///< low pass roll (deg) 297 float fLPThe; ///< low pass pitch (deg) 298 float fLPPsi; ///< low pass yaw (deg) 299 float fLPRho; ///< low pass compass (deg) 300 float fLPChi; ///< low pass tilt from vertical (deg) 301 float fLPR[3][3]; ///< low pass filtered orientation matrix 302 Quaternion fLPq; ///< low pass filtered orientation quaternion 303 float fLPRVec[3]; ///< rotation vector 304 float fOmega[3]; ///< angular velocity (deg/s) 305 int32_t systick; ///< systick timer 306 // end: elements common to all motion state vectors 307 float fR[3][3]; ///< unfiltered orientation matrix 308 Quaternion fq; ///< unfiltered orientation quaternion 309 float fdeltat; ///< fusion time interval (s) 310 float flpf; ///< low pass filter coefficient 311 int8_t resetflag; ///< flag to request re-initialization on next pass 312 }; 313 314 /// SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure. 315 struct SV_3DOF_Y_BASIC 316 { 317 // start: elements common to all motion state vectors 318 float fPhi; ///< roll (deg) 319 float fThe; ///< pitch (deg) 320 float fPsi; ///< yaw (deg) 321 float fRho; ///< compass (deg) 322 float fChi; ///< tilt from vertical (deg) 323 float fR[3][3]; ///< unfiltered orientation matrix 324 Quaternion fq; ///< unfiltered orientation quaternion 325 float fRVec[3]; ///< rotation vector 326 float fOmega[3]; ///< angular velocity (deg/s) 327 int32_t systick; ///< systick timer 328 // end: elements common to all motion state vectors 329 float fdeltat; ///< fusion filter sampling interval (s) 330 int8_t resetflag; ///< flag to request re-initialization on next pass 331 }; 332 333 /// SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure. 334 struct SV_6DOF_GB_BASIC 335 { 336 // start: elements common to all motion state vectors 337 float fLPPhi; ///< low pass roll (deg) 338 float fLPThe; ///< low pass pitch (deg) 339 float fLPPsi; ///< low pass yaw (deg) 340 float fLPRho; ///< low pass compass (deg) 341 float fLPChi; ///< low pass tilt from vertical (deg) 342 float fLPR[3][3]; ///< low pass filtered orientation matrix 343 Quaternion fLPq; ///< low pass filtered orientation quaternion 344 float fLPRVec[3]; ///< rotation vector 345 float fOmega[3]; ///< virtual gyro angular velocity (deg/s) 346 int32_t systick; ///< systick timer 347 // end: elements common to all motion state vectors 348 float fR[3][3]; ///< unfiltered orientation matrix 349 Quaternion fq; ///< unfiltered orientation quaternion 350 float fDelta; ///< unfiltered inclination angle (deg) 351 float fLPDelta; ///< low pass filtered inclination angle (deg) 352 float fdeltat; ///< fusion time interval (s) 353 float flpf; ///< low pass filter coefficient 354 int8_t resetflag; ///< flag to request re-initialization on next pass 355 }; 356 357 /// SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure. 358 struct SV_6DOF_GY_KALMAN 359 { 360 // start: elements common to all motion state vectors 361 float fPhiPl; ///< roll (deg) 362 float fThePl; ///< pitch (deg) 363 float fPsiPl; ///< yaw (deg) 364 float fRhoPl; ///< compass (deg) 365 float fChiPl; ///< tilt from vertical (deg) 366 float fRPl[3][3]; ///< a posteriori orientation matrix 367 Quaternion fqPl; ///< a posteriori orientation quaternion 368 float fRVecPl[3]; ///< rotation vector 369 float fOmega[3]; ///< average angular velocity (deg/s) 370 int32_t systick; ///< systick timer; 371 // end: elements common to all motion state vectors 372 float fQw6x6[6][6]; ///< covariance matrix Qw 373 float fK6x3[6][3]; ///< kalman filter gain matrix K 374 float fQwCT6x3[6][3]; ///< Qw.C^T matrix 375 float fQv; ///< measurement noise covariance matrix leading diagonal 376 float fZErr[3]; ///< measurement error vector 377 float fqgErrPl[3]; ///< gravity vector tilt orientation quaternion error (dimensionless) 378 float fbPl[3]; ///< gyro offset (deg/s) 379 float fbErrPl[3]; ///< gyro offset error (deg/s) 380 float fAccGl[3]; ///< linear acceleration (g) in global frame 381 float fdeltat; ///< sensor fusion interval (s) 382 float fAlphaOver2; ///< PI / 180 * fdeltat / 2 383 float fAlphaSqOver4; ///< (PI / 180 * fdeltat)^2 / 4 384 float fAlphaSqQvYQwbOver12; ///< (PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12 385 float fAlphaQwbOver6; ///< (PI / 180 * fdeltat) * Qwb / 6 386 float fQwbOver3; ///< Qwb / 3 387 float fMaxGyroOffsetChange; ///< maximum permissible gyro offset change per iteration (deg/s) 388 int8_t resetflag; ///< flag to request re-initialization on next pass 389 }; 390 391 /// SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector structure. 392 struct SV_9DOF_GBY_KALMAN 393 { 394 // start: elements common to all motion state vectors 395 float fPhiPl; ///< roll (deg) 396 float fThePl; ///< pitch (deg) 397 float fPsiPl; ///< yaw (deg) 398 float fRhoPl; ///< compass (deg) 399 float fChiPl; ///< tilt from vertical (deg) 400 float fRPl[3][3]; ///< a posteriori orientation matrix 401 Quaternion fqPl; ///< a posteriori orientation quaternion 402 float fRVecPl[3]; ///< rotation vector 403 float fOmega[3]; ///< average angular velocity (deg/s) 404 int32_t systick; ///< systick timer; 405 // end: elements common to all motion state vectors 406 float fQw9x9[9][9]; ///< covariance matrix Qw 407 float fK9x6[9][6]; ///< kalman filter gain matrix K 408 float fQwCT9x6[9][6]; ///< Qw.C^T matrix 409 float fZErr[6]; ///< measurement error vector 410 float fQv6x1[6]; ///< measurement noise covariance matrix leading diagonal 411 float fDeltaPl; ///< a posteriori inclination angle from Kalman filter (deg) 412 float fsinDeltaPl; ///< sin(fDeltaPl) 413 float fcosDeltaPl; ///< cos(fDeltaPl) 414 float fqgErrPl[3]; ///< gravity vector tilt orientation quaternion error (dimensionless) 415 float fqmErrPl[3]; ///< geomagnetic vector tilt orientation quaternion error (dimensionless) 416 float fbPl[3]; ///< gyro offset (deg/s) 417 float fbErrPl[3]; ///< gyro offset error (deg/s) 418 float fAccGl[3]; ///< linear acceleration (g) in global frame 419 float fVelGl[3]; ///< velocity (m/s) in global frame 420 float fDisGl[3]; ///< displacement (m) in global frame 421 float fdeltat; ///< sensor fusion interval (s) 422 float fgdeltat; ///< g (m/s2) * fdeltat 423 float fAlphaOver2; ///< PI / 180 * fdeltat / 2 424 float fAlphaSqOver4; ///< (PI / 180 * fdeltat)^2 / 4 425 float fAlphaSqQvYQwbOver12; ///< (PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12 426 float fAlphaQwbOver6; ///< (PI / 180 * fdeltat) * Qwb / 6 427 float fQwbOver3; ///< Qwb / 3 428 float fMaxGyroOffsetChange; ///< maximum permissible gyro offset change per iteration (deg/s) 429 int8_t iFirstAccelMagLock; ///< denotes that 9DOF orientation has locked to 6DOF eCompass 430 int8_t resetflag; ///< flag to request re-initialization on next pass 431 }; 432 433 /// Excluding SV_1DOF_P_BASIC, Any of the SV_ fusion structures above could 434 /// be cast to type SV_COMMON for dereferencing. 435 struct SV_COMMON { 436 float fPhi; ///< roll (deg) 437 float fThe; ///< pitch (deg) 438 float fPsi; ///< yaw (deg) 439 float fRho; ///< compass (deg) 440 float fChi; ///< tilt from vertical (deg) 441 float fRM[3][3]; ///< orientation matrix 442 Quaternion fq; ///< orientation quaternion 443 float fRVec[3]; ///< rotation vector 444 float fOmega[3]; ///< average angular velocity (deg/s) 445 int32_t systick; ///< systick timer; 446 }; 447 typedef struct SV_COMMON *SV_ptr; 448 449 /// \brief The top level fusion structure 450 /// 451 /// The top level fusion structure grows/shrinks based upon flag definitions 452 /// contained in build.h. These same flags will populate the .iFlags field for 453 /// run-time access. 454 typedef struct SensorFusionGlobals 455 { 456 // Subsystem Pointers 457 ///@{ 458 /// @name SubsystemPointers 459 /// The Status and Control subsystems can be used as-is, or completely 460 /// replaced with alternate implementations, as long as those implementations 461 /// provide the same interfaces defined in control.h and status.h. 462 struct ControlSubsystem *pControlSubsystem; 463 struct StatusSubsystem *pStatusSubsystem; 464 ///@} 465 ///@{ 466 /// @name MiscFields 467 uint32_t iFlags; ///< a bit-field of sensors and algorithms used 468 struct PhysicalSensor *pSensors; ///< a linked list of physical sensors 469 volatile uint8_t iPerturbation; ///< test perturbation to be applied 470 // Book-keeping variables 471 int32_t loopcounter; ///< counter incrementing each iteration of sensor fusion (typically 25Hz) 472 int32_t systick_I2C; ///< systick counter to benchmark I2C reads 473 int32_t systick_Spare; ///< systick counter for counts spare waiting for timing interrupt 474 ///@} 475 ///@{ 476 /// @name SensorRelatedStructures 477 /// These structures provide homes for sensor readings, as well as 478 /// various calibration functions. Only those needed for a specific 479 /// build are included. 480 #if F_1DOF_P_BASIC 481 struct PressureSensor Pressure; ///< pressure sensor storage 482 #endif 483 #if F_USING_ACCEL 484 struct AccelSensor Accel; ///< accelerometer storage 485 struct AccelCalibration AccelCal; ///< structures for accel calibration 486 struct AccelBuffer AccelBuffer; ///< storage for points used for calibration 487 #endif 488 #if F_USING_MAG 489 struct MagSensor Mag; ///< magnetometer storage 490 struct MagCalibration MagCal; ///< mag cal storage 491 struct MagBuffer MagBuffer; ///< mag cal constellation points 492 #endif 493 #if F_USING_GYRO 494 struct GyroSensor Gyro; ///< gyro storage 495 #endif 496 ///@} 497 ///@{ 498 /// @name FusionSpecificStructures 499 #if F_1DOF_P_BASIC 500 struct SV_1DOF_P_BASIC SV_1DOF_P_BASIC; ///< Pressure 501 #endif 502 #if F_3DOF_G_BASIC 503 struct SV_3DOF_G_BASIC SV_3DOF_G_BASIC; ///< Gravity 504 #endif 505 #if F_3DOF_B_BASIC 506 struct SV_3DOF_B_BASIC SV_3DOF_B_BASIC; ///< Magnetic 507 #endif 508 #if F_3DOF_Y_BASIC 509 struct SV_3DOF_Y_BASIC SV_3DOF_Y_BASIC; ///< Gyro 510 #endif 511 #if F_6DOF_GB_BASIC // 6DOF accel and mag eCompass: (accel + mag) 512 struct SV_6DOF_GB_BASIC SV_6DOF_GB_BASIC; ///< eCompass (Gravity + Magnetic) 513 #endif 514 #if F_6DOF_GY_KALMAN 515 struct SV_6DOF_GY_KALMAN SV_6DOF_GY_KALMAN; ///< 6-axis gravity + angular rates Kalman storage 516 #endif 517 #if F_9DOF_GBY_KALMAN 518 struct SV_9DOF_GBY_KALMAN SV_9DOF_GBY_KALMAN; ///< 9-axis storage 519 #endif 520 ///@} 521 ///@{ 522 /// @name FunctionPointers 523 /// Function pointers (the SF library external interface) 524 installSensor_t *installSensor; ///< function for installing a new sensor into t 525 initializeFusionEngine_t *initializeFusionEngine ; ///< set sensor fusion structures to initial values 526 applyPerturbation_t *applyPerturbation ; ///< apply step function for testing purposes 527 readSensors_t *readSensors; ///< read all physical sensors 528 runFusion_t *runFusion; ///< run the fusion routines 529 conditionSensorReadings_t *conditionSensorReadings; ///< preprocessing step for sensor fusion 530 clearFIFOs_t *clearFIFOs; ///< clear sensor FIFOs 531 setStatus_t *setStatus; ///< change status indicator immediately 532 setStatus_t *queueStatus; ///< queue status change for next regular interval 533 updateStatus_t *updateStatus; ///< status=next status 534 updateStatus_t *testStatus; ///< increment to next enumerated status value (test only) 535 ///@} 536 } SensorFusionGlobals; 537 538 // The following functions are defined in sensor_fusion.c 539 void initSensorFusionGlobals( 540 SensorFusionGlobals *sfg, ///< Global data structure pointer 541 struct StatusSubsystem *pStatusSubsystem, ///< Status subsystem pointer 542 struct ControlSubsystem *pControlSubsystem ///< Control subsystem pointer 543 ); 544 installSensor_t installSensor; 545 initializeFusionEngine_t initializeFusionEngine ; 546 /// conditionSensorReadings() transforms raw software FIFO readings into forms that 547 /// can be consumed by the sensor fusion engine. This include sample averaging 548 /// and (in the case of the gyro) integrations, applying hardware abstraction layers, 549 /// and calibration functions. 550 /// This function is normally involved via the "sfg." global pointer. 551 void conditionSensorReadings( 552 SensorFusionGlobals *sfg ///< Global data structure pointer 553 ); 554 void clearFIFOs( 555 SensorFusionGlobals *sfg ///< Global data structure pointer 556 ); 557 runFusion_t runFusion; 558 readSensors_t readSensors; 559 void zeroArray( 560 struct StatusSubsystem *pStatus, ///< Status subsystem pointer 561 void* data, ///< pointer to array to be zeroed 562 uint16_t size, ///< data type size = 8, 16 or 32 563 uint16_t numElements, ///< number of elements to zero out 564 uint8_t check ///< true if you would like to verify writes, false otherwise 565 ); 566 /// \brief conditionSample ensures that we never encounter the maximum negative two's complement 567 /// value for a 16-bit variable (-32768). 568 /// 569 /// conditionSample ensures that we never encounter the maximum negative two's complement 570 /// value for a 16-bit variable (-32768). This value cannot be negated, because the maximum 571 /// positive value is +32767. We need the ability to negate to gaurantee that subsequent 572 /// HAL operations can be run successfully. 573 void conditionSample( 574 int16_t sample[3] ///< 16-bit register value from triaxial sensor read 575 ); 576 577 // The following functions are defined in <hal_board_name>.c. 578 // Please note that these are board-dependent 579 580 /// \brief addToFifo is called from within sensor driver read functions 581 /// 582 /// addToFifo is called from within sensor driver read functions to transfer new readings into 583 /// the sensor structure corresponding to accel, gyro or mag. This function ensures that the software 584 /// FIFOs are not overrun. 585 /// 586 /// example usage: if (status==SENSOR_ERROR_NONE) addToFifo((FifoSensor*) &(sfg->Mag), MAG_FIFO_SIZE, sample); 587 void addToFifo( 588 union FifoSensor *sensor, ///< pointer to structure of type AccelSensor, MagSensor or GyroSensor 589 uint16_t maxFifoSize, ///< the size of the software (not hardware) FIFO 590 int16_t sample[3] ///< the sample to add 591 ); 592 /// \brief Apply the accelerometer Hardware Abstraction Layer 593 void ApplyAccelHAL( 594 struct AccelSensor *Accel ///< pointer to accelerometer logical sensor 595 ); 596 /// \brief Apply the magnetometer Hardware Abstraction Layer 597 void ApplyMagHAL( 598 struct MagSensor *Mag ///< pointer to magnetometer logical sensor 599 ); 600 /// \brief Apply the gyroscope Hardware Abstraction Layer 601 void ApplyGyroHAL( 602 struct GyroSensor *Gyro ///< pointer to gyroscope logical sensor 603 ); 604 /// \brief ApplyPerturbation is a reverse unit-step test function 605 /// 606 /// The ApplyPerturbation function applies a user-specified step function to 607 /// prior fusion results which is then "released" in the next fusion cycle. 608 /// When used in conjuction with the NXP Sensor Fusion Toolbox, this provides 609 /// a visual indication of the dynamic behavior of the library. ApplyPerturbation() 610 /// is defined in debug.c. 611 612 // The following function is defined in debug.c: 613 applyPerturbation_t ApplyPerturbation; 614 615 #include "matrix.h" // this is only down here so we can take advantage of _t style typedefs above 616 617 #endif // SENSOR_FUSION_TYPES_H 618