++ed by:
HAMMER TYLDUM BKB

3 PAUSE users

Tom Wyant
and 1 contributors

NAME

Astro::Coord::ECI::TLE - Compute satellite locations using NORAD orbit propagation models

SYNOPSIS

The following is a semi-brief script to calculate Iridium flares. You will need to substitute your own location where indicated.

 use Astro::SpaceTrack;
 use Astro::Coord::ECI;
 use Astro::Coord::ECI::TLE;
 use Astro::Coord::ECI::TLE::Set;
 use Astro::Coord::ECI::Utils qw{deg2rad rad2deg};
 
 # 1600 Pennsylvania Avenue, Washington DC, USA
 my $your_north_latitude_in_degrees = 38.898748;
 my $your_east_longitude_in_degrees = -77.037684;
 my $your_height_above_sea_level_in_meters = 16.68;
 
 # Create object representing the observers' location.
 # Note that the input to geodetic() is latitude north
 # and longitude west, in RADIANS, and height above sea
 # level in KILOMETERS.
 
 my $loc = Astro::Coord::ECI->geodetic (
    deg2rad ($your_north_latitude_in_degrees),
    deg2rad ($your_east_longitude_in_degrees),
    $your_height_above_sea_level_in_meters/1000);
 
 # Get all the Space Station data from NASA's human
 # spaceflight page. It is all direct-fetched, so no
 # password is needed.
 
 my $st = Astro::SpaceTrack->new (direct => 1);
 my $data = $st->spaceflight ('-all');
 $data->is_success or die $data->status_line;
 
 # Parse the fetched data, yielding TLE objects. Aggregate
 # them into Set objects where this is warranted, since the
 # Manned Spaceflight website gives multiple sets of
 # orbital elements for each object, and aggregation lets
 # us use whichever one is best for the time.
 
 my @sats = Astro::Coord::ECI::TLE::Set->aggregate(
     Astro::Coord::ECI::TLE->parse ($data->content));

 # Turn off the ability to use orbital elements before their
 # epoch. This is normally harmless, but in this case the
 # data may include predicted Space Shuttle data, in which
 # case we are really using the epoch of the first data set
 # as proxy for liftoff time.
 
 foreach my $tle (@sats) {
    $tle->set(backdate => 0);
 }
 
 # We want passes for the next 7 days.
  
 my $start = time ();
 my $finish = $start + 7 * 86400;
 my @passes;
 foreach my $tle (@sats) {
    push @passes, $tle->pass($loc, $start, $finish);
 }
 print <<eod;
      Date/Time          Satellite        Elevation  Azimuth Event
 eod
 foreach my $pass (sort {$a->{time} <=> $b->{time}} @passes) {
 
 #  The returned angles are in radians, so we need to
 #  convert back to degrees.
 #
 #  Note that unless Scalar::Util::dualvar works, the event output
 #  will be integers.
 
    print "\n";
 
    foreach my $event (@{$pass->{events}}) {
        printf "%s %-15s %9.1f %9.1f %-5s\n",
            scalar localtime $event->{time},
            $event->{body}->get ('name'),
            rad2deg ($event->{elevation}),
            rad2deg ($event->{azimuth}),
            $event->{event};
    }
 }

DESCRIPTION

This module implements the NORAD orbital propagation models described in their "SPACETRACK REPORT NO. 3, Models for Propagation of NORAD Element Sets." In other words, it turns the two- or three-line element sets available from such places as http://www.space-track.org/ or http://celestrak.com/ into predictions of where the relevant orbiting bodies will be. Additionally, the pass() method implements an actual visibility prediction system.

The models implemented are:

  SGP - fairly simple, only useful for near-earth bodies;
  SGP4 - more complex, only useful for near-earth bodies;
  SDP4 - corresponds to SGP4, but for deep-space bodies;
  SGP8 - more complex still, only for near-earth bodies;
  SDP8 - corresponds to SGP8, but for deep-space bodies;
  SGP4R - updates and combines SGP4 and SDP4.

