From: djk Date: Wed, 8 Mar 2000 22:16:37 +0000 (+0000) Subject: fixed sh/qra so that it shows the correct lat/long X-Git-Tag: R_1_39~22 X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?p=spider.git;a=commitdiff_plain;h=9cac31473878fc88778cb13d843fa77c5fd33d65 fixed sh/qra so that it shows the correct lat/long tidied up satellite stuff --- diff --git a/cmd/Commands_en.hlp b/cmd/Commands_en.hlp index 313520e4..c266fa58 100644 --- a/cmd/Commands_en.hlp +++ b/cmd/Commands_en.hlp @@ -719,6 +719,47 @@ See also SHOW/DXCC Show the name and location where every program module was load from. This is useful for checking where you think you have loaded a .pm file from. +=== 0^SHOW/QRA []^Show distance between locators +=== 0^SHOW/QRA ^Convert latitude and longitude to a locator +This is a multipurpose command that allows you either to calculate the +distance and bearing between two locators or (if only one locator is +given on the command line) the distance and beraing from your station +to the locator. For example:- + +SH/QRA IO92QL +SH/QRA JN06 IN73 + +The first example will show the distance and bearing to the locator from +yourself, the second example will calculate the distance and bearing from +the first locator to the second. You can use 4 or 6 character locators. + +It is also possible to convert a latitude and longitude to a locator by +using this command with a latitude and longitude as an argument, for +example:- + +SH/QRA 52 41 N 0 58 E + +=== 0^SHOW/SATELLITE [ ]^Show tracking data +Show the tracking data from your location to the satellite of your choice +from now on for the next few hours. + +If you use this command without a satellite name it will display a list +of all the satellites known currently to the system. + +If you give a name then you can obtain tracking data of all the passes +that start and finish 5 degrees below the horizon. As default it will +give information for the next three hours for every five minute period. + +You can alter the number of hours and the step size, within certain +limits. + +Each pass in a period is separated with a row of '-----' characters + +So for example:- + +SH/SAT AO-10 +SH/SAT FENGYUN1 12 2 + === 0^SHOW/SUN [|]^Show sun rise and set times Show the sun rise and set times for a (list of) prefixes or callsigns, together with the azimuth and elevation of the sun currently at those diff --git a/cmd/load/keps.pl b/cmd/load/keps.pl new file mode 100644 index 00000000..71229e1d --- /dev/null +++ b/cmd/load/keps.pl @@ -0,0 +1,8 @@ +# +# load the the keps file after changing it +# +my $self = shift; +return (1, $self->msg('e5')) if $self->priv < 9; +my @out = Sun::load($self); +@out = ($self->msg('ok')) if !@out; +return (1, @out); diff --git a/cmd/show/qra.pl b/cmd/show/qra.pl index 2bbb606f..6269a0d5 100644 --- a/cmd/show/qra.pl +++ b/cmd/show/qra.pl @@ -8,6 +8,7 @@ my ($self, $line) = @_; my @list = split /\s+/, $line; # generate a list of callsigns +return (1, $self->msg('qrashe1')) unless @list > 0; my @out; my $fll; @@ -23,38 +24,30 @@ if (!$long && !$lat) { my $fqra = DXBearing::is_qra($list[0]); my $sqra = $list[0] =~ /^[A-Za-z][A-Za-z]\d\d$/; my $ll = $line =~ /^\d+\s+\d+\s*[NSns]\s+\d+\s+\d+\s*[EWew]/; -return (1, $self->msg('qrashe1')) unless @list > 0; return (1, $self->msg('qrae2', $list[0])) unless $fqra || $sqra || $ll; +# convert a lat/long into a qra locator if ($ll) { my ($llat, $llong) = DXBearing::stoll($line); return (1, "QRA $line = " . DXBearing::lltoqra($llat, $llong)); } -#print "$lat $long\n"; +unshift @list, $self->user->qra if @list == 1 && $self->user->qra; +unshift @list, DXBearing::lltoqra($lat, $long) unless @list > 1; -my $l = uc $list[0]; -my $f; +my $f = uc $list[0]; +$f .= 'MM' if $f =~ /^[A-Z][A-Z]\d\d$/; +($lat, $long) = DXBearing::qratoll($f); +return (1, $self->msg('qrae2', $list[1])) unless (DXBearing::is_qra($list[1]) || $list[1] =~ /^[A-Za-z][A-Za-z]\d\d$/); -if (@list > 1) { - $f = $l; - $f .= 'MM' if $f =~ /^[A-Z][A-Z]\d\d$/; - ($lat, $long) = DXBearing::qratoll($f); - $fll = DXBearing::lltos($lat, $long); - #print "$lat $long\n"; - - return (1, $self->msg('qrae2', $list[1])) unless (DXBearing::is_qra($list[1]) || $list[1] =~ /^[A-Za-z][A-Za-z]\d\d$/); - $l = uc $list[1]; -} +my $l = uc $list[1]; -$l .= 'MM' if $l =~ /^[A-Z][A-Z]\d\d$/; - -my ($qlat, $qlong) = DXBearing::qratoll($l); -#print "$qlat $qlong\n"; $fll = DXBearing::lltos($lat, $long); -$fll =~ s/\s+([NSEW])/$1/g; +my ($qlat, $qlong) = DXBearing::qratoll($l); $tll = DXBearing::lltos($qlat, $qlong); + $tll =~ s/\s+([NSEW])/$1/g; +$fll =~ s/\s+([NSEW])/$1/g; my ($b, $dx) = DXBearing::bdist($lat, $long, $qlat, $qlong); my ($r, $rdx) = DXBearing::bdist($qlat, $qlong, $lat, $long); diff --git a/cmd/show/satellite.pl b/cmd/show/satellite.pl index 0f6131dd..a6c07448 100644 --- a/cmd/show/satellite.pl +++ b/cmd/show/satellite.pl @@ -2,55 +2,105 @@ # # show satellite az/el # -# 1999/12/9 Steve Franke K9AN +# copyright (c) 1999 Steve Franke K9AN # +# $Id$ # -my ($self, $satname) = @_; +my ($self, $line) = @_; my @out; -my ($lat, $lon, $alt, $jtime); # lats and longs in radians -my ($sec, $min, $hr, $day, $mon, $yr) = (gmtime($main::systime))[0,1,2,3,4,5]; -#printf("%2.2d %2.2d %2.2d %2.2d %2.2d\n",$min,$hr,$day,$mon,$yr); - -$mon++; -$yr += 1900; -$lat=$main::mylatitude; -$lon=$main::mylongitude; -$alt=0.0; - -$jtime=Sun::Julian_Day($yr,$mon,$day)+$hr/24+$min/60/24; -($yr,$mon,$day,$hr,$min)=Sun::Calendar_date_and_time_from_JD($jtime); -#printf("%2.2d %2.2d %2.2d %2.2d %2.2d\n",$min,$hr,$day,$mon,$yr); -push @out,sprintf("Tracking table for $satname"); -push @out,sprintf("dd/mm UTC Lat Lon Alt(km) Az El Dist(km)"); -my ($slat,$slon,$salt,$az,$el,$distance)= - Sun::get_satellite_pos( - $jtime,$lat*$d2r,$lon*$d2r,$alt,$satname); -push @out,sprintf( # print the current satellite position - "Now %2.2d:%2.2d %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f", - $hr,$min,$slat*$r2d,$slon*$r2d,$salt, - $az*$r2d,$el*$r2d,$distance); - -my $numsteps=0; -my $step = 2; # tracking table resolution in minutes -$jtime=$jtime+$step/24/60; -while ( $numsteps < 6*60/$step ) # for now, look 6 hours ahead for tracking table +my @f = split /\s+/, $line; +my $satname = uc shift @f; +my $numhours = shift @f; # the number of hours ahead to print +my $step = shift @f; # tracking table resolution in minutes + +# default hours and step size +$numhours = 3 unless $numhours && $numhours =~ /^\d+$/; +$step = 5 unless $step && $step =~ /^\d+$/; + +# get nearest lat and long (I can see we will need the altitude here soon as well :-) +my $lat = $self->user->lat; +my $lon = $self->user->long; +my $alt = 0; +my $call = $self->call; +unless ($lon || $lat) { + $lat = $main::mylatitude; + $lon = $main::mylongitude; + $call = $main::mycall; +} + +if ($satname && $Sun::keps{$satname}) { + my $jtime; # lats and longs in radians + my ($sec, $min, $hr, $day, $mon, $yr) = (gmtime($main::systime))[0,1,2,3,4,5]; + #printf("%2.2d %2.2d %2.2d %2.2d %2.2d\n",$min,$hr,$day,$mon,$yr); + + $mon++; + $yr += 1900; + $alt=0.0; + + $jtime=Sun::Julian_Day($yr,$mon,$day)+$hr/24+$min/60/24; + ($yr,$mon,$day,$hr,$min)=Sun::Calendar_date_and_time_from_JD($jtime); + #printf("%2.2d %2.2d %2.2d %2.2d %2.2d\n",$min,$hr,$day,$mon,$yr); + push @out, $self->msg("pos", $call, slat($lat), slong($lon)); + push @out, $self->msg("sat1", $satname, $numhours, $step); + push @out, $self->msg("sat2"); + + my ($slat,$slon,$salt,$az,$el,$distance)=Sun::get_satellite_pos($jtime,$lat*$d2r,$lon*$d2r,$alt,$satname); + # print the current satellite position + push @out,sprintf("Now %2.2d:%2.2d %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f", + $hr,$min,$slat*$r2d,$slon*$r2d,$salt, + $az*$r2d,$el*$r2d,$distance); + + my $numsteps=0; + $jtime=$jtime+$step/24/60; + my $disc = 0; # discontinuity flag + while ( $numsteps < $numhours*60/$step ) # look $numhours ahead for tracking table { - my ($yr,$mon,$day,$hr,$min)=Sun::Calendar_date_and_time_from_JD($jtime); - my ($slat,$slon,$salt,$az,$el,$distance)= - Sun::get_satellite_pos( - $jtime,$lat*$d2r,$lon*$d2r,$alt,$satname); - if( $el*$r2d > -5 ) { - push @out,sprintf( - "%2.2d/%2.2d %2.2d:%2.2d %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f", - $day,$mon,$hr,$min,$slat*$r2d,$slon*$r2d,$salt, - $az*$r2d,$el*$r2d,$distance); + my ($yr,$mon,$day,$hr,$min)=Sun::Calendar_date_and_time_from_JD($jtime); + my ($slat,$slon,$salt,$az,$el,$distance)=Sun::get_satellite_pos($jtime,$lat*$d2r,$lon*$d2r,$alt,$satname); + if ( $el*$r2d > -5 ) { + if ($disc) { + $disc = 0; + push @out, $self->msg("satdisc"); + } + push @out,sprintf("%2.2d/%2.2d %2.2d:%2.2d %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f", + $day,$mon,$hr,$min,$slat*$r2d,$slon*$r2d,$salt, + $az*$r2d,$el*$r2d,$distance); + } else { + $disc++; + } + $numsteps++; + $jtime=$jtime+$step/60/24; + } +} else { + push @out, $self->msg("satnf", $satname) if $satname; + push @out, $self->msg("sat3"); + push @out, $self->msg("sat4"); + my @l; + my $i = 0; + my $sat; + foreach $sat (sort keys %Sun::keps) { + if ($i >= 6) { + push @out, join ' + ', @l; + @l = (); + $i = 0; } - $numsteps++; - $jtime=$jtime+$step/60/24; + push @l, $sat; + $i++; } + push @out, join ' + ', @l; +} return (1,@out); + + + + + + + + + diff --git a/perl/Messages b/perl/Messages index 33fa718b..b7d8a648 100644 --- a/perl/Messages +++ b/perl/Messages @@ -130,7 +130,7 @@ package DXM; pingi => 'Ping Returned from $_[0] $_[1] (Ave $_[2]) secs', pinge1 => 'Cannot ping yourself!', pingint => 'Ping interval on $_[0] set to $_[1] secs', - + pos => 'From Callsign: $_[0] Lat: $_[1] Long: $_[2]', pr => '$_[0] de $main::mycall $main::cldate $main::ztime >', pr2 => '($_[0]) de $main::mycall $main::cldate $main::ztime >', priv => 'Privilege level changed on $_[0]', @@ -146,6 +146,12 @@ package DXM; read1 => 'Sorry, no new messages for you', read2 => 'Msg $_[0] not found', read3 => 'Msg $_[0] not available', + sat1 => 'Tracking Table for $_[0] for the next $_[1] hours every $_[2] mins', + sat2 => 'dd/mm UTC Lat Lon Alt Km Az El Dist Km', + sat3 => 'Syntax: SH/SAT [ ]', + sat4 => 'Satellites available:-', + satnf => 'Satellite $_[0] unknown', + satdisc => '-----', shutting => '$main::mycall shutting down...', sloc => 'Cluster lat $_[0] long $_[1], DON\'T FORGET TO CHANGE YOUR DXVars.pm', snode1 => 'Node Call Sort Version', diff --git a/perl/Sun.pm b/perl/Sun.pm index 4bb349f6..09af995b 100644 --- a/perl/Sun.pm +++ b/perl/Sun.pm @@ -28,12 +28,29 @@ require Exporter; @EXPORT = qw($pi $d2r $r2d ); use strict; -use vars qw($pi $d2r $r2d ); +use vars qw($pi $d2r $r2d); $pi = 3.141592653589; $d2r = ($pi/180); $r2d = (180/$pi); +use vars qw(%keps); +use Keps; +use DXVars; +use DXUtil; + +# reload the keps data +sub load +{ + my @out; + my $s = readfilestr("$main::root/local/Keps.pm"); + if ($s) { + eval $s; + push @out, $@ if $@; + } + return @out; +} + sub Julian_Day { my $year = shift; @@ -563,50 +580,6 @@ sub get_satellite_pos # #Temporary keps database... # -my %keps = ( - noaa15 => { - number => 25338, - id => 98030, - epoch => 99341.00000000, - mm1 => .00000376, - mm2 => .00000e-0, - bstar => .18612e-3, - inclination => 98.6601, - raan => 8.2003, - eccentricity => .0011401, - argperigee => 112.4684, - meananomaly => 42.5140, - meanmotion => 14.23047277081382, - }, - tdrs5 => { - number => 21639, - id => 91054, - epoch => 99341.34471854, - mm1 => .00000095, - mm2 => .00000e-0, - bstar => .10000e-3, - inclination => 1.5957, - raan => 88.4884, - eccentricity => .003028, - argperigee => 161.6582, - meananomaly => 135.4323, - meanmotion => 1.00277774, - }, - oscar16 => { - number => 20439, - id => 90005, - epoch => 99341.14501399, - mm1 => .00000343, - mm2 => .00000e-0, - bstar => .14841e-3, - inclination => 98.4690, - raan => 55.0032, - eccentricity => .0012163, - argperigee => 66.4615, - meananomaly => 293.7842, - meanmotion => 14.303202855, - }, -); my $jtime = shift; my $lat = shift; my $lon = shift; @@ -901,6 +874,10 @@ sub Calendar_date_and_time_from_JD $yr = $c-4715 if( $mon == 1 || $mon == 2 ); $hr = int($frac*24); $min= int(($frac*24 - $hr)*60+0.5); + if ($min == 60) { # this may well prove inadequate DJK + $hr += 1; + $min = 0; + } return ($yr,$mon,$day,$hr,$min); } diff --git a/perl/convkeps.pl b/perl/convkeps.pl new file mode 100755 index 00000000..5102e3d2 --- /dev/null +++ b/perl/convkeps.pl @@ -0,0 +1,129 @@ +#!/usr/bin/perl -w +# +# Convert an Amsat 2 line keps bull into Sun.pm format +# +# This program will accept on stdin a standard AMSAT 2 line keps +# bull such as you would find in an email or from the packet network +# +# It will write a file called /spider/local/Keps.pm, this means that +# the latest version will be read in every time you restart the +# cluster.pl. You can also call Sun::load from a cron line if +# you like to re-read it automatically. +# +# This program is designed to be called from /etc/aliases or +# a .forward file so you can get yourself on the keps mailing +# list from AMSAT and have the keps updated automatically once +# a week. +# +# I will distribute the latest keps with every patch but you can +# get your own data from: +# +# http://www.amsat.org/amsat/ftp/keps/current/nasa.all +# +# Copyright (c) 2000 Dirk Koopman G1TLH +# +# $Id$ +# + +require 5.004; + +# search local then perl directories +BEGIN { + # root of directory tree for this system + $root = "/spider"; + $root = $ENV{'DXSPIDER_ROOT'} if $ENV{'DXSPIDER_ROOT'}; + + unshift @INC, "$root/perl"; # this IS the right way round! + unshift @INC, "$root/local"; +} + +use strict; +use Data::Dumper; + +use vars qw($root); + +my $fn = "$root/local/Keps.pm"; +my $state = 0; +my $name; +my %keps; +my $ref; +my $line; + +while () { + ++$line; + chomp; + s/^\s+//; + s/\s+$//; + next unless $_; + last if m{^/EX}i; + last if m{^-}; + + if ($state == 0 && /^TO ALL/) { + $state = 1; + } elsif ($state == 1) { + last if m{^/EX/i}; + + if (/^\w+/) { + s/\s/-/g; + $name = $_; + $ref = $keps{$name} = {}; + $state = 2; + } + } elsif ($state == 2) { + if (/^1 /) { + my ($id, $number, $epoch, $decay, $mm2, $bstar, $elset) = unpack "xxa5xxa5xxxa15xa10xa8xa8xxxa4x", $_; + $ref->{id} = $id - 0; + $ref->{number} = $number - 0; + $ref->{epoch} = $epoch - 0; + $ref->{mm1} = $decay - 0; + $ref->{mm2} = genenum($mm2); + $ref->{bstar} = genenum($bstar); + $ref->{elset} = $elset - 0; +# print "$id $number $epoch $decay $mm2 $bstar $elset\n"; +# print "mm2: $ref->{mm2} bstar: $ref->{bstar}\n"; + + $state = 3; + } else { + print "out of order on line $line\n"; + undef $ref; + delete $keps{$name}; + $state = 1; + } + } elsif ($state == 3) { + if (/^2 /) { + my ($id, $incl, $raan, $ecc, $peri, $man, $mmo, $orbit) = unpack "xxa5xa8xa8xa7xa8xa8xa11a5x", $_; + $ref->{meananomaly} = $man - 0; + $ref->{meanmotion} = $mmo - 0; + $ref->{inclination} = $incl - 0; + $ref->{eccentricity} = ".$ecc" - 0; + $ref->{argperigee} = $peri - 0; + $ref->{raan} = $raan - 0; + $ref->{orbit} = $orbit - 0; + } else { + print "out of order on line $line\n"; + delete $keps{$name}; + } + undef $ref; + $state = 1; + } +} + +my $dd = new Data::Dumper([\%keps], [qw(*keps)]); +$dd->Indent(1); +$dd->Quotekeys(0); +open(OUT, ">$fn") or die "$fn $!"; +print OUT "#\n# this file is automatically produced by convkeps.pl\n#\n"; +print OUT "\npackage Sun;\n\n"; +print OUT $dd->Dumpxs; +print OUT "\n"; +close(OUT); + + +# convert (+/-)00000-0 to (+/-).00000e-0 +sub genenum +{ + my ($sign, $frac, $esign, $exp) = unpack "aa5aa", shift; + my $n = $sign . "." . $frac . 'e' . $esign . $exp; + return $n - 0; +} + diff --git a/src/README b/src/README new file mode 100644 index 00000000..e69de29b