As of early 2017 the flaring Iridium satellites are being taken out of service, to be replaced by non-flaring Iridium Next satellites. Once the flaring Iridium satellites are out of service, I plan to deprecate and remove all functionality relating to the acquisition of Iridium status.

I have not yet decided on the disposition of Astro::Coord::ECI::TLE::Iridium. My thought at the moment is that it will be moved to its own package rather than deleted, because the flare functionality may be of historical interest. By the same reasoning, the TLE parsing logic in Astro::Coord::ECI::TLE will remain able to rebless satellites as Iridium, but the canned status will be 'tumbling'.

This class is a subclass of Astro::Coord::ECI::TLE, representing original-design Iridium satellites. This class will probably not work for the Iridium Next satellites, which are being launched starting early 2017.

The Astro::Coord::ECI::TLE->parse() method makes use of built-in data to determine which satellites to rebless into this class, based on the object's NORAD SATCAT ID. This internal data can be modified using the Astro::Coord::ECI::TLE->status method to correct errors or for historical research. It is also possible to get an Iridium object by calling $tle->rebless (iridium => {status => $status}) directly.

What this subclass adds is the ability to generate information on Iridium flares (or glints, as they are also called). Members of this class are considered capable of generating flares based on their status, as follows:

0 => in service
1 => spare (may or may not flare)
2 => failed - no predictable flares.

CelesTrak-style statuses ('+', 'S', and '-' respectively) are accepted on input. See Astro::SpaceTrack method iridium_status for a way to get current Iridium constellation status.

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 of the inheritance hierarchy, it removes the status attribute.

This method returns true (in the Perl sense) if the object is capable of producing flares, and false otherwise. If the optional $spare argument is true, spares are considered capable of flaring, otherwise not. If $spare is 'all', then all objects are considered capable of flaring.

This method returns the list of flares produced by the given Iridium satellite at the given station between the given start time and the given end time. This list may be empty. If called in scalar context you get the number of flares.

* The time of the object passed in the {body} element is not necessarily set to the time of the flare.

* The {center}{body} element contains an Astro::Coord::ECI object set to the location of the center of the flare at the given time. The center is defined as the intersection of the plane of the observer's horizon with the line from the virtual image of the illuminating body through the flaring satellite.

* The {mma} element indicates which Main Mission Antenna generated the flare. The antennae are numbered clockwise (looking down on the vehicle) from the front, so 0, 1, and 2 correspond to Heavens Above's 'Front', 'Right', and 'Left' respectively.

* The {specular} element is actually the limb darkening factor if applicable. Otherwise, it is 1 if the reflection is specular, and 0 if not.

* The {status} key is reserved for an explanation of why there is no flare. When the hash is generated by the flare() method, this key will always be false (in the Perl sense).

* The {type} element contains 'day' if the flare occurs between the beginning of twilight in the morning and the end of twilight in the evening, 'am' if the flare is after midnight but not during the day, and 'pm' if the flare is before midnight but not during the day.

* The {virtual_image} element is an Astro::Coord::ECI object representing the location of the virtual image of the illuminator at the time of the flare.

The short answer is "I don't know, because I don't know how Heavens Above gets their answers."

In a little more detail, there appear to be several things going on:

First, there appears to be no standard reference for how to calculate the magnitude of a flare. This module calculates specular reflections as though the sky were opaque, and the flaring Main Mission Antenna were a window through to the virtual image of the Sun. Limb darkening is taken into account, as is atmospheric extinction. Non-specular flares are calculated by a fairly arbitrary equation whose coefficients were fitted to visual flare magnitude estimates collected by Ron Lee and made available on the Web by Randy John as part of his skysat web site at http://home.comcast.net/~skysat/. Atmospheric extinction is also taken into account for the non-specular flares.

Atmospheric extinction is calculated according to the article by Daniel W. Green in the July 1992 issue of "International Comet Quarterly", and available at http://www.cfa.harvard.edu/icq/ICQExtinct.html. Because Heavens Above does not display flares dimmer than a certain magnitude (-6 for day flares, and apparently 0 for night flares), it may not display a flare that this code predicts. I have no information how Heavens Above calculates magnitudes, but I find that this class gives estimates about a magnitude brighter than Heavens Above at the dim end of the scale.

Second, I suspect that the positions and velocities calculated by Astro::Coord::ECI::TLE differ slightly from those used by Heavens Above. I do not know this, because I do not know what positions Heavens Above uses, but there are slight differences among the results of all the orbital propagation models I have looked at. All I can say about the accuracy of Astro::Coord::ECI::TLE is that it duplicates the test data given in "Spacetrack Report Number Three". But small differences are important -- 0.1 degree at the satellite can make the difference between seeing and not seeing a flare, and smaller differences can affect the magnitude predictions, especially if they make the difference between predicting a specular or non-specular flare. Occasionally I find that I get very different results than Heavens Above, even when using orbital data published on that web site.

