Astro-satpass

 view release on metacpan or  search on metacpan

lib/Astro/Coord/ECI/TLE.pm  view on Meta::CPAN

    $self->eci (@args);

    $self->equinox_dynamical ($self->{epoch_dynamical});

    return $self;
}

# Called by pass() to find the illumination. The arguments are the sun
# object (or nothing), the time, and a reference to the pass information
# hash. The return is either nothing (if $sun is not defined) or
# ( illumination => $illum ).
sub _find_illumination {
    my ( $sun, $when, $info ) = @_;
    $sun
	or return;
    my $illum = $info->[0]{illumination};
    foreach my $evt ( @{ $info } ) {
	$evt->{time} > $when
	    and last;
	$illum = $evt->{illumination};
    }
    return ( illumination	=> $illum );
}

# Called by pass() to calculate azimuth, elevation, and range. The
# arguments are the TLE object, the station object, and the time. If the
# TLE's 'lazy_pass_position' attribute is true, nothing is returned.
# Otherwise the azimuth, elevation, and range are calculated and
# returned as three name/value pairs (i.e. a six-element list).
sub _find_position {
    my ( $tle, $sta, $when ) = @_;
    $tle->get( 'lazy_pass_position' )
	and return;
    $tle->universal( $when );
    my ( $azimuth, $elevation, $range ) = $sta->azel( $tle );
    return (
	azimuth	=> $azimuth,
	elevation	=> $elevation,
	range		=> $range,
    );
}

# Initial value of the 'inertial' attribute. TLEs are assumed to be
# inertial until set otherwise.

sub __initial_inertial{ return 1 };

# Unsupported, experimental, and subject to change or retraction without
# notice. The intent is to provide a way for the Astro::App::Satpass2
# 'list' command to pick an appropriate template to format each line of
# the listing based on the object being listed.
sub __list_type {
    my ( $self ) = @_;
    return $self->{inertial} ? 'inertial' : 'fixed';
}

# _looks_like_real
#
# This returns a boolean which is true if the input looks like a real
# number and is false otherwise. It is based on looks_like_number, but
# excludes things like NaN, and Inf.
sub _looks_like_real {
    my ( $number ) = @_;
    looks_like_number( $number )
	or return;
    $number =~ m/ \A nan \z /smxi
	and return;
    $number =~ m/ \A [+-]? inf (?: inity )? \z /smxi
	and return;
    return 1;
}

# *equinox_dynamical = \&Astro::Coord::ECI::equinox_dynamical;

#	$text = $self->_make_tle();
#
#	This method manufactures a TLE. It's a 'real' TLE if the 'name'
#	attribute is not set, and a 'NASA' TLE (i.e. the 'T' stands for
#	'three') if the 'name' attribute is set. The output is intended
#	to be equivalent to the TLE (if any) that initialized the
#	object, not identical to it. This method is used to manufacture
#	a TLE in the case where $self->get('tle') was called but the
#	object was not initialized by the parse() method.

{

    my %hack = (
	effective => sub {
##	    my ( $self, $name, $value ) = @_;
	    my ( undef, undef, $value ) = @_;	# Invocant & name unused
	    my $whole = floor($value);
	    my ($sec, $min, $hr, undef, undef, $year, undef, $yday) =
		gmtime $value;
	    my $effective = 
		sprintf '%04d/%03d/%02d:%02d:%06.3f',
		$year + 1900, $yday + 1, $hr, $min,
		$sec + ($value - $whole);
	    $effective =~ s/ [.]? 0+ \z //smx;
	    return ( '--effective', $effective );
	},
	rcs => sub {
##	    my ( $self, $name, $value ) = @_;
	    my ( undef, undef, $value ) = @_;	# Invocant & name unused
	    return ( '--rcs', $value );
	},
    );

    my @required_fields = qw{
	firstderivative secondderivative bstardrag inclination
	ascendingnode eccentricity argumentofperigee meananomaly
	meanmotion revolutionsatepoch
    };

    sub _make_tle {
	my $self = shift;
	my $output;

	my $oid = $self->get('id');
	my $name = $self->get( 'name' );
	my @line0;

lib/Astro/Coord/ECI/TLE.pm  view on Meta::CPAN

	    $intldes_valid{$name}->( $val ) :
	    $val;

	my %intldes;
	foreach my $key ( qw{ launch_year launch_num launch_piece } ) {
	    $intldes{$key} = $value_or_empty->( $self, $key );
	}
	$intldes{launch_year} eq ''
	    or $intldes{launch_year} %= 100;

	my $tplt = join '',
	    ( $intldes{launch_year} eq '' ? '%2s' : '%02d' ),
	    ( $intldes{launch_num} eq '' ? '%3s' : '%03d' ),
	    '%s';
	$self->{international} = sprintf $tplt, map { $intldes{$_} }
	    qw{ launch_year launch_num launch_piece };

	return 0;
    }

}

# _set_object_type
#
# This acts as a mutator for the object type.
{
    my %name_to_type;
    my @number_to_type;
    foreach my $type (
	BODY_TYPE_UNKNOWN,
	BODY_TYPE_DEBRIS,
	BODY_TYPE_ROCKET_BODY,
	BODY_TYPE_PAYLOAD,
    ) {
	$number_to_type[$type] = $type;
	$name_to_type{ fold_case( $type ) } = $type;
    }
    sub _set_object_type {
	my ( $self, $name, $value ) = @_;
	if ( defined $value ) {
	    if ( $value =~ RE_ALL_DIGITS ) {
		$self->{$name} = $number_to_type[$value];
	    } else {
		$self->{$name} = $name_to_type{ fold_case( $value ) };
	    }
	    unless ( defined $self->{$name} ) {
		carp "Invalid $name '$value'; setting to unknown";
		$self->{$name} = BODY_TYPE_UNKNOWN;
	    }
	} else {
	    $self->{$name} = undef;
	}
	return 0;
    }
}

# _set_optional_float_no_reinit
#
# This acts as a mutator for any attribute whose value is either undef
# or a floating-point number, and which does not cause the model to be
# renitialized when its value changes. We disallow NaN.

sub _set_optional_float_no_reinit {
    my ( $self, $name, $value ) = @_;
    if ( defined $value && ! _looks_like_real( $value ) ) {
	carp "Invalid $name '$value'; must be a float or undef";
	$value = undef;
    }
    $self->{$name} = $value;
    return 0;
}

# _set_optional_unsigned_integer_no_reinit
#
# This acts as a mutator for any attribute whose value is either undef
# or an unsigned integer, and which does not cause the model to be
# reinitialized when its value changes.

sub _set_optional_unsigned_integer_no_reinit {
    my ( $self, $name, $value ) = @_;
    if ( defined $value && $value =~ m/ [^0-9] /smx ) {
	carp "Invalid $name '$value'; must be unsigned integer or undef";
	$value = undef;
    }
    $self->{$name} = $value;
    return 0;
}

sub _next_elevation_screen {
    my ( $sta, $pass_step, @args ) = @_;
    ref $sta
	or confess 'Programming error - station not a reference';
    my ( $suntim, $dawn ) = $sta->next_elevation( @args );
    defined $suntim
	or confess 'Programming error - time of next elevation undefined';
    $dawn or $pass_step = - $pass_step;
    my $sun_screen = $suntim + $pass_step / 2;
    return ( $suntim, $dawn, $sun_screen,
	$dawn ? $sun_screen : $suntim,
    );
}

#######################################################################

#	Initialization of aliases and status

{
    # The following classes initialize themselves on load.
    local $@ = undef;
    eval {	## no critic (RequireCheckingReturnValueOfEval)
	require Astro::Coord::ECI::TLE::Iridium;
    };
}

# $$ BEGIN magnitude_table

# The following is all the Celestrak visual list that have magnitudes in
# Heavens Above. These data are generated by the following:
#
#   $ tools/heavens-above-mag --celestrak --update
#



( run in 2.280 seconds using v1.01-cache-2.11-cpan-98e64b0badf )