DEIMOS
Earth Observation Mission CFI Software
Usage Guide for Object Oriented Software
ESA

COORDINATE TRANSFORMATIONS

The Earth Observation CFI software provides the following classes in [LIB_SUM]for handling coordinate systems and object state vectors:

Together with these classes, the change method for the Attitude class (in Pointing Library) allows to transform between two reference frames, including satellite or instrument attitude CS. This CS change can include the translation between the frames or only the rotation. For more info about how to set the Attitude go to Attitude computation.

Example

// ------------------------------------------------------------------------
//
//                           C++ Example Program.
//                           COORDINATES
//
// ------------------------------------------------------------------------

// Non-EOCFI include files
#include <string>
#include <vector>
#include <iostream>

// EOCFI includes
#include "CfiError.h"
#include "LibData.h"
#include "TimeCorrelation.h"
#include "EETime.h"
#include "Coord.h"
#include "StateVector.h"
#include "Star.h"
#include "SatId.h"
#include "Geodetic.h"
#include "LibFunc.h"
#include "ModelId.h"


// Namespaces
using namespace EECFI;
using namespace std;

// Main program
int main (int argc, char *argv[])
{
  //-------------------------------------------------
  //-------------------------------------------------

  try
  {
    ModelId modelId;

    // ------------------------------------------------------------------------
    // Time references initialization                                           
    // ------------------------------------------------------------------------ 

    double initTime[4];

    initTime[0] = -245.1000000000000000;   // TAI time [days] 
    initTime[1] = -245.0995949074074074;   // UTC time [days] (= TAI - 35.0 s)
    initTime[2] = -245.0995879629629630;   // UT1 time [days] (= TAI - 35.6 s) 
    initTime[3] = -245.0997800925925926;   // GPS time [days] (= TAI - 19.0 s) 

    // Construct the TimeCorrelation object
    TimeCorrelation timeCorr(initTime);

    // ------------------------------------------------------------------------
    //  Transform cartesian coordinates.
    // ------------------------------------------------------------------------ 
    
    cout << "\n\nState vector: Change of reference frame" << endl; 

    Time t(timeCorr, -2456.0, XLCFI_TIME_TAI);

    double efPos[3] = {4859964.138, -5265612.059, 0.002};
    double efVel[3] = {-1203.303801, -1098.845511, 7377.224410};
    double efAcc[3] = {0.0, 0.0, 0.0};

    Coord efCoord(XLCFI_CS_EF, XLCFI_DER_2ND, efPos, efVel, efAcc);

    StateVector efVector(t, efCoord);


    // Change From GM2000 to MOD
    StateVector todVector = efVector.change(modelId, XLCFI_DER_2ND, XLCFI_CS_TOD);

    cout << "Input state vector:" << endl;
    cout << "   Time = " << efVector.time.time << " ref= " << efVector.time.ref << endl;
    cout << "   Position (EF)    : " << efVector.coord.pos[0] << efVector.coord.pos[1] << efVector.coord.pos[2] << endl;
    cout << "   Velocity (EF)    : " << efVector.coord.vel[0] << efVector.coord.vel[1] << efVector.coord.vel[2] << endl;
    cout << "   Acceleration (EF): " << efVector.coord.acc[0] << efVector.coord.acc[1] << efVector.coord.acc[2] << endl;
    
    cout << "Output state vector:" << endl;
    cout << "   Time = " << todVector.time.time << " ref= " << todVector.time.ref << endl;
    cout << "   Position (EF)    : " << todVector.coord.pos[0] << todVector.coord.pos[1] << todVector.coord.pos[2] << endl;
    cout << "   Velocity (EF)    : " << todVector.coord.vel[0] << todVector.coord.vel[1] << todVector.coord.vel[2] << endl;
    cout << "   Acceleration (EF): " << todVector.coord.acc[0] << todVector.coord.acc[1] << todVector.coord.acc[2] << endl; 

    // ------------------------------------------------------------------------
    // Transform  cartesian to and from geodetic coordinates
    // ------------------------------------------------------------------------ 

    cout << "\n\nGeodetic: Transform  cartesian to geodetic coordinates" << endl; 

    //using efCoord from previous example
    Geodetic geo = efCoord.getGeodetic(modelId, XLCFI_DER_1ST);

    cout << "Input state vector:" << endl;
    cout << "   Position (EF)    : " << efCoord.pos[0] << efCoord.pos[1] << efCoord.pos[2] << endl;
    cout << "   Velocity (EF)    : " << efCoord.vel[0] << efCoord.vel[1] << efCoord.vel[2] << endl;
    cout << "   Acceleration (EF): " << efCoord.acc[0] << efCoord.acc[1] << efCoord.acc[2] << endl;
   
    cout << "Output geodetic coordinates:" << endl;
    cout << "   Longitude = " << geo.lon << endl;
    cout << "   Latitude  = " << geo.lat << endl;
    cout << "   Altitude  = " << geo.alt << endl;
    cout << "   Long. Der = " << geo.lonDer << endl;
    cout << "   Lat Der   = " << geo.latDer << endl;
    cout << "   Alt Der   = " << geo.altDer << endl;

    cout << "\n\nGeodetic: Transform geodetic to cartesian coordinates" << endl; 

 
    efCoord.setGeodetic(modelId, XLCFI_DER_1ST, geo);
 
    cout << "Output state vector:" << endl;

    cout << "   Position (EF)    : " << efCoord.pos[0] << efCoord.pos[1] << efCoord.pos[2] << endl;
    cout << "   Velocity (EF)    : " << efCoord.vel[0] << efCoord.vel[1] << efCoord.vel[2] << endl;
    cout << "   Acceleration (EF): " << efCoord.acc[0] << efCoord.acc[1] << efCoord.acc[2] << endl;

    // ------------------------------------------------------------------------
    // Transform from cartesian state vector to keplerian elements
    // ------------------------------------------------------------------------ 

    cout << "\nCoord: Transform from cartesian state vector to keplerian elements" << endl; 

    double pos[3] = {4859964.138, -5265612.059, 0.002};
    double vel[3] = {-1203.303801, -1098.845511, 7377.224410};
    double acc[3] = {0., 0., 0.};

    Coord coord2(XLCFI_CS_TOD, XLCFI_DER_1ST, pos, vel, acc);

    Kepler kep = coord2.getKepler(modelId, XLCFI_KEPLER_OSC); 
    cout << "- Elements type  : " 
         << (kep.mode == XLCFI_KEPLER_OSC? "OSCULATING": "MEAN") << endl;
    cout << "- Reference frame  : " << kep.cs << endl;
    cout << "- Semi-major axis  : " << kep.a  << endl;
    cout << "- Eccenticity      : " << kep.e  << endl;
    cout << "- Inclination      : " << kep.i  << endl;
    cout << "- RAAN             : " << kep.ra << endl;
    cout << "- Arg. of Perigee  : " << kep.w  << endl;
    cout << "- Mean Anomaly     : " << kep.m  << endl;


    // ------------------------------------------------------------------------
    // Transform from keplerian elements to cartesian state vector
    // ------------------------------------------------------------------------ 
    cout << "\nCoord: Transform from keplerian elements to cartesian state vector" << endl; 
   
    Kepler kep2;

    kep2.mode = XLCFI_KEPLER_OSC;
    kep2.cs   = XLCFI_CS_TOD;
    kep2.a    = 7000.0;       // Semi-major axis          [m] 
    kep2.e    =    0.001;     // Eccenticity                  
    kep2.i    =   92.0;       // Inclination            [deg] 
    kep2.ra   =  128.0;       // R.A. of Ascending Node [deg] 
    kep2.w    =  110.0;       // Arg. of Perigee        [deg] 
    kep2.m    =   73.1;       // Mean Anomaly           [deg] 

    Coord coord3;
    coord3.setKepler(modelId, kep2);
   
    cout << "Output state vector:" << endl;
    cout << "   Position (EF)    : " << coord3.pos[0] << coord3.pos[1] << coord3.pos[2] << endl;
    cout << "   Velocity (EF)    : " << coord3.vel[0] << coord3.vel[1] << coord3.vel[2] << endl;

    // ------------------------------------------------------------------------
    // Calculate the geodesic (minimum) distance between two points that lay  
    // at a given altitude on the same ellipsoid 
    // ------------------------------------------------------------------------ 
    cout << "\nGeodetic: Distance between two points on an ellipsoid" << endl; 

    Geodetic geo2(4.17,  // longitude
                  10.0,  // latitude
                  0.0);  // altitude

    double distance, az1, az2, auxD;
    double lon, lat;

    // get geodesic distance to the following point
    lon = 90.0;
    lat = 0.0;

    distance = geo2.geoDistance(modelId, lon, lat,
                                az1, az2);

    cout << "Geodesic distance = " << distance/1000. << " Km" << endl;
    cout << "Geodesic azimuth of initial point = " << az1 << " deg" << endl;
    cout << "Geodesic azimuth of final point = "   << az2 << " deg" << endl;

    // ------------------------------------------------------------------------
    // Calculate Sun, Moon and Planets position and velocity in the Earth Fixed CS
    // ------------------------------------------------------------------------ 
    cout << "\nStateVector: get Sun, Moon and Planets state vector" << endl; 

    Time ut1Time(timeCorr, 0.0, XLCFI_TIME_UT1);

    StateVector sunVec, moonVec, planetVec;

    sunVec.setSun(modelId, ut1Time);
    moonVec.setMoon(modelId, ut1Time);
    planetVec.setPlanet(modelId, ut1Time, XLCFI_VENUS);

    cout << "Output Sun state vector:" << endl;

    cout << "   Time = " << sunVec.time.time << " ref= " << sunVec.time.ref << endl;
    cout << "   CS = "   << sunVec.coord.cs << "deriv = " << sunVec.coord.deriv << endl;
    cout << "   Position (EF)    : " << sunVec.coord.pos[0] << sunVec.coord.pos[1] << sunVec.coord.pos[2] << endl;
    cout << "   Velocity (EF)    : " << sunVec.coord.vel[0] << sunVec.coord.vel[1] << sunVec.coord.vel[2] << endl;
    cout << "   Acceleration (EF): " << sunVec.coord.acc[0] << sunVec.coord.acc[1] << sunVec.coord.acc[2] << endl; 

    cout << "Output Moon state vector:" << endl;

    cout << "   Time = " << moonVec.time.time << " ref= " << moonVec.time.ref << endl;
    cout << "   CS = "   << moonVec.coord.cs << "deriv = " << moonVec.coord.deriv << endl;
    cout << "   Position (EF)    : " << moonVec.coord.pos[0] << moonVec.coord.pos[1] << moonVec.coord.pos[2] << endl;
    
    // [...]

    // ------------------------------------------------------------------------
    // Calculating star coordinates in the Mean of Date coordinate system
    // ------------------------------------------------------------------------ 
    cout << "\nStar: get star RA and Decl." << endl; 
      
    ut1Time.time = -200.0; // using the same object as before

    double ra, dec;

    double ra0     =   0.35399670615; // Star right ascension in the Barycentric Mean of 2000.0 coordinate at J2000.0 [rad] 
    double dec0    =   4.8672587;     // Star declination in the Barycentric Mean of 2000.0 coordinate at J2000.0 [rad] 
    double muRa    =   0.001;           // Star proper motion in the right ascension [rad/century] 
    double muDec   =  -0.001;           // Star proper motion in the declination [rad/century] 
    double radVel  =   0.01;              // Star radial velocity [au/century] 
    double par     =   0.0001;          // Star parallax [rad]


    StarData star(ra0,     dec0, 
                  muRa,    muDec,
                  radVel,  radVel,
                  XLCFI_CS_BM2000); 

    star.getStar(modelId, ut1Time, ra, dec);

    cout << "Output Star:" << endl;
    cout << "   RA  = " << ra  << endl;
    cout << "   Dec = " << dec << endl;

    // ------------------------------------------------------------------------
    // Calculation of the satellite orbital position (True Latitude)
    // ------------------------------------------------------------------------ 
    cout << "\nStateVector: getPositionOnOrbit" << endl; 
  
    long angleType, deriv;
    double angle, angleRate, angleRateRate;

    pos[0] =          0.138;
    pos[1] =   -2365612.059;
    pos[2] =    6763859.946;
    
    vel[0] =       132.303801;
    vel[1] =     -1203.845511;
    vel[2] =     -1203.845511;
    
    acc[0] =         0.0634168;
    acc[1] =        -0.0249763;
    acc[2] =        -0.3018956;

    Time t1(timeCorr, 0.0, XLCFI_TIME_UT1);
 
    Coord coord4(XLCFI_CS_EF, XLCFI_DER_2ND, pos, vel, acc);

    StateVector sv (t1, coord4);

    angleType = XLCFI_ANGLE_TYPE_TRUE_LAT_TOD;
    deriv = XLCFI_DER_2ND;
  
    sv.getPositionOnOrbit(modelId, angleType, deriv, 
                          angle, angleRate, angleRateRate);

    cout << "Output Position On Orbit = " 
         << angle << "deg; "
         << angleRate << "deg/s; "
         << angleRateRate << "deg/s2 " << endl << endl;

    // ------------------------------------------------------------------------
    // Conversion between cartesian coordinates and RA and declination 
    // ------------------------------------------------------------------------ 
    cout << "\nCoord: getRaDec & Star:getCart" << endl; 

    double pc        = 3.08568025E16;

    pos[0] = -8.82*pc;
    pos[1] = -5.93*pc;
    pos[2] = 3.7*pc;
  
    vel[0] = -57.7E3;
    vel[1] = 31.5E3;
    vel[2] = -102.3E3;
  
    Coord coord5(XLCFI_CS_BM1950, XLCFI_DER_1ST, pos, vel, acc);
 
    // Get spherical coords.
    StarData radec = coord5.getRaDec(modelId, XLCFI_DER_1ST);

    cout << "Input cartesian coordinates" << endl;
    cout << "   CS = " << coord5.cs << endl;
    cout << "   Position = " << coord5.pos[0] << ", " << coord5.pos[1] << ", " << coord5.pos[2] << endl;
    cout << "   Velocity = " << coord5.vel[0] << ", " << coord5.vel[1] << ", " << coord5.vel[2] << endl;

    cout << "Output Star coordinates from input cartesian coordinates" << endl;
    cout << "   Right Ascension      = " << radec.ra       << endl;
    cout << "   Declination          = " << radec.dec      << endl;
    cout << "   Proper motion in RA  = " << radec.muRa     << endl;
    cout << "   Proper motion in Dec = " << radec.muDec    << endl;
    cout << "   Radial Velocity      = " << radec.radVel   << endl;
    cout << "   Parallax             = " << radec.parallax << endl << endl;

    // Get cartesian coords.
    Coord coordFromStar = radec.getCart(modelId, XLCFI_DER_1ST);

    cout << "Output Cartesian Star coordinates from previous spherical coordinates" << endl;
    cout << "   CS = " << coordFromStar.cs << endl;
    cout << "   Position = " << coordFromStar.pos[0] << ", " << coordFromStar.pos[1] << ", " << coordFromStar.pos[2] << endl;
    cout << "   Velocity = " << coordFromStar.vel[0] << ", " << coordFromStar.vel[1] << ", " << coordFromStar.vel[2] << endl;

    // ------------------------------------------------------------------------
    // Star coordinates conversion from Fk4 to FK5
    // ------------------------------------------------------------------------ 
    cout << "\nStar: changeCatalog" << endl; 

    StarData star1(6.27906181420277,     // RA
                   -1.34986658532673,    // Dec
                   -0.0001394081738438,  // mu_ra
                   -0.0000857635400903,  // mu_dec
                   0.,                   // radial vel.
                   0.,                   // parallax
                   XLCFI_CS_BM1950);        // reference frame (XLCFI_FK4)
    
    Time starTime(timeCorr, 1646.0, XLCFI_TIME_UTC);

    long newCatalog = XLCFI_FK5;

    StarData star2 = star1.changeCatalog(modelId, starTime, newCatalog);

    cout << "   INPUTS." << endl;
    cout << "       UTC time = " << starTime.time << endl;
    cout << "       RA = " << star1.ra << " \tDec = " << star1.dec << endl;
    cout << "       mu_ra = " << star1.muRa << " \tmu_dec = " << star1.muDec << endl;
    cout << "       rad_vel = "  << star1.radVel << ", \tparallax = " << star1.parallax << endl;
   
    cout << "   OUTPUTS." << endl;
    cout << "       RA = " << star2.ra << " \tDec = " << star2.dec << endl << endl;

    // ------------------------------------------------------------------------
    // Conversion between EF and Topocentric coordinates
    // ------------------------------------------------------------------------ 
    cout << "\nCoord: topocentricToEf & efToTopocentric" << endl; 


    Topocentric topo = {20, 30, 10000, 0, 0, 0};
    Topocentric topo2;

    pos[0] = 3460675.389;
    pos[1] = 2903851.443;
    pos[2] = 4487348.409;

    vel[0] = 0.;
    vel[1] = 0.;
    vel[2] = 0.;

    Coord topOrigin(XLCFI_CS_EF, XLCFI_DER_1ST, pos, vel, acc);

    Coord coordFromTop;

    // topocentric to EF CS
    coordFromTop.topocentricToEf(modelId, XLCFI_MODE_FLAG_LOCATION, XLCFI_DER_1ST, 
                                 topOrigin, topo);

    cout << "Inputs." << endl;
    cout << "   Mode = LOCATION" << endl;
    cout << "   Deriv = 1st. Derivative" << endl;
    cout << "   Center of the Topocentric CS   = " << pos[0] <<",  " << pos[1] << ", " << pos[2] << endl;
    cout << "   Velocity of the Topocentric CS = " << vel[0] <<",  " << vel[1] << ", " << vel[2] << endl;
    cout << "   Azimuth, Elevation, Altitude = " 
         << topo.azim << ",  " << topo.elev << ", " << topo.range << endl;
    cout << "   Rates for Azimuth, Elevation, Altitude = " 
         << topo.azimDer  << ", " << topo.elevDer << ", " << topo.rangeDer << endl;
    
    cout << "Output Cartesian coordinates" << endl;
    cout << "   CS = " << coordFromStar.cs << endl;
    cout << "   Position = " << coordFromTop.pos[0] << ", " << coordFromTop.pos[1] << ", " << coordFromTop.pos[2] << endl;
    cout << "   Velocity = " << coordFromTop.vel[0] << ", " << coordFromTop.vel[1] << ", " << coordFromTop.vel[2] << endl;
    
    // EF to topocentric
    coordFromTop.efToTopocentric(modelId, XLCFI_MODE_FLAG_LOCATION, XLCFI_DER_1ST, 
                                 topOrigin, topo2);

    cout << "Output topocentric parameters from previous cartesian coordinates" << endl;
    cout << "Topocentric Azimuth = "   << topo2.azim  << endl;
    cout << "Topocentric Elevation = " << topo2.elev  << endl;
    cout << "Topocentric Range = "     << topo2.range << endl;

    cout << "Topocentric Azimuth rate = "   << topo2.azimDer  << endl;
    cout << "Topocentric Elevation rate = " << topo2.elevDer  << endl;
    cout << "Topocentric Range rate = "     << topo2.rangeDer << endl;
  }//end try

  catch (CfiError cfiError)
  {
    //If an exception is thrown, there have been errors during execution
    vector<string> errorMessages;
    
    // Get error messages
    cfiError.getMsg(errorMessages);

    // Pring Error messages
    for (long i = 0; i < errorMessages.size(); i++)
    {
      cout << errorMessages[i] << endl;
    }
  }

  return 0;

}


Generated on Mon Dec 11 2023 13:28:37 for by  doxygen 1.7.1