00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00023 #include <cmath>
00024 #include <iostream>
00025
00026 #include "CoordinateConverter.h"
00027
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;
00045 float mHeight = 35;
00046 m_CellSize = 0.05;
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
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
00162 Vector3D THIS::sphericalPlaneToWorldCoordRad(float range, float h, float theta_rad, float phi_rad)
00163 {
00164 const float cos_phi = cos(phi_rad);
00165
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
00180
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
00221
00222
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