All the above models compute ECI coordinates in kilometers, and velocities along the same axes in kilometers per second.

There are also some meta-models, with the smarts to run either a near-earth model or the corresponding deep-space model depending on the body the object represents:

  model - uses the preferred model (sgp4r);
  model4 - runs sgp4 or sdp4;
  model4r - runs sgp4r;
  model8 - runs sgp8 or sdp8.

In addition, I have on at least one occasion wanted to turn off the automatic calculation of position when the time was set. That is accomplished with this model:

  null - does nothing.

The models do not return the coordinates directly, they simply set the coordinates represented by the object (by virtue of being a subclass of Astro::Coord::ECI) and return the object itself. You can then call the appropriate inherited method to get the coordinates of the body in whatever coordinate system is convenient. For example, to find the latitude, longitude, and altitude of a body at a given time, you do

  my ($lat, $long, $alt) = $body->model ($time)->geodetic;

Or, assuming the model attribute is set the way you want it, by

  my ($lat, $long, $alt) = $body->geodetic ($time);

It is also possible to run the desired model (as specified by the model attribute) simply by setting the time represented by the object.

As of release 0.016, the recommended model to use is SGP4R, which was added in that release. The SGP4R model, described in "Revisiting Spacetrack Report #3" (http://celestrak.com/publications/AIAA/2006-6753/), combines SGP4 and SDP4, and updates them. For the details of the changes, see the report.

Prior to release 0.016, the recommended model to use was either SGP4 or SDP4, depending on whether the orbital elements are for a near-earth or deep-space body. For the purpose of these models, any body with a period of at least 225 minutes is considered to be a deep-space body.

The NORAD report claims accuracy of 5 or 6 places a day after the epoch of an element set for the original FORTRAN IV, which used (mostly) 8 place single-precision calculations. Perl typically uses many more places, but it does not follow that the models are correspondingly more accurate when implemented in Perl. My understanding is that in general (i.e. disregarding the characteristics of a particular implementation of the models involved) the total error of the predictions (including error in measuring the position of the satellite) runs from a few hundred meters to as much as a kilometer.

I have no information on the accuracy claims of SGP4R.

This module is a computer-assisted translation of the FORTRAN reference implementations in "SPACETRACK REPORT NO. 3" and "Revisiting Spacetrack Report #3." That means, basically, that I ran the FORTRAN through a Perl script that handled the translation of the assignment statements into Perl, and then fixed up the logic by hand. Dominik Borkowski's SGP C-lib was used as a reference implementation for testing purposes, because I didn't have a Pascal compiler, and I have yet to get any model but SGP to run correctly under g77.

Methods

The following methods should be considered public:

$tle = Astro::Coord::ECI::TLE->new()

This method instantiates an object to represent a NORAD two- or three-line orbital element set. This is a subclass of Astro::Coord::ECI.

Any arguments get passed to the set() method.

It is both anticipated and recommended that you use the parse() method instead of this method to create an object, since the models currently have no code to guard against incomplete data.

$tle->after_reblessing (\%possible_attributes)

This method supports reblessing into a subclass, with the argument representing attributes that the subclass may wish to set. It is called by rebless() and should not be called by the user.

At this level it does nothing.

Astro::Coord::ECI::TLE->alias (name => class ...)

This static method adds an alias for a class name, for the benefit of users of the status() method and 'illum' attributes, and ultimately of the rebless() method. It is intended to be used by subclasses to register short names for themselves upon initialization, though of course you can call it yourself as well.

For example, this class calls

 __PACKAGE__->alias (tle => __PACKAGE__);

You can register more than one alias in a single call. Aliases can be deleted by assigning them a false value (e.g. '' or undef).

If called without arguments, it returns the current aliases.

You can actually call this as a normal method, but it still behaves like a static method.

$tle->before_reblessing ()

This method supports reblessing into a subclass. It is intended to do any cleanup the old class needs before reblessing into the new class. It is called by rebless(), and should not be called by the user.

At this level it does nothing.

$tle->can_flare ()

This method returns true if the object is capable of generating flares (i.e. predictable bright flashes) and false otherwise. At this level of the inheritance hierarchy, it always returns false, but subclasses may return true.

$value = $tle->ds50($time)

This method converts the time to days since 1950 Jan 0, 0 h GMT. The time defaults to the epoch of the data set. This method does not affect the $tle object - it is exposed for convenience and for testing purposes.

It can also be called as a "static" method, i.e. as Astro::Coord::ECI::TLE->ds50 ($time), but in this case the time may not be defaulted, and no attempt has been made to make this a pretty error.

$value = $tle->get('attribute')

This method retrieves the value of the given attribute. See the "Attributes" section for a description of the attributes.

$deep = $tle->is_deep();

This method returns true if the object is in deep space - meaning that its period is at least 225 minutes (= 13500 seconds).

$boolean = $tle->is_model_attribute ($name);

This method returns true if the named attribute is an attribute of the model - i.e. it came from the TLE data and actually affects the model computations. It is really for the benefit of Astro::Coord::ECI::TLE::Set, so that class can determine how its set() method should handle the attribute.

$boolean = $tle->is_valid_model ($model_name);

This method returns true if the given name is the name of an orbital model, and false otherwise.

Actually, in the spirit of UNIVERSAL::can, it returns a reference to the code if the model exists, and undef otherwise.

This is really for the benefit of Astro::Coord::ECI::TLE::Set, so it can select the correct member object before running the model.

$tle = $tle->model($time)

This method calculates the position of the body described by the TLE object at the given time, using the preferred model. As of Astro::Coord::ECI::TLE 0.010_10 this is sgp4r; previously it was sgp4 or sdp4, whichever was appropriate.

The intent is that this method will use whatever model is currently preferred. If the preferred model changes, this method will use the new preferred model as soon as I:

  - Find out about the change;
  - Can get the specifications for the new model;
  - Can find the time to code up the new model.

You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

$tle = $tle->model4 ($time)

This method calculates the position of the body described by the TLE object at the given time, using either the SGP4 or SDP4 model, whichever is appropriate.

You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

$tle = $tle->model4r ($time)

This method calculates the position of the body described by the TLE object at the given time, using the "Revisiting Spacetrack Report #3" model (sgp4r). It is really just a synonym for sgp4r, which covers both near-earth and deep space bodies, but is provided for consistency's sake. If some other model becomes preferred, this method will still call sgp4r.

You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

$tle = $tle->model8 ($time)

This method calculates the position of the body described by the TLE object at the given time, using either the SGP8 or SDP8 model, whichever is appropriate.

You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

$tle = $tle->null ($time)

This method does nothing. It is a valid orbital model, though. If you call $tle->set (model => 'null'), no position calculation is done as a side effect of calling $tle->universal ($time).

@elements = Astro::Coord::ECI::TLE->parse (@data);

This method parses a NORAD two- or three-line element set (or a mixture), returning a list of Astro::Coord::ECI::TLE objects. The "Attributes" section identifies those attributes which will be filled in by this method.

The input will be split into individual lines, and all blank lines and lines beginning with '#' will be eliminated. The remaining lines are assumed to represent two- or three-line element sets, in so-called external format. Internal format (denoted by a 'G' in column 79 of line 1 of the set, not counting the common name if any) is not supported, and the presence of such data will result in an exception being thrown.

@passes = $tle->pass ($station, $start, $end, \@sky)

This method returns passes of the body over the given station between the given start end end times. The \@sky argument is background bodies to compute appulses with.

All arguments except $station are optional, the defaults being

 $start = time()
 $end = $start + 7 days
 \@sky = []

The return is a list of passes, which may be empty. Each pass is represented by an anonymous hash containing the following keys:

  {body} => Reference to body making pass;
  {time} => Time of pass (culmination);
  {events} => [the individual events of the pass].

The individual events are also anonymous hashes, with each hash containing the following keys:

  {azimuth} => Azimuth of event in radians;
  {body} => Reference to body making pass;
  {appulse} => {  # This is present only for PASS_EVENT_APPULSE;
      {angle} => minimum separation in radians;
      {body} => other body involved in appulse;
      }
  {elevation} => Elevation of event in radians;
  {event} => Event code (PASS_EVENT_xxxx);
  {illumination} => Illumination at time of event (PASS_EVENT_xxxx);
  {range} => Distance to event in kilometers;
  {station} => Reference to observing station;
  {time} => Time of event;

Note that the time set in the various {body} and {station} objects is not guaranteed to be anything in particular. Specifically, it is almost certainly not the time of the event.

The events are coded by the following manifest constants:

  PASS_EVENT_NONE => dualvar (0, '');
  PASS_EVENT_SHADOWED => dualvar (1, 'shdw');
  PASS_EVENT_LIT => dualvar (2, 'lit');
  PASS_EVENT_DAY => dualvar (3, 'day');
  PASS_EVENT_RISE => dualvar (4, 'rise');
  PASS_EVENT_MAX => dualvar (5, 'max');
  PASS_EVENT_SET => dualvar (6, 'set');
  PASS_EVENT_APPULSE => dualvar (7, 'apls');

The dualvar function comes from Scalar::Util, and generates values which are numeric in numeric context and strings in string context. If Scalar::Util cannot be loaded the numeric values are returned.

These manifest constants can be imported using the individual names, or the tags ':constant' or ':all'. They can also be accessed as methods using (e.g.) $tle->PASS_EVENT_LIT, or as static methods using (e.g.) Astro::Coord::ECI::TLE->PASS_EVENT_LIT.

Illumination is represented by one of PASS_EVENT_SHADOWED, PASS_EVENT_LIT, or PASS_EVENT_DAY. The first two are calculated based on whether the illuminating body (i.e. the body specified by the 'illum' attribute) is above the horizon; the third is based on whether the Sun is higher than specified by the 'twilight' attribute, and trumps the other two (i.e. if it's day it doesn't matter whether the satellite is illuminated).

Time resolution of the events is typically to the nearest second, except for appulses, which need to be calculated more closely to detect transits. The time reported for the event is the time after the event occurred. For example, the time reported for rise is the earliest time the body is found above the horizon, and the time reported for set is the earliest time the body is found below the horizon.

The operation of this method is affected by the following attributes, in addition to its arguments and the orbital elements associated with the object:

  * appulse     # Maximum appulse to report
  * geometric   # Use geometric horizon for pass rise/set
  * horizon     # Effective horizon
  * interval    # Interval for pass() positions, if positive
  * illum       # Source of illumination.
  * limb        # Whether lit when upper limb above horizon
  * twilight    # Distance of illuminator below horizon
  * visible     # Pass() reports only illuminated passes
$seconds = $tle->period ($model);

This method returns the orbital period of the object in seconds using the given model. If the model is unspecified (or specified as a false value), the current setting of the 'model' attribute is used.

There are actually only two period calculations available. If the model is 'sgp4r' (or its equivalents 'model' and 'model4r'), the sgp4r calculation will be used. Otherwise the calculation from the original Space Track Report Number 3 will be used. 'Otherwise' includes the case where the model is 'null'.

The difference between using the original and the revised algorithm is minimal. For the objects in the sgp4-ver.tle file provided with the 'Revisiting Spacetrack Report #3' code, the largest is about 50 nanoseconds for OID 23333, which is in a highly eccentric orbit.

The difference between using the various values of gravconst_r with sgp4r is somewhat more pronounced. Among the objects in sgp4-ver.tle the largest difference was about a millisecond, again for OID 23333.

Neither of these differences seems to me significant, but I thought it would be easier to take the model into account than to explain why I did not.

$tle = $tle->rebless ($class, \%possible_attributes)

This method reblesses a TLE object. The class must be either Astro::Coord::TLE or a subclass thereof, as must the object passed in to be reblessed. If the $tle object has its reblessable attribute false, it will not be reblessed, but will be returned unmodified. Before reblessing, the before_reblessing() method is called. After reblessing, the after_reblessing() method is called with the \%possible_attributes hash reference as argument.

It is possible to omit the $class argument if the \%possible_attributes argument contains the keys {class} or {type}, taken in that order. If the $class argument is omitted and the \%possible_attributes hash does not have the requisite keys, the $tle object is unmodified.

It is also possible to omit both arguments, in which case the object will be reblessed according to the content of the internal status table.

For convenience, you can pass an alias instead of the full class name. The following aliases are recognized:

 iridium => 'Astro::Coord::ECI::TLE::Iridium'
 tle => 'Astro::Coord::ECI::TLE'

Other aliases may be defined with the alias() static method.

Note that this method returns the original object (possibly reblessed). It does not under any circumstances manufacture another object.

$kilometers = $tle->semimajor();

This method calculates the semimajor axis of the orbit, using Kepler's Third Law (Isaac Newton's version) in the form

 T ** 2 / a ** 3 = 4 * pi ** 2 / mu

