00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include<iostream>
00019 #include<vector>
00020 #include<iomanip>
00021 #include<fstream>
00022 #include<cmath>
00023 #include<boost/numeric/ublas/vector.hpp>
00024 #include "uvsim/guidance/GeoCoord.h"
00025
00026
00027 namespace uvsim
00028 {
00029
00030 GeoCoord::GeoCoord()
00031 {
00032 }
00033 GeoCoord::~GeoCoord()
00034 {
00035 }
00036 GeoCoord::GeoCoord(double latitude, double longitude, double altitude)
00037 {
00038
00039 setGeoCoord(latitude, longitude, altitude);
00040 }
00041
00042 void GeoCoord::setGeoCoord (double latitude, double longitude, double altitude)
00043 {
00044 m_Latitude = latitude;
00045 m_Longitude = longitude;
00046 m_Altitude = altitude;
00047 }
00048
00049 std::ostream& operator<< (std::ostream &out, GeoCoord &geoCoord)
00050 {
00051 std::cout << std::fixed << std::setprecision(3) << std::setfill('0') << std::setw(7) << geoCoord.m_Latitude
00052 << " " << std::setw(7) << geoCoord.m_Longitude << " " << std::setw(7)
00053 << geoCoord.m_Altitude << std::endl;
00054 return out;
00055 }
00056
00057 void GeoCoord::print()
00058 {
00059 std::cout << m_Latitude << std::setw(16)
00060 << m_Longitude << std::setw(15)
00061 << m_Altitude << std::endl;
00062 }
00063
00064 vector<double> GeoCoord::getCartesian()
00065 {
00066
00067 vector<double> cartesian(3);
00068 double const earthSemiMajorAxis = 6378137;
00069 double const recipFlattening = 1 / 298.257223563;
00070 double eccentSquared = 2 * recipFlattening - pow(recipFlattening,2);
00071 double chi;
00072 chi = sqrt(1 - eccentSquared * pow((sin(m_Latitude * M_PI / 180)),2));
00073 cartesian[0] = (earthSemiMajorAxis / chi + m_Altitude)
00074 * cos(m_Latitude * M_PI / 180) * cos(m_Longitude * M_PI / 180);
00075 cartesian[1] = (earthSemiMajorAxis / chi + m_Altitude)
00076 * cos(m_Latitude * M_PI / 180) * sin(m_Longitude * M_PI / 180);
00077 cartesian[2] = (earthSemiMajorAxis * (1 - eccentSquared) / chi + m_Altitude)
00078 * sin(m_Latitude * M_PI / 180);
00079
00080 return (cartesian);
00081 }
00082
00083 void GeoCoord::getGeoCoord(double cartesianX, double cartesianY, double cartesianZ)
00084 {
00085
00086 double earthSemiMajorAxis = 6378137;
00087 double recipFlattening = 1 / 298.257223563;
00088 double earthSemiMinorAxis = earthSemiMajorAxis * (1 - recipFlattening);
00089
00090 double eccentSquared = 2 * recipFlattening - pow(recipFlattening,2);
00091 double eccent2Squared = recipFlattening * (2 - recipFlattening) / (pow((1 - recipFlattening), 2));
00092
00093 double r2 = pow(cartesianX,2) + pow(cartesianY,2);
00094 double r = sqrt(r2);
00095 double E2 = pow(earthSemiMajorAxis,2) - pow(earthSemiMinorAxis,2);
00096 double F = 54 * pow(earthSemiMinorAxis,2) * pow(cartesianZ,2);
00097 double G = r2 + (1 - eccentSquared) * pow(cartesianZ,2) - eccentSquared * E2;
00098 double c = (eccentSquared * eccentSquared * F * r2) / (G * G * G);
00099 double s = pow((1 + c + sqrt(c * c + 2 * c)),1/3);
00100 double P = F / (3 * pow((s + 1 / s + 1),2) * G * G);
00101 double Q = sqrt(1 + 2 * eccentSquared * eccentSquared * P);
00102 double ro = -(eccentSquared * P * r) / (1 + Q) + sqrt((earthSemiMajorAxis * earthSemiMajorAxis / 2)
00103 * (1 + 1 / Q) - ((1 - eccentSquared) * P * pow(cartesianZ, 2)) / (Q * (1 + Q)) - P * r2/2);
00104 double tmp = pow((r - eccentSquared * ro), 2);
00105 double U = sqrt( tmp + pow(cartesianZ,2));
00106 double V = sqrt( tmp + (1 - eccentSquared) * pow(cartesianZ,2));
00107 double zo = (pow(earthSemiMinorAxis,2)*cartesianZ) / (earthSemiMajorAxis * V);
00108
00109 m_Altitude = U * (1 - pow(earthSemiMinorAxis,2) / (earthSemiMajorAxis * V));
00110 m_Latitude = atan((cartesianZ + eccent2Squared * zo) / r) * 180 / M_PI;
00111 m_Longitude = atan2(cartesianY,cartesianX) * 180 / M_PI;
00112 }
00113 }
00114
00115