| Earth Observation Mission CFI Software Usage Guide for Object Oriented Software |

# ORBITAL CALCULATIONS

## Getting orbital information and OSV computation

The Earth Observation CFI software contain clases to do computations related to orbits. Before doing any computation, the orbital information has to be stored in an object of the OrbitId class (See [ORBIT_SUM]).

After creating the OrbitId object, it allows the following operations:

- Transformations between time and orbit number
- Getting the Orbit data that is stored in the OrbitId object.
- Getting orbital information about a given orbit number
- Computing the orbit state vector at a given time

The strategy to follow for initialising the orbit and the afterward usage can be summarize in the following steps:

- Time correlation initialisation: A TimeCorrelaton object is needed to create the OrbitID.
- Optionally, initialise the ModelId with the models to be used for the orbital computations. The ModelId object is needed to create the OrbitID
- Create the OrbitID object: In this step, the user provides orbital information that will be used in further calculations. The input data are stored in the OrbitID. There are several ways of initialising the orbit:
  1. Providing information about the orbital geometry
  2. Providing a osculating state vector for a given time and orbit number.
  3. Providing orbit files with orbital geometry (OSF's)
  4. Providing orbit files with a list of state vectors (POF's, ROF's, DORIS Navigator files)
  5. Providing an osculating state vector or files with state vector plus data for the precise numerical propagator
  Note1: orbital files usually contain time correlation data. To ensure that orbit routines produce correct results, the same time correlations should be in the orbit file and the TimeCorrelaton object.
  Note2: Files can be given via filenames or as an object from the DataHandlilng library (OsfFile, OrbitFile, DorisFile).
- Call methods for orbit computations.

Among the funcionalities provided by the OrbitId, one of the most important is the computation of state vectors at a given time (OrbitId::osvCompute). This computation depends on the way that the OrbitId was constructed. Please, refer to the documentation of this function for further info ([ORBIT_SUM]).

## Other orbital operations

The Orbit library contais a class called ANXTime. This class consist on an orbit number and a time that represents the elapsed time since the satellite passed the ascending node (ANX). This class has the following characteristics:

- In general, the object should be contructed with an OrbitId. However if the OrbitId is not included in the object, the ANXTime will be just a simple structure for storing the data and its methods are not supported.
- It allows to get orbital information for the orbit number in the object
- It allows to get the MJD200 time that corresponds to the ANXTime and vice verse
- It allows arithmetic operations: adding a subtracting an amount of seconds
- It allows logic operations: comparison between ANXTime objects

Another useful class within the Orbit library, is the TimeSegment class. This class consist on a pair of ANXTime objects that represent the start and stop of an interval of time. This class is important as the Visibility functions in the Visibility library return lists of TimeSegment objects.

## Example

    // ------------------------------------------------------------------------
    //
    //                           JAVA Example Program.
    //                           ORBIT COMPUTATIONS
    //
    // ------------------------------------------------------------------------

    import EECFI.*;

    import java.util.Vector;
    import java.lang.String;
    import java.lang.Long;

    // Main program
    public class Example
    {
      public static void main(String[] args)
      {

        // Accessors data
        Vector<OsvRec> osvRecords = new Vector<OsvRec>();
        Vector<OsfRecords> osfRecords = new Vector<OsfRecords>();
        ValidityTime valTime = new ValidityTime();
        Vector<ANXExtra> extraInfo = new Vector<ANXExtra>();
        String orbitFile = new String();

        // common variables
        long satId = XLCFI_SAT_CRYOSAT;

        double time0, time1;
        long orbit0, orbit1;

        // xo_timeTo_orbit & xo_orbito_time variables
        long orbit, seconds, microseconds;
        double timeT;
        long timeRef;
        long absOrbit;
        double[] pos = new double[3];
        double[] vel = new double[3];

        // orbit initilization
        long timeMode, orbit_mode, orbitMode;
        Vector<String> filesVector = new Vector<String>();

        long status;
        int jj;

        //-------------------------------------------------
        // Put all the code inside try-catch statements
        // so, if something fails, an exception is thrown
        //-------------------------------------------------
        try
        {
          ModelId  modelId;

          // Initializing Time Reference: Used for the first and second example
          double[] coorTime = new double[4];

          coorTime[0]   = -1100.1000000000000;   // TAI time [days]
          coorTime[1]   = -1100.0995949074074;   // UTC time [days] (= TAI + 35.0 s)
          coorTime[2]   = -1100.0995914351852;   // UT1 time [days] (= TAI + 35.3 s)
          coorTime[3]   = -1100.099780092;       // GPS time [days] (= TAI + 19.0 s)

          TimeCorrelation timeCorr = new TimeCorrelation(coorTime);

          // ------------------------------------------------------------------------
          // Orbit initialization. Example1: One state Vector
          //-------------------------------------------------------------------------

          // Initialize OrbitId with
          timeT    = 3460.;
          timeRef  = XLCFI_TIME_UT1;
          pos[0]   = 6500000.;
          pos[1]   = 2000000.;
          pos[2]   = 0.;
          vel[0]   = 463.;
          vel[1]   = -1600.;
          vel[2]   = 7300.;
          absOrbit = 2;

          OrbitId orbitId1 = new OrbitId( new SatId(satId), modelId, timeCorr, timeRef, timeT, pos, vel, absOrbit );

          // Get OSV records
          osvRecords = orbitId1.getOsv();
          System.out.println( "OrbitId::getOsv: Number of OSV records = " + osvRecords.size() );

          for (jj = 0 ; jj < osvRecords.size() ; jj++)
          {
            System.out.println( "\tOSV record " + jj + ": Tai time = " + osvRecords[jj].taiTime );
            System.out.println( "\tOSV record " + jj + ": Utc time = " + osvRecords[jj].utcTime );
            System.out.println( "\tOSV record " + jj + ": Ut1 time = " + osvRecords[jj].ut1Time );
            System.out.println( "\tOSV record " + jj + ": Abs orbit = " + osvRecords[jj].absOrbit );
            System.out.println( "\tOSV record " + jj + ": Ref frame = " + osvRecords[jj].refFrame );
            System.out.println( "\tOSV record " + jj + ": Position = ( " + osvRecords[jj].position[0]
            + ", " + osvRecords[jj].position[1] + ", " + osvRecords[jj].position[2]
            + " )" );
            System.out.println( "\tOSV record " + jj + ": Velocity = ( " + osvRecords[jj].velocity[0]
            + ", " + osvRecords[jj].velocity[1] + ", " + osvRecords[jj].velocity[2]
            + " )" );
            System.out.println( "\tOSV record " + jj + ": Quality = " + osvRecords[jj].quality );
            System.out.println( endl;
          }

          // ------------------------------------------------------------------------
          // Orbit initialization. Example2: Orbit Scenario File
          //-------------------------------------------------------------------------
          // Set input values
          orbitFile = new String("./osf.xml");

          satId      = XLCFI_SAT_CRYOSAT;
          timeRef    = XLCFI_TIME_UT1;
          orbit_mode = XOCFI_ORBIT_INIT_OSF_MODE;
          timeMode   = XOCFI_SEL_FILE;

          // Create Vector with input files
          filesVector.clear();
          filesVector.addElement( orbitFile );

          OrbitId  orbitId2 = new OrbitId( new SatId(satId), modelId, timeCorr, timeRef, orbit_mode, filesVector,
            timeMode, time0, time1, orbit0, orbit1 );

          // Get status of OrbitId
          status = orbitId2.status();
          System.out.println( "OrbitId->status: Status = " + status );

          // Get Satellite Id
          SatId satId = orbitId2.satId();
          System.out.println( "OrbitId->satId: satellite = " + satId.getSatellite() );

          // Get Mode
          orbitMode  = orbitId2.mode();
          System.out.println( "OrbitId->orbitId: mode = " + orbitMode );

          // Get OSF records
          osfRecords = orbitId2.getOsf();

          System.out.println( "OrbitId->getOsf: Number of records = " + osfRecords.size() );
          for (jj = 0 ; jj < osfRecords.size() ; jj++)
          {
            System.out.println( endl;
            System.out.println( "\tOSF record " + jj + ": Mission info - abs orbit = " + osfRecords[jj].missionInfo.absOrbit );
            System.out.println( "\tOSF record " + jj + ": Mission info - rel orbit = " + osfRecords[jj].missionInfo.relOrbit );
            System.out.println( "\tOSF record " + jj + ": Mission info - cycle = " + osfRecords[jj].missionInfo.cycle );
            System.out.println( "\tOSF record " + jj + ": Mission info - phase = " + osfRecords[jj].missionInfo.phase );

            System.out.println( "\tOSF record " + jj + ": Reference orbit info - drift mode = " + osfRecords[jj].refOrbitinfo.driftMode );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - inclination = " + osfRecords[jj].refOrbitinfo.inclination );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - rep cycle = " + osfRecords[jj].refOrbitinfo.repCycle );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - cycle length = " + osfRecords[jj].refOrbitinfo.cycleLength );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - ANX long = " + osfRecords[jj].refOrbitinfo.AnxLong );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - MLST = " + osfRecords[jj].refOrbitinfo.mlst );
            System.out.println( "\tOSF record " + jj + ": Reference orbit info - MLST drift = " + osfRecords[jj].refOrbitinfo.mlstDrift );
            // [...]
          }

          // Get validity time
          valTime = orbitId2.getValTime();
          System.out.println( endl;
          System.out.println( "OrbitId::getValTime : validity start = " + valTime.start );
          System.out.println( "OrbitId::getValTime : validity stop = " + valTime.stop );

          // ------------------------------------------------------------------------
          // Getting info from the OrbitId.
          //-------------------------------------------------------------------------

          long         absOrbit, relOrbit, cycle, phase;
          OrbitalInfo  orbitalInfo = new OrbitalInfo();
          OrbitInfo    orbitInfo1 = new OrbitInfo();
          OrbitInfo    orbitInfo2 = new OrbitInfo();
          OrbitInfo    orbitInfo3 = new OrbitInfo();

          // 1. Get orbital info
          absOrbit = 300;
          orbitalInfo = orbitId2.getOrbitInfo( absOrbit );

          System.out.println( endl;
          System.out.println( "ANX longitude = " + orbitalInfo.phasing     + " deg" );
          System.out.println( "UTC at ANX = "    + orbitalInfo.utcAnx      );
          System.out.println( "Nodal period  = " + orbitalInfo.nodalPeriod + " s" );
          // [...]

          // 2. Get relative orbit and phase from the absolute orbit number
          absOrbit = 2800;

          orbitInfo1 = orbitId2.getOrbitNumbersFromAbs( absOrbit );

          System.out.println( "Absolute orbit = " + orbitInfo1.absOrbit );
          System.out.println( "Relative orbit = " + orbitInfo1.relOrbit );
          System.out.println( "Cycle = "          + orbitInfo1.cycle    );
          System.out.println( "Phase = "          + orbitInfo1.phase    );

          // 3. Get absolute orbit from relative

          relOrbit = orbitInfo1.relOrbit;
          cycle    = orbitInfo1.cycle;

          orbitInfo2 = orbitId2.getOrbitNumbersFromRel( relOrbit, cycle );

          System.out.println( "Absolute orbit = " + orbitInfo2.absOrbit );
          System.out.println( "Relative orbit = " + orbitInfo2.relOrbit );
          System.out.println( "Cycle = "          + orbitInfo2.cycle    );
          System.out.println( "Phase = "          + orbitInfo2.phase    );

          // 4. Get absolute orbit from phase
          phase = orbitInfo2.phase;

          orbitInfo3 = orbitId2.getOrbitNumbersFromPhase( phase );

          System.out.println( "Absolute orbit = " + orbitInfo3.absOrbit );
          System.out.println( "Relative orbit = " + orbitInfo3.relOrbit );
          System.out.println( "Cycle = "          + orbitInfo3.cycle    );
          System.out.println( "Phase = "          + orbitInfo3.phase    );

          // ------------------------------------------------------------------------
          // Propagate the orbit: osvCompute
          //-------------------------------------------------------------------------
          long                 mode;
          double               time;
          StateVector          sv;
          StateVectorExtraInfo svExtra;

          // Computing the satellite position for the 01-01-2000 00:00:00
          time = 0;
          sv = orbitId2.osvCompute( mode, timeRef, time);
          System.out.println( "Input time   = " + time );
          System.out.println( "Position     = ( " + sv.coord.pos[0] + ", " + sv.coord.pos[1] + ", " + sv.coord.pos[2] + " )" );
          System.out.println( "Velocity     = ( " + sv.coord.vel[0] + ", " + sv.coord.vel[1] + ", " + sv.coord.vel[2] + " )" );
          System.out.println( "Acceleration = ( " + sv.coord.acc[0] + ", " + sv.coord.acc[1] + ", " + sv.coord.acc[2] + " )" );

          // Get orbital info related to the propagated time
          mode = XOCFI_ORBIT_EXTRA_ALL_RESULTS;

          svExtra = orbitId2.osvComputeExtra( mode );
          System.out.println( "Satellite geocentric position" );
          System.out.println( "   Longitude   = " + svExtra.modelIndep[XOCFI_ORBIT_EXTRA_GEOC_LONG] );
          System.out.println( "   Latitude   = "  + svExtra.modelIndep[XOCFI_ORBIT_EXTRA_GEOD_LAT] );
          System.out.println( "   Altitude   = "  + svExtra.modelIndep[XOCFI_ORBIT_EXTRA_GEOD_ALT] );
          // [...]

          // ------------------------------------------------------------------------
          // Using ANXTime objects
          //-------------------------------------------------------------------------

          orbit        = 500;
          seconds      = 0;
          microseconds = 0;
          timeRef      = XLCFI_TIME_UT1;

          // ANXTime constructor
          ANXTime  anxTime = new ANXTime(orbitId2, 500, 0, 0);

          // Get equivalent time
          timeT = anxTime.orbitToTime( timeRef );

          System.out.println( "ANXTime::orbitToTime : orbit = " + orbit + " seconds = " + seconds
          + " microseconds = " + microseconds + " => time = " + timeT );

          timeT += 1; // adding 1 day

          // ANXTime constructor
          anxTime.timeToOrbit( timeRef, timeT );

          System.out.println( endl;
          System.out.println( "ANXTime::orbitToTime : time = " + timeT + " => orbit = "
          + anxTime.orbit + " seconds = " + anxTime.seconds
          + " microseconds = " + anxTime.microseconds );

        }//end try

        catch (CfiError cfiError)
        {
          //If an exception is thrown, there have been errors during execution
          Vector<String> errorMessages = new Vector<String>();

          // Get error messages
          errorMessages = cfiError.getMsg(errorMessages);

          // Pring Error messages
          for (int i = 0; i < errorMessages.size(); i++)
          {
            System.out.println( errorMessages.elementAt(i) );
          }
        }

      }

    }