where

 T is the orbital period,
 a is the semimajor axis of the orbit,
 pi is the circle ratio (3.14159 ...), and
 mu is the Earth's gravitational constant,
    3.986005e5 km ** 3 / sec ** 2

The calculation is carried out using the period implied by the current model.

$tle->set (attribute => value ...)

This method sets the values of the various attributes. The changing of attributes actually used by the orbital models will cause the models to be reinitialized. This happens transparently, and is no big deal. For a description of the attributes, see "Attributes".

Because this is a subclass of Astro::Coord::ECI, any attributes of that class can also be set.

Astro::Coord::ECI::TLE->status (command => arguments ...)

This method maintains the internal status table, which is used by the parse() method to determine which subclass (if any) to bless the created object into. The first argument determines what is done to the status table; subsequent arguments depend on the first argument. Valid commands and arguments are:

status (add => $id, $type => $status, $name, $comment) adds an item to the status table or modifies an existing item. The $id is the NORAD ID of the body. The only currently-supported $type is 'Astro::Coord::ECI::TLE::Iridium', but any alias to this will also work (see alias(); 'iridium' is defined by default). The $status is 0, 1, or 2, representing in-service, spare, or failed respectively. The strings '+' or '' will be interpreted as 0, 'S', 's', or '?' as 1, and any other non-numeric string as 2. The $name and $comment arguments default to empty.

