Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Astro::Coord::ECI::TLEUser Contributed Perl DocumentaAstro::Coord::ECI::TLE(3)

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

SYNOPSIS
       The following is	a semi-brief script to calculate International Space
       Station visibility. 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 the 'stations' catalog from Celestrak. This includes
	# all space stations and related bodies.
	# The data are all direct-fetched, so no password is
	# needed.

	my $st = Astro::SpaceTrack->new( direct	=> 1 );
	my $data = $st->celestrak( 'stations' );
	$data->is_success or die $data->status_line;

	# Parse	the fetched data, yielding TLE objects.	Aggregate
	# them into Set	objects	where this is warranted. We grep
	# the data because the Celestrak catalog we fetched
	# contains other stuff than the	International Space
	# Station.

	my @sats = grep	{ '25544' eq $_->get( 'id' ) }
	    Astro::Coord::ECI::TLE::Set->aggregate(
	    Astro::Coord::ECI::TLE->parse( $data->content() ) );

	# We want passes for the next 7	days.

	my $start = time ();
	my $finish = $start + 7	* 86400;

	# Loop through our objects and predict passes. The
	# validate() step is usually not needed	for data from
	# Space	Track, but NASA's predicted elements for Space
	# Shuttle flights can be funky.

	my @passes;
	foreach	my $tle	(@sats)	{
	   $tle->validate($start, $finish) or next;
	   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};
	   }
	}

NOTICE
       Users of	JSON functionality (if any!) should be aware of	a potential
       problem in the way JSON::XS encodes numbers. The	problem	basically is
       that the	locale leaks into the encoded JSON, and	if the locale uses
       commas for decimal points the encoded JSON can not be decoded. As I
       understand the discussion on the	associated Perl	ticket the problem has
       always been there, but changes introduced in Perl 5.19.8	made it	more
       likely to manifest.

       Unfortunately the nature	of the JSON interface is such that I have no
       control over the	issue, since the workaround needs to be	applied	at the
       point the JSON "encode()" method	is called. See test t/tle_json.t for
       the workaround that allows tests	to pass	in the affected	locales.  The
       relevant	JSON::XS ticket	is
       <https://rt.cpan.org/Public/Bug/Display.html?id=93307>. The relevant
       Perl ticket is <https://github.com/perl/perl5/issues/13620>.

       The "pass_threshold" attribute has undergone a slight change in
       functionality from version 0.046, in which it was introduced. In	the
       new functionality, if the "visible" attribute is	true, the satellite
       must actually be	visible	above the threshold to be reported. This is
       actually	how the	attribute would	have worked when introduced if I had
       thought it through clearly.

       Use of the "SATNAME" JSON attribute to represent	the common name	of the
       satellite is deprecated in favor	of the "OBJECT_NAME" attribute,	since
       the latter is what Space	Track uses in their TLE	data. Beginning	with
       0.053_01, JSON output of	TLEs will use the new name.

       Beginning with release 0.056_01,	loading	JSON TLE data which specifies
       "SATNAME" produces a warning the	first time it happens. As of version
       0.061 there is a	warning	every time it happens. As of version 0.066
       loading JSON TLE	data which specifies "SATNAME" is a fatal error. Six
       months after this, all code referring to	"SATNAME" will be removed,
       meaning that the	key will be silently ignored.

