CoordinateConverter.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *  CoordinateConverter.cpp
00003  *
00004  *  (C) 2006 AG Aktives Sehen <agas@uni-koblenz.de>
00005  *           Universitaet Koblenz-Landau
00006  *
00007  *  $Id: CoordinateConverter.cpp 44313 2011-04-06 22:46:28Z agas $
00008  ******************************************************************************/
00009 
00010 
00023 #include <cmath>
00024 #include <iostream>
00025 
00026 #include "CoordinateConverter.h"
00027 //#include "Architecture/Config/Config.h"
00028 
00029 #define THIS CoordinateConverter
00030 
00031 using namespace std;
00032 
00033 THIS* THIS::m_Instance = 0;
00034 
00035 THIS* THIS::getInstance() {
00036   if(m_Instance == 0){
00037     m_Instance = new THIS();
00038   }
00039   return m_Instance;
00040 }
00041 
00042 
00043 THIS::THIS() {
00044   float mWidth = 35;//Config::getInt("Map.iSize");
00045   float mHeight = 35;//Config::getInt("Map.iSize");
00046   m_CellSize = 0.05;//Config::getInt("Map.iCellSize");
00047 
00048 
00049   m_MapWidth = mWidth / m_CellSize + 1;
00050   m_MapHeight = mHeight / m_CellSize + 1;
00051   m_MapHalfWidth = m_MapWidth / 2;
00052   m_MapHalfHeight = m_MapHeight / 2;
00053 }
00054 
00055 
00056 THIS::~THIS() {
00057 }
00058 
00059 
00063 
00064 
00065 Point2D THIS::robotToWorld(Pose robotPose, Point2D robotPoint) {
00066   float sinTheta = sin(robotPose.theta());
00067   float cosTheta = cos(robotPose.theta());
00068   float x = cosTheta * robotPoint.x() - sinTheta * robotPoint.y() + robotPose.x();
00069   float y = sinTheta * robotPoint.x() + cosTheta * robotPoint.y() + robotPose.y();
00070   return Point2D(x, y);
00071 }
00072 
00073 Pose THIS::robotToWorld( Pose robotPose, Pose pose) {
00074 
00075   Point2D newPose = robotToWorld ( robotPose, Point2D(pose.x(), pose.y()) );
00076 
00077   double angle = robotPose.theta() + pose.theta();
00078   while(angle > M_PI){
00079     angle -= 2*M_PI;
00080   }
00081   while(angle < -M_PI){
00082     angle += 2*M_PI;
00083   }
00084 
00085   return Pose(newPose.x(), newPose.y(), angle);
00086 }
00087 
00088 Transformation2D THIS::robotToWorld(Pose robotPose, Transformation2D transformation) {
00089   float sinTheta = sin(robotPose.theta());
00090   float cosTheta = cos(robotPose.theta());
00091   float x = cosTheta * transformation.x() - sinTheta * transformation.y();
00092   float y = sinTheta * transformation.x() + cosTheta * transformation.y();
00093   return Transformation2D(x, y, transformation.theta());
00094 }
00095 
00096 Point2D THIS::worldToRobot(Pose robotPose, Point2D worldPoint) {
00097   float sinTheta = sin(-robotPose.theta());
00098   float cosTheta = cos(-robotPose.theta());
00099   float x = cosTheta * (worldPoint.x() - robotPose.x()) - sinTheta * (worldPoint.y() - robotPose.y());
00100   float y = sinTheta * (worldPoint.x() - robotPose.x()) + cosTheta * (worldPoint.y() - robotPose.y());
00101   return Point2D(x, y);
00102 }
00103 
00104 Transformation2D THIS::worldToRobot(Pose robotPose, Transformation2D transformation) {
00105   float sinTheta = sin(-robotPose.theta());
00106   float cosTheta = cos(-robotPose.theta());
00107   float x = cosTheta * (transformation.x() - robotPose.x()) - sinTheta * (transformation.y() - robotPose.y());
00108   float y = sinTheta * (transformation.x() - robotPose.x()) + cosTheta * (transformation.y() - robotPose.y());
00109   return Transformation2D(x, y, transformation.theta());
00110 }
00111 
00112 Pixel THIS::worldToMap(Point2D worldPoint) {
00113   int pixelX = m_MapHalfWidth - (worldPoint.y()/m_CellSize+0.5);
00114   int pixelY = m_MapHalfHeight - (worldPoint.x()/m_CellSize+0.5);
00115   if (pixelX < 0 || pixelX >= m_MapWidth || pixelY < 0 || pixelY >= m_MapHeight) {
00116     if ( pixelX < 0 ) { pixelX=0; }
00117     if ( pixelX >= m_MapWidth ) { pixelX=m_MapWidth-1; }
00118     if ( pixelY < 0 ) { pixelY=0; }
00119     if ( pixelY >= m_MapHeight ) { pixelY=m_MapHeight-1; }
00120   }
00121   return Pixel(pixelX, pixelY);
00122 }
00123 
00124 Point2D THIS::worldToMapPoint(Point2D worldPoint) {
00125   double pixelX = double(m_MapHalfWidth) - (worldPoint.y()/double(m_CellSize)+0.5);
00126   double pixelY = double(m_MapHalfHeight) - (worldPoint.x()/double(m_CellSize)+0.5);
00127   if (pixelX < 0 || pixelX >= m_MapWidth || pixelY < 0 || pixelY >= m_MapHeight) {
00128     if ( pixelX < 0 ) { pixelX=0; }
00129     if ( pixelX >= m_MapWidth ) { pixelX=m_MapWidth-1; }
00130     if ( pixelY < 0 ) { pixelY=0; }
00131     if ( pixelY >= m_MapHeight ) { pixelY=m_MapHeight-1; }
00132   }
00133   return Point2D(pixelX, pixelY);
00134 }
00135 
00136 void THIS::worldToMap(float worldX, float worldY, int& mapX, int& mapY) {
00137   Pixel mapPixel = worldToMap(Point2D(worldX, worldY));
00138   mapX = mapPixel.x();
00139   mapY = mapPixel.y();
00140 }
00141 
00142 Pixel THIS::worldToMap(Pose worldPose) {
00143   return worldToMap(Point2D(worldPose.x(), worldPose.y()));
00144 }
00145 
00146 Point2D THIS::mapToWorld(Pixel mapPoint) {
00147   float worldX = (float(m_MapHalfHeight) - 0.5 - float(mapPoint.y())) * float(m_CellSize);
00148   float worldY = (float(m_MapHalfWidth) - 0.5 - float(mapPoint.x())) * float(m_CellSize);
00149   return Point2D(worldX, worldY);
00150 }
00151 
00152 
00153 // spherical to cartesian
00154 Vector3D THIS::sphericalToCartesian(float range, float phi, float theta){
00155   float x = range * sin(phi) * cos(theta);
00156   float y = range * sin(phi) * sin(theta);
00157   float z = range * cos(phi);
00158   return Vector3D(x, y, z);
00159 }
00160 
00161 // spherical plane to world coordinate
00162 Vector3D THIS::sphericalPlaneToWorldCoordRad(float range, float h, float theta_rad, float phi_rad)
00163 {
00164     const float cos_phi = cos(phi_rad);
00165     // alpha = theta - 90 degree (theta = 0, alpha = -90; theta = 90, alpha = 0; theta = 180, alpha = 90)
00166     const float difference = 90.0*M_PI/180.0;
00167     const float alpha = theta_rad-difference;
00168 
00169     float x = range * cos(alpha) * cos_phi + h * cos(theta_rad);
00170     float y = range * sin(phi_rad);
00171     float z = range * sin(alpha) * cos_phi + h * sin(theta_rad);
00172   return Vector3D( x, y, z );
00173 }
00174 
00175 Vector3D THIS::simLaser3DToLaser3D(float alpha, float beta, float range){
00176   return sphericalToCartesian(range, (M_PI/2.0 + beta), alpha);
00177 }
00178 
00179 // computes the worldpoints itself and does not call robotToWorld(Pose, Point2D)
00180 // to avoid multiple computation of sin(theta) and cos(theta)
00181 vector<Point2D> THIS::robotToWorld(Pose robotPose, const vector<Point2D>& robotPoints) {
00182   float sinTheta = sin(robotPose.theta());
00183   float cosTheta = cos(robotPose.theta());
00184   vector<Point2D> worldPoints( robotPoints.size() );
00185   for (unsigned int i = 0; i < robotPoints.size(); i++) {
00186     float x = cosTheta * robotPoints[i].x() - sinTheta * robotPoints[i].y() + robotPose.x();
00187     float y = sinTheta * robotPoints[i].x() + cosTheta * robotPoints[i].y() + robotPose.y();
00188     worldPoints[i].setX( x );
00189     worldPoints[i].setY( y );
00190   }
00191   return worldPoints;
00192 }
00193 
00194 vector<Pixel> THIS::worldToMap( const vector<Point2D>& worldPoints ) {
00195   vector<Pixel> ret( worldPoints.size() );
00196   for (unsigned int i = 0; i < worldPoints.size(); i++) {
00197     ret[i] = worldToMap(worldPoints[i]);
00198   }
00199   return ret;
00200 }
00201 
00202 vector<Point2D> THIS::mapToWorld( const vector<Pixel>& mapPoints ) {
00203   vector<Point2D> ret( mapPoints.size() );
00204   for (unsigned int i = 0; i < mapPoints.size(); i++) {
00205     ret[i]= mapToWorld( mapPoints[i] );
00206   }
00207   return ret;
00208 }
00209 
00210 vector<Vector3D> THIS::simLaser3DToLaser3D(float fovH, float fovV, float resH, float resV, vector<float> *range){
00211   vector<Vector3D> ret;
00212   float index = 0;
00213   float angleH = 0;
00214   float angleV = 0;
00215   float deg2rad = 1.0/180.0 * M_PI;
00216   float stepH = fovH / resH;
00217   float stepV = fovV / resV;
00218   fovH = -1.0 * fovH/2.0;
00219   fovV = -1.0 * fovV/2.0;
00220   //cout<<"   Resolution: "<<resH<<"x"<<resV<<endl;
00221   //cout<<"          FOV: "<<fovH<<"x"<<fovV<<endl;
00222   //cout<<"         Step: "<<stepH<<"x"<<stepV<<endl;
00223   for (int v = 0; v<resV; v++){
00224       angleV = (fovV + (v * stepV)) * deg2rad;
00225       for (int h = 0; h<resH; h++){
00226         angleH = (fovH + (h * stepH)) * deg2rad;
00227         index = v*resH+h;
00228         if(index < range->size()) ret.push_back(simLaser3DToLaser3D(angleH, angleV, range->at(index)));
00229       }
00230   }
00231   return ret;
00232 }
00233 
00234 
00235 
00236 
00237 Pixel THIS::robotToMap(Pose robotPose, Point2D robotPoint) {
00238   return worldToMap(robotToWorld(robotPose, robotPoint));
00239 }
00240 
00241 vector<Pixel> THIS::robotToMap(Pose robotPose, const vector<Point2D>& robotPoints) {
00242   vector<Point2D> worldPoints = robotToWorld(robotPose, robotPoints);
00243   return worldToMap( worldPoints);
00244 }
00245 
00246 void THIS::robotToMap(float robotX, float robotY, float robotTheta, float pointX, float pointY, int& mapX, int& mapY) {
00247   Pixel pix = robotToMap(Pose(robotX, robotY, robotTheta), Point2D(pointX, pointY));
00248   mapX = pix.x();
00249   mapY = pix.y();
00250 }
00251 
00252 Point2D THIS::polarToCartesian(float theta, float distance) {
00253   float x = sin(theta) * distance;
00254   float y = cos(theta) * distance;
00255   return Point2D(x, y);
00256 }
00257 
00258 #undef THIS


obj_rec_gui
Author(s): AGAS/agas@uni-koblenz.de
autogenerated on Mon Oct 6 2014 02:53:43