status ('clear') clears the status table.

status (clear => 'type') clears all entries of the given type in the status table. For supported types, see the discussion of 'add', above.

status (drop => $id) removes the given NORAD ID from the status table.

status ('show') returns a list of list references, representing the 'add' commands which would be used to regenerate the status table.

$tle = $tle->sgp($time)

This method calculates the position of the body described by the TLE object at the given time, using the SGP model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

"Spacetrack Report Number 3" (see "Acknowledgments") says that this model can be used for either near-earth or deep-space orbits, but the reference implementation they provide dies on an attempt to use this model for a deep-space object, and I have followed the reference implementation.

$tle = $tle->sgp4($time)

This method calculates the position of the body described by the TLE object at the given time, using the SGP4 model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. See the "DESCRIPTION" heading above for how to retrieve the coordinates you just calculated.

"Spacetrack Report Number 3" (see "Acknowledgments") says that this model can be used only for near-earth orbits.

$tle = $tle->sdp4($time)

This method calculates the position of the body described by the TLE object at the given time, using the SDP4 model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

"Spacetrack Report Number 3" (see "Acknowledgments") says that this model can be used only for deep-space orbits.

$tle = $tle->sgp8($time)

This method calculates the position of the body described by the TLE object at the given time, using the SGP8 model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