DESCRIPTION
       This module implements the orbital propagation models described in
       "SPACETRACK REPORT NO. 3, Models	for Propagation	of NORAD Element Sets"
       and "Revisiting Spacetrack Report #3." See the ACKNOWLEDGMENTS section
       for details on these reports.

       In other	words, this module turns the two- or three-line	element	sets
       available from such places as <https://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.

       $kilometers = $tle->apoapsis();
	   This	method returns the apoapsis of the orbit, in kilometers. Since
	   Astro::Coord::ECI::TLE objects always represent bodies orbiting the
	   Earth, this is more usually called apogee.

	   Note	that this is the distance from the center of the Earth,	not
	   the altitude.

       $kilometers = $tle->apogee();
	   This	method is simply a synonym for apoapsis().

       $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.

       $type = $tle->body_type ()
	   This	method returns the type	of the body as one of the BODY_TYPE_*
	   constants. This is the 'object_type'	attribute if that is defined.
	   Otherwise it	is derived from	the common name	using an algorithm
	   similar to the one used by the Space	Track web site.	This algorithm
	   will	not work if the	common name is not available, or if it does
	   not conform to the Space Track naming conventions. Known or
	   suspected differences from the algorithm described at the bottom of
	   the Satellite Box Score page	include:

	   * The "Astro::Coord::ECI::TLE" algorithm is not case-sensitive. The
	   Space Track algorithm appears to assume all upper-case.

	   * The "Astro::Coord::ECI::TLE" algorithm looks for words (that is,
	   alphanumeric	strings	delimited by non-alphanumeric characters),
	   whereas the Space Track documentation seems to say it just looks
	   for substrings.  However, implementing the documented algorithm
	   literally results in	OID 20479 'DEBUT (ORIZURU)' being classified
	   as debris, whereas Space Track returns it in	response to a query
	   for name 'deb' that excludes	debris.

	   The possible	returns	are:

	   "BODY_TYPE_UNKNOWN => dualvar( 0, 'unknown' )" if the value of the
	   "name" attribute is "undef",	or if it is empty or contains only
	   white space.

	   "BODY_TYPE_DEBRIS =>	dualvar( 1, 'debris' )"	if the value of	the
	   "name" attribute contains one of the	words 'deb', 'debris',
	   'coolant', 'shroud',	or 'westford needles', all checks being	case-
	   insensitive.

	   "BODY_TYPE_ROCKET_BODY => dualvar( 2, 'rocket body' )" if the body
	   is not debris, but the value	of the "name" attribute	contains one
	   of the strings 'r/b', 'akm' (for 'apogee kick motor') or 'pkm' (for
	   'perigee kick motor') all checks being case-insensitive.

	   "BODY_TYPE_PAYLOAD => dualvar( 3, 'payload' )" if the body is not
	   unknown, debris, or a rocket	body.

	   The above constants are not exported	by default, but	they are
	   exportable either by	name or	using the ":constants" tag.

	   If Scalar::Util does	not export "dualvar()",	the constants are
	   defined to be numeric. The cautious programmer will therefore test
	   them	using numeric tests.

       $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.

       $elevation = $tle->correct_for_refraction( $elevation )
	   This	override of the	superclass' method simply returns the
	   elevation passed to it. Atmospheric refraction at orbital altitudes
	   is going to be negligible except extremely close to the horizon,
	   and I have no algorithm for that.

	   If I	do come	up with	something to handle refraction close to	the
	   horizon, though, it will appear here. One would expect the
	   refraction right at the limb	to be twice that calculated by
	   Thorfinn's algorithm	(used in the superclass) because the light
	   travels to the Earth's surface and back out again.

	   See the Astro::Coord::ECI "azel()" and "azel_offset()"
	   documentation for whether this class' "correct_for_refraction()"
	   method is actually called by	those methods.

       $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.

       $illuminated = $tle->illuminated();
	   This	method returns a true value if the body	is illuminated,	and a
	   false value if it is	not.

       @events = $tle->intrinsic_events( $start, $end );
	   This	method returns any events that are intrinsic to	the $tle
	   object.  If optional	argument $start	is defined, only events
	   occurring at	or after that Perl time	are returned. Similarly, if
	   optional argument $end is defined, only events occurring before
	   that	Perl time are returned.

	   The return is an array of array references. Each array reference
	   specifies the Perl time of the event	and a text description of the
	   event.

	   At this level of the	object hierarchy nothing is returned.
	   Subclasses may override this	to add "pass()"	events.	The overrides
	   should return anything returned by "SUPER::intrinsic_events(...)"
	   in addition to anything they	return themselves.

	   The order of	the returned events is undefined.

       $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 knows it needs to	select the correct member object before
	   running the model.

	   This	method can be called as	a static method, or even as a
	   subroutine.

       $mag = $tle->magnitude( $station	);
	   This	method returns the magnitude of	the body as seen from the
	   given station. If no	$station is specified, the object's 'station'
	   attribute is	used. If that is not set, and exception	is thrown.

	   This	is calculated from the 'intrinsic_magnitude' attribute,	the
	   distance from the station to	the satellite, and the fraction	of the
	   satellite illuminated. The formula is from Mike McCants.

	   We return "undef" if	the 'intrinsic_magnitude' or 'illum'
	   attributes are "undef", or if the illuminating body is below	the
	   horizon as seen from	the satellite.

	   After this method returns the time set in the station attribute
	   should be considered	undefined. In fact, it will be set to the same
	   time	as the invocant	if a defined magnitude was returned. But if
	   "undef" was returned, the station's time may	not have been changed.

	   Some	very desultory investigation of	International Space Station
	   magnitude predictions suggests that this method produces magnitude
	   estimates about half	a magnitude less bright	than Heavens Above.

       Astro::Coord::ECI::TLE->magnitude_table(	command	=> arguments ...)
	   This	method maintains the internal magnitude	table, which is	used
	   by the parse() method to fill in magnitudes,	since they are not
	   normally available from the usual sources.  The first argument
	   determines what is done to the status table;	subsequent arguments
	   depend on the first argument. Valid commands	and arguments are:

	   "magnitude_table( add =" $id, $mag )> adds a	magnitude entry	to the
	   table, replacing the	existing entry for the given OID if any.

	   "magnitude_table( adjust =" $adjustment )> maintains	a magnitude
	   adjustment to be added to the value in the magnitude	table before
	   setting the "intrinsic_magnitude" of	an object. If the argument is
	   "undef" the current adjustment is returned; otherwise the argument
	   becomes the new adjustment. Actual magnitude	table entries are not
	   modified by this operation; the adjustment is done in the "parse()"
	   method.

	   "magnitude_table( 'clear' )"	clears the magnitude table.

	   "magnitude_table( drop =" $id )> removes the	given OID from the
	   table if it is there.

	   "magnitude_table( magnitude =" \%mag	) replaces the magnitude table
	   with	the contents of	the given hash.	The keys will be normalized to
	   5 digits.

	   "magnitude_table( molczan ="	$file_name, $mag_offset	)> replaces
	   the magnitude table with the	contents of the	named Molczan-format
	   file. The $file_name	argument can also be a scalar reference	with
	   the scalar containing the data, or an open handle. The $mag_offset
	   is an adjustment to be added	to the magnitudes read from the	file,
	   and defaults	to 0.

	   "magnitude_table( quicksat =" $file_name, $mag_offset )> replaces
	   the magnitude table with the	contents of the	named Quicksat-format
	   file. The $file_name	argument can also be a scalar reference	with
	   the scalar containing the data, or an open handle. The $mag_offset
	   is an adjustment to be added	to the magnitudes read from the	file,
	   and defaults	to 0. In addition to this value, 0.7 is	added to the
	   magnitude before storage to adjust the data from full-phase to
	   half-phase.

	   "magnitude_table( show =" ... )> returns an array which is a	slice
	   of the magnitude table, which is stored as a	hash. In other words,
	   it returns OID/magnitude pairs in no	particular order. If any
	   further arguments are passed, they are the OIDs to return.
	   Otherwise all are returned.

	   Examples of Molczan-format data are contained in mcnames.zip	and
	   vsnames.zip available on Mike McCants' web site; these can be
	   fetched using the Astro::SpaceTrack "mccants()" method. An example
	   of Quicksat-format data is contained	in qsmag.zip. See Mike
	   McCants' web	site, <https://www.prismnet.com/~mmccants/> for	an
	   explanation of the differences.

	   Note	that if	you have one of	the reported pure Perl versions	of
	   Scalar::Util, you can not pass open handles to functionality	that
	   would otherwise accept them.

       $time = $tle->max_effective_date(...);
	   This	method returns the maximum date	among its arguments and	the
	   effective date of the $tle object as	set in the "effective"
	   attribute, if that is defined. If no	effective date is set but the
	   "backdate" attribute	is false, the "epoch" of the object is used as
	   the effective date. If there	are no arguments and no	effective
	   date, "undef" is returned.

       $tle = $tle->members();
	   This	method simply returns the object it is called on. It exists
	   for convenience in getting back validated objects when iterating
	   over	a mixture of Astro::Coord::ECI::TLE and
	   Astro::Coord::ECI::TLE::Set objects.

       $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 NORAD two- or three-line element sets, JSON
	   element sets, 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.

	   TLE 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.

	   Input beginning with	"[{" (with optional spaces) is presumed	to be
	   NORAD JSON element sets and parsed accordingly.

	   Optionally, the first argument (after the invocant) can be a
	   reference to	a hash of default attribute values. These are
	   preferred over the static values, but attributes provided by	the
	   TLE or JSON input override both.

       @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 (see note	3).

	   A pass is detected by this method when the body sets. Unless
	   "PASS_VARIANT_TRUNCATE" (see	below) is in effect, this means	that
	   passes are not usefully detected for	geosynchronous or near-
	   geosynchronous bodies, and that passes where	the body sets after
	   the $end time will not be detected.

	   All arguments are optional, the defaults being

	    $station = the 'station' attribute of the invocant
	    $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 (see note	1);
	     {body} => Reference to body making	pass (see note 2);
	     {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 (see note 1);
	     {event} =>	Event code (PASS_EVENT_xxxx);
	     {illumination} => Illumination at time of event (PASS_EVENT_xxxx);
	     {range} =>	Distance to event in kilometers	(see note 1);
	     {station} => Reference to observing station (see note 2);
	     {time} => Time of 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');
	     PASS_EVENT_START => dualvar( 11, 'start' );
	     PASS_EVENT_END => dualvar(	12, 'end' );
	     PASS_EVENT_BRIGHTEST => dualvar( 13, 'brgt' );

	   The "PASS_EVENT_START" and "PASS_EVENT_END" events are not normally
	   generated. You can get them in lieu of whatever events start	and
	   end the pass	by setting "PASS_VARIANT_START_END" in the
	   "pass_variant" attribute. Unless you	are filtering out non-visible
	   events, though, they	are just the rise and set events under
	   different names.

	   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 ':constants' 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
	     * edge_of_earths_shadow	   # Used in the calculation of
			   # whether the satellite is illuminated or in
			   # shadow.
	     * geometric   # Use geometric horizon for pass rise/set
	     * horizon	   # Effective horizon
	     * interval	   # Interval for pass() positions, if positive
	     * lazy_pass_position # {azimuth}, {elevation} and {range}
			   # are optional if true (see note 1).
	     * pass_threshold #	Minimum	elevation satellite must reach
			   # for the pass to be	reportable. If visible
			   # is	true, it must be visible above this
			   # elevation
	     * pass_variant # Tweak what pass()	returns; currently no
			   # effect unless 'visible' is	true.
	     * illum	   # Source of illumination.
	     * twilight	   # Distance of illuminator below horizon
	     * visible	   # Pass() reports only illuminated passes

	   Note	1:

	   If the "lazy_pass_position" attribute is true, the {azimuth},
	   {elevation},	and {range} keys may not be present. This attribute
	   gives the event-calculating algorithm permission to omit these if
	   the time of the event can be	determined without computing the
	   position of the body.  Currently this happens only for events
	   generated in	response to setting the	"interval" attribute, but the
	   user	should not make	this assumption	in his or her own code.

	   Typically you will only want	to set this true if, after calling the
	   "pass()" method, you	are not	interested in the azimuth, elevation
	   and range, but compute the event positions in some coordinates
	   other than azimuth, elevation, and range.

	   Note	2:

	   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.	If you make use	of the {body}
	   object you will probably need to set	its time to the	time of	the
	   event before	you do so.

	   Note	3:

	   The algorithm for computing appulses	has been modified slightly in
	   version 0.056_04. This modification only applies to elements	of the
	   optional "\@sky" array that represent artificial satellites.

	   The problem I'm trying to address is	that two satellites in very
	   similar orbits can appear to	converge again after their appulse,
	   due to their	increasing distance from the observer. If this happens
	   early enough	in the pass it can fool	the binary search algorithm
	   that	determines the appulse time.

	   The revision	is to first step across	the pass, finding the closest
	   approach of the two bodies. A binary	search is then done on a small
	   interval around the closest approach.

       $kilometers = $tle->periapsis();
	   This	method returns the periapsis of	the orbit, in kilometers.
	   Since Astro::Coord::ECI::TLE	objects	always represent bodies
	   orbiting the	Earth, this is more usually called perigee.

	   Note	that this is the distance from the center of the Earth,	not
	   the altitude.

       $kilometers = $tle->perigee();
	   This	method is simply a synonym for periapsis().

       $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.

	   A note on subclassing: A body that is not in	orbit should return a
	   period of "undef".

       $tle = $tle->rebless ($class, \%possible_attributes)
	   This	method reblesses a TLE object. The class must be either
	   Astro::Coord::ECI 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:

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

	   If you install Astro::Coord::ECI::TLE::Iridium it will define alias

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

	   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.

       $kilometers = $tle->semiminor();
	   This	method calculates the semiminor	axis of	the orbit, using the
	   semimajor axis and the eccentricity,	by the equation

	    b =	a * sqrt(1 - e)

	   where a is the semimajor axis and e is the eccentricity.

       $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.

	   No types are	supported out of the box, but if you have installed
	   Astro::Coord::ECI::TLE::Iridium that	or 'iridium' will work.

	   The $status is 0, 1,	2, or 3	representing in-service, spare,
	   failed, or decayed respectively.  The strings '+' or	'' will	be
	   interpreted as 0, 'S', 's', or '?' as 1, 'D'	as 3, 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.

	   Initially, the status table is populated with the status as of
	   December 3, 2010.

       $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.

       $text = $tle->tle_verbose(...);
	   This	method returns a verbose version of the	TLE data, with one
	   data	field per line,	labeled. The optional arguments	are key-value
	   pairs affecting the formatting of the output. The only key
	   implemented at the moment is

	    date_format
	      specifies	the strftime() format used for dates
	      (default:	'%d-%b-%Y %H:%M:%S').

       $hash_ref = $tle->TO_JSON();
	   Despite its name, this method does not convert the object to	JSON.
	   What	it does	instead	is to return a reference to a hash that	the
	   JSON	class will use to encode the object into JSON. The possible
	   keys	are, to	the extent possible, those used	by the Space Track
	   REST	interface.

	   In order to get JSON	to use this hook you need to instantiate a
	   JSON	object and turn	on the conversion of blessed objects, like so:

	    my $json = JSON->new()->convert_blessed( 1 );
	    print $json->encode( $tle );

	   The returned	keys are a mish-mash of	the keys returned by the Space
	   Track "satcat" and "tle" classes, plus others that are not
	   maintained by Space Track. Since the	Space Track keys are all upper
	   case, I have	made the non-Space Track keys all lower	case.

	   At this point I am not going	to document the	keys returned by this
	   method, but they are	generally self-explanatory. I find the most
	   cryptic one is "{INTLDES}", which is	the International Launch
	   Designator, encoded with a four-digit year.

       $valid =	$tle->validate($options, $time ...);
	   This	method checks to see if	the currently-selected model can be
	   run successfully. If	so, it returns 1; if not, it returns 0.

	   The $options	argument is itself optional. If	passed,	it is a
	   reference to	a hash of option names and values. At the moment the
	   only	option used is

	    quiet => 1 to suppress output to STDERR.

	   If the "quiet" option is not	specified, or is specified as a	false
	   value, validation failures will produce output to STDERR.

	   Each	$time argument is adjusted by passing it through
	   "$tle->max_effective_date", and the distinct	adjusted times are
	   sorted into ascending order.	The currently-selected model is	run at
	   each	of the times thus computed. The	return is 0 if any run fails,
	   or 1	if they	all succeed.

	   If there are	no $time arguments, the	model is run at	the effective
	   date	if that	is specified, or the epoch if the effective date is
	   not specified.

   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.

       ascendingnode (numeric, parse)
	   This	attribute contains the right ascension of the ascending	node
	   of the orbit	at the epoch, 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.

       effective (numeric, parse)
	   This	attribute contains the effective date of the TLE, as a Perl
	   time	in seconds since the epoch. As a convenience, it can be	set in
	   the format used by NASA to specify this, as
	   year/day/hour:minute:second,	where all fields are numeric, and the
	   day is the day number of the	year, January 1	being 1, and December
	   31 being either 365 or 366.

       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.

       file (numeric)
	   This	attribute contains the file number of the TLE data. It is
	   typically present only if the TLE object was	parsed from a Space
	   Track JSON file; otherwise it is undefined.

       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,
	   for the purpose of detecting	things like Iridium flares. This is
	   distinguished from the parent class'	'sun' attribute, which is used
	   to determine	night or day.

	   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.

       intrinsic_magnitude (numeric or undef)
	   If defined, this is the typical magnitude of	the body at half phase
	   and range 1000 kilometers, when illuminated by the Sun. I am	not
	   sure	how standard this definition really is.	 This is the
	   definition used by Ted Molczan, but Mike McCants' Quicksat data
	   uses	maximum	magnitude full phase.

       lazy_pass_position (boolean, static)
	   This	attribute tells	the pass() method that the "{azimuth}",
	   "{elevation}", and "{range}"	keys in	the pass event hashes need not
	   be generated.

	   This	attribute was intended for the case where the user wants event
	   positions in	coordinate systems other than, or in addition to,
	   azimuth, elevation, and range. In this case,	it may be faster for
	   the user to set this	attribute, and then compute the	event
	   positions after the "pass()"	method has generated the events. Note
	   that	if you do this,	you will have to call "universal()" on the
	   event's "{body}", passing it	the event's "{time}", before
	   retrieving the coordinates you want.

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

       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.

       object_type
	   This	attribute contains the object type of the TLE data. It is
	   typically present only if the TLE object was	parsed from a Space
	   Track JSON file; otherwise it is undefined. However,	if it is
	   defined it will be returned by the "body_type()" method.

	   When	setting	this, possible values are those	returned by
	   "body_type()" -- either the dualvar constants themselves, or	the
	   numeric or case-insensitive strings corresponding to	them. Whatever
	   is set, what	is stored and returned will be one of the
	   "BODY_TYPE_*" constants. Any	unrecognized value will	be stored as
	   "BODY_TYPE_UNKNOWN",	with a warning.

       ordinal (numeric)
	   This	attribute contains the ordinal number of the TLE data. It is
	   typically present only if the TLE object was	parsed from a Space
	   Track JSON file; otherwise it is undefined.

       originator (string)
	   This	attribute contains the name of the originator of the TLE data.
	   It is typically present only	if the TLE object was parsed from a
	   Space Track JSON file; otherwise it is undefined.

       pass_variant (bits)
	   This	attribute tweaks the pass output as specified by its value,
	   which should	be the bitwise 'or' (i.e. "|") of the following
	   values:

	   * "PASS_VARIANT_VISIBLE_EVENTS" - Specifies that events which are
	   not visible (that is, which take place either during	daylight or
	   with	the body in shadow) are	not reported. Illumination changes,
	   however, are	always reported. This has no effect unless the
	   "visible" attribute is true.

	   * "PASS_VARIANT_FAKE_MAX" - Specifies that if
	   "PASS_VARIANT_VISIBLE_EVENTS" filters out the max, a	new max	event,
	   at the same time as either the first	or last	reported event,	will
	   be inserted.	This has no effect unless
	   "PASS_VARIANT_VISIBLE_EVENTS" is specified, and the "visible"
	   attribute is	true.

	   * "PASS_VARIANT_START_END" -	Specifies that the first and last
	   events of the pass are to be	identified as "PASS_EVENT_START" and
	   "PASS_EVENT_END" respectively. If the "visible" attribute is	true
	   and "PASS_VARIANT_VISIBLE_EVENTS" is	in effect, "PASS_EVENT_START"
	   will	replace	either "PASS_EVENT_RISE" or "PASS_EVENT_LIT", and
	   "PASS_EVENT_END" will replace either	"PASS_EVENT_SET",
	   "PASS_EVENT_SHADOWED", or "PASS_EVENT_DAY". Otherwise, they replace
	   "PASS_EVENT_RISE" and "PASS_EVENT_SET" respectively.

	   * "PASS_VARIANT_NO_ILLUMINATION" - Specifies	that no	illumination
	   calculations	are to be made at all. This means no "PASS_EVENT_LIT",
	   "PASS_EVENT_SHADOWED", or "PASS_EVENT_DAY" events are generated,
	   and that the	"illumination" key on other events will	not be
	   present. I find that	setting	this (with "visible => 0") saves about
	   20% in wall clock time versus not setting it. Your mileage may, of
	   course, vary.  This has no effect unless the	"visible" attribute is
	   false.

	   * "PASS_VARIANT_TRUNCATE" - Specifies that any pass in progress at
	   the beginning or end	of the calculation interval is to be truncated
	   to the interval. If the calculation interval	starts with the	body
	   already above the horizon, the initial event	of that	pass will be
	   "PASS_EVENT_START" rather than "PASS_EVENT_RISE". Similarly,	if the
	   calculation interval	ends with the body still above the horizon,
	   the final event of that pass	will be	"PASS_EVENT_END". With this
	   variant in effect, 'passes' will be computed	for synchronous
	   satellites. This variant is to be considered	experimental.

	   * "PASS_VARIANT_BRIGHTEST" -	Specifies that the the moment the
	   satellite is	brightest be computed as part of the pass statistics.
	   The computation is to the nearest second, and is not	done if
	   "PASS_VARIANT_NO_ILLUMINATION" is set, the satellite	has no
	   intrinsic magnitude set, or the satellite is	not illuminated	during
	   the pass.

	   * "PASS_VARIANT_NONE" - Specifies that no pass variant processing
	   take	place.

	   The above constants are not exported	by default, but	are exported
	   by the ":constants" tag.

	   The default is "PASS_VARIANT_NONE"

       rcs (string, parse)
	   This	attribute represents the radar cross-section of	the body, in
	   square meters.

       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.

       secondderivative	(numeric, parse)
	   This	attribute contains the second time derivative of the mean
	   motion, in radians per minute cubed.

       pass_threshold (numeric or undef)
	   If defined, this attribute defines the elevation in radians that
	   the satellite must reach above the horizon for its passes to	be
	   reported. If	the "visible" attribute	is true, the satellite must be
	   visible above this elevation.

	   If undefined, any pass above	the horizon will be reported (i.e. you
	   get the same	behavior as before this	attribute was introduced in
	   version 0.046.)

	   Note	a slight change	in the behavior	of this	attribute from version
	   0.046. In that version, it did not matter whether the satellite was
	   visible, even if the	"visible" attribute was	true.

	   You might use this attribute	if you want to use a nominal horizon
	   of .35 radians (20 degrees),	but are	only interested	in passes that
	   reach an elevation of .70 radians (40 degrees).

	   The default is "undef".

       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 (<https://www.brodo.de/>), whose SGP C-lib (available
       at <https://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.

       The TLE data used in testing the	"sgp4r"	model are from "Revisiting
       Spacetrack Report #3" (made available at	the CelesTrak web site as
       cited above), and are used with the kind	permission of Dr. Kelso.

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.

SUPPORT
       Support is by the author. Please	file bug reports at
       <https://rt.cpan.org/Public/Dist/Display.html?Name=Astro-satpass>,
       <https://github.com/trwyant/perl-Astro-Coord-ECI/issues>, or in
       electronic mail to the author.

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

COPYRIGHT AND LICENSE
       Copyright (C) 2005-2021 by Thomas R. Wyant, III

       This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl 5.10.0. For	more details, see the full
       text of the licenses in the directory LICENSES.

       This program is distributed in the hope that it will be useful, but
       without any warranty; without even the implied warranty of
       merchantability or fitness for a	particular purpose.

perl v5.32.1			  2021-11-10	     Astro::Coord::ECI::TLE(3)

NAME | SYNOPSIS | NOTICE | DESCRIPTION | ACKNOWLEDGMENTS | SEE ALSO | SUPPORT | AUTHOR | COPYRIGHT AND LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Astro::Coord::ECI::TLE&sektion=3&manpath=FreeBSD+13.1-RELEASE+and+Ports>

home | help