VisualOdometry.cc
Go to the documentation of this file.00001 #include "VisualOdometry.h"
00002 #include "Behaviors/StateMachine.h"
00003 #include "DualCoding/VRmixin.h"
00004
00005
00006
00007 void OpticalFlowOdometry::update(bool sleepOverride) {
00008 if ( !sleepOverride && !VRmixin::isWalkingFlag ) {
00009 sleeping = true;
00010 lastTranslation = 0;
00011 lastAngle = 0;
00012 return;
00013 }
00014 float lastFlow = integratedFlow;
00015 updateFlow();
00016 if ( ! sleeping ) {
00017 lastTranslation = integratedFlow - lastFlow;
00018 lastAngle = lastTranslation / scalingFactor;
00019 } else {
00020 lastTranslation = 0;
00021 lastAngle = 0;
00022 sleeping = false;
00023
00024 }
00025 }
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 void OpticalFlowOdometry::setConversionParameters(float slope, float offset) {
00041 scalingFactor = slope;
00042 }
00043
00044
00045
00046
00047 void ImageProfileOdometry::update(bool sleepOverride) {
00048 if ( !sleepOverride && !VRmixin::isWalkingFlag ) {
00049 sleeping = true;
00050 lastTranslation = 0;
00051 lastAngle = 0;
00052 return;
00053 }
00054 buildImageProfile();
00055 if ( ! sleeping ) {
00056 lastTranslation = minTranslation();
00057 lastAngle = translationToAngle(lastTranslation);
00058 } else {
00059 lastTranslation = 0;
00060 lastAngle = 0;
00061 sleeping = false;
00062
00063 }
00064 displayImageProfile();
00065 displayTranslationProfile();
00066 swapCurrentProfile();
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void ImageProfileOdometry::buildImageProfile() {
00093 static Sketch<uchar> rawY(VRmixin::sketchFromRawY(), "rawY", true);
00094 rawY = VRmixin::sketchFromRawY();
00095
00096 for(unsigned int i = 0; i < currImageProfile->size(); i++) {
00097 (*currImageProfile)[i] = 0;
00098 }
00099
00100 for(unsigned int i = 0; i < currImageProfile->size(); i++) {
00101 for(unsigned int j = 0; j < RobotInfo::CameraResolutionY; j++) {
00102 (*currImageProfile)[i] += rawY(i,j);
00103 }
00104 }
00105 }
00106
00107 void ImageProfileOdometry::swapCurrentProfile() {
00108 if ( currImageProfile == &profile1 )
00109 currImageProfile = &profile2;
00110 else
00111 currImageProfile = &profile1;
00112 }
00113
00114 void ImageProfileOdometry::buildTranslationProfile() {
00115 int upper = RobotInfo::CameraResolutionX/2;
00116 int lower = -upper;
00117
00118 float currDistance;
00119 int index = 0;
00120 for(int i = lower; i < upper; i++, index++) {
00121 if(currImageProfile == &profile1)
00122 currDistance = differenceMeasure(i);
00123 else
00124 currDistance = differenceMeasure(i);
00125
00126 translationProfile[index] = currDistance;
00127 }
00128
00129 float maxElement = *(max_element(translationProfile.begin(), translationProfile.end()));
00130
00131 const unsigned int width = RobotInfo::CameraResolutionX;
00132 const unsigned int height = RobotInfo::CameraResolutionY;
00133 for(unsigned int i = 0; i < width; i++) {
00134 translationProfile[i] = width - floor(translationProfile[i] / (maxElement/height));
00135 }
00136 }
00137
00138 float ImageProfileOdometry::translationToAngle(int translation) {
00139 if ( slope == 0.0f )
00140 return 0.0f;
00141 else
00142 return ((float)translation + offset)/slope;
00143 }
00144
00145 void ImageProfileOdometry::setConversionParameters(float tSlope, float tOffset) {
00146 this->slope = tSlope;
00147 this->offset = tOffset;
00148 }
00149
00150
00151
00152
00153
00154
00155 float ImageProfileOdometry::differenceMeasure(int s) {
00156 bool direction = currImageProfile == &profile1;
00157 int bounds = RobotInfo::CameraResolutionX - fabs(s) - 1;
00158
00159 float manDifference = 0.0f;
00160 float differenceComponent = 0.0f;
00161 for(int i = 0; i < bounds; i++) {
00162 int currIndex = i + std::max(0,s);
00163 int prevIndex = i - std::min(0,s);
00164
00165 if(direction)
00166 differenceComponent = profile1[currIndex] - profile2[prevIndex];
00167 else
00168 differenceComponent = profile1[prevIndex] - profile2[currIndex];
00169
00170 manDifference += fabs(differenceComponent);
00171 }
00172
00173 return manDifference / (bounds + 1);
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 int ImageProfileOdometry::minTranslation() {
00183 int upper = RobotInfo::CameraResolutionX/2;
00184 int lower = -upper;
00185
00186 int minTrans = lower;
00187 float minDistance = 255 * RobotInfo::CameraResolutionX;
00188 float currDistance;
00189 for (int i = lower; i < upper; i++) {
00190 currDistance = differenceMeasure(i);
00191 if(currDistance < minDistance) {
00192 minDistance = currDistance;
00193 minTrans = i;
00194 }
00195 }
00196
00197 return minTrans;
00198 }
00199
00200 void ImageProfileOdometry::displayImageProfile() {
00201 static Sketch<bool> hist(visops::zeros(VRmixin::camSkS), "imageProfile", true);
00202 hist = false;
00203
00204 const unsigned int MAX_INTENSITY = 255;
00205 const unsigned int height = RobotInfo::CameraResolutionY;
00206 for(unsigned int i = 0; i < RobotInfo::CameraResolutionX; i++) {
00207 float scaledHeight = (float)(*currImageProfile)[i] / MAX_INTENSITY;
00208 for(int j = height-1; j > height-scaledHeight-1; j--) {
00209 hist(i,j) = true;
00210 }
00211 }
00212 }
00213
00214 void ImageProfileOdometry::displayTranslationProfile() {
00215 static Sketch<bool> transDisp(visops::zeros(VRmixin::camSkS), "translationProfile", true);
00216
00217 transDisp = false;
00218
00219 int scaledValue;
00220 const unsigned int width = RobotInfo::CameraResolutionX;
00221 for(unsigned int bin = 0; bin < width; bin++) {
00222 scaledValue = translationProfile[bin];
00223 for(unsigned int j = width-1; j > width-scaledValue-1; j--) {
00224 transDisp(bin,j) = true;
00225 }
00226 }
00227 }
00228
00229 const float VisualOdometry::ANGULAR_RESOLUTION =
00230 RobotInfo::CameraResolutionX / (RobotInfo::CameraHorizFOV / M_PI * 180);