Пример #1
0
        public static List <Pass> CalculatePasses(Coordinate position, Tle satellite, EpochTime startTime, int accuracy = 15,
                                                  int maxNumberOfDays = 5, Sgp4.wgsConstant wgs = Sgp4.wgsConstant.WGS_84)
        {
            List <Pass> results = new List <Pass>();
            EpochTime   epoch   = new EpochTime(startTime);
            EpochTime   end     = new EpochTime(startTime);

            end.addDays(maxNumberOfDays);
            while (epoch < end)
            {
                Sgp4Data satPos = getSatPositionAtTime(satellite, epoch, wgs);
                if (SatFunctions.isSatVisible(position, 0.0, epoch, satPos))
                {
                    EpochTime passStart    = new EpochTime(epoch);
                    Point3d   spherical    = SatFunctions.calcSphericalCoordinate(position, epoch, satPos);
                    double    maxElevation = spherical.z;
                    epoch.addTick(accuracy);
                    satPos = getSatPositionAtTime(satellite, epoch, wgs);
                    while (SatFunctions.isSatVisible(position, 0.0, epoch, satPos))
                    {
                        spherical = SatFunctions.calcSphericalCoordinate(position, epoch, satPos);
                        if (maxElevation < spherical.z)
                        {
                            maxElevation = spherical.z;
                        }
                        epoch.addTick(accuracy);
                    }
                    results.Add(new One_Sgp4.Pass(position, passStart, new EpochTime(epoch), maxElevation * 180.0 / pi));
                }
                epoch.addTick(accuracy);
            }
            return(results);
        }
Пример #2
0
        //! Calculate Range, Azimuth and elevation for satellite
        //! for given time point and satellite position

        /*!
         *  \param Station to calcuate if satellite is in View
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \return Point3d containing range(km), azimuth(degrees), elevation(degrees)
         */
        public static Point3d calcSphericalCoordinate(Coordinate coordinate,
                                                      EpochTime time, Sgp4Data satPosData)
        {
            double lsr = time.getLocalSiderealTime(coordinate.getLongitude());

            Point3d groundLocation = coordinate.toECI(lsr);
            Point3d result         = new Point3d();

            Point3d r = new Point3d();

            r.x = satPosData.getX() - groundLocation.x;
            r.y = satPosData.getY() - groundLocation.y;
            r.z = satPosData.getZ() - groundLocation.z;

            double r_lat = coordinate.getLatetude() * toRadians;

            double sin_lat   = Math.Sin(r_lat);
            double cos_lat   = Math.Cos(r_lat);
            double sin_theta = Math.Sin(lsr);
            double cos_theta = Math.Cos(lsr);

            double rs = sin_lat * cos_theta * r.x + sin_lat * sin_theta * r.y - cos_lat * r.z;
            double re = -sin_theta * r.x + cos_theta * r.y;
            double rz = cos_lat * cos_theta * r.x + cos_lat * sin_theta * r.y + sin_lat * r.z;

            result.x = Math.Sqrt((rs * rs) + (re * re) + (rz * rz));
            result.y = AcTan(-re, rs);
            result.z = Math.Asin(rz / result.x);

            result.y = (result.y + pi) * toDegrees;
            result.z = result.z * toDegrees;

            return(result);
        }
