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

Modules/SelfLocator/SpecialPerceptSelfLocator.cpp

Go to the documentation of this file.
00001 /**
00002  * @file Modules/SelfLocator/SpecialPerceptSelfLocator.cpp
00003  * 
00004  * This file contains a class for self-localization based on
00005  * special percepts, e.g. checkerboard percepts.
00006  *
00007  * @author <a href="mailto:dueffert@informatik.hu-berlin.de">Uwe Düffert</a>
00008  */
00009 
00010 #include "SpecialPerceptSelfLocator.h"
00011 #include "Tools/FieldDimensions.h"
00012 #include "Platform/SystemCall.h"
00013 #include <math.h>
00014 
00015 
00016 SpecialPerceptSelfLocator::SpecialPerceptSelfLocator(const SelfLocatorInterfaces& interfaces)
00017 : SelfLocator(interfaces),lastRobotPose(0,0,0),psdCrashCount(0),
00018 /*
00019 //6x6-Kalman:
00020 H(1,0,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0),
00021 A(1,0,0,1,0,0, 0,1,0,0,1,0, 0,0,1,0,0,1, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,1),
00022 P(1000,10,10,10,10,10,  10,1000,10,10,10,10,  10,10,1000,10,10,10,
00023   10,10,10,1000,10,10,  10,10,10,10,1000,10,  10,10,10,10,10,1000),
00024 R(10, 0.03, 0.03,   0.03, 20, 0.03,   0.03, 0.03, 5),
00025 K(1,0,0, 0,1,0, 0,0,1, 0,0,0, 0,0,0, 0,0,0)
00026 */
00027 /*
00028 //2x2-Kalman:
00029 H(1,0),
00030 A(Vector2<double>(1,1),Vector2<double>(0,1)),
00031 P(Vector2<double>(100,1),Vector2<double>(1,100)),
00032 R(10),
00033 K(1,0)
00034 */
00035 robotPosX (0.15, 0.25, 0.0, 0, -3600, 0, 100),
00036 robotPosY (0.15, 0.25, 0.0, 0, -yPosLeftFlags, yPosLeftFlags, 100),
00037 robotPosR(0.15, 0.25, 0.0, 0, -pi, pi, 1),
00038 lastFrame(0)
00039 {
00040 /*
00041   //quadratische Kurve:
00042   perceptPoseBuffer.init();
00043   perceptTimeBuffer.init();
00044 */
00045 }
00046 
00047 void SpecialPerceptSelfLocator::execute()
00048 {
00049   selfLocatorSamples.link(NULL, 0,0);
00050   Pose2D odometry = odometryData - lastOdometry;
00051   lastOdometry = odometryData;
00052   robotPose.setFrameNumber(specialPercept.frameNumber);
00053   static PIDsmoothedValue rspeed(0.1, 0.15, 0.0, 0, -3, 3, 100);
00054   
00055   if (specialPercept.type==SpecialPercept::checkerboard)
00056   {
00057     psdCrashCount=0;
00058     /*
00059     //6x6-Kalman:
00060     Vector3<double> z(specialPercept.checkerPose.translation.x,specialPercept.checkerPose.translation.y,specialPercept.checkerPose.rotation);
00061     static Matrix_6x1 x = K * z;
00062     
00063     //@todo: framediff * wiederholen ???:
00064     //@todo: Kalman dokumentieren, wie passt man bei Kalman R ordentlich an
00065     Matrix_6x1 xpre = A*x;
00066     Matrix_6x6 Ppre = A*P*A.transpose();
00067     
00068     K = Ppre * H.transpose() * (H * Ppre * H.transpose() * R).inverse();
00069     x = xpre + K * (z - (H * xpre));
00070     P = (Matrix_6x6() - (K * H)) * Ppre;
00071     */
00072     
00073     /*
00074     //2x2-Kalman nahezu:
00075     double z=specialPercept.checkerPose.translation.x;
00076     static Vector2<double> x = K * z;
00077     
00078     //@todo: framediff * wiederholen ???:
00079     //@todo: Kalman dokumentieren, wie passt man bei Kalman R ordentlich an
00080     Math::
00081       Vector2<double> xpre = (A*x);
00082     Matrix2x2<double> Ppre = A*P*A.transpose();
00083     
00084     K = Ppre * H.transpose() / (H * Ppre * H.transpose() * R);
00085     x = xpre + K * (z - (H * xpre));
00086     P = (Matrix2x2<double>(Vector2<double>(1-K.x*H.x,-K.y*H.x),Vector2<double>(1-K.x*H.y,-K.y*H.y))) * Ppre;
00087     */
00088     
00089     /*
00090     //quadratische Kurve:
00091     unsigned long time=specialPercept.frame; //SystemCall::getCurrentSystemTime();
00092     perceptTimeBuffer.add(time);
00093     perceptPoseBuffer.add(specialPercept.checkerPose);
00094     long tdiff=perceptTimeBuffer[0]-perceptTimeBuffer[perceptTimeBuffer.getNumberOfEntries()-1];
00095     
00096     if ((perceptTimeBuffer.getNumberOfEntries()>4)&&(tdiff<1000))
00097     {
00098       //some helping variables:
00099       double St0=0,St1=0,St2=0,St3=0,St4=0,Sx1=0,St1x1=0,St2x1=0,Sy1=0,St1y1=0,St2y1=0,Sr1=0,St1r1=0,St2r1=0;
00100       for (int i=0;i<perceptTimeBuffer.getNumberOfEntries();i++)
00101       {
00102         double t=perceptTimeBuffer[0]-perceptTimeBuffer[i];
00103         double x=perceptPoseBuffer[i].translation.x;
00104         double y=perceptPoseBuffer[i].translation.y;
00105         //rotation only works because robot is always facing forwards -> no -pi/pi jump
00106         double r=perceptPoseBuffer[i].rotation;
00107         St0 ++;
00108         St1 += t;
00109         St2 += t*t;
00110         St3 += t*t*t;
00111         St4 += t*t*t*t;
00112         
00113         Sx1 += x;
00114         St1x1 += t*x;
00115         St2x1 += t*t*x;
00116         
00117         Sy1 += y;
00118         St1y1 += t*y;
00119         St2y1 += t*t*y;
00120         
00121         Sr1 += r;
00122         St1r1 += t*r;
00123         St2r1 += t*t*r;
00124       }
00125       
00126       //approximate the t coordinates with quadratic equation f_x(t)=m_x*t^2+n_x*t+o_x, minimize square error, result (Mathematica):
00127       double divisor = (St0*St3*St3 + St1*St1*St4 - St2*(2*St1*St3 + St0*St4 - St2*St2));
00128       //double m_x = (St0*(St1x1*St3 - St2*St2x1) + St2*St2*Sx1 - St1*(St1x1*St2 + St3*Sx1 - St1*St2x1)) / divisor;
00129       //double n_x = (St2*(St1x1*St2 - St1*St2x1 - St3*Sx1) + St0*(St2x1*St3 - St1x1*St4) + St1*St4*Sx1) / divisor;
00130       double o_x = (St1*(St1x1*St4 - St2x1*St3) + St3*St3*Sx1 - St2*(St1x1*St3 + St4*Sx1 - St2*St2x1)) / divisor;
00131       //approximate the y coordinates with quadratic equation f_y(t)=m_y*t^2+n_y*t+o_y, minimize square error, result (Mathematica):
00132       //double m_y = (St0*(St1y1*St3 - St2*St2y1) + St2*St2*Sy1 - St1*(St1y1*St2 + St3*Sy1 - St1*St2y1)) / divisor;
00133       //double n_y = (St2*(St1y1*St2 - St1*St2y1 - St3*Sy1) + St0*(St2y1*St3 - St1y1*St4) + St1*St4*Sy1) / divisor;
00134       double o_y = (St1*(St1y1*St4 - St2y1*St3) + St3*St3*Sy1 - St2*(St1y1*St3 + St4*Sy1 - St2*St2y1)) / divisor;
00135       //approximate the rotation with quadratic equation f_r(t)=m_r*t^2+n_r*t+o_r, minimize square error, result (Mathematica):
00136       //double m_r = (St0*(St1r1*St3 - St2*St2r1) + St2*St2*Sr1 - St1*(St1r1*St2 + St3*Sr1 - St1*St2r1)) / divisor;
00137       //double n_r = (St2*(St1r1*St2 - St1*St2r1 - St3*Sr1) + St0*(St2r1*St3 - St1r1*St4) + St1*St4*Sr1) / divisor;
00138       double o_r = (St1*(St1r1*St4 - St2r1*St3) + St3*St3*Sr1 - St2*(St1r1*St3 + St4*Sr1 - St2*St2r1)) / divisor;
00139       
00140       //2do: Ausreisserfilter?
00141       
00142       //double t=time;
00143       //robotPose.translation.x = m_x*m_x*t+n_x*t+o_x;
00144       //robotPose.translation.y = m_y*m_y*t+n_y*t+o_y;
00145       //robotPose.rotation = m_r*m_r*t+n_r*t+o_r;
00146       robotPose.translation.x = o_x;
00147       robotPose.translation.y = o_y;
00148       robotPose.rotation = o_r;
00149       double validity = 1/
00150         (
00151         1+
00152         fabs(specialPercept.checkerPose.translation.x-robotPose.translation.x)/15+
00153         fabs(specialPercept.checkerPose.translation.y-robotPose.translation.y)/50+
00154         fabs(specialPercept.checkerPose.rotation-robotPose.rotation)/0.2
00155         );
00156       robotPose.setValidity(validity);
00157     }
00158     */
00159     
00160     //filter away single outliers
00161     lastWasOutlier = ((!lastWasOutlier)&&
00162       ((fabs(specialPercept.checkerPose.translation.x-robotPosX.getVal())>300)||
00163       (fabs(specialPercept.checkerPose.translation.y-robotPosY.getVal())>300)||
00164       (fabs(specialPercept.checkerPose.rotation-robotPosR.getVal())>0.4)));
00165 
00166     //PIDsmoothed:
00167     if (lastWasOutlier)
00168     {
00169       Pose2D pose = lastRobotPose + odometry;
00170       robotPose.translation=pose.translation;
00171       robotPose.rotation=pose.rotation;
00172       //dont modify validity here, we only misdetected for one single frame
00173     }
00174     else
00175     {
00176       if (specialPercept.frameNumber-lastFrame>=125)
00177       {
00178         robotPosX.resetTo(specialPercept.checkerPose.translation.x);
00179         robotPosY.resetTo(specialPercept.checkerPose.translation.y);
00180         robotPosR.resetTo(specialPercept.checkerPose.rotation);
00181         //2do: 25/30 according to robot type:
00182         rspeed.resetTo(30*odometry.rotation);
00183       }
00184       else
00185       {
00186         robotPosX.approximateVal(specialPercept.checkerPose.translation.x);
00187         robotPosY.approximateVal(specialPercept.checkerPose.translation.y);
00188         robotPosR.approximateVal(specialPercept.checkerPose.rotation);
00189       }
00190       robotPose.translation.x=robotPosX.getVal();
00191       robotPose.translation.y=robotPosY.getVal();
00192       robotPose.rotation=robotPosR.getVal();
00193       robotPose.setValidity(0.9);
00194       lastFrame=specialPercept.frameNumber;
00195     }
00196   }
00197   else
00198   {
00199     lastWasOutlier=false;
00200     if (psdPercept.numOfPercepts>0)
00201     {
00202       for (int i=0;i<psdPercept.numOfPercepts;i++)
00203       {
00204         if ((psdPercept[i].isValid)&&
00205             (!psdPercept[i].tooFarAway)&&
00206             (psdPercept[i].frameNumber>lastFrame)&&
00207             ((psdPercept[i].x)*(psdPercept[i].x)+(psdPercept[i].y)*(psdPercept[i].y)<=450*450)&&
00208             (psdPercept[i].z>130))
00209         {
00210           psdCrashCount++;
00211           //we can only crash into the wall if we are near to it. otherwise it is a measurement error due to stamping or noise
00212           if ((psdCrashCount>3)&&((robotPose.translation.x>-660)||(psdPercept[i].frameNumber-lastFrame>125)))
00213           {
00214             robotPose.translation.x=-400;
00215             robotPose.translation.y=0;
00216             robotPose.setValidity(0.05);
00217             //OUTPUT(idText,text, "psd < 450");
00218             return;
00219           }
00220         }
00221       }
00222       //OUTPUT(idText,text, "no checkerboard, psd: x=" << psdPercept[0].x << ", z=" << psdPercept[0].z);
00223     }
00224     //we use this approximation while measuring turning:
00225     robotPose = lastRobotPose + odometry;
00226     robotPose.setValidity(0.4);
00227   }
00228   
00229   //2do: 25/30 according to robot type:
00230   rspeed.approximateVal(30*(robotPose.rotation-lastRobotPose.rotation));
00231   robotPose.speedbyDistanceToGoal = rspeed.getVal();
00232 
00233   lastRobotPose.translation=robotPose.translation;
00234   lastRobotPose.rotation=robotPose.rotation;
00235 }
00236 
00237 /*
00238  * Change log :
00239  * 
00240  * $Log: SpecialPerceptSelfLocator.cpp,v $
00241  * Revision 1.2  2004/06/09 08:20:46  dueffert
00242  * some fine tuning
00243  *
00244  * Revision 1.1.1.1  2004/05/22 17:20:49  cvsadm
00245  * created new repository GT2004_WM
00246  *
00247  * Revision 1.15  2004/05/11 16:32:37  dueffert
00248  * psd crash detection improved
00249  *
00250  * Revision 1.14  2004/05/03 18:52:27  dueffert
00251  * comments corrected
00252  *
00253  * Revision 1.13  2004/03/29 15:31:13  dueffert
00254  * misdetection of near checkerboard corrected
00255  *
00256  * Revision 1.12  2004/03/26 09:22:22  dueffert
00257  * crash detection improved
00258  *
00259  * Revision 1.11  2004/03/19 09:20:48  dueffert
00260  * allow higher distance to checkerboard for 400mm/s-measurement
00261  *
00262  * Revision 1.10  2004/03/15 12:34:05  dueffert
00263  * cool filter for single outliers implemented
00264  *
00265  * Revision 1.9  2004/03/08 02:11:48  roefer
00266  * Interfaces should be const
00267  *
00268  * Revision 1.8  2004/02/29 13:42:30  dueffert
00269  * beautified
00270  *
00271  * Revision 1.7  2004/02/23 16:45:02  dueffert
00272  * ERS7 adaptions of evolution
00273  *
00274  * Revision 1.6  2004/01/20 16:20:03  dueffert
00275  * frameNumber handling corrected
00276  *
00277  * Revision 1.5  2004/01/16 15:47:51  dueffert
00278  * some improvements
00279  *
00280  * Revision 1.4  2003/11/14 19:02:26  goehring
00281  * frameNumber added
00282  *
00283  * Revision 1.3  2003/11/13 16:47:38  goehring
00284  * frameNumber added
00285  *
00286  * Revision 1.2  2003/11/10 13:34:07  dueffert
00287  * checkerboard localization improved
00288  *
00289  * Revision 1.3  2003/08/09 14:53:10  dueffert
00290  * files and docu beautified
00291  *
00292  * Revision 1.2  2003/07/30 14:47:46  dueffert
00293  * SpecialPerceptSelfLocator for Checkboard added
00294  *
00295  * Revision 1.1.1.1  2003/07/02 09:40:24  cvsadm
00296  * created new repository for the competitions in Padova from the 
00297  * tamara CVS (Tuesday 2:00 pm)
00298  *
00299  * removed unused solutions
00300  *
00301  * Revision 1.2  2003/05/21 13:36:20  brunn
00302  * set selfLocatorSamples to NULL as these locators do not have any samples
00303  *
00304  * Revision 1.1  2003/01/22 14:59:49  dueffert
00305  * checkerboard stuff added
00306  *
00307  *
00308  */

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