"Spacetrack Report Number 3" (see "Acknowledgments") says that this model can be used only for near-earth orbits.

$tle = $tle->sdp8($time)

This method calculates the position of the body described by the TLE object at the given time, using the SDP8 model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. You need to call one of the Astro::Coord::ECI methods (e.g. geodetic () or equatorial ()) to retrieve the position you just calculated.

"Spacetrack Report Number 3" (see "Acknowledgments") says that this model can be used only for near-earth orbits.

$self->time_set();

This method sets the coordinates of the object to whatever is computed by the model specified by the model attribute. The 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

Although there is no reason this method can not be called directly, it exists to take advantage of the hook in the Astro::Coord::ECI object, to allow the position of the body to be computed when the time of the object is set.

$tle = $tle->sgp4r($time)

This method calculates the position of the body described by the TLE object at the given time, using the revised SGP4 model. The universal time of the object is set to $time, and the 'equinox_dynamical' attribute is set to the current value of the 'epoch_dynamical' attribute.

The result is the original object reference. See the "DESCRIPTION" heading above for how to retrieve the coordinates you just calculated.

The algorithm for this model comes from "Revisiting Spacetrack Report Number 3" (see ACKNOWLEDGMENTS). That report considers the algorithm to be a correction and extension of SGP4 (merging it with SDP4), and simply calls the algorithm SGP4. I have appended the "r" (for 'revised' or 'revisited', take your pick) because I have preserved the original algorithm as well.

