MAV'RIC
/home/travis/build/lis-epfl/MAVRIC_Library/sensing/imu.hpp
00001 /*******************************************************************************
00002  * Copyright (c) 2009-2016, MAV'RIC Development Team
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  * this list of conditions and the following disclaimer.
00010  *
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  * this list of conditions and the following disclaimer in the documentation
00013  * and/or other materials provided with the distribution.
00014  *
00015  * 3. Neither the name of the copyright holder nor the names of its contributors
00016  * may be used to endorse or promote products derived from this software without
00017  * specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  ******************************************************************************/
00031 
00032 /*******************************************************************************
00033  * \file imu.hpp
00034  *
00035  * \author MAV'RIC Team
00036  * \author Felix Schill
00037  * \author Gregoire Heitz
00038  * \author Julien Lecoeur
00039  *
00040  * \brief Inertial measurement unit (IMU)
00041  *
00042  ******************************************************************************/
00043 
00044 
00045 #ifndef IMU_HPP_
00046 #define IMU_HPP_
00047 
00048 #include <cstdint>
00049 #include <cstdbool>
00050 #include <array>
00051 
00052 #include "drivers/accelerometer.hpp"
00053 #include "drivers/gyroscope.hpp"
00054 #include "drivers/magnetometer.hpp"
00055 #include "status/state.hpp"
00056 
00057 extern "C"
00058 {
00059 #include "util/quaternions.h"
00060 }
00061 
00062 #define GYRO_LPF 0.1f                       ///< The gyroscope linear pass filter gain
00063 #define ACC_LPF 0.05f                       ///< The accelerometer linear pass filter gain
00064 #define MAG_LPF 0.1f                        ///< The magnetometer linear pass filter gain
00065 
00066 
00070 typedef struct
00071 {
00072     std::array<float, 3>    bias;         
00073     std::array<float, 3>    scale_factor; 
00074     std::array<float, 3>    sign;         
00075     std::array<uint8_t, 3>  axis;         
00076     std::array<float, 3>    max_values;   
00077     std::array<float, 3>    min_values;   
00078     std::array<float, 3>    mean_values;  
00079 } imu_sensor_config_t;
00080 
00081 
00085 typedef struct
00086 {
00087     imu_sensor_config_t accelerometer;  
00088     imu_sensor_config_t gyroscope;      
00089     imu_sensor_config_t magnetometer;   
00090     std::array<float, 3> magnetic_north;
00091     float lpf_acc;                      
00092     float lpf_gyro;                     
00093     float lpf_mag;                      
00094     float lpf_mean;                     
00095     float startup_calib_gyro_threshold; 
00096     float startup_calib_duration_s;     
00097 } imu_conf_t;
00098 
00099 
00105 static inline imu_conf_t imu_default_config(void);
00106 
00107 
00117 class Imu
00118 {
00119 public:
00123     Imu(Accelerometer& accelerometer,
00124         Gyroscope& gyroscope,
00125         Magnetometer& magnetometer,
00126         imu_conf_t config = imu_default_config());
00127 
00128 
00134     bool update(void);
00135 
00136 
00142     const float& last_update_us(void) const;
00143 
00144 
00150     const float& dt_s(void) const;
00151 
00152 
00158     const std::array<float, 3>& acc(void) const;
00159 
00160 
00166     const std::array<float, 3>& gyro(void) const;
00167 
00168 
00174     const std::array<float, 3>& mag(void) const;
00175 
00181     const std::array<float, 3>& magnetic_north(void) const;
00182 
00183 
00189     bool is_ready(void) const;
00190 
00198     imu_conf_t* get_config(void);
00199 
00200     // -------------------------------------------------------------------------
00201     //
00202     // TODO implement calibration
00203     //
00204     // -------------------------------------------------------------------------
00205 
00218     bool start_accelerometer_bias_calibration(void);
00219 
00220 
00233     bool start_gyroscope_bias_calibration(void);
00234 
00235 
00251     bool start_magnetometer_bias_calibration(void);
00252 
00253 
00266     bool start_magnetic_north_calibration(void);
00267 
00268 
00276     bool stop_accelerometer_bias_calibration(void);
00277 
00278 
00286     bool stop_gyroscope_bias_calibration(void);
00287 
00288 
00297     bool stop_magnetometer_bias_calibration(void);
00298 
00299 
00307     bool stop_magnetic_north_calibration(void);
00308 
00309 
00310 private:
00316     bool is_calibration_ongoing(void) const;
00317 
00318 
00324     void do_calibration(void);
00325 
00326 
00327     Accelerometer&  accelerometer_;     
00328     Gyroscope&      gyroscope_;         
00329     Magnetometer&   magnetometer_;      
00330 
00331     imu_conf_t      config_;            
00332 
00333     std::array<float, 3> oriented_acc_; 
00334     std::array<float, 3> oriented_gyro_;
00335     std::array<float, 3> oriented_mag_; 
00336 
00337     std::array<float, 3> scaled_acc_;   
00338     std::array<float, 3> scaled_gyro_;  
00339     std::array<float, 3> scaled_mag_;   
00340     float magnetic_inclination_;        
00341     float magnetic_norm_;               
00342 
00343     bool do_startup_calibration_;               
00344     bool do_accelerometer_bias_calibration_;    
00345     bool do_gyroscope_bias_calibration_;        
00346     bool do_magnetometer_bias_calibration_;     
00347     bool do_magnetic_north_calibration_;        
00348     bool is_ready_;                             
00349 
00350     float dt_s_;                        
00351     float last_update_us_;              
00352     float startup_calibration_start_time_;       
00353 };
00354 
00355 
00356 
00362 static inline imu_conf_t imu_default_config()
00363 {
00364     imu_conf_t conf = {};
00365 
00366     // Accelerometer
00367     // Bias
00368     conf.accelerometer.bias[0] = 0.0f;      
00369     conf.accelerometer.bias[1] = 0.0f;
00370     conf.accelerometer.bias[2] = 0.0f;
00371 
00372     // Scale
00373     conf.accelerometer.scale_factor[0] = 1.0f;      
00374     conf.accelerometer.scale_factor[1] = 1.0f;
00375     conf.accelerometer.scale_factor[2] = 1.0f;
00376 
00377     // Axis and sign
00378     conf.accelerometer.sign[0] = +1.0f; 
00379     conf.accelerometer.sign[1] = +1.0f;
00380     conf.accelerometer.sign[2] = +1.0f;
00381     conf.accelerometer.axis[0] = 0;     
00382     conf.accelerometer.axis[1] = 1;
00383     conf.accelerometer.axis[2] = 2;
00384 
00385     // Min and max values
00386     conf.accelerometer.max_values[0] = -10000.0f;
00387     conf.accelerometer.max_values[1] = -10000.0f;
00388     conf.accelerometer.max_values[2] = -10000.0f;
00389     conf.accelerometer.min_values[0] = 10000.0f;
00390     conf.accelerometer.min_values[1] = 10000.0f;
00391     conf.accelerometer.min_values[2] = 10000.0f;
00392     conf.accelerometer.mean_values[0] = 0.0f;
00393     conf.accelerometer.mean_values[1] = 0.0f;
00394     conf.accelerometer.mean_values[2] = 0.0f;
00395 
00396     // Gyroscope
00397     // Bias
00398     conf.gyroscope.bias[0] = 0.0f;      
00399     conf.gyroscope.bias[1] = 0.0f;
00400     conf.gyroscope.bias[2] = 0.0f;
00401 
00402     // Scale
00403     conf.gyroscope.scale_factor[0] = 1.0f;      
00404     conf.gyroscope.scale_factor[1] = 1.0f;
00405     conf.gyroscope.scale_factor[2] = 1.0f;
00406 
00407     // Axis and sign
00408     conf.gyroscope.sign[0] = +1.0f; 
00409     conf.gyroscope.sign[1] = +1.0f;
00410     conf.gyroscope.sign[2] = +1.0f;
00411     conf.gyroscope.axis[0] = 0;     
00412     conf.gyroscope.axis[1] = 1;
00413     conf.gyroscope.axis[2] = 2;
00414 
00415     // Min and max values
00416     conf.gyroscope.max_values[0] = -10000.0f;
00417     conf.gyroscope.max_values[1] = -10000.0f;
00418     conf.gyroscope.max_values[2] = -10000.0f;
00419     conf.gyroscope.min_values[0] = 10000.0f;
00420     conf.gyroscope.min_values[1] = 10000.0f;
00421     conf.gyroscope.min_values[2] = 10000.0f;
00422     conf.gyroscope.mean_values[0] = 0.0f;
00423     conf.gyroscope.mean_values[1] = 0.0f;
00424     conf.gyroscope.mean_values[2] = 0.0f;
00425 
00426     // Magnetometer
00427     // Bias
00428     conf.magnetometer.bias[0] = 0.0f;       
00429     conf.magnetometer.bias[1] = 0.0f;
00430     conf.magnetometer.bias[2] = 0.0f;
00431 
00432     // Scale
00433     conf.magnetometer.scale_factor[0] = 1.0f;       
00434     conf.magnetometer.scale_factor[1] = 1.0f;
00435     conf.magnetometer.scale_factor[2] = 1.0f;
00436 
00437     // Axis and sign
00438     conf.magnetometer.sign[0] = +1.0f;  
00439     conf.magnetometer.sign[1] = +1.0f;
00440     conf.magnetometer.sign[2] = +1.0f;
00441     conf.magnetometer.axis[0] = 0;      
00442     conf.magnetometer.axis[1] = 1;
00443     conf.magnetometer.axis[2] = 2;
00444 
00445     // Min and max values
00446     conf.magnetometer.max_values[0] = -10000.0f;
00447     conf.magnetometer.max_values[1] = -10000.0f;
00448     conf.magnetometer.max_values[2] = -10000.0f;
00449     conf.magnetometer.min_values[0] = 10000.0f;
00450     conf.magnetometer.min_values[1] = 10000.0f;
00451     conf.magnetometer.min_values[2] = 10000.0f;
00452     conf.magnetometer.mean_values[0] = 0.0f;
00453     conf.magnetometer.mean_values[1] = 0.0f;
00454     conf.magnetometer.mean_values[2] = 0.0f;
00455 
00456     // Magnetic north (default value in Lausanne: 62° inclination)
00457     conf.magnetic_north[0] = 0.46947156f;   // cos(62°)
00458     conf.magnetic_north[1] = 0.0f;
00459     conf.magnetic_north[2] = 0.88294759f;   // sin(62°)
00460 
00461     // Low pass filter
00462     conf.lpf_acc    = 0.1f;
00463     conf.lpf_gyro   = 0.05f;
00464     conf.lpf_mag    = 0.1f;
00465     conf.lpf_mean   = 0.01f;
00466 
00467     // startup calibration length
00468     conf.startup_calib_gyro_threshold = 0.5f;
00469     conf.startup_calib_duration_s     = 10.0f;
00470 
00471     return conf;
00472 }
00473 
00474 #endif /* IMU_HPP_ */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines