Beispiel #1
0
/*
 * calculate lookangle between the observer and the passed in Eci object
 */
CoordTopocentric Observer::GetLookAngle(const Eci &eci)
{
    /*
     * update the observers Eci to match the time of the Eci passed in
     * if necessary
     */
    Update(eci.GetDateTime());

    /*
     * calculate differences
     */
    Vector range_rate = eci.Velocity() - m_eci.Velocity();
    Vector range = eci.Position() - m_eci.Position();

    range.w = range.Magnitude();

    /*
     * Calculate Local Mean Sidereal Time for observers longitude
     */
    double theta = eci.GetDateTime().ToLocalMeanSiderealTime(m_geo.longitude);

    double sin_lat = sin(m_geo.latitude);
    double cos_lat = cos(m_geo.latitude);
    double sin_theta = sin(theta);
    double cos_theta = cos(theta);

    double top_s = sin_lat * cos_theta * range.x
        + sin_lat * sin_theta * range.y - cos_lat * range.z;
    double top_e = -sin_theta * range.x
        + cos_theta * range.y;
    double top_z = cos_lat * cos_theta * range.x 
        + cos_lat * sin_theta * range.y + sin_lat * range.z;
    double az = atan(-top_e / top_s);

    if (top_s > 0.0)
    {
        az += kPI;
    }

    if (az < 0.0)
    {
        az += 2.0 * kPI;
    }

    double el = asin(top_z / range.w);
    double rate = range.Dot(range_rate) / range.w;

    /*
     * azimuth in radians
     * elevation in radians
     * range in km
     * range rate in km/s
     */
    return CoordTopocentric(az,
            el,
            range.w,
            rate);
}
int computeCartesianToTwoLineElementResiduals( const gsl_vector* independentVariables,
                                               void* parameters,
                                               gsl_vector* residuals )
{
    const Vector6 targetState
        = static_cast< CartesianToTwoLineElementsParameters< Vector6 >* >( parameters )->targetState;
    const Tle templateTle
        = static_cast< CartesianToTwoLineElementsParameters< Vector6 >* >( parameters )->templateTle;

    // Create a TLE object with the mean TLE elements generated by the root-finder.
    Tle tle = templateTle;

    Real meanInclination = sml::computeModulo( std::fabs( gsl_vector_get( independentVariables, 0 ) ), 180.0 );
    Real meanRightAscendingNode = sml::computeModulo( gsl_vector_get( independentVariables, 1 ), 360.0 );

    Real meanEccentricity = gsl_vector_get( independentVariables, 2 );
    if ( meanEccentricity < 0.0 )
    {
        meanEccentricity = std::fabs( gsl_vector_get( independentVariables, 2 ) );
    }

    if ( meanEccentricity > 0.999 )
    {
        meanEccentricity = 0.99;
    }

    Real meanArgumentPerigee =  sml::computeModulo( gsl_vector_get( independentVariables, 3 ), 360.0 );
    Real meanMeanAnomaly =  sml::computeModulo( gsl_vector_get( independentVariables, 4 ), 360.0 );
    Real meanMeanMotion = std::fabs( gsl_vector_get( independentVariables, 5 ) );

    tle.updateMeanElements( meanInclination,
                            meanRightAscendingNode,
                            meanEccentricity,
                            meanArgumentPerigee,
                            meanMeanAnomaly,
                            meanMeanMotion );

    // Propagate the TLE object to the specified epoch using the SGP4 propagator.
    SGP4 sgp4( tle );
    Eci cartesianState = sgp4.FindPosition( 0.0 );

    // Compute residuals by computing the difference between the Cartesian state generated by the
    // SGP4 propagator and the target Cartesian state.
    gsl_vector_set( residuals, astro::xPositionIndex, cartesianState.Position( ).x - targetState[ astro::xPositionIndex ] );
    gsl_vector_set( residuals, astro::yPositionIndex, cartesianState.Position( ).y - targetState[ astro::yPositionIndex ] );
    gsl_vector_set( residuals, astro::zPositionIndex, cartesianState.Position( ).z - targetState[ astro::zPositionIndex ] );
    gsl_vector_set( residuals, astro::xVelocityIndex, cartesianState.Velocity( ).x - targetState[ astro::xVelocityIndex ] );
    gsl_vector_set( residuals, astro::yVelocityIndex, cartesianState.Velocity( ).y - targetState[ astro::yVelocityIndex ] );
    gsl_vector_set( residuals, astro::zVelocityIndex, cartesianState.Velocity( ).z - targetState[ astro::zVelocityIndex ] );

    return GSL_SUCCESS;
}
Beispiel #3
0
void tle::eph_impl(double mjd2000, array3D &r, array3D &v) const {
	Vector position;
	Vector velocity;
	double minutes_since = (mjd2000-m_ref_mjd2000)*24*60;

	try 
	{
		Eci eci = m_sgp4_propagator.FindPosition(minutes_since);
		position = eci.Position();
		velocity = eci.Velocity();
		r[0] = position.x*1000; r[1] = position.y*1000; r[2] = position.z*1000;
		v[0] = velocity.x*1000; v[1] = velocity.y*1000; v[2] = velocity.z*1000;
	}
	catch (SatelliteException& e)
	{
		std::cout << "SatelliteException caught while computing ephemerides" << std::endl;
		throw_value_error(e.what());
	}
	catch (DecayedException& e)
	{
		std::cout << "DecayedException caught while computing ephemerides" << std::endl;
		throw_value_error(e.what());
	}
}
Beispiel #4
0
int computeAtomResiduals( const gsl_vector* independentVariables,
                          void* parameters,
                          gsl_vector* residuals )
{
    // Store parameters locally.
    const Vector3 departurePosition = static_cast< AtomParameters< Real, Vector3 >* >(
        parameters )->departurePosition;

    const DateTime departureEpoch
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->departureEpoch;

    const Vector3 targetPosition = static_cast< AtomParameters< Real, Vector3 >* >(
        parameters )->targetPosition;

    const Real timeOfFlight
        = static_cast< AtomParameters< Real, Vector3 >* >(
            parameters )->timeOfFlight;

    const Real earthGravitationalParameter
        = static_cast< AtomParameters< Real, Vector3 >* >(
            parameters )->earthGravitationalParameter;

    const Real earthMeanRadius
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->earthMeanRadius;

    const Tle referenceTle
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->referenceTle;

    const Real absoluteTolerance
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->absoluteTolerance;

    const Real relativeTolerance
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->relativeTolerance;

    const int maximumIterations
        = static_cast< AtomParameters< Real, Vector3 >* >( parameters )->maximumIterations;

    // Set Departure state [km; km/s].
    std::vector< Real > departureVelocity( 3 );
    for ( int i = 0; i < 3; i++ )
    {
        departureVelocity[ i ] = gsl_vector_get( independentVariables, i );
    }

    std::vector< Real > departureState( 6 );
    for ( int i = 0; i < 3; i++ )
    {
        departureState[ i ] = departurePosition[ i ];
    }
    for ( int i = 0; i < 3; i++ )
    {
        departureState[ i + 3 ] = departureVelocity[ i ];
    }

    // Convert departure state to TLE.
    std::string dummyString = "";
    int dummyint = 0;
    const Tle departureTle = convertCartesianStateToTwoLineElements(
        departureState,
        departureEpoch,
        dummyString,
        dummyint,
        referenceTle,
        earthGravitationalParameter,
        earthMeanRadius,
        absoluteTolerance,
        relativeTolerance,
        maximumIterations );

    // Propagate departure TLE by time-of-flight using SGP4 propagator.
    SGP4 sgp4( departureTle );
    DateTime arrivalEpoch = departureEpoch.AddSeconds( timeOfFlight );
    Eci arrivalState = sgp4.FindPosition( arrivalEpoch );

    // Evaluate system of non-linear equations and store residuals.
    gsl_vector_set( residuals, 0,
                    ( arrivalState.Position( ).x - targetPosition[ 0 ] ) / earthMeanRadius );
    gsl_vector_set( residuals, 1,
                    ( arrivalState.Position( ).y - targetPosition[ 1 ] ) / earthMeanRadius );
    gsl_vector_set( residuals, 2,
                    ( arrivalState.Position( ).z - targetPosition[ 2 ] ) / earthMeanRadius );

    return GSL_SUCCESS;
}
Beispiel #5
0
const std::pair< Vector3, Vector3 > executeAtomSolver(
    const Vector3& departurePosition,
    const DateTime& departureEpoch,
    const Vector3& arrivalPosition,
    const Real timeOfFlight,
    const Vector3& departureVelocityGuess,
    std::string& solverStatusSummary,
    int& numberOfIterations,
    const Tle& referenceTle,
    const Real earthGravitationalParameter,
    const Real earthMeanRadius,
    const Real absoluteTolerance,
    const Real relativeTolerance,
    const int maximumIterations )
{
    // Set up parameters for residual function.
    AtomParameters< Real, Vector3 > parameters( departurePosition,
                                                departureEpoch,
                                                arrivalPosition,
                                                timeOfFlight,
                                                earthGravitationalParameter,
                                                earthMeanRadius,
                                                referenceTle,
                                                absoluteTolerance,
                                                relativeTolerance,
                                                maximumIterations );

    // Set up residual function.
    gsl_multiroot_function atomFunction
        = {
            &computeAtomResiduals< Real, Vector3 >, 3, &parameters
          };

    // Set initial guess.
    gsl_vector* initialGuess = gsl_vector_alloc( 3 );
    for ( int i = 0; i < 3; i++ )
    {
        gsl_vector_set( initialGuess, i, departureVelocityGuess[ i ] );
    }

    // Set up solver type (derivative free).
    const gsl_multiroot_fsolver_type* solverType = gsl_multiroot_fsolver_hybrids;

    // Allocate memory for solver.
    gsl_multiroot_fsolver* solver = gsl_multiroot_fsolver_alloc( solverType, 3 );

    // Set solver to use residual function with initial guess.
    gsl_multiroot_fsolver_set( solver, &atomFunction, initialGuess );

     // Declare current solver status and iteration counter.
    int solverStatus = false;
    int counter = 0;

    // Set up buffer to store solver status summary table.
    std::ostringstream summary;

    // Print header for summary table to buffer.
    summary << printAtomSolverStateTableHeader( );

    do
    {
        // Print current state of solver for summary table.
        summary << printAtomSolverState( counter, solver );

        // Increment iteration counter.
        ++counter;
        // Execute solver iteration.
        solverStatus = gsl_multiroot_fsolver_iterate( solver );

        // Check if solver is stuck; if it is stuck, break from loop.
        if ( solverStatus )
        {
            std::cerr << "GSL solver status: " << solverStatus << std::endl;
            std::cerr << summary.str( ) << std::endl;
            std::cerr << std::endl;
            throw std::runtime_error( "ERROR: Non-linear solver is stuck!" );
        }

        // Check if root has been found (within tolerance).
        solverStatus = gsl_multiroot_test_delta(
          solver->dx, solver->x, absoluteTolerance, relativeTolerance );
    } while ( solverStatus == GSL_CONTINUE && counter < maximumIterations );

    // Save number of iterations.
    numberOfIterations = counter - 1;

    // Print final status of solver to buffer.
    summary << std::endl;
    summary << "Status of non-linear solver: " << gsl_strerror( solverStatus ) << std::endl;
    summary << std::endl;

    // Write buffer contents to solver status summary string.
    solverStatusSummary = summary.str( );

    // Store final departure velocity.
    Vector3 departureVelocity = departureVelocityGuess;
    for ( int i = 0; i < 3; i++ )
    {
        departureVelocity[ i ] = gsl_vector_get( solver->x, i );
    }

    // Set departure state [km/s].
    std::vector< Real > departureState( 6 );
    for ( int i = 0; i < 3; i++ )
    {
        departureState[ i ] = departurePosition[ i ];
    }
    for ( int i = 0; i < 3; i++ )
    {
        departureState[ i + 3 ] = departureVelocity[ i ];
    }

    // Convert departure state to TLE.
    std::string dummyString = "";
    int dummyint = 0;
    const Tle departureTle = convertCartesianStateToTwoLineElements< Real >(
        departureState,
        departureEpoch,
        dummyString,
        dummyint,
        referenceTle,
        earthGravitationalParameter,
        earthMeanRadius,
        absoluteTolerance,
        relativeTolerance,
        maximumIterations );

    // Propagate departure TLE by time-of-flight using SGP4 propagator.
    SGP4 sgp4( departureTle );
    DateTime arrivalEpoch = departureEpoch.AddSeconds( timeOfFlight );
    Eci arrivalState = sgp4.FindPosition( arrivalEpoch );

    Vector3 arrivalVelocity = departureVelocity;
    arrivalVelocity[ 0 ] = arrivalState.Velocity( ).x;
    arrivalVelocity[ 1 ] = arrivalState.Velocity( ).y;
    arrivalVelocity[ 2 ] = arrivalState.Velocity( ).z;

    // Free up memory.
    gsl_multiroot_fsolver_free( solver );
    gsl_vector_free( initialGuess );

    // Return departure and arrival velocities.
    return std::make_pair< Vector3, Vector3 >( departureVelocity, arrivalVelocity );
}