Go to the documentation of this file.00001
00002
00003
00004
00005
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
00032 }
00033
00034
00035 bool MKCalibrator::doGyroDriftEstim()
00036 {
00037 ROS_INFO("Starting Drift Estimation!");
00038
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
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
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
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
00077 minDrifts.x = driftGyroX->getValue();
00078 minDrifts.y = driftGyroY->getValue();
00079 minDrifts.z = driftGyroZ->getValue();
00080 maxDrifts = minDrifts;
00081
00082
00083 driftCounters.x = 0;
00084 driftCounters.y = 0;
00085 driftCounters.z = 0;
00086 driftEstimDone = driftCounters;
00087
00088
00089
00090 MKInt saveTimeMirrorPeriod = timeMirrorPeriod->getValue();
00091 MKInt saveMirrorDataActive = mirrorDataActive->getValue();
00092 MKActiveIDs saveActiveIDs = connection->getActiveDataIDs();
00093
00094
00095
00096 connection->setActiveDataIDs(MKData::getPattern(MKDataPattern::AccOffsetGyroDrift));
00097 connection->setValue(timeMirrorPeriod->getMKSingleValuePacketWithValue(1));
00098 connection->setValue(mirrorDataActive->getMKSingleValuePacketWithValue(MKDataDefines::MKINT_LOGICAL_ON));
00099 connection->setValue(driftEstimActive->getMKSingleValuePacketWithValue(MKDataDefines::MKINT_LOGICAL_ON));
00100
00101
00102 connection->registerMKDataListener(this);
00103
00104 Timer timeoutTimer;
00105
00106
00107 bool returnValue = false;
00108
00109 while(timeoutTimer.getElapsed().toDSec() < options.tDriftEstimTimeout->getValue()) {
00110
00111 if (driftEstimDone.x && driftEstimDone.y && driftEstimDone.z) {
00112
00113
00114 returnValue = true;
00115 break;
00116 }
00117
00118
00119 usleep(1000);
00120 }
00121
00122
00123 connection->unRegisterMKDataListener(this);
00124
00125
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
00142 switch (value->getID()) {
00143 case MKDataDefines::DRIFT_GYRO_X:
00144
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
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
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
00215 break;
00216 }
00217
00218 }
00219
00220 }