Note well that this algorithm depends on the setting of the 'gravconst_r' attribute. The default setting of that attribute in this module is 84, but the test data that comes with "Revisiting Spacetrack Report #3" uses 72.

This algorithm is also (currently) the only one that returns a useful value in the model_error attribute, as follows:

 0 = success
 1 = mean eccentricity < 0 or > 1, or a < .95
 2 = mean motion < 0.0
 3 = instantaneous eccentricity < 0 or > 1
 4 = semi-latus rectum < 0
 5 = epoch elements are sub-orbital
 6 = satellite has decayed

These errors are dualvars if your Scalar::Util supports these. That is, they are interpreted as numbers in numeric context and the corresponding string in string context. The string is generally the explanation, except for 0, which is '' in string context. If your Scalar::Util does not support dualvar, the numeric value is returned.

Currently, errors 1 through 4 cause an explicit exception to be thrown after setting the model_error attribute. Exceptions will also be thrown if the TLE eccentricity is negative or greater than one, or the TLE mean motion is negative.

Errors 5 and 6 look more like informational errors to me. Error 5 indicates that the perigee is less than the radius of the earth. This could very well happen if the TLE represents a coasting arc of a spacecraft being launched or preparing for re-entry. Error 6 means the actual computed position was underground. Maybe this should be an exception, though I have never needed this kind of exception previously.

Note that this first release of the 'Revisiting Spacetrack Report #3' functionality should be considered alpha code. That is to say, I may need to change the way it behaves, especially in the matter of what is an exception and what is not.

Attributes

This class has the following additional public attributes. The description gives the data type. It may also give one of the following if applicable:

parse - if the attribute is set by the parse() method;

read-only - if the attribute is read-only;

static - if the attribute may be set on the class as well as an object.

Note that the orbital elements provided by NORAD are tweaked for use by the models implemented by this class. If you plug them in to the same-named parameters of other models, your mileage may vary significantly.

appulse (numeric, static)

This attribute contains the angle of the widest appulse to be reported by the pass() method, in radians.

The default is equivalent to 10 degrees.

argumentofperigee (numeric, parse)

This attribute contains the argument of perigee (angular distance from ascending node to perigee) of the orbit, in radians.

backdate (boolean, static)

This attribute determines whether the pass() method will go back before the epoch of the data. If false, the pass() method will silently adjust its start time forward. If this places the start time after the end time, an empty list is returned.

Note that this is a change from the behavior of Astro::Coord::ECI::TLE version 0.010, which threw an exception if the backdate adjustment placed the start time after the end time.

The default is 1 (i.e. true).

bstardrag (numeric, parse)

