Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Modules/SensorBehaviorControl/MotionRecognition.cpp

Go to the documentation of this file.
00001 /**
00002 * @file MotionRecognition.cpp
00003 *
00004 * Implementation of class MotionRecognition
00005 *
00006 * @author <a href="mailto:ordyniak@informatik.hu-berlin.de">Sebastian Ordyniak</a>
00007 * @author <a href="mailto:richert@informatik.hu-berlin.de">Marten Richert</a>
00008 */
00009 
00010 #include "MotionRecognition.h"
00011 
00012 MotionRecognition::MotionRecognition(const SensorBehaviorControlInterfaces& interfaces)
00013 : SensorBehaviorControl(interfaces)
00014 {
00015   pixelDimensions = 
00016     Vector2<double>
00017     (
00018     sin(image.cameraInfo.openingAngleWidth / 2.0)*BRENNWEITE / 
00019     (image.cameraInfo.resolutionWidth / 2.0),
00020     sin(image.cameraInfo.openingAngleHeight / 2.0)*BRENNWEITE / 
00021     (image.cameraInfo.resolutionHeight / 2.0)
00022     );
00023   currentImage = 0;
00024   start = 1;
00025   imagesLeft = IMAGEBUFFERSIZE;
00026 }
00027 
00028 double MotionRecognition::getCameraZ(Vector2<double> angleYZ) {
00029   double ztranslation = cameraMatrix.translation.z;
00030   double back;
00031   back = - ztranslation /
00032       (cameraMatrix.rotation.c[0].z + cameraMatrix.rotation.c[1].z*sin(angleYZ.y) + cameraMatrix.rotation.c[2].z*sin(angleYZ.x));
00033   if (back < 0)
00034     back = DISTANCE_INFINITY;
00035   return back;
00036 }
00037 
00038 Vector2<double> MotionRecognition::getCoorInmm(Vector2<int> p) {
00039   return Vector2<double>(p.x*pixelDimensions.x,p.y*pixelDimensions.y);
00040 }
00041 
00042 Vector2<int> MotionRecognition::getCoorInPixel(Vector2<double> p) {
00043   return Vector2<int>((int)(p.x/pixelDimensions.x), (int)(p.y/pixelDimensions.y));
00044 }
00045 
00046 
00047 Vector2<int> MotionRecognition::getCenteredCoor(Vector2<int> p) {
00048   // zentrieren
00049   Vector2<int> back = Vector2<int>(p.x - image.cameraInfo.resolutionWidth / 2,
00050                     image.cameraInfo.resolutionHeight / 2 - p.y);
00051   return back;
00052 }
00053 
00054 
00055 int MotionRecognition::isDiff(Image& image1, Image& image2, Vector2<int> p1, Vector2<int> p2) {
00056   int diff = image1.image[p1.y][0][p1.x] - image2.image[p2.y][0][p2.x];
00057   if (diff > 50)
00058     return 1;
00059   return 0;
00060 }
00061 
00062 Vector2<double> MotionRecognition::getAngleYZ(Vector2<int> pCentered) {
00063   double angleY, angleZ;
00064   angleY = (double)pCentered.y / (image.cameraInfo.resolutionHeight / 2.0) * (image.cameraInfo.openingAngleHeight / 2.0);
00065   angleZ = -(double)pCentered.x / (image.cameraInfo.resolutionWidth / 2.0) * (image.cameraInfo.openingAngleWidth / 2.0);
00066   return Vector2<double>(angleY, angleZ);
00067 }
00068 
00069 Vector2<int> MotionRecognition::getPixelFlow(Vector2<double> pCenteredmm, double z, Vector3<double> cameraTranslation, Vector3<double> cameraRotation) {
00070   /** translationskoeffizienten */
00071   double tx_z = cameraTranslation.x/z;
00072   double ty_z = cameraTranslation.y/z;
00073   double tz_z = cameraTranslation.z/z;
00074 
00075   /** Brennweite der Kamera */
00076   double f = 2.18;
00077 
00078   /** rotationskoeffizenten*/
00079   double xy_f = pCenteredmm.x*(-pCenteredmm.y)/f;
00080   double xx_f_f = pCenteredmm.x*pCenteredmm.x/f+f;
00081   double yy_f_f = pCenteredmm.y*pCenteredmm.y/f+f;
00082 
00083   Vector2<double> back = Vector2<double>(0,0);
00084   back.x = (ty_z*f + tx_z*pCenteredmm.x + xy_f*cameraRotation.y - xx_f_f*cameraRotation.z + pCenteredmm.y*cameraRotation.x);
00085   back.y = (tz_z*f + tx_z*(-pCenteredmm.y) + yy_f_f*cameraRotation.y - xy_f*cameraRotation.z - pCenteredmm.x*cameraRotation.x);
00086   return getCoorInPixel(back);
00087 }
00088 
00089 Vector2<int> MotionRecognition::getNewPixelPos(Vector2<int> p, Vector3<double> cameraTranslation, Vector3<double> cameraRotation) {
00090   /** transformiere p in Kamerazentrierte */
00091   Vector2<int> cCentered = getCenteredCoor(p);
00092 
00093   /** transformiere in Grad */
00094   Vector2<double> angleYZ = getAngleYZ(cCentered);
00095   
00096   /** berechne z Koordinate der xy-Ebene */
00097   double cameraZ = getCameraZ(angleYZ);
00098   
00099   /** berechne Fluss in Pixeln */
00100   Vector2<int> back = getPixelFlow(getCoorInmm(cCentered), cameraZ, cameraTranslation, cameraRotation);
00101   return p + back;
00102 }
00103 
00104 Vector3<double> MotionRecognition::getCameraTranslation(Vector3<double> robotTranslation) {
00105   RotationMatrix rm = cameraMatrix.rotation;
00106   return rm.invert()*robotTranslation;
00107 }
00108 
00109 Vector3<double> MotionRecognition::getRobotTranslationForRotation(double robotRotationZ) {
00110   double d = cameraMatrix.translation.x;
00111   return Vector3<double>(cos(robotRotationZ)*d - d, sin(robotRotationZ)*d, 0); 
00112 }
00113 
00114 void MotionRecognition::drawPixelFlow(Vector3<double> cameraTranslation, Vector3<double> cameraRotation) {
00115   for (int x = 10;x <= image.cameraInfo.resolutionWidth - 10;x+=10) {
00116     for (int y = 10;y <= image.cameraInfo.resolutionHeight - 10;y+=10) {
00117       Vector2<int> p = Vector2<int>(x,y);
00118       Vector2<int> pt = getNewPixelPos(p, cameraTranslation, cameraRotation);
00119       LINE(sketch, p.x, p.y, pt.x, pt.y,1,1,Drawings::yellow);
00120       DOT(sketch, pt.x,pt.y, Drawings::red, Drawings::red);
00121     }
00122   }
00123 }
00124 
00125 int MotionRecognition::pixelInImage(Vector2<int> p) {
00126   if (p.x >= 0 && p.y >= 0 && p.x < image.cameraInfo.resolutionWidth && p.y < image.cameraInfo.resolutionHeight)
00127     return 1;
00128   return 0;
00129 }
00130 
00131 Vector3<double> MotionRecognition::getRobotTranslationFromOdometry() {
00132   Vector2<double> translationdiff = odometryData.translation - previousOdometry.translation;
00133   double rotation = odometryData.rotation - previousOdometry.rotation;
00134 
00135   Vector3<double> robotTranslation = Vector3<double>(translationdiff.x, translationdiff.y, 0) +
00136     getRobotTranslationForRotation(rotation);
00137   return robotTranslation;
00138 }
00139 
00140 Vector3<double> MotionRecognition::getRobotTranslationFromBounce(double bounce) {
00141   return Vector3<double>(0,0,0);
00142 }
00143 
00144 Vector3<double> MotionRecognition::getRobotRotationFromOdometry() {
00145   return Vector3<double>(0,0, previousOdometry.rotation - odometryData.rotation);
00146 }
00147 
00148 Vector3<double> MotionRecognition::getRobotRotationFromBounce(double bounce) {
00149   return Vector3<double>(0,fromDegrees(bounce),0);
00150 }
00151 
00152 Vector3<double> MotionRecognition::getCameraTranslation(double bounce) {
00153   Vector3<double> robotTranslation = getRobotTranslationFromOdometry() + 
00154                   getRobotTranslationFromBounce(bounce);
00155   return getCameraTranslation(robotTranslation);
00156 }
00157 
00158 Vector3<double> MotionRecognition::getCameraRotation(double bounce) {
00159   Vector3<double> robotRotation = getRobotRotationFromOdometry() +
00160                   getRobotRotationFromBounce(bounce);
00161   return getCameraTranslation(robotRotation);
00162 }
00163 
00164 double MotionRecognition::getPixelDiff(Vector2<int> raster, double bounce, Image& image1, Image& image2, int draw) {
00165   Vector3<double> cameraTranslation = getCameraTranslation(bounce);
00166   Vector3<double> cameraRotation = getCameraRotation(bounce);
00167 
00168   int diffSum = 0;
00169   int countPixel = 0;
00170   for (int x = 0;x < image.cameraInfo.resolutionWidth;x+=raster.x) {
00171     for (int y = 0;y < image.cameraInfo.resolutionHeight;y+=raster.y) {
00172       Vector2<int> p = Vector2<int>(x,y);
00173       Vector2<int> pt = getNewPixelPos(p, cameraTranslation, cameraRotation);
00174       if (pixelInImage(pt)) {
00175         countPixel++;
00176         if (isDiff(image1, image2, p, pt)) {
00177           diffSum++;
00178           if (draw)
00179             motionRecognitionImage.image[pt.y][0][pt.x] = 200;
00180         }
00181       }
00182       if (draw) {
00183         if (isDiff(image1, image2, p, p))
00184           processorGradientsImage.image[p.y][0][p.x] = 200;
00185       }
00186     }
00187   }
00188   return (double)diffSum / (double)countPixel;
00189 }
00190 
00191 double MotionRecognition::getPixelDiff(Vector2<int> raster, double bounce, Image& image1, Image& image2) {
00192   return getPixelDiff(raster, bounce, image1, image2, 0);
00193 }
00194 
00195 void MotionRecognition::drawDynamicDiff(Image& image1, Image& image2, double timeDiff) {
00196   
00197   motionRecognitionImage = image2;
00198     int x;
00199   for (x = 0;x < image.cameraInfo.resolutionWidth;x++) {
00200     for (int y = 0;y < image.cameraInfo.resolutionHeight;y++) {
00201       motionRecognitionImage.image[y][0][x] = 0;
00202     }
00203   }
00204   processorGradientsImage = image2;
00205   for (x = 0;x < image.cameraInfo.resolutionWidth;x++) {
00206     for (int y = 0;y < image.cameraInfo.resolutionHeight;y++) {
00207       processorGradientsImage.image[y][0][x] = 0;
00208     }
00209   }
00210   double minDiff = 65000;
00211   int minIndex = 0;
00212   int z;
00213   for (z = -15;z <=15;z+=5) {
00214     double relDiffSum = getPixelDiff(Vector2<int>(4,1), (z / 3.0), image1, image2);
00215     if (relDiffSum < minDiff) {
00216       minDiff = relDiffSum;minIndex = z;
00217     }
00218   }
00219   
00220   minDiff = 65000;
00221   int fastIndex = minIndex;
00222   for (z = fastIndex-3;z <=fastIndex+3;z++) {
00223     double relDiffSum = getPixelDiff(Vector2<int>(1,1), (z / 3.0), image1, image2);
00224     if (relDiffSum < minDiff) {
00225       minDiff = relDiffSum;minIndex = z;
00226     }
00227   }
00228   
00229   getPixelDiff(Vector2<int>(1,1), (minIndex / 3.0), image1, image2, 1);
00230   INIT_DEBUG_IMAGE(imageMotionRecognition, motionRecognitionImage);
00231   SEND_DEBUG_IMAGE(imageMotionRecognition);
00232   INIT_DEBUG_IMAGE(imageProcessorGradients, processorGradientsImage);
00233   SEND_DEBUG_IMAGE(imageProcessorGradients);
00234 
00235   drawPixelFlow(getCameraTranslation((minIndex / 3.0)),getCameraRotation((minIndex / 3.0)));
00236 }
00237 
00238 void MotionRecognition::execute()
00239 {
00240   if (start) {
00241     start = 0;
00242     headControlMode.headControlMode = HeadControlMode::lookStraightAhead;
00243     motionRequest.motionType = MotionRequest::getup;
00244   } else {
00245     imageBuffer[currentImage] = image;
00246     imageTimes[currentImage] = SystemCall::getCurrentSystemTime();
00247     if (!imagesLeft) {
00248       int prevImage = currentImage - 1;
00249       if (prevImage < 0)
00250         prevImage = IMAGEBUFFERSIZE - 1;
00251       drawDynamicDiff(imageBuffer[prevImage], imageBuffer[currentImage], (imageTimes[currentImage] - imageTimes[prevImage]) / 1000.0);
00252     }
00253     else
00254       imagesLeft--;
00255     ++currentImage %= (IMAGEBUFFERSIZE);
00256   }
00257 
00258   previousOdometry = odometryData;
00259   DEBUG_DRAWING_FINISHED(sketch);
00260 }
00261 
00262 bool MotionRecognition::handleMessage(InMessage& message)
00263 {
00264   bool handled = true;
00265   return handled;
00266 }
00267 
00268 /*
00269 * Change log :
00270 * 
00271 * $Log: MotionRecognition.cpp,v $
00272 * Revision 1.1.1.1  2004/05/22 17:20:52  cvsadm
00273 * created new repository GT2004_WM
00274 *
00275 * Revision 1.17  2004/03/08 02:11:49  roefer
00276 * Interfaces should be const
00277 *
00278 * Revision 1.16  2004/01/10 17:03:09  roefer
00279 * Warnings removed
00280 *
00281 * Revision 1.15  2004/01/07 17:16:00  ordyniak
00282 * debugimages angepasst
00283 *
00284 * Revision 1.14  2004/01/07 16:53:41  ordyniak
00285 * umgestellt auf odometrydata für logfiles
00286 *
00287 * Revision 1.13  2004/01/07 14:26:40  richert
00288 * no message
00289 *
00290 * Revision 1.12  2004/01/07 09:54:42  schumann
00291 * corrected misdeclaration of variable z and removed compiler error in _GT2004
00292 *
00293 * Revision 1.11  2004/01/07 04:35:34  richert
00294 * bugfix
00295 *
00296 * Revision 1.10  2004/01/07 04:09:44  richert
00297 * added HeadControlMode "direct"
00298 *
00299 * Revision 1.9  2004/01/04 10:10:27  juengel
00300 * Errors and warnings removed.
00301 *
00302 * Revision 1.8  2004/01/03 23:12:51  ordyniak
00303 * new concept
00304 *
00305 * Revision 1.7  2003/12/31 23:50:38  roefer
00306 * Removed inclusion of RobotDimensions.h because it is not used
00307 *
00308 * Revision 1.6  2003/12/30 20:12:03  roefer
00309 * Image size is now 208 x 160. Smaller images are placed in the upper left corner
00310 *
00311 * Revision 1.5  2003/12/26 19:58:58  richert
00312 * better angel for horizon (hardcoded)
00313 *
00314 * Revision 1.4  2003/12/26 00:53:08  ordyniak
00315 * z bewegung
00316 *
00317 * Revision 1.3  2003/12/16 19:43:06  roefer
00318 * Warnings removed
00319 *
00320 * Revision 1.2  2003/12/12 17:21:13  richert
00321 * the beginning of a new solution: MotionRegcognition
00322 *
00323 *
00324 *
00325 */

Generated on Thu Sep 23 19:57:32 2004 for GT2004 by doxygen 1.3.6