MKCalibrator.cpp
Go to the documentation of this file.
00001 /*
00002  * MKCalibrator.cpp
00003  *
00004  *  Created on: Dec 7, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include <tk_mkinterface/MKCalibrator.hpp>
00009 
00010 #define DRIFT_ESTIM_WINDOW_SIZE 50
00011 
00012 namespace TELEKYB_NAMESPACE {
00013 
00014 MKCalibratorOptions::MKCalibratorOptions()
00015         : OptionContainer("MKCalibrator")
00016 {
00017         tDriftEstimTimeout = addBoundsOption<double>("tDriftEstimTimeout",
00018                         "Timeout for DriftEstim in seconds", 10.0, 0.1, 30.0, false, true);
00019         tDriftEstimDeltaThreshold = addBoundsOption<int>("tDriftEstimDeltaThreshold",
00020                         "Threshold for Drift Estimation Deltas", 100, 10, 500, false, false);
00021 }
00022 
00023 MKCalibrator::MKCalibrator(MKInterfaceConnection* connection_)
00024         : connection(connection_), gyroDriftEstimRunning(false)
00025 {
00026 
00027 }
00028 
00029 MKCalibrator::~MKCalibrator()
00030 {
00031  // not needed
00032 }
00033 
00034 // blocking DriftEstim
00035 bool MKCalibrator::doGyroDriftEstim()
00036 {
00037         ROS_INFO("Starting Drift Estimation!");
00038         // get certain values
00039         MKValue* timeMirrorPeriod = connection->getMKDataRef().getValueByID(MKDataDefines::MIRROR_TIME_PERIOD);
00040         MKValue* motorState = connection->getMKDataRef().getValueByID(MKDataDefines::MOTOR_STATE);
00041         MKValue* driftEstimActive = connection->getMKDataRef().getValueByID(MKDataDefines::DRIFT_ESTIM_ACTIVE);
00042         MKValue* mirrorDataActive = connection->getMKDataRef().getValueByID(MKDataDefines::MIRROR_DATA_ACTIVE);
00043 
00044         if (!(connection->updateValue(timeMirrorPeriod->getID()) &&
00045                         connection->updateValue(motorState->getID()) &&
00046                         connection->updateValue(driftEstimActive->getID()) &&
00047                         connection->updateValue(mirrorDataActive->getID())) ) {
00048                 ROS_ERROR("Could not update values. Drift not successful.");
00049                 return false;
00050         }
00051 
00052         // Check
00053         if (motorState->getValue() != MotorState::Off) {
00054                 MotorState currMotorState(motorState->getValue());
00055                 ROS_ERROR("Motor State must be off for Drift Estimation! Current: %s" ,currMotorState.str());
00056                 return false;
00057         }
00058 
00059         // ok
00060         if (driftEstimActive->getValue() != MKDataDefines::MKINT_LOGICAL_OFF) {
00061                 ROS_WARN("Drift Estimation is unequal to MKINT_LOGICAL_OFF. Unexpected State to start..");
00062         }
00063 
00064         // get Initial Drift Values;
00065         MKValue* driftGyroX = connection->getMKDataRef().getValueByID(MKDataDefines::DRIFT_GYRO_X);
00066         MKValue* driftGyroY = connection->getMKDataRef().getValueByID(MKDataDefines::DRIFT_GYRO_Y);
00067         MKValue* driftGyroZ = connection->getMKDataRef().getValueByID(MKDataDefines::DRIFT_GYRO_Z);
00068         if (!(  connection->updateValue(driftGyroX->getID()) &&
00069                         connection->updateValue(driftGyroY->getID()) &&
00070                         connection->updateValue(driftGyroZ->getID()) )) {
00071 
00072                 ROS_ERROR("Unable to get initial Gyro Drift States for Drift Estimation!");
00073                 return false;
00074         }
00075 
00076         // Set initial Values
00077         minDrifts.x = driftGyroX->getValue();
00078         minDrifts.y = driftGyroY->getValue();
00079         minDrifts.z = driftGyroZ->getValue();
00080         maxDrifts = minDrifts;
00081 
00082         // Null Init
00083         driftCounters.x = 0;
00084         driftCounters.y = 0;
00085         driftCounters.z = 0;
00086         driftEstimDone = driftCounters;
00087 
00088 
00089         // save
00090         MKInt saveTimeMirrorPeriod = timeMirrorPeriod->getValue();
00091         MKInt saveMirrorDataActive = mirrorDataActive->getValue();
00092         MKActiveIDs saveActiveIDs = connection->getActiveDataIDs();
00093 
00094         // START ACTUAL ESTIMATION
00095         // no checking for success.
00096         connection->setActiveDataIDs(MKData::getPattern(MKDataPattern::AccOffsetGyroDrift));
00097         connection->setValue(timeMirrorPeriod->getMKSingleValuePacketWithValue(1)); // highest rate
00098         connection->setValue(mirrorDataActive->getMKSingleValuePacketWithValue(MKDataDefines::MKINT_LOGICAL_ON));
00099         connection->setValue(driftEstimActive->getMKSingleValuePacketWithValue(MKDataDefines::MKINT_LOGICAL_ON));
00100 
00101         // register
00102         connection->registerMKDataListener(this);
00103 
00104         Timer timeoutTimer;
00105 
00106         // loop
00107         bool returnValue = false;
00108 
00109         while(timeoutTimer.getElapsed().toDSec() < options.tDriftEstimTimeout->getValue()) {
00110 
00111                 if (driftEstimDone.x && driftEstimDone.y && driftEstimDone.z) {
00112                         // all done
00113                         //ROS_INFO("Successfully did driftEstimation!");
00114                         returnValue = true;
00115                         break;
00116                 }
00117 
00118 
00119                 usleep(1000);
00120         }
00121 
00122         // done estimating
00123         connection->unRegisterMKDataListener(this);
00124 
00125         // set back
00126         connection->setValue(driftEstimActive->getMKSingleValuePacketWithValue(MKDataDefines::MKINT_LOGICAL_OFF));
00127         connection->setValue(mirrorDataActive->getMKSingleValuePacketWithValue(saveMirrorDataActive));
00128         connection->setValue(timeMirrorPeriod->getMKSingleValuePacketWithValue(saveTimeMirrorPeriod));
00129         connection->setActiveDataIDs(saveActiveIDs);
00130 
00131         if (returnValue) {
00132                 ROS_INFO("Drift Estimation was successful!");
00133         } else {
00134                 ROS_ERROR("Drift Estimation was not done successfully.");
00135         }
00136         return returnValue;
00137 }
00138 
00139 void MKCalibrator::dataValueUpdated(MKValue* value)
00140 {
00141         // we are only interested in the drift values.
00142         switch (value->getID()) {
00143                 case MKDataDefines::DRIFT_GYRO_X:
00144                         // already done.
00145                         if (driftEstimDone.x != 0) {
00146                                 break;
00147                         }
00148 
00149                         if (driftCounters.x == DRIFT_ESTIM_WINDOW_SIZE) {
00150                                 ROS_INFO("Drift Error X: %d", maxDrifts.x - minDrifts.x);
00151                                 if (maxDrifts.x - minDrifts.x < options.tDriftEstimDeltaThreshold->getValue()) {
00152                                         driftEstimDone.x = 1;
00153                                         ROS_INFO("Drift Estimation X done!");
00154                                 }
00155 
00156                                 minDrifts.x = value->getValue();
00157                                 maxDrifts.x = value->getValue();
00158                                 driftCounters.x = 0;
00159                         }
00160 
00161                         minDrifts.x = std::min(minDrifts.x, (int)value->getValue());
00162                         maxDrifts.x = std::max(maxDrifts.x, (int)value->getValue());
00163                         driftCounters.x++;
00164 
00165                         break;
00166                 case MKDataDefines::DRIFT_GYRO_Y:
00167                         // already done.
00168                         if (driftEstimDone.y != 0) {
00169                                 break;
00170                         }
00171 
00172                         if (driftCounters.y == DRIFT_ESTIM_WINDOW_SIZE) {
00173                                 ROS_INFO("Drift Error Y: %d", maxDrifts.y - minDrifts.y);
00174                                 if (maxDrifts.y - minDrifts.y < options.tDriftEstimDeltaThreshold->getValue()) {
00175                                         driftEstimDone.y = 1;
00176                                         ROS_INFO("Drift Estimation Y done!");
00177                                 }
00178 
00179                                 minDrifts.y = value->getValue();
00180                                 maxDrifts.y = value->getValue();
00181                                 driftCounters.y = 0;
00182                         }
00183 
00184                         minDrifts.y = std::min(minDrifts.y, (int)value->getValue());
00185                         maxDrifts.y = std::max(maxDrifts.y, (int)value->getValue());
00186                         driftCounters.y++;
00187 
00188                         break;
00189                 case MKDataDefines::DRIFT_GYRO_Z:
00190                         // already done.
00191                         if (driftEstimDone.z != 0) {
00192                                 break;
00193                         }
00194 
00195                         if (driftCounters.z == DRIFT_ESTIM_WINDOW_SIZE) {
00196                                 ROS_INFO("Drift Error Z: %d", maxDrifts.z - minDrifts.z);
00197                                 if (maxDrifts.z - minDrifts.z < options.tDriftEstimDeltaThreshold->getValue()) {
00198                                         driftEstimDone.z = 1;
00199                                         ROS_INFO("Drift Estimation Z done!");
00200                                 }
00201 
00202                                 minDrifts.z = value->getValue();
00203                                 maxDrifts.z = value->getValue();
00204                                 driftCounters.z = 0;
00205                         }
00206 
00207                         minDrifts.z = std::min(minDrifts.z, (int)value->getValue());
00208                         maxDrifts.z = std::max(maxDrifts.z, (int)value->getValue());
00209                         driftCounters.z++;
00210 
00211                         break;
00212 
00213                 default:
00214                         // we don't care about other values
00215                         break;
00216         }
00217 
00218 }
00219 
00220 } /* namespace telekyb */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


tk_mkinterface
Author(s): Martin Riedel
autogenerated on Wed Apr 24 2013 11:29:54