This attribute contains the B* drag term, decoded into a number.

classification (string, parse)

This attribute contains the security classification. You should expect to see only the value 'U', for 'Unclassified.'

ds50 (numeric, readonly, parse)

This attribute contains the epoch, in days since 1950. Setting the epoch also modifies this attribute.

eccentricity (numeric, parse)

This attribute contains the orbital eccentricity, with the implied decimal point inserted.

elementnumber (numeric, parse)

This attribute contains the element set number of the data set. In theory, this gets incremented every time a data set is issued.

ephemeristype (numeric, parse)

This attribute records a field in the data set which is supposed to specify which model to use with this data. In practice, it seems always to be zero.

epoch (numeric, parse)

This attribute contains the epoch of the orbital elements - that is, the 'as-of' date and time - as a Perl date. Setting this attribute also modifies the epoch_dynamical and ds50 attributes.

epoch_dynamical (numeric, readonly, parse)

This attribute contains the dynamical time corresponding to the epoch. Setting the epoch also modifies this attribute.

firstderivative (numeric, parse)

This attribute contains the first time derivative of the mean motion, in radians per minute squared.

geometric (boolean, static)

Tells the pass() method whether to calculate rise and set relative to the geometric horizon (if true) or the horizon attribute (if false)

The default is 0 (i.e. false).

gravconst_r (numeric, static)

Tells the sgp4r() method which set of gravitational constants to use. Legal values are:

 72 - Use WGS-72 values;
 721 - Use old WGS-72 values;
 84 - Use WGS-84 values.

The 'old WGS-72 values' appear from the code comments to be those embedded in the original SGP4 model given in "Space Track Report Number 3".

Note well that "Revisiting Spacetrack Report #3" says "We use WGS-72 as the default value." It does not state whether it means the values specified by 72 or the values specified by 721, but the former gives results closer to the test results included with the code.

Comparing the positions computed by this code to the positions given in the published test results, the following maximum deviations are found, depending on the gravconst_r value used:

 72 - 4 mm (oid 23333, X at epoch)
 721 - 57 cm (OID 28350, X at 1320 minutes from epoch)
 84 - 3.22 km (OID 23333, X at epoch)

The default is 72, to agree with "Revisiting Spacetrack Report #3".

id (numeric, parse)

This attribute contains the NORAD SATCAT catalog ID.

illum (string, static)

This attribute specifies the source of illumination for the body. You may specify the class name 'Astro::Coord::ECI' or the name of any subclass (though in practice only 'Astro::Coord::ECI::Sun' or 'Astro::Coord::ECI::Moon' will do anything useful), or an alias() thereof, or you may specify an object of the appropriate class. When you access this attribute, you get an object.

In addition to the full class names, 'sun' and 'moon' are set up as aliases for Astro::Coord::ECI::Sun and Astro::Coord::ECI::Moon respectively. Other aliases can be set up using the alias() mechanism. The value 'sun' (or something equivalent) is probably the only useful value, but I know people have looked into Iridium 'Moon flares', so I exposed the attribute.

The default is 'sun'.

interval (numeric, static)

If positive, this attribute specifies that the pass() method return positions at this interval (in seconds) across the sky. The associated event code of these will be PASS_EVENT_NONE. If zero or negative, pass() will only return times when some event of interest occurs.

The default is 0.

inclination (numeric, parse)

This attribute contains the orbital inclination in radians.

international (string, parse)

This attribute contains the international launch designator. This consists of three parts: a two-digit number (with leading zero if needed) giving the last two digits of the launch year (in the range 1957-2056); a three-digit number (with leading zeros if needed) giving the order of the launch within the year, and one to three letters designating the "part" of the launch, with payload(s) getting the first letters, and spent boosters, debris, etc getting the rest.

limb (boolean, static)

This attribute tells the pass() method how to compute illumination of the body. If true, it is computed based on the upper limb of the source of illumination; if false, it is based on the center.

The default is 1 (i.e. true).