Пример #3
0
        //! Calculate Latitude, longitude and height for satellite on Earth
        //! at given time point and position of the satellite

        /*!
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \param int WGS-Data to use 0 = WGS_72; 1 = WGS_84
         *  \param int Nr of iterations used to calculate the latetude
         *  \return Coordinate containing longitude, latitude, altitude/height
         */
        public static Coordinate calcSatSubPoint(EpochTime time, Sgp4Data satPosData,
                                                 One_Sgp4.Sgp4.wgsConstant wgs)
        {
            double sat_X = satPosData.getX();
            double sat_Y = satPosData.getY();
            double sat_Z = satPosData.getZ();

            double f     = WGS_72.f;
            double wgs_R = WGS_72.radiusEarthKM;

            if (wgs == Sgp4.wgsConstant.WGS_84)
            {
                f     = WGS_84.f;
                wgs_R = WGS_84.radiusEarthKM;
            }
            double delta = 1.0e-07;
            double f_2   = f * f;
            double e     = 2 * f - f_2;

            double r        = Math.Sqrt((sat_X * sat_X) + (sat_Y * sat_Y));
            double latitude = AcTan(sat_Z, r);
            double c        = 1.0;
            double height   = 0.0;

            double phi;

            do
            {
                phi      = latitude;
                c        = 1.0 / (Math.Sqrt(1.0 - e * (Math.Sin(latitude) * Math.Sin(latitude))));
                latitude = AcTan(sat_Z + (wgs_R * c * e * Math.Sin(latitude)), r);
            }while (Math.Abs(latitude - phi) > delta);

            double longitude = AcTan(sat_Y, sat_X) - time.getLocalSiderealTime();

            height = (r / Math.Cos(latitude)) - (wgs_R * c);

            if (longitude < pi)
            {
                longitude += twoPi;
            }
            if (longitude > pi)
            {
                longitude -= twoPi;
            }

            latitude  = toDegrees * latitude;
            longitude = toDegrees * longitude;

            return(new Coordinate(latitude, longitude, height));
        }
