bma180_calibrate.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Bosch LLC
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  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Bosch LLC nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /*********************************************************************
00031  *
00032  * Disclaimer
00033  *
00034  * This source code is not officially released or supported by Bosch Sensortec.
00035  * Please contact the listed authors with bugs or other modifications.
00036  * If you would like the official Bosch Sensortec drivers, please contact:
00037  * contact@bosch-sensortec.com
00038  *
00039  *********************************************************************/
00040 
00041 
00042 #include <math.h>
00043 #include <ros/ros.h>
00044 #include <std_msgs/String.h>
00045 #include <bma180/bma180meas.h>
00046 #include <ros/time.h>
00047 #include <bma180/bma180.h>
00048 #include <bma180/bma180_calibrate.h>
00049 
00050 bma180_calibrate::bma180_calibrate() {
00051   for (iActiveDataIndex=0; iActiveDataIndex < 2; iActiveDataIndex++) {
00052     CalibSensor[iActiveDataIndex].bCalib_complete               = false;
00053     CalibSensor[iActiveDataIndex].bCalibsensID_set              = false;
00054     CalibSensor[iActiveDataIndex].iNumOfCalibMeas               = 0;
00055   }
00056   iActiveDataIndex              = 0;    //primary is always index 0
00057   bVerification_activated = false;
00058 };
00059 
00060 
00061 bma180_calibrate::~bma180_calibrate() {
00062 };
00063 
00064 bool bma180_calibrate::setdata_bma180(OneBma180Meas OneMeas) {
00065   double        std_estbias_acc;
00066   double        measdev_accX;
00067   double        measdev_accY;
00068   double        measdev_accZ;
00069   bool  bSetdata_success = false;
00070 
00071   if (CalibSensor[iActiveDataIndex].bCalibsensID_set == true) {
00072     if  ( ( CalibSensor[iActiveDataIndex].Sensor_ID.Sub20ID == OneMeas.strSerial ) && (CalibSensor[iActiveDataIndex].Sensor_ID.iChipSelect == OneMeas.iChipSelect[0]) ) {
00073       if ( CalibSensor[iActiveDataIndex].bCalib_complete == false ) {
00074         if (CalibSensor[iActiveDataIndex].iNumOfCalibMeas == 0) {
00075           //since first data set - current measurement equals bias
00076           CalibSensor[iActiveDataIndex].dBias_AccX                      = OneMeas.dAccX[0];
00077           CalibSensor[iActiveDataIndex].dBias_AccY                      = OneMeas.dAccY[0];
00078           CalibSensor[iActiveDataIndex].dBias_AccZ                      = OneMeas.dAccZ[0];
00079           CalibSensor[iActiveDataIndex].AgeOfBias                       = OneMeas.dtomeas;
00080           CalibSensor[iActiveDataIndex].iNumOfCalibMeas++;
00081           bSetdata_success = true;
00082         }
00083         else {
00084           //calculate variance of estimated bias
00085           std_estbias_acc               = bma180_spec::std_acc_g/sqrt((double)CalibSensor[iActiveDataIndex].iNumOfCalibMeas);
00086 
00087           //calculate measurement deviation
00088           measdev_accX = fabs(OneMeas.dAccX[0] - CalibSensor[iActiveDataIndex].dBias_AccX);
00089           measdev_accY = fabs(OneMeas.dAccY[0] - CalibSensor[iActiveDataIndex].dBias_AccY);
00090           measdev_accZ = fabs(OneMeas.dAccZ[0] - CalibSensor[iActiveDataIndex].dBias_AccZ);
00091 
00092 //                                      std::cout << "Num of Meas " << CalibSensor.iNumOfCalibMeas  << "std est bias " << std_estbias_acc << " \r";
00093 
00094           //verify if an outlier is detected
00095           if  ( (measdev_accX > bma180_spec::outlier_sigma*(std_estbias_acc  + bma180_spec::std_acc_g)) ||
00096                 (measdev_accY > bma180_spec::outlier_sigma*(std_estbias_acc  + bma180_spec::std_acc_g)) ||
00097                 (measdev_accZ > bma180_spec::outlier_sigma*(std_estbias_acc  + bma180_spec::std_acc_g)) ) {
00098 
00099             // movement during calibration
00100             ROS_INFO("***DUDE - CALIBRATION - DO NOT TOUCH***");
00101             //Reset validation counter to zero
00102             CalibSensor[iActiveDataIndex].iNumOfCalibMeas = 0;
00103           }
00104           else {
00105             // Filter bias based on filterconstant tau
00106             // bias_k1 = bias_k0 + 1/Tau*(meas_k1-bias_k0), where TAU needs to be adjusted to
00107             // to the filter period as defined by the Allan Variance
00108             CalibSensor[iActiveDataIndex].dBias_AccX    = CalibSensor[iActiveDataIndex].dBias_AccX      + 1/((double)bma180_spec::calib_varreduct)*(OneMeas.dAccX[0]-CalibSensor[iActiveDataIndex].dBias_AccX);
00109             CalibSensor[iActiveDataIndex].dBias_AccY    = CalibSensor[iActiveDataIndex].dBias_AccY  + 1/((double)bma180_spec::calib_varreduct)*(OneMeas.dAccY[0]-CalibSensor[iActiveDataIndex].dBias_AccY);
00110             CalibSensor[iActiveDataIndex].dBias_AccZ    = CalibSensor[iActiveDataIndex].dBias_AccZ  + 1/((double)bma180_spec::calib_varreduct)*(OneMeas.dAccZ[0]-CalibSensor[iActiveDataIndex].dBias_AccZ);
00111 
00112             CalibSensor[iActiveDataIndex].iNumOfCalibMeas++;
00113             //set age of bias
00114             CalibSensor[iActiveDataIndex].AgeOfBias             = OneMeas.dtomeas;
00115             //verify if calibration accuracy is satisfied
00116 //                                              std::cout << " Meas Count: " << CalibSensor.iNumOfCalibMeas << " calibe reduct " <<  bma180_spec::calib_varreduct << std::endl;
00117             if ( CalibSensor[iActiveDataIndex].iNumOfCalibMeas >= bma180_spec::calib_varreduct ) {
00118               //indicate that system has been calibrated
00119               CalibSensor[iActiveDataIndex].bCalib_complete     = true;
00120               //measurement successful
00121               bSetdata_success = true;
00122               //std::cout << "Calibration completed BiasX " << CalibSensor[iActiveDataIndex].dBias_AccX << " BiasY " << CalibSensor[iActiveDataIndex].dBias_AccY << " BiasZ " << CalibSensor[iActiveDataIndex].dBias_AccZ << std::endl;
00123             }
00124           }
00125         }
00126       }
00127       else {
00128 //                      std::cout << " Calibration completed " << std::endl;
00129       }
00130     }
00131     else {
00132       //message does contain data from other sensor
00133     }
00134   }
00135   else {
00136     //Sensor is not set
00137   }
00138   return (bSetdata_success);
00139 };
00140 
00141 void bma180_calibrate::setcalibsens(OneBma180Meas OneMeas) {
00142   int iCount;
00143   for (iCount=0; iCount < 2; iCount++) {
00144     CalibSensor[iCount].Sensor_ID.iChipSelect   = OneMeas.iChipSelect[0];
00145     CalibSensor[iCount].Sensor_ID.Sub20ID               = OneMeas.strSerial;
00146     CalibSensor[iCount].bCalibsensID_set                = true;
00147     CalibSensor[iCount].bCalib_complete                 = false;
00148     CalibSensor[iCount].iNumOfCalibMeas                 = 0;
00149   }
00150 }
00151 
00152 void bma180_calibrate::clearcalibsens() {
00153   int iCount;
00154   for (iCount=0; iCount < 2; iCount++) {
00155     CalibSensor[iCount].bCalibsensID_set                = false;
00156     CalibSensor[iCount].bCalib_complete                 = false;
00157     CalibSensor[iCount].iNumOfCalibMeas                 = 0;
00158   };
00159   iActiveDataIndex = 0;
00160 };
00161 
00162 bool bma180_calibrate::calibsens_completed() {
00163   return(CalibSensor[0].bCalib_complete);
00164 };
00165 
00166 bool bma180_calibrate::verification_completed() {
00167   return(CalibSensor[1].bCalib_complete);
00168 };
00169 
00170 bool bma180_calibrate::calibsens_set() {
00171   return(CalibSensor[0].bCalibsensID_set);
00172 };
00173 
00174 bool bma180_calibrate::verification_active() {
00175   return(bVerification_activated);
00176 };
00177 
00178 bool bma180_calibrate::get_estbiases(double* dAccX, double* dAccY, double* dAccZ ) {
00179   bool bSuccess;
00180   //always provides the primary bias
00181   if ( (CalibSensor[0].bCalibsensID_set==true)&&(CalibSensor[0].bCalib_complete==true) ) {
00182     *dAccX = CalibSensor[0].dBias_AccX;
00183     *dAccY = CalibSensor[0].dBias_AccY;
00184     *dAccZ = CalibSensor[0].dBias_AccZ;
00185     bSuccess = true;
00186   }
00187   else {
00188     *dAccX = 0;
00189     *dAccY = 0;
00190     *dAccZ = 0;
00191     bSuccess = false;
00192   }
00193   return(bSuccess);
00194 };
00195 
00196 bool bma180_calibrate::biasverify(void) {
00197   bool bSuccess;
00198   if ( (CalibSensor[0].bCalibsensID_set==true)&&(CalibSensor[0].bCalib_complete==true) ) {
00199     iActiveDataIndex = 1;
00200     bVerification_activated = true;
00201     bSuccess = true;
00202   }
00203   else {
00204     bSuccess = false;
00205   }
00206   return (bSuccess);
00207 };
00208 
00209 bool bma180_calibrate::get_verifiedbiases(double* dAccX, double* dAccY, double* dAccZ ) {
00210   bool bSuccess;
00211   if ( (CalibSensor[1].bCalibsensID_set==true)&&(CalibSensor[1].bCalib_complete==true) ) {
00212     *dAccX = CalibSensor[1].dBias_AccX;
00213     *dAccY = CalibSensor[1].dBias_AccY;
00214     *dAccZ = CalibSensor[1].dBias_AccZ;
00215     bSuccess = true;
00216   }
00217   else {
00218     *dAccX = 0;
00219     *dAccY = 0;
00220     *dAccZ = 0;
00221     bSuccess = false;
00222   }
00223   return(bSuccess);
00224 };
00225 


bma180
Author(s): Lukas Marti, Nikhil Deshpande, Philip Roan (Maintained by Philip Roan)
autogenerated on Mon Oct 6 2014 10:10:49