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