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

Representations/Perception/BallPercept.cpp

Go to the documentation of this file.
00001 /**
00002  * @file BallPercept.cpp
00003  *
00004  * Implementation of class BallPercept.
00005  *
00006  * @author <A href=mailto:roefer@tzi.de>Thomas Röfer</A>
00007  * @author <a href="mailto:juengel@informatik.hu-berlin.de">Matthias Juengel</a>
00008  * @author <a href="mailto:walter.nistico@uni-dortmund.de">Walter Nistico</a>
00009  */
00010 
00011 #include "BallPercept.h"
00012 #include <math.h>
00013 
00014 BallPercept& BallPercept::operator=(const BallPercept& other)
00015 {
00016   cameraInfo = other.cameraInfo;
00017   ballCenter = other.ballCenter;
00018   ballRadiusInPixel = other.ballRadiusInPixel;
00019   anglesToCenter = other.anglesToCenter;
00020   ballRadiusAsAngle = other.ballRadiusAsAngle;
00021   ballWasSeen = other.ballWasSeen;
00022   frameNumber = other.frameNumber;
00023   isCameraMatrixValid = other.isCameraMatrixValid;
00024   translationOfCamera = other.translationOfCamera;
00025   return *this;
00026 }
00027 
00028 void BallPercept::add(
00029   Vector2<double> anglesToCenter,
00030   double ballRadiusAsAngle,
00031   Vector3<double> translationOfCamera,
00032   bool isCameraMatrixValid
00033   )
00034 {  
00035   this->anglesToCenter = anglesToCenter;
00036   this->ballRadiusAsAngle = ballRadiusAsAngle;
00037   this->translationOfCamera = translationOfCamera;
00038   this->isCameraMatrixValid = isCameraMatrixValid;
00039   ballWasSeen = true;
00040 }
00041 
00042 void BallPercept::add(
00043   CameraInfo cameraInfo,
00044   Vector2<int> ballCenter,
00045   double ballRadiusInPixel,
00046   Vector2<double> anglesToCenter,
00047   double ballRadiusAsAngle,
00048   Vector3<double> translationOfCamera,
00049   bool isCameraMatrixValid
00050   )
00051 {
00052   this->cameraInfo = cameraInfo;
00053   this->ballCenter = ballCenter;
00054   this->ballRadiusInPixel = ballRadiusInPixel;
00055   this->anglesToCenter = anglesToCenter;
00056   this->ballRadiusAsAngle = ballRadiusAsAngle;
00057   this->translationOfCamera = translationOfCamera;
00058   this->isCameraMatrixValid = isCameraMatrixValid;
00059   ballWasSeen = true;
00060 }
00061 
00062 void BallPercept::getOffsetBearingBased(Vector2<double>& offset) const
00063 {
00064   double distanceBearingBased;
00065   if(anglesToCenter.y < 0)
00066   {
00067     distanceBearingBased = (translationOfCamera.z - ballRadius) / tan(-anglesToCenter.y);
00068   }
00069   else
00070   {
00071     distanceBearingBased = 10000;
00072   }
00073 
00074   offset.x = translationOfCamera.x + distanceBearingBased * cos(anglesToCenter.x);
00075   offset.y = translationOfCamera.y + distanceBearingBased * sin(anglesToCenter.x);
00076   checkOffset(offset);
00077 }
00078 
00079 void BallPercept::getOffsetIntrinsic(Vector2<double>& offset) const
00080 {
00081   double distanceSizeBased = Geometry::getDistanceBySize(
00082                                           cameraInfo,
00083                                           (int)ballRadius,
00084                                           ballRadiusInPixel,
00085                                           ballCenter.x,
00086                                           ballCenter.y
00087                                           );
00088   //~ offset.x = translationOfCamera.x + distanceSizeBased * cos(anglesToCenter.x);
00089   //~ offset.y = translationOfCamera.y + distanceSizeBased * sin(anglesToCenter.x);
00090   double distanceFromCameraToBallCenterOnGround;
00091 
00092   if(distanceSizeBased > fabs(translationOfCamera.z - ballRadius))
00093   {
00094     distanceFromCameraToBallCenterOnGround = sqrt(sqr(distanceSizeBased) - sqr(translationOfCamera.z  - ballRadius));
00095   }
00096   else
00097   {
00098     distanceFromCameraToBallCenterOnGround = 0;
00099   }
00100 
00101   offset.x = translationOfCamera.x + distanceFromCameraToBallCenterOnGround * cos(anglesToCenter.x);
00102   offset.y = translationOfCamera.y + distanceFromCameraToBallCenterOnGround * sin(anglesToCenter.x);
00103   checkOffset(offset);
00104 }
00105 
00106 void BallPercept::getOffsetSizeBased(Vector2<double>& offset) const
00107 {
00108   double distanceFromCameraToBallCenter = 
00109     Geometry::getBallDistanceByAngleSize(int(2 * ballRadius), 2 * ballRadiusAsAngle);
00110 
00111   double distanceFromCameraToBallCenterOnGround;
00112 
00113   if(distanceFromCameraToBallCenter > fabs(translationOfCamera.z - ballRadius))
00114   {
00115     distanceFromCameraToBallCenterOnGround = sqrt(sqr(distanceFromCameraToBallCenter) - sqr(translationOfCamera.z  - ballRadius));
00116   }
00117   else
00118   {
00119     distanceFromCameraToBallCenterOnGround = 0;
00120   }
00121 
00122   offset.x = translationOfCamera.x + distanceFromCameraToBallCenterOnGround * cos(anglesToCenter.x);
00123   offset.y = translationOfCamera.y + distanceFromCameraToBallCenterOnGround * sin(anglesToCenter.x);
00124   checkOffset(offset);
00125 }
00126 
00127 void BallPercept::getOffset(Vector2<double>& offset) const
00128 {
00129   if(!isCameraMatrixValid || anglesToCenter.y >= 0 || (getDistanceSizeBased() > 300.0)) 
00130     getOffsetSizeBased(offset);
00131   else if (getDistanceSizeBased() > 200.0)
00132   {
00133     //interpolate between both offsets
00134     double factor = (300.0 - getDistanceSizeBased()) / 100.0;
00135     Vector2<double> offsetSize, offsetBearing;
00136     getOffsetSizeBased(offsetSize);
00137     getOffsetBearingBased(offsetBearing);
00138     offset = offsetBearing * factor + offsetSize * (1.0 - factor);
00139   }
00140   else 
00141     getOffsetBearingBased(offset);
00142 }
00143 
00144 double BallPercept::getDistance() const
00145 {
00146   Vector2<double> offset;
00147   getOffset(offset);
00148   return offset.abs();
00149 }
00150 
00151 double BallPercept::getAngle() const
00152 {
00153   Vector2<double> offset;
00154   getOffset(offset);
00155   return offset.angle();
00156 }
00157 
00158 double BallPercept::getDistanceBearingBased() const
00159 {
00160   Vector2<double> offset;
00161   getOffsetBearingBased(offset);
00162   return offset.abs();
00163 }
00164 
00165 double BallPercept::getDistanceSizeBased() const
00166 {
00167   Vector2<double> offset;
00168   getOffsetSizeBased(offset);
00169   return offset.abs();
00170 }
00171 
00172 double BallPercept::getAngleBearingBased() const
00173 {
00174   Vector2<double> offset;
00175   getOffsetBearingBased(offset);
00176   return offset.angle();
00177 }
00178 
00179 double BallPercept::getAngleSizeBased() const
00180 {
00181   Vector2<double> offset;
00182   getOffsetSizeBased(offset);
00183   return offset.angle();
00184 }
00185 
00186 double BallPercept::getDistanceIntrinsicBased() const
00187 {
00188   Vector2<double> offset;
00189   getOffsetIntrinsic(offset);
00190   return offset.abs();
00191 }
00192 
00193 double BallPercept::getAngleIntrinsicBased() const
00194 {
00195   Vector2<double> offset;
00196   getOffsetIntrinsic(offset);
00197   return offset.angle();
00198 }
00199 
00200 In& operator>>(In& stream,BallPercept& ballPercept)
00201 {
00202   int temp;
00203   stream >> ballPercept.ballCenter;
00204   stream >> ballPercept.ballRadiusInPixel;
00205   stream >> ballPercept.cameraInfo;
00206   stream >> ballPercept.anglesToCenter.x;
00207   stream >> ballPercept.anglesToCenter.y;
00208   stream >> ballPercept.ballRadiusAsAngle;
00209   stream >> ballPercept.translationOfCamera.x;
00210   stream >> ballPercept.translationOfCamera.y;
00211   stream >> ballPercept.translationOfCamera.z;
00212   stream >> temp;
00213   ballPercept.ballWasSeen = (temp != 0);
00214   stream >> ballPercept.frameNumber;
00215   stream >> temp;
00216   ballPercept.isCameraMatrixValid = (temp != 0);
00217   return stream;
00218 }
00219  
00220 Out& operator<<(Out& stream, const BallPercept& ballPercept)
00221 {
00222   stream << ballPercept.ballCenter;
00223   stream << ballPercept.ballRadiusInPixel;
00224   stream << ballPercept.cameraInfo;
00225   stream << ballPercept.anglesToCenter.x;
00226   stream << ballPercept.anglesToCenter.y;
00227   stream << ballPercept.ballRadiusAsAngle;
00228   stream << ballPercept.translationOfCamera.x;
00229   stream << ballPercept.translationOfCamera.y;
00230   stream << ballPercept.translationOfCamera.z;
00231   stream << ballPercept.ballWasSeen;
00232   stream << ballPercept.frameNumber;
00233   stream << ballPercept.isCameraMatrixValid;
00234   return stream;
00235 }
00236 
00237 
00238 /*
00239  * Change log :
00240  * 
00241  * $Log: BallPercept.cpp,v $
00242  * Revision 1.7  2004/06/14 23:20:07  spranger
00243  * -changed some functions in Geometry from int to double including ballradius(fieldimensions)
00244  * -maybe all Geometric-functions in Geometry should be as precise as possible, avoiding int to double conversion errors
00245  *
00246  * Revision 1.6  2004/06/14 22:38:17  risler
00247  * getOffset interpolates betweeen size and bearing based percepts
00248  *
00249  * Revision 1.5  2004/06/11 14:30:39  mkunz
00250  * use bearing based calculations only if ball is very near
00251  *
00252  * Revision 1.4  2004/06/05 18:36:04  nistico
00253  * Cleanup
00254  *
00255  * Revision 1.3  2004/06/04 21:35:10  juengel
00256  * Added getBallDistanceByAngleSize.
00257  *
00258  * Revision 1.2  2004/05/22 22:52:02  juengel
00259  * Renamed ballP_osition to ballModel.
00260  *
00261  * Revision 1.1.1.1  2004/05/22 17:25:31  cvsadm
00262  * created new repository GT2004_WM
00263  *
00264  * Revision 1.11  2004/04/08 15:33:08  wachter
00265  * GT04 checkin of Microsoft-Hellounds
00266  *
00267  * Revision 1.11  2004/03/25 15:12:59  nistico
00268  * Ball detection improved in MSH2004ImageProcessor
00269  * Ball distance measurement stabilized in MSH2004BallLocator (NOTE: to work with RIP, a small change has to be done in RIP code, just ask me...)
00270  * Fixed bugs with visualization of percepts (using intrinsic camera parameter based measurements)
00271  *
00272  * Revision 1.10  2004/02/10 10:48:04  nistico
00273  * Introduced Intrinsic camera parameters to perform geometric calculations (distance, angle, size...) without opening angle
00274  * Implemented radial distortion correction function
00275  * Implemented ball distance calculation based on size and intrinsic params (potentially more stable)
00276  * To Be Done: calculate intrinsic params for ERS7, as soon as we get our puppies back
00277  *
00278  * Revision 1.9  2003/12/29 20:57:56  roefer
00279  * Removed crash
00280  *
00281  * Revision 1.8  2003/12/18 14:55:24  schumann
00282  * removed crash that occured about every 10th boot:
00283  *   if(distanceFromCameraToBallCenter > translationOfCamera.z - ballRadius)
00284  *   {
00285  *     distanceFromCameraToBallCenterOnGround = sqrt(sqr(distanceFromCameraToBallCenter) - sqr(translationOfCamera.z  - ballRadius));
00286  * [...]
00287  * Case:
00288  * distanceFromCameraToBallCenter=10
00289  * translationOfCamera.z=0
00290  * ballRadius=40
00291  * condition is assumed as true
00292  * Problem:
00293  * distanceFromCameraToBallCenterOnGround = sqrt(sqr(10) - sqr(-42));
00294  * instruction tries to get a square root of a negative number ==> CRASH
00295  *
00296  * Revision 1.7  2003/12/15 11:46:13  juengel
00297  * Introduced CameraInfo
00298  *
00299  * Revision 1.6  2003/11/16 14:43:57  goehring
00300  * getBallDistance and Angle methods for size- and bearing  added
00301  *
00302  * Revision 1.5  2003/11/15 17:58:45  juengel
00303  * implemented getOffset
00304  *
00305  * Revision 1.4  2003/11/15 17:09:02  juengel
00306  * changed BallPercept
00307  *
00308  * Revision 1.3  2003/11/12 16:19:35  goehring
00309  * frameNumber added to percepts
00310  *
00311  * Revision 1.2  2003/11/05 16:34:28  goehring
00312  * FrameNumber added
00313  *
00314  * Revision 1.1  2003/10/07 10:09:35  cvsadm
00315  * Created GT2004 (M.J.)
00316  *
00317  * Revision 1.1.1.1  2003/07/02 09:40:22  cvsadm
00318  * created new repository for the competitions in Padova from the 
00319  * tamara CVS (Tuesday 2:00 pm)
00320  *
00321  * removed unused solutions
00322  *
00323  * Revision 1.3  2003/04/16 06:58:06  roefer
00324  * Balls are sorted by size
00325  *
00326  * Revision 1.3  2003/04/12 06:29:34  roefer
00327  * Less balls and position improved
00328  *
00329  * Revision 1.2  2002/09/17 23:55:20  loetzsch
00330  * - unraveled several datatypes
00331  * - changed the WATCH macro
00332  * - completed the process restructuring
00333  *
00334  * Revision 1.1  2002/09/10 15:26:40  cvsadm
00335  * Created new project GT2003 (M.L.)
00336  * - Cleaned up the /Src/DataTypes directory
00337  * - Removed Challenge Code
00338  * - Removed processing of incoming audio data
00339  * - Renamed AcousticMessage to SoundRequest
00340  *
00341  * Revision 1.1.1.1  2002/05/10 12:40:13  cvsadm
00342  * Moved GT2002 Project from ute to tamara.
00343  *
00344  * Revision 1.9  2002/04/25 20:29:57  roefer
00345  * New BallPercept and BallP_osition, GTMath errors in SimGT2002 fixed
00346  *
00347  * Revision 1.8  2002/02/11 11:19:56  roefer
00348  * no message
00349  *
00350  * Revision 1.7  2002/02/11 11:13:06  roefer
00351  * BallPerceptor and BallLocator inserted
00352  *
00353  * Revision 1.6  2002/02/05 03:30:52  loetzsch
00354  * replaced direct member access by
00355  * inline const VALUE& get...() const   and
00356  * inline void set...(const Value&) methods.
00357  *
00358  * Revision 1.5  2002/01/22 00:06:55  loetzsch
00359  * In den Get...() Funktionen wurden die Parameter nicht als Referenz übergeben,
00360  * geändert
00361  *
00362  * Revision 1.4  2002/01/11 23:50:55  xiang
00363  * BallPercept von Hong & Lang
00364  *
00365  * Revision 1.3  2001/12/10 17:47:05  risler
00366  * change log added
00367  *
00368  */
00369 

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