Пример #4
0
        //! Calculate visibility of a satellite from a point on Earth

        /*!
         *  \param Station to calcuate if satellite is in View
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \param string name of the satellite
         *  \param double tick in witch time is increased by each step
         *  \return true if object is visible at given time and current location
         */
        public static bool isSatVisible(Coordinate coordinate,
                                        double minElevation, EpochTime time, Sgp4Data satPosData)
        {
            double  lsr            = time.getLocalSiderealTime(coordinate.getLongitude());
            Point3d groundLocation = coordinate.toECI(lsr);

            Point3d v = new Point3d();

            v.x = satPosData.getX() - groundLocation.x;
            v.y = satPosData.getY() - groundLocation.y;
            v.z = satPosData.getZ() - groundLocation.z;

            double r_lat = coordinate.getLatetude() * toRadians;

            double sin_lat = Math.Sin(r_lat);
            double cos_lat = Math.Cos(r_lat);
            double sin_srt = Math.Sin(lsr);
            double cos_srt = Math.Cos(lsr);


            double rs = sin_lat * cos_srt * v.x
                        + sin_lat * sin_srt * v.y
                        - cos_lat * v.z;
            double re = -sin_srt * v.x
                        + cos_srt * v.y;
            double rz = cos_lat * cos_srt * v.x
                        + cos_lat * sin_srt * v.y + sin_lat * v.z;

            double range     = Math.Sqrt(rs * rs + re * re + rz * rz);
            double elevation = Math.Asin(rz / range);
            double azimuth   = Math.Atan(-re / rs);

            if (rs > 0.0)
            {
                azimuth += pi;
            }
            if (azimuth < 0.0)
            {
                azimuth += twoPi;
            }

            if (elevation >= minElevation)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #5
0
        //! Calculate visibility of a satellite from a point on Earth

        /*!
         *  \param Station to calcuate if satellite is in View
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \param string name of the satellite
         *  \param double tick in witch time is increased by each step
         *  \return true if object is visible at given time and current location
         */
        public static bool isSatVisible(Coordinate coordinate,
                                        double minElevation, EpochTime time, Sgp4Data satPosData)
        {
            Point3d res       = calcSphericalCoordinate(coordinate, time, satPosData);
            double  elevation = res.z;

            if (elevation >= minElevation)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #6
0
        //! Calculate Range, Azimuth and elevation for satellite
        //! for given time point and satellite position

        /*!
         *  \param Station to calcuate if satellite is in View
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \return Point3d containing range, azimuth, elevation
         */
        public static Point3d calcSphericalCoordinate(Coordinate coordinate,
                                                      EpochTime time, Sgp4Data satPosData)
        {
            double  lsr            = time.getLocalSiderealTime(coordinate.getLongitude());
            Point3d groundLocation = coordinate.toECI(lsr);
            Point3d result         = new Point3d();

            Point3d v = new Point3d();

            v.x = satPosData.getX() - groundLocation.x;
            v.y = satPosData.getY() - groundLocation.y;
            v.z = satPosData.getZ() - groundLocation.z;

            double r_lat = coordinate.getLatetude() * toRadians;

            double sin_lat = Math.Sin(r_lat);
            double cos_lat = Math.Cos(r_lat);
            double sin_srt = Math.Sin(lsr);
            double cos_srt = Math.Cos(lsr);


            double rs = sin_lat * cos_srt * v.x
                        + sin_lat * sin_srt * v.y
                        - cos_lat * v.z;
            double re = -sin_srt * v.x
                        + cos_srt * v.y;
            double rz = cos_lat * cos_srt * v.x
                        + cos_lat * sin_srt * v.y + sin_lat * v.z;

            result.x = Math.Sqrt(rs * rs + re * re + rz * rz);
            result.y = Math.Atan(-re / rs);
            result.z = Math.Asin(rz / result.x);

            if (rs > 0.0)
            {
                result.y += pi;
            }
            if (result.y < 0.0)
            {
                result.y += twoPi;
            }

            return(result);
        }
Пример #7
0
        //! Calculate Latitude, longitude and height for satellite on Earth
        //! at given time point and position of the satellite

        /*!
         *  \param TimeDate start time
         *  \param List<Sgp4Data> satellite position vector
         *  \param int WGS-Data to use 0 = WGS_72; 1 = WGS_84
         *  \param int Nr of iterations used to calculate the latetude
         *  \return Coordinate containing longitude, latitude, altitude/height
         */
        public static Coordinate calcSatSubPoint(EpochTime time, Sgp4Data satPosData,
                                                 int wgsID = 0)
        {
            double sat_X = satPosData.getX();
            double sat_Y = satPosData.getY();
            double sat_Z = satPosData.getZ();

            //calculat Longitude
            double latitude = Math.Atan((sat_Z / (Math.Sqrt(
                                                      sat_X * sat_X + sat_Y * sat_Y))));

            double longitude = AcTan(sat_Y, sat_X) - time.getLocalSiderealTime();
            double height    = Math.Sqrt(sat_X * sat_X + sat_Y * sat_Y + sat_Z * sat_Z) - 6378.135;

            latitude  = toDegrees * latitude;
            longitude = toDegrees * longitude;

            return(new Coordinate(latitude, longitude, height));
        }
Пример #8
0
        //! Calculate Latitude, longitude and height for satellite on Earth
        //! at given time point and position of the satellite
        /*!
            \param TimeDate start time
            \param List<Sgp4Data> satellite position vector
            \param int WGS-Data to use 0 = WGS_72; 1 = WGS_84
            \param int Nr of iterations used to calculate the latetude
            \return Coordinate containing longitude, latitude, altitude/height
        */
        public static Coordinate calcSatSubPoint(EpochTime time, Sgp4Data satPosData,
            int wgsID = 0)
        {
            double sat_X = satPosData.getX();
            double sat_Y = satPosData.getY();
            double sat_Z = satPosData.getZ();

            //calculat Longitude
            double latitude = Math.Atan((sat_Z / (Math.Sqrt(
                                sat_X * sat_X + sat_Y * sat_Y))));

            double longitude = AcTan(sat_Y, sat_X) - time.getLocalSiderealTime();
            double height = Math.Sqrt(sat_X * sat_X + sat_Y * sat_Y + sat_Z * sat_Z) - 6378.135;

            latitude = toDegrees * latitude;
            longitude = toDegrees * longitude;

            return new Coordinate(latitude, longitude, height);
        }
Пример #9
0
        //! Calculate Passes of a satellite for ceratin number of days from a starting time

        /*!
         *  \param Coordinate position of observer
         *  \param Tle satellite data
         *  \param EpochTime of startpoint
         *  \param int accuracy time between calculations default 15 seconds
         *  \param int number of days to calculate default 5 days
         *  \param int WGS-Data to use 0 = WGS_72; 1 = WGS_84 default WGS 84
         *  \return List<Pass> List of passes satellite is visible
         */
        public static List <Pass> CalculatePasses(Coordinate position, Tle satellite, EpochTime startTime, int accuracy = 15,
                                                  int maxNumberOfDays = 5, Sgp4.wgsConstant wgs = Sgp4.wgsConstant.WGS_84)
        {
            List <Pass> results = new List <Pass>();
            EpochTime   epoch   = new EpochTime(startTime);
            EpochTime   end     = new EpochTime(startTime);

            end.addDays(maxNumberOfDays);

            while (epoch < end)
            {
                Sgp4Data satPos = getSatPositionAtTime(satellite, epoch, wgs);
                if (SatFunctions.isSatVisible(position, 0.0, epoch, satPos))
                {
                    Point3d    spherical     = SatFunctions.calcSphericalCoordinate(position, epoch, satPos);
                    PassDetail startDetails  = new PassDetail(new EpochTime(epoch), spherical.z, spherical.y, spherical.x);
                    PassDetail maxEleDetails = new PassDetail(new EpochTime(epoch), spherical.z, spherical.y, spherical.x);
                    //double maxElevation = spherical.z;
                    epoch.addTick(accuracy);
                    satPos = getSatPositionAtTime(satellite, epoch, wgs);
                    while (spherical.z >= 0)
                    //while (SatFunctions.isSatVisible(position, 0.0, epoch, satPos))
                    {
                        spherical = SatFunctions.calcSphericalCoordinate(position, epoch, satPos);
                        if (maxEleDetails.elevation < spherical.z)
                        {
                            maxEleDetails = new PassDetail(new EpochTime(epoch), spherical.z, spherical.y, spherical.x);
                        }
                        epoch.addTick(accuracy);
                        satPos = getSatPositionAtTime(satellite, epoch, wgs);
                    }
                    PassDetail endDetails = new PassDetail(new EpochTime(epoch), spherical.z, spherical.y, spherical.x);
                    results.Add(new One_Sgp4.Pass(position, startDetails, maxEleDetails, endDetails));
                }
                epoch.addTick(accuracy);
            }
            return(results);
        }
Пример #10
0
        //! Calculate visibility of a satellite from a point on Earth
        /*!
            \param Station to calcuate if satellite is in View
            \param TimeDate start time
            \param List<Sgp4Data> satellite position vector
            \param string name of the satellite
            \param double tick in witch time is increased by each step
            \return true if object is visible at given time and current location
        */
        public static bool isSatVisible(Coordinate coordinate, 
            double minElevation, EpochTime time, Sgp4Data satPosData)
        {
            double lsr = time.getLocalSiderealTime(coordinate.getLongitude());
                Point3d groundLocation = coordinate.toECI(lsr);

                Point3d v = new Point3d();
                v.x = satPosData.getX() - groundLocation.x;
                v.y = satPosData.getY() - groundLocation.y;
                v.z = satPosData.getZ() - groundLocation.z;

                double r_lat = coordinate.getLatetude() * toRadians;

                double sin_lat = Math.Sin(r_lat);
                double cos_lat = Math.Cos(r_lat);
                double sin_srt = Math.Sin(lsr);
                double cos_srt = Math.Cos(lsr);

                double rs = sin_lat * cos_srt * v.x
                          + sin_lat * sin_srt * v.y
                          - cos_lat * v.z;
                double re = - sin_srt * v.x
                            + cos_srt * v.y;
                double rz = cos_lat * cos_srt * v.x
                            + cos_lat * sin_srt * v.y + sin_lat * v.z;

                double range = Math.Sqrt(rs * rs + re * re + rz * rz);
                double elevation = Math.Asin(rz / range);
                double azimuth = Math.Atan(-re / rs);

                if (rs > 0.0)
                {
                    azimuth += pi;
                }
                if (azimuth < 0.0)
                {
                    azimuth += twoPi;
                }

                if (elevation >= minElevation)
                {
                    return true;
                }
                else
                {
                    return false;
                }
        }
Пример #11
0
        //! Calculate Range, Azimuth and elevation for satellite
        //! for given time point and satellite position
        /*!
            \param Station to calcuate if satellite is in View
            \param TimeDate start time
            \param List<Sgp4Data> satellite position vector
            \return Point3d containing range, azimuth, elevation
        */
        public static Point3d calcSphericalCoordinate(Coordinate coordinate,
            EpochTime time, Sgp4Data satPosData)
        {
            double lsr = time.getLocalSiderealTime(coordinate.getLongitude());
            Point3d groundLocation = coordinate.toECI(lsr);
            Point3d result = new Point3d();

            Point3d v = new Point3d();
            v.x = satPosData.getX() - groundLocation.x;
            v.y = satPosData.getY() - groundLocation.y;
            v.z = satPosData.getZ() - groundLocation.z;

            double r_lat = coordinate.getLatetude() * toRadians;

            double sin_lat = Math.Sin(r_lat);
            double cos_lat = Math.Cos(r_lat);
            double sin_srt = Math.Sin(lsr);
            double cos_srt = Math.Cos(lsr);

            double rs = sin_lat * cos_srt * v.x
                      + sin_lat * sin_srt * v.y
                      - cos_lat * v.z;
            double re = -sin_srt * v.x
                        + cos_srt * v.y;
            double rz = cos_lat * cos_srt * v.x
                        + cos_lat * sin_srt * v.y + sin_lat * v.z;

            result.x = Math.Sqrt(rs * rs + re * re + rz * rz);
            result.y = Math.Atan(-re / rs);
            result.z = Math.Asin(rz / result.x);

            if (rs > 0.0)
            {
                result.y += pi;
            }
            if (result.y < 0.0)
            {
                result.y += twoPi;
            }

            return result;
        }
Пример #12
0
        Sgp4Data calcSgp4()
        {
            double am, axnl, aynl, betal, cnod, cos2u, coseo1 = 0.0;
            double cosi, cosip, cosisq, cossu, cosu, delm, delomg;
            double ecose, el2, eo1, esine;
            double cosim, emsq, sinim;
            double argpdf, pl, mrt;
            double mvt, rdotl, rl, rvdot, rvdotl, sin2u, sineo1 = 0.0;
            double sini, sinip, sinsu, sinu, snod, su, t2, t3, t4, tem5, temp;
            double temp1, temp2, tempa, tempe, templ;
            double u, ux, uy, uz, vx, vy, vz;
            double xinc;
            double xl, xlm;
            double xmdf, xmx, xmy, omegadf;
            double xnode;
            double tc, x2o3;
            int ktr;

            x2o3 = 2.0 / 3.0;

            double vkmpersec = radiusEarthKm * xke / 60.0;

            satCalcData.rec_error = 0;

            xmdf = satCalcData.rec_mo + satCalcData.neo.neo_mdot * satCalcData.neo.neo_t;
            argpdf = satCalcData.rec_argpo + satCalcData.neo.neo_argpdot * satCalcData.neo.neo_t;
            omegadf = satCalcData.rec_omegao + satCalcData.neo.neo_omegadot * satCalcData.neo.neo_t;
            argpm = argpdf;
            mm = xmdf;
            t2 = satCalcData.neo.neo_t * satCalcData.neo.neo_t;
            omegam = omegadf + satCalcData.neo.neo_omegacf * t2;
            tempa = 1.0 - satCalcData.neo.neo_cc1 * satCalcData.neo.neo_t;
            tempe = satCalcData.rec_bstar * satCalcData.neo.neo_cc4 * satCalcData.neo.neo_t;
            templ = satCalcData.neo.neo_t2cof * t2;

            if (satCalcData.neo.neo_isimp != 1)
            {
                delomg = satCalcData.neo.neo_omgcof * satCalcData.neo.neo_t;
                delm = satCalcData.neo.neo_xmcof *
                    (Math.Pow((1.0 + satCalcData.neo.neo_eta * Math.Cos(xmdf)), 3) -
                    satCalcData.neo.neo_delmo);
                temp = delomg + delm;
                mm = xmdf + temp;
                argpm = argpdf - temp;
                t3 = t2 * satCalcData.neo.neo_t;
                t4 = t3 * satCalcData.neo.neo_t;
                tempa = tempa - satCalcData.neo.neo_d2 * t2
                    - satCalcData.neo.neo_d3 * t3 - satCalcData.neo.neo_d4 * t4;
                tempe = tempe + satCalcData.rec_bstar * satCalcData.neo.neo_cc5
                    * (Math.Sin(mm) - satCalcData.neo.neo_sinmao);
                templ = templ + satCalcData.neo.neo_t3cof * t3 + t4 *
                    (satCalcData.neo.neo_t4cof + satCalcData.neo.neo_t *
                    satCalcData.neo.neo_t5cof);
            }
            nm = satCalcData.rec_no;
            em = satCalcData.rec_ecco;
            inclm = satCalcData.rec_inclo;
            if ( satCalcData.neo.neo_method == 2 ) {
                tc = satCalcData.neo.neo_t;
                deepSpaceContr(satCalcData.dso.dso_irez,
                    satCalcData.dso.dso_d2201,
                    satCalcData.dso.dso_d2211, satCalcData.dso.dso_d3210,
                    satCalcData.dso.dso_d3222, satCalcData.dso.dso_d4410,
                    satCalcData.dso.dso_d4422, satCalcData.dso.dso_d5220,
                    satCalcData.dso.dso_d5232, satCalcData.dso.dso_d5421,
                    satCalcData.dso.dso_d5433, satCalcData.dso.dso_dedt,
                    satCalcData.dso.dso_del1, satCalcData.dso.dso_del2,
                    satCalcData.dso.dso_del3, satCalcData.dso.dso_didt,
                    satCalcData.dso.dso_dmdt, satCalcData.dso.dso_dnodt,
                    satCalcData.dso.dso_domdt, satCalcData.rec_argpo,
                    satCalcData.neo.neo_argpdot, satCalcData.neo.neo_t,
                    tc, satCalcData.dso.dso_gsto, satCalcData.dso.dso_xfact,
                    satCalcData.dso.dso_xlamo, satCalcData.rec_no);
            }
            // Check if mean motion is less than or equal to zero
            if (nm <= 0.0)
            {
                satCalcData.rec_error = 2;
                throw new System.ArgumentException(tleElementData.getName() + " -MeanMotion is zero or less", "Sgp4Calculation");
                // throw an exception only if this is a fatal condition
                // which may result in a divide by zero error, otherwise
                // try and recover
            }

            am = Math.Pow((xke / nm), x2o3) * tempa * tempa;
            nm = xke / Math.Pow(am, 1.5);
            // subtract drag effects on the eccentricity
            em = em - tempe;

            // Check for eccentricity being out of bounds
            if ((em >= 1.0) || (em < -0.001) || (am < 0.95))
            {
                satCalcData.rec_error = 1;
                throw new System.ArgumentException(tleElementData.getName() + " -Eccentricity is out of bounds", "Sgp4Calculation");
            }
            // If it is less than zero, try and correct by making eccentricity a
            // small value
            if (em < 0.0)
                em = 1.0e-6;
            mm = mm + satCalcData.rec_no * templ;
            xlm = mm + argpm + omegam;
            emsq = em * em;
            temp = 1.0 - emsq;
            omegam = modfunc(omegam, twoPi);
            argpm = modfunc(argpm, twoPi);
            xlm = modfunc(xlm, twoPi);
            mm = modfunc(xlm - argpm - omegam, twoPi);

            sinim = Math.Sin(inclm);
            cosim = Math.Cos(inclm);

            satCalcData.rec_ep = em;
            satCalcData.rec_xincp = inclm;
            satCalcData.rec_argpp = argpm;
            satCalcData.rec_omegap = omegam;
            satCalcData.rec_mp = mm;
            sinip = sinim;
            cosip = cosim;
            if (satCalcData.neo.neo_method == 2) {
                tc = satCalcData.neo.neo_t;
                deepSpacePeriodic(satCalcData.dso.dso_e3, satCalcData.dso.dso_ee2,
                            satCalcData.dso.dso_peo,
                            satCalcData.dso.dso_pgho, satCalcData.dso.dso_pho,
                            satCalcData.dso.dso_pinco, satCalcData.dso.dso_plo,
                            satCalcData.dso.dso_se2, satCalcData.dso.dso_se3,
                            satCalcData.dso.dso_sgh2, satCalcData.dso.dso_sgh3,
                            satCalcData.dso.dso_sgh4, satCalcData.dso.dso_sh2,
                            satCalcData.dso.dso_sh3, satCalcData.dso.dso_si2,
                            satCalcData.dso.dso_si3, satCalcData.dso.dso_sl2,
                            satCalcData.dso.dso_sl3, satCalcData.dso.dso_sl4,
                            satCalcData.neo.neo_t, satCalcData.dso.dso_xgh2,
                            satCalcData.dso.dso_xgh3, satCalcData.dso.dso_xgh4,
                            satCalcData.dso.dso_xh2, satCalcData.dso.dso_xh3,
                            satCalcData.dso.dso_xi2, satCalcData.dso.dso_xi3,
                            satCalcData.dso.dso_xl2, satCalcData.dso.dso_xl3,
                            satCalcData.dso.dso_xl4, satCalcData.dso.dso_zmol,
                            satCalcData.dso.dso_zmos, 0);

                // Correct for negative inclination
                if (satCalcData.rec_xincp < 0.0)
                {
                    satCalcData.rec_xincp = -satCalcData.rec_xincp;
                    satCalcData.rec_omegap = satCalcData.rec_omegap + Math.PI;
                    satCalcData.rec_argpp = satCalcData.rec_argpp - Math.PI;
                }

                // Another eccentricity check
                if ((satCalcData.rec_ep < 0.0) || (satCalcData.rec_ep > 1.0))
                {
                    satCalcData.rec_error = 1;
                    throw new System.ArgumentException(tleElementData.getName() + " -Eccentricity is out of bounds", "Sgp4Calculation");
                }
            }

            if (satCalcData.neo.neo_method == 2) {
                sinip = Math.Sin(satCalcData.rec_xincp);
                cosip = Math.Cos(satCalcData.rec_xincp);
                satCalcData.neo.neo_aycof = -0.5 * j3oj2 * sinip;
                satCalcData.neo.neo_xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip)
                    / (1.0 + cosip);
            }
            axnl = satCalcData.rec_ep * Math.Cos(satCalcData.rec_argpp);
            temp = 1.0 / (am * (1.0 - satCalcData.rec_ep * satCalcData.rec_ep));
            aynl = satCalcData.rec_ep * Math.Sin(satCalcData.rec_argpp) + temp
                * satCalcData.neo.neo_aycof;
            xl = satCalcData.rec_mp + satCalcData.rec_argpp + satCalcData.rec_omegap + temp
                * satCalcData.neo.neo_xlcof * axnl;

            /* --------------------- solve kepler's equation --------------- */
            u = modfunc(xl - satCalcData.rec_omegap, twoPi);
            eo1 = u;
            tem5 = 9999.9;
            ktr = 1;

            while (( Math.Abs(tem5) >= 1.0e-12) && (ktr <= 10))
            {
                sineo1 = Math.Sin(eo1);
                coseo1 = Math.Cos(eo1);
                tem5 = 1.0 - coseo1 * axnl - sineo1 * aynl;
                tem5 = (u - aynl * coseo1 + axnl * sineo1 - eo1) / tem5;
                if (Math.Abs(tem5) >= 0.95)
                    tem5 = tem5 > 0.0 ? 0.95 : -0.95;
                eo1 = eo1 + tem5;
                ktr = ktr + 1;
            }

            ecose = axnl * coseo1 + aynl * sineo1;
            esine = axnl * sineo1 - aynl * coseo1;
            el2 = axnl * axnl + aynl * aynl;
            pl = am * (1.0 - el2);

            if (pl < 0.0)
            {
                satCalcData.rec_error = 4;
                throw new System.InvalidOperationException(tleElementData.getName() + " -No data could be generated");
                // This error results in no data generated
            }
            else
            {
                rl = am * (1.0 - ecose);
                rdotl = Math.Sqrt(am) *esine / rl;
                rvdotl = Math.Sqrt(pl) / rl;
                betal = Math.Sqrt(1.0 - el2);
                temp =esine / (1.0 + betal);
                sinu = am / rl * (sineo1 - aynl - axnl * temp);
                cosu = am / rl * (coseo1 - axnl + aynl * temp);
                su = Math.Atan2(sinu, cosu);
                sin2u = (cosu + cosu) * sinu;
                cos2u = 1.0 - 2.0 * sinu * sinu;
                temp = 1.0 / pl;
                temp1 = 0.5 * j2 * temp;
                temp2 = temp1 * temp;

                /* -------------- update for short period periodics ------------ */
                if (satCalcData.neo.neo_method == 2)
                {
                    cosisq = cosip * cosip;
                    satCalcData.neo.neo_con41 = 3.0 * cosisq - 1.0;
                    satCalcData.neo.neo_x1mth2 = 1.0 - cosisq;
                    satCalcData.neo.neo_x7thm1 = 7.0 * cosisq - 1.0;
                }

                mrt = rl * (1.0 - 1.5 * temp2 * betal * satCalcData.neo.neo_con41)
                    + 0.5 * temp1 * satCalcData.neo.neo_x1mth2 * cos2u;
                su = su - 0.25 * temp2 * satCalcData.neo.neo_x7thm1 * sin2u;
                xnode = satCalcData.rec_omegap + 1.5 * temp2 * cosip * sin2u;
                xinc = satCalcData.rec_xincp + 1.5 * temp2 * cosip * sinip * cos2u;
                mvt = rdotl - nm * temp1 * satCalcData.neo.neo_x1mth2 * sin2u / xke;
                rvdot = rvdotl
                    + nm
                    * temp1
                    * (satCalcData.neo.neo_x1mth2 * cos2u + 1.5 * satCalcData.neo.neo_con41)
                    / xke;

                /* --------------------- orientation vectors ------------------- */
                sinsu = Math.Sin(su);
                cossu = Math.Cos(su);
                snod = Math.Sin(xnode);
                cnod = Math.Cos(xnode);
                sini = Math.Sin(xinc);
                cosi = Math.Cos(xinc);
                xmx = -snod * cosi;
                xmy = cnod * cosi;
                ux = xmx * sinsu + cnod * cossu;
                uy = xmy * sinsu + snod * cossu;
                uz = sini * sinsu;
                vx = xmx * cossu - cnod * sinsu;
                vy = xmy * cossu - snod * sinsu;
                vz = sini * cossu;

                /* ------------------- position and velocity ------------------- */

                satCalcData.rec_r[0] = mrt * ux;
                satCalcData.rec_r[1] = mrt * uy;
                satCalcData.rec_r[2] = mrt * uz;
                satCalcData.rec_v[0] = mvt * ux + rvdot * vx;
                satCalcData.rec_v[1] = mvt * uy + rvdot * vy;
                satCalcData.rec_v[2] = mvt * uz + rvdot * vz;
            }

            if (satCalcData.rec_error > 0)
            {
                if (satCalcData.rec_error == 4)
                {

                }
            }

            Sgp4Data data = new Sgp4Data(satCalcData.rec_satnum);

            data.setX(satCalcData.rec_r[0] * radiusEarthKm);
            data.setY(satCalcData.rec_r[1] * radiusEarthKm);
            data.setZ(satCalcData.rec_r[2] * radiusEarthKm);

            data.setXDot(satCalcData.rec_v[0] * vkmpersec);
            data.setYDot(satCalcData.rec_v[1] * vkmpersec);
            data.setZDot(satCalcData.rec_v[2] * vkmpersec);

            return data;
        }