meananomaly (numeric, parse)

This attribute contains the mean orbital anomaly at the epoch, in radians. In slightly less technical terms, this is the angular distance a body in a circular orbit of the same period (that is what the 'mean' means) would be from perigee at the epoch, measured in the plane of the orbit.

meanmotion (numeric, parse)

This attribute contains the mean motion of the body, in radians per minute.

model (string, static)

This attribute contains the name of the model to be run (i.e. the name of the method to be called) when the time_set() method is called, or a false value if no model is to be run. Legal model names are: model, model4, model4r, model8, null, sgp, sgp4, sgp4r, sgp8, sdp4, and sdp8.

The default is 'model'. Setting the value on the class changes the default.

model_error (number)

The sgp4r() model sets this to the number of the error encountered, with 0 representing success. See the documentation to that model for the values set. All other models simply set this to undef. This is not a read-only attribute, so the interested user can clear the value if desired.

The default is undef.

name (string, parse (three-line sets only))

This attribute contains the common name of the body.

reblessable (boolean)

This attribute says whether the rebless() method is allowed to rebless this object. If false, the object will not be reblessed when its id changes.

Note that if this attribute is false, setting it true will cause the object to be reblessed.

The default is true (i.e. 1).

revolutionsatepoch (numeric, parse)

This attribute contains number of revolutions the body has made since launch, at the epoch.

rightascension (numeric, parse)

This attribute contains the right ascension of the ascending node of the orbit at the epoch, in radians.

secondderivative (numeric, parse)

This attribute contains the second time derivative of the mean motion, in radians per minute cubed.

tle (string, readonly, parse)

This attribute contains the input data used by the parse() method to generate this object. If the object was not created by the parse() method, a (hopefully) equivalent TLE will be constructed and returned if enough attributes have been set, otherwise an exception will be raised.

visible (boolean, static)

This attribute tells the pass() method whether to report only passes which are illuminated (if true) or all passes (if false).

The default is 1 (i.e. true).

ACKNOWLEDGMENTS

The author wishes to acknowledge the following individuals.

Dominik Brodowski (http://www.brodo.de/), whose SGP C-lib (available at http://www.brodo.de/space/sgp/) provided a reference implementation that I could easily run, and pick apart to help get my own code working. Dominik based his work on Dr. Kelso's Pascal implementation.

Felix R. Hoots and Ronald L. Roehric, the authors of "SPACETRACK REPORT NO. 3 - Models for Propagation of NORAD Element Sets," which provided the basis for the Astro::Coord::ECI::TLE module.

David A. Vallado, Paul Crawford, Richard Hujsak, and T. S. Kelso, the authors of "Revisiting Spacetrack Report #3", presented at the 2006 AIAA/AAS Astrodynamics Specialist Conference.

Dr. T. S. Kelso, who made these two key reports available at http://celestrak.com/NORAD/documentation/spacetrk.pdf and http://celestrak.com/publications/AIAA/2006-6753/ respectively. Dr. Kelso's Two-Line Element Set Format FAQ (http://celestrak.com/columns/v04n03/) was also extremely helpful, as was his discussion of the coordinate system used (http://celestrak.com/columns/v02n01/) and (indirectly) his Pascal implementation of these models.

SEE ALSO

I am aware of no other modules that perform calculations with NORAD orbital element sets. The Astro-Coords package by Tim Jenness provides calculations using orbital elements, but the NORAD elements are tweaked for use by the models implemented in this package.

AUTHOR

Thomas R. Wyant, III (wyant at cpan dot org)

COPYRIGHT

Copyright 2005, 2006, 2007, 2008, 2009 by Thomas R. Wyant, III (wyant at cpan dot org). All rights reserved.

LICENSE

This module is free software; you can use it, redistribute it and/or modify it under the same terms as Perl itself. Please see http://perldoc.perl.org/index-licence.html for the current licenses.

This software is provided without any warranty of any kind, express or implied. The author will not be liable for any damages of any sort relating in any way to this software.