Third, Heavens Above issues predictions on satellites that my source says are spares. I have skipped the spares by default because I do not know that their attitudes are maintained to the requisite precision, though perhaps they would be, to demonstrate that the spares are functional. This software currently uses the Iridium status from CelesTrak (http://celestrak.com/SpaceTrack/query/iridium.txt), since it represents one-stop shopping, and Dr. Kelso has expressed the intent to check with Iridium Satellite LLC monthly for status. Mike McCants' "Status of Iridium Payloads" at http://users2.ev1.net/~mmccants/tles/iridium.html notes that flares may be unreliable for spares, so can_flare () returns false for them. If this is not what you want, call can_flare with a true value (e.g. can_flare(1)).

Fourth, the Heavens Above definition of 'daytime' differs from mine. Heavens Above does not document what their definition is, at least not that I have found. My definition of daytime includes twilight, which by default means the center of the Sun is less than 6 degrees below the horizon. I know that, using that definition, this software classifies some flares as daytime flares which Heavens Above classifies as nighttime flares. It appears to me that Heavens Above considers it night whenever the Sun is below the horizon.

Fifth, the orbital elements used to make the prediction can differ. I have occasionally seen Heavens Above using elements a day old, versus the ones available from Space Track, and seen this difference make a difference of six or eight seconds in the time of the flare.

Sixth, this method takes no account of the decrease in magnitude that would result from the Sun being extremely close to the horizon as seen from the flaring satellite. I do not know whether Heavens Above does this or not, but I have seen an instance where this code predicted a flare but Heavens Above did not, where the observed flare was much dimmer than this code predicted, and reddened. Subsequent calculations put the Sun 0.1 degrees above the horizon as seen from the satellite.

NOTE that the algorithm used to calculate flares does not work at latitudes beyond 85 degrees north or south, nor does it work for any location that is not fixed to the Earth's surface. This may be fixed in a future release. The chances of it being fixed in a future release will be enhanced if someone claims to actually need it. This someone will be invited to help test the new code.

NOTE also that as of version 0.002_01 of this class, the 'backdate' attribute determines whether a set of orbital elements can be used for computations of flares before the epoch of the elements. If 'backdate' is false and the start time passed to flare() is earlier than the epoch, the start time is silently moved forward to the epoch. The initial version of this functionality raised an exception if this adjustment placed the start time after the end time, but as of version 0.003_01 of this class, you simply get no flares if this happens.

This override of the superclass' method method returns the magnitude of the body as seen from the given station at the body's currently-set time. If no $station is specified, the object's 'station' attribute is used. If that is not set, and exception is thrown.

This method calls the superclass' magnitude(), and returns undef if the superclass does. Otherwise it adds to the magnitude of the body itself the magnitude of any flare in progress, and returns the result.

This method returns a list of references to hashes containing the same data as returned for a flare, calculated for the given observer and time for all Main Mission Antennae. If $time is undef, the current time setting of the invocant is used. If $station is undef the current station attribute is used. Note the following differences from the flare() hash:

If the hash contains a 'status' key which is true (in the Perl sense), no reflection occurred, and the content of the key is a message saying why not. If the 'mma' key exists in addition to the 'status' key, the failure applies only to that MMA, and other MMAs may possibly generate a reflection. If the 'mma' key does not exist, then the satellite is either not illuminated or below the horizon for the given observer, and the @data list will contain only a single entry.

Other than (maybe) 'mma', no other keys should be assumed to exist if the 'status' key is true.

If called in scalar context, a reference to the \@data list is returned.

NOTE that prior to 0.061_01 the $time argument defaulted to the current time. This behavior was undocumented, and therefore I felt free to change it.

If true, flare magnitude calculations will take atmospheric extinction into account. If false, they will not. The observer who wishes to compare forecast magnitudes to nearby stars may wish to set this to some value Perl considers false (e.g. undef).

This attribute is used in the flare calculation to screen passes for flare potential. The position of the satellite is calculated at intervals during a pass, and for each position the mirror angle (defined as the angle subtended at the satellite between the observer and the reflection of the Sun) is calculated. If no calculated mirror angle is less than the value of this attribute, no flare is predicted. If one of the mirror angles is less than this, a flare is predicted and its maximum magnitude calculated.

The default value is equivalent to 10 degrees. This is fine for fairly bright flares, but if you are looking for really dim ones (relative to the maximum brightness given the source of illumination) you want to increase this. The cost of increasing it is, of course, increased computation. The maximum useful value is the equivalent of 180 degrees, but this is not enforced. If you have a particular angle in mind, you will want to set this to about 10 degrees more, because of the way it is used in the flare algorithm.

By default, the can_flare() method returns true only if the status is 0. But if given a true argument (e.g. can_flare(1)) it will also return true if the status is 1.

When setting this attribute, both T. S. Kelso and Mike McCants style strings are accepted. That is:

'+' or '' will be considered 0;
'S' or '?' will be considered 1;
anything else will be considered 2.

Technically, the default is 0. But if the object is manufactured by Astro::Coord::ECI::TLE->parse(), the status will be set based on the internal status table in Astro::Coord::ECI::TLE.

Note that Mike McCants' Iridium statuses are no longer maintained, so his status codes ('' and '?') are being put through a deprecation cycle. In 6 months they will warn on the first use; 6 months after that they will warn on every use, and 6 months after that they will become fatal.