--- predict-2.2.3.orig/debian/predict-gsat.dirs +++ predict-2.2.3/debian/predict-gsat.dirs @@ -0,0 +1,2 @@ +usr/bin +usr/share/man/man1 --- predict-2.2.3.orig/debian/predict-map.1 +++ predict-2.2.3/debian/predict-map.1 @@ -0,0 +1,22 @@ +.TH PREDICT-MAP 1 "31 August 2003" +.SH NAME +predict-map \- GUI for predict +.SH SYNOPSIS +\fB predict-map\fP +[ +.I system-name +] +.SH DESCRIPTION +\fBPREDICT-MAP\fP +is a graphical satellite tracking application written by Ivan Galysh, +KD4HBO , that makes use of the socket-based +interface in PREDICT to obtain real-time satellite tracking data. +"predict-map" requires the XForms libraries to compile and run. +.PP +Once started, Predict-Map spawns itself as a background process. +.SH ARGUMENTS + system-name +.br +hostname of system running predict server. +.SH AUTHOR +This man page was written by A. Maitland Bottoms, AA4HS, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/README.source +++ predict-2.2.3/debian/README.source @@ -0,0 +1,58 @@ +This package uses quilt to manage all modifications to the upstream +source. Changes are stored in the source package as diffs in +debian/patches and applied during the build. + +To configure quilt to use debian/patches instead of patches, you want +either to export QUILT_PATCHES=debian/patches in your environment +or use this snippet in your ~/.quiltrc: + + for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do + if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then + export QUILT_PATCHES=debian/patches + break + fi + done + +To get the fully patched source after unpacking the source package, cd to +the root level of the source package and run: + + quilt push -a + +The last patch listed in debian/patches/series will become the current +patch. + +To add a new set of changes, first run quilt push -a, and then run: + + quilt new + +where is a descriptive name for the patch, used as the filename in +debian/patches. Then, for every file that will be modified by this patch, +run: + + quilt add + +before editing those files. You must tell quilt with quilt add what files +will be part of the patch before making changes or quilt will not work +properly. After editing the files, run: + + quilt refresh + +to save the results as a patch. + +Alternately, if you already have an external patch and you just want to +add it to the build system, run quilt push -a and then: + + quilt import -P /path/to/patch + quilt push -a + +(add -p 0 to quilt import if needed). as above is the filename to +use in debian/patches. The last quilt push -a will apply the patch to +make sure it works properly. + +To remove an existing patch from the list of patches that will be applied, +run: + + quilt delete + +You may need to run quilt pop -a to unapply patches first before running +this command. --- predict-2.2.3.orig/debian/gsat.1 +++ predict-2.2.3/debian/gsat.1 @@ -0,0 +1,46 @@ +.TH GSAT 1 "31 August 2003" +.SH NAME +gsat \- Graphical Predict client +.SH SYNOPSIS +\fB gsat\fP +[ +.I -u +] [ +.I -l +] [ +.I -g +] [ +.I -h +] [ +.I -s predictservername +] +.SH DESCRIPTION +The gsat program is a graphical client for the 'predict' satellite tracking +program running in server mode, built using gtk. +.PP +Visualization of satellite coverage and orbital ground tracks are one feature +of this application, but it also allows for display and control of Doppler +corrected frequencies of a radio and antenna rotor control via predict(1). +.PP +Since this program can be run on a different machine than predict, there is +no dependency specified... but you need access to a copy of 'predict' +installed somewhere on the network for this programs to be useful! +.SH OPTIONS + -u +Times in UTC + -l +Times in Local Time Zone + -g +Show grid + -h +Show short usage text + -s +Predict Server Name +.SH ENVIRONMENT +gsat uses the following environment variables: +.br +PREDICTHOST +.br +GSATPLUGINSDIR +.SH AUTHOR +This man page was written by A. Maitland Bottoms, AA4HS, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/geosat.man +++ predict-2.2.3/debian/geosat.man @@ -0,0 +1,11 @@ +.TH GEOSAT 1 "20 December 1999" +.SH NAME +geosat \- Calculate Az and El to Geostationary Satellites +.SH SYNOPSIS +\fB geosat\fP +.SH DESCRIPTION +\fBGEOSAT\fP is a small program which prompts for a longtitude, and displays +the azimuth and elevation to a geostationary satellite at that longitude. The +location of the observer is taken from the data files for predict(1). +.SH AUTHOR +This man page was written by Bdale Garbee, N3EUA, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/predict-earthtrack.dirs +++ predict-2.2.3/debian/predict-earthtrack.dirs @@ -0,0 +1 @@ +usr/bin --- predict-2.2.3.orig/debian/earthtrack.1 +++ predict-2.2.3/debian/earthtrack.1 @@ -0,0 +1,134 @@ +.TH EARTHTRACK 1 "31 August 2003" +.SH NAME +earthtrack \- Combine xplanet and predict +.SH SYNOPSIS +\fB earthtrack\fP +[ +.I -h +] +[ +.I -p +] +[ +.I -x +] +[ +.I -u +] +[ +.I -o +] +[ +.I -c +] +[ +.I -C +] +.SH OPERATION +"earthtrack" uses "xplanet" to produce an orthographic image of the +earth upon which satellite names are placed over their respective +sub-satellite points. The globe can be centered either over your +groundstation location (default), or over the location any satellite +being tracked by PREDICT. The second method allows you to "fly with +the satellite" as it circles the globe. The map is updated every 20 +seconds. By default, "earthtrack" connects to the PREDICT server +running on "localhost". These defaults may be overridden through +several command-line switches. +.PP +The -h switch allows a different PREDICT server name to be specified. +The -x switch option allows additional command-line parameters to be +passed to xplanet through earthtrack. (Note that +the argument that follows the -x switch must be enclosed in "quotes".) +The -u switch allows a different map update interval to be specified, +and the -c switch allows the map to be centered on a specific satellite. +.PP +For example: +.PP + earthtrack -c ISS -u 15 -h predictserver.org +.PP +allows earthtrack to invoke "xearth" as a display, centering the map +on the location of satellite "ISS", using host "predictserver.org" +as the host running PREDICT in server mode. The satellite name +specified must be the same as PREDICT displays in Multi-Tracking +mode. If a space appears in the name, then the entire name must +be enclosed in double quotes. +.PP +"xplanet" uses highly detailed photo-realistic maps of the world +available from a variety of sources to produce spectacular views +of the earth. +For example, if an uppercase -C is used rather than a lowercase +-c for the map center switch, such as in the following example: +.PP + earthtrack -C ISS +.PP +the map is not only centered on the location of the ISS, but the +map is also zoomed into an area slightly larger than the footprint +of the satellite. A range circle is also drawn on the map to +indicate the actual footprint of the spacecraft at the current +time. +.PP +If a map centered on the groundstation location is desired, then +footprint range circles for neighboring satellites are drawn on the +map. Range circles are drawn for satellites between 5 minutes prior +to AOS through the point of LOS. Such a display may be created simply +by executing "earthtrack" without any switches: +.PP + earthtrack +.PP +or with the -h switch to identify the remote host running PREDICT in +server mode: +.PP + earthtrack -h predictserver.org +.PP +If the satellite being tracked is in sunlight, then the satellite +name and range circle are displayed in white. If the satellite +is in darkness, then the color blue is used. If the satellite +is optically visible to the groundstation, then yellow is used. +.PP +"earthtrack" may also be used to generate graphics files for +use in web server environments. For example: +.PP + earthtrack2 -c ISS -x "-geometry 800x600 -output graphic.png" +.PP +will invoke "xplanet" to produce an 800x600 PNG image of the world +centered on the sub-satellite point of the ISS with a name of +"graphic.png". This feature, along with capabilities demonstrated +in the ~/predict/clients/samples directory, can be used to develop +satellite tracking and orbital prediction content for a web server. +.PP +"earthtrack" exits when its connection to +the PREDICT server is broken, such as would occur if PREDICT +is terminated while "earthtrack" is still running. The +application may be run as background processes by placing +an ampersand (&) at the end of the command line. +.PP +This version includes a -o switch to send the output to +the file /tmp/xplanet.png instead of to the screen. +.PP +For more creative uses of PREDICT and earthtrack, see John +Heaton, G1YYH's PREDICT and earthtrack modification web page +at: +.PP + http://voyager.mcc.ac.uk/Predict/ +.PP +Happy Tracking! +.PP +73, de John, KD2BD +.br +June 2003 +.SH OPTIONS + -c (center on satellite) +.br + -C (center on satellite and zoom in) +.br + -h +.br + -o +.br + -p +.br + -x +.br + -u +.SH AUTHOR +This man page was written by A. Maitland Bottoms, AA4HS, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/control +++ predict-2.2.3/debian/control @@ -0,0 +1,36 @@ +Source: predict +Section: hamradio +Priority: optional +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: A. Maitland Bottoms +Uploaders: Bdale Garbee +Build-Depends: debhelper (>= 7), quilt, libncurses5-dev, libgtk2.0-dev, libforms-dev, autotools-dev, automake +Standards-Version: 3.8.4 + +Package: predict +Architecture: any +Depends: ${shlibs:Depends}, netbase (>= 4.07) +Suggests: ntp, predict-gsat +Description: Satellite Tracking Program with Optional Voice Output + This is a satellite tracking program. It is probably mostly of interest to + users of amateur satellites, but includes support for optionally announcing + azimuth and elevation to help in manual antenna pointing, or optical + observation of satellites. + . + The upstream predict sources include a front-end called 'map', which is + called predict-map in the Debian package. + . + The 'ntp' package is suggested because accurate satellite tracking depends + on precise knowledge of ground station time and location. + +Package: predict-gsat +Architecture: any +Depends: ${shlibs:Depends}, netbase (>= 4.07) +Suggests: ntp, predict +Description: Graphical Satellite Tracking Client Program + The gsat program is a graphical client for the 'predict' satellite tracking + program running in server mode, built using gtk. + . + Since this program can be run on a different machine than predict, there is + no dependency specified... but you need access to a copy of 'predict' + installed somewhere on the network for this programs to be useful! --- predict-2.2.3.orig/debian/rules +++ predict-2.2.3/debian/rules @@ -0,0 +1,163 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) +CFLAGS += -O0 +else +CFLAGS += -O2 -fomit-frame-pointer +endif + +build: build-stamp +build-stamp: + dh_testdir + + QUILT_PATCHES=debian/patches quilt push -a || test $$? = 2 + + cc $(CFLAGS) \ + -o predict predict.c -I/usr/include/ncurses \ + -lm -lncurses -lpthread + cc $(CFLAGS) \ + -o predict-g1yyh predict-g1yyh.c -I/usr/include/ncurses \ + -lm -lncurses -lpthread -lmenu + cc $(CFLAGS) \ + vocalizer/vocalizer.c -o vocalizer/vocalizer + + (cd utils/fodtrack-0.1 ; cc $(CFLAGS) fodtrack.c -o fodtrack -lm ) + (cd utils/geosat ; cc $(CFLAGS) geosat.c -o geosat -lm ) + (cd utils/moontracker ; cc $(CFLAGS) moontracker.c -o moontracker -lm ) + (cd clients/earthtrack ; cc $(CFLAGS) earthtrack.c -o earthtrack -lm ) + (cd clients/map; cc $(CFLAGS) -o predict-map map.c map_cb.c map_main.c -I/usr/include/X11 -lforms -lX11 -lm) + + + #mv clients/gsat-1.1.0/config.sub clients/gsat-1.1.0/config.sub.upstream + -test -r /usr/share/misc/config.sub && \ + cp -f /usr/share/misc/config.sub clients/gsat-1.1.0/config.sub + #mv clients/gsat-1.1.0/config.guess clients/gsat-1.1.0/config.guess.upstream + -test -r /usr/share/misc/config.guess && \ + cp -f /usr/share/misc/config.guess clients/gsat-1.1.0/config.guess + #mv clients/gsat-1.1.0/src/Makefile.in clients/gsat-1.1.0/src/Makefile.in.upstream + + (cd clients/gsat-1.1.0 ; aclocal; autoconf; automake -a; ./configure --prefix=/usr ) + make -C $(CURDIR)/clients/gsat-1.1.0 + make -C $(CURDIR)/clients/gsat-1.1.0/plugins + + #mv clients/gsat-1.1.0/src/Makefile.in.upstream clients/gsat-1.1.0/src/Makefile.in + #mv clients/gsat-1.1.0/config.guess.upstream clients/gsat-1.1.0/config.guess + #mv clients/gsat-1.1.0/config.sub.upstream clients/gsat-1.1.0/config.sub + + (cd clients/kep_reload ; \ + cc $(CFLAGS) kep_reload.c -o kep_reload ) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + #Need a cleaner way to do this. + QUILT_PATCHES=debian/patches quilt push -a || test $$? = 2 + + rm -f predict predict-g1yyh vocalizer/vocalizer + rm -f utils/geosat/geosat clients/kep_reload/kep_reload + rm -f utils/fodtrack-0.1/fodtrack utils/moontracker/moontracker + rm -f clients/earthtrack/earthtrack + rm -f clients/map/predict-map + if [ ! -f $(CURDIR)/clients/gsat-1.1.0/config.status ]; then touch $(CURDIR)/clients/gsat-1.1.0/config.status; fi + if [ -f $(CURDIR)/clients/gsat-1.1.0/Makefile ]; then ( cd clients/gsat-1.1.0 ; aclocal; autoconf; automake --add-missing; make distclean ); fi + if [ -f $(CURDIR)/clients/gsat-1.1.0/plugins/Makefile ]; then ( cd clients/gsat-1.1.0/plugins ; make clean ); fi + ( cd clients/gsat-1.1.0/src ; rm -f *.o gsat ) + + QUILT_PATCHES=debian/patches quilt pop -a -R || test $$? = 2 + rm -f clients/gsat-1.1.0/config.log + rm -f clients/gsat-1.1.0/config.sub + rm -f clients/gsat-1.1.0/config.cache + rm -f clients/gsat-1.1.0/config.status + rm -f clients/gsat-1.1.0/Makefile.in + rm -f clients/gsat-1.1.0/src/Makefile.in + rm -f clients/gsat-1.1.0/aclocal.m4 + rm -f clients/gsat-1.1.0/configure + rm -f clients/gsat-1.1.0/depcomp + rm -rf .pc + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cp predict predict-g1yyh debian/predict/usr/bin + cp clients/kep_reload/kep_reload debian/predict/usr/bin + cp clients/earthtrack/earthtrack debian/predict/usr/bin + cp clients/map/predict-map debian/predict-gsat/usr/bin + echo "#!/bin/sh" > debian/predict/usr/share/doc/predict/kepupdate + sed 's/\/local//' clients/kep_reload/kepupdate >> debian/predict/usr/share/doc/predict/kepupdate + chmod +x debian/predict/usr/share/doc/predict/kepupdate + cp utils/fodtrack-0.1/fodtrack.conf debian/predict/etc/ + cp utils/fodtrack-0.1/fodtrack debian/predict/usr/bin + cp utils/geosat/geosat debian/predict/usr/bin + cp utils/moontracker/moontracker debian/predict/usr/bin + make -C $(CURDIR)/clients/gsat-1.1.0 install prefix=$(CURDIR)/debian/predict-gsat/usr + + for file in radio_FT736 radio_FT847 radio_ICR10 radio_TMD700 radio_PCR100 radio_print \ + radio_test rotor_print rotor_pictrack ; do \ + cp clients/gsat-1.1.0/plugins/$$file \ + debian/predict-gsat/usr/lib/gsat/plugins/$$file ;\ + done + rmdir debian/predict-gsat/usr/share/gsat/pixmaps + rmdir debian/predict-gsat/usr/share/gsat + + cp -p vocalizer/*wav debian/predict/usr/lib/predict/ + cp -p vocalizer/vocalizer debian/predict/usr/lib/predict/ + + cp docs/man/predict.man debian/predict/usr/share/man/man1/predict.1 + cp debian/gsat.1 debian/predict-gsat/usr/share/man/man1/gsat.1 + cp debian/predict-map.1 debian/predict-gsat/usr/share/man/man1/predict-map.1 + cp debian/earthtrack.1 debian/predict/usr/share/man/man1/earthtrack.1 + cp debian/moontracker.1 debian/predict/usr/share/man/man1/moontracker.1 + cp debian/kep_reload.1 debian/predict/usr/share/man/man1/kep_reload.1 + cp debian/predict-g1yyh.man \ + debian/predict/usr/share/man/man1/predict-g1yyh.1 + cp debian/geosat.man debian/predict/usr/share/man/man1/geosat.1 + cp utils/fodtrack-0.1/fodtrack.8 debian/predict/usr/share/man/man8/ + cp utils/fodtrack-0.1/fodtrack.conf.5 debian/predict/usr/share/man/man5/ + mkdir debian/predict/usr/lib/predict/default + cp default/* debian/predict/usr/lib/predict/default + +# Build architecture-independent files here. +binary-indep: build install + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + cp utils/geosat/README \ + debian/predict/usr/share/doc/predict/README.geosat + dh_installexamples + dh_installmenu + dh_installcron + dh_installman + dh_installinfo + dh_installchangelogs --package=predict CHANGES + dh_installchangelogs --package=predict-gsat clients/gsat-1.1.0/ChangeLog + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install --- predict-2.2.3.orig/debian/README.Debian +++ predict-2.2.3/debian/README.Debian @@ -0,0 +1,24 @@ +* The predict_2.2.3.orig.tar.gz differs from the upstream + predict-2.2.3.tar.gz in that the possibly non-DFSG compliant + .wav files from AT&T have been replaced with a set of + files generated using festival text to speech tools. Also + removed some clients/gsat-1.1.0/config.[log,cache,status] + files. + +* Included Ralf Baechle, DO1GRB, gsat-1.1.0 plugin support for the + Yaesu FT-847 transceiver. + ftp://ftp.linux-mips.net/pub/ham/predict-2.2.2/ + +* Added a new UDP socket command (GET_SAT_AT) to return PREDICT's + calculation for a satellite at a given time to networked clients. + This allows for applications to do non-real-time planning, or + generate responses for web queries for example. (predictat patch). + +* The predict-g1yyh is predict-2.2.1jh4.c plus the predictat patch. + (John Heaton, G1YYH, has added 2.2.3 fixes) + +* This earthtrack application only uses xplanet, and includes a -o + switch to send the output to a file like G1YYH's filetrack and a + -p switch to set the projection (default ortho). + + -- A. Maitland Bottoms , Sat, 5 Aug 2006 20:44:50 -0400 --- predict-2.2.3.orig/debian/predictat.patch +++ predict-2.2.3/debian/predictat.patch @@ -0,0 +1,176 @@ +--- predict-2.2.1jh4.c 2006-08-05 21:11:43.317306878 -0400 ++++ predict-g1yyh.c 2006-08-05 21:16:00.751348441 -0400 +@@ -56,6 +56,8 @@ + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + #define halfdelaytime 10 + ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ); ++ + /* Constants used by SGP4/SDP4 code */ + + #define km2mi 0.621371 /* km to miles */ +@@ -2044,6 +2046,7 @@ + + int i, j, n, sock; + socklen_t alen; ++ double dLat, dLong; /* parameters for PredictAt */ + struct sockaddr_in fsin; + char buf[80], buff[1000], satname[50], tempname[30], ok; + time_t t; +@@ -2199,6 +2202,34 @@ + sendto(sock,buff,strlen(buff),0,(struct sockaddr *)&fsin,sizeof(fsin)); + ok=1; + } ++ ++ // calculate the satellite position at a given moment in time... ++ if ( strncmp ( "GET_SAT_AT", buf, 10 ) == 0 ) { ++ // get the parameters... ++ sscanf ( &buf[10], "%s %ld %lf %lf", satname, (unsigned long *) &t, &dLat, &dLong ); ++ ++ // find the satellite id ++ for ( i=0; i<24; i++ ) { ++ if ( strcmp ( sat[i].name, satname ) == 0) { ++ //syslog ( LOG_INFO, "%s | %ld\n", sat[i].name, (unsigned long) t ); ++ ++ // get the position ++ PredictAt ( i, t, dLat, dLong ); ++ ++ // print out the info... ++ sprintf ( buff, "GOT_SAT_AT %ld %f %f %f %f %ld %f %f\n", \ ++ (unsigned long)t, \ ++ long_array[i], \ ++ lat_array[i], \ ++ az_array[i], \ ++ el_array[i], \ ++ aos_array[i], \ ++ range_array[i], \ ++ doppler[i] ); ++ sendto(sock,buff,strlen(buff),0,(struct sockaddr *)&fsin,sizeof(fsin)); ++ } ++ } ++ } + + if (strncmp("GET_TIME$",buf,9)==0) { + buff[0]=0; +@@ -6179,6 +6210,121 @@ + return 0; + } + ++double GetDayNum ( struct timeval *tv ) ++{ ++ /* used by PredictAt */ ++ return ( ( ( (double) (tv->tv_sec) - 0.000001 * ( (double) (tv->tv_usec) ) ) / 86400.0) - 3651.0 ); ++} ++ ++/* ++ void PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++ ++ Computes the satellites possition at the given time... ++ ... so that we can report it via a socket. ++ ++ Returns: ++ TRUE if successful. ++ ++ Author/Editor: ++ February 2003 ++ Glenn Richardson ++ glenn@spacequest.com ++*/ ++ ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++{ ++ double dDayNum; /* time of prediction */ ++ double dOldRange, dOldClock; /* range / time of pre-prediction position */ ++ double dDoppler = 0.0; /* doppler calculation */ ++ double dDeltaTime, dDeltaPos; /* used in doppler calc */ ++ double dQLat, dQLong; /* remember the groundstation lat/long */ ++ int iInRange; /* is the satellite in view? */ ++ struct timeval tv; /* time structure... */ ++ ++ /* remember... */ ++ dQLat = qth.stnlat; ++ dQLong = qth.stnlong; ++ qth.stnlat = dLat; ++ qth.stnlong = dLong; ++ ++ /* are the keps ok? */ ++ if ( ( sat[iSatID].meanmo == 0.0) || ( Decayed ( iSatID, 0.0 ) == 1 ) || ( Geostationary ( iSatID ) ) || !( AosHappens ( iSatID ) ) ) ++ { ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ /* !!!! NOTE: we only compute LEOs !!!! */ ++ /* syslog ( LOG_INFO, "PredictAT() can't do this one..."); */ ++ return FALSE; ++ } ++ ++ /* syslog ( LOG_INFO, "PredictAT: ttDayNum... %ld, %s", (unsigned long) ttDayNum, ctime ( &ttDayNum ) ); */ ++ /* first, prepare for doppler by computing pos 5 sec ago */ ++ indx = iSatID; ++ tv.tv_sec = ttDayNum - 5; ++ tv.tv_usec = 0; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dOldClock = 86400.0 * daynum; ++ dOldRange = sat_range * 1000.0; ++ ++ /* now, recompute at current position */ ++ tv.tv_sec = ttDayNum; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dDayNum = daynum; ++ ++ /* setup for doppler... */ ++ dDeltaTime = dDayNum * 86400.0 - dOldClock; ++ dDeltaPos = (sat_range * 1000.0) - dOldRange; ++ ++ if ( sat_azi >= 0.0 ) ++ { ++ iInRange = 1; ++ ++ /* compute the doppler */ ++ dDoppler = - ( ( dDeltaPos / dDeltaTime ) / 299792458.0 ); ++ dDoppler = dDoppler * 100.0e6; ++ } ++ else ++ { ++ /* compute the doppler */ ++ iInRange = 0; ++ } ++ ++ /* printf ("InRange? %d, doppler: %f, Az: %f, El: %f, %s", ++ iInRange, dDoppler, azimuth, elevation, ctime ( &ttDayNum ) ); */ ++ /* remember values for socket connection... */ ++ az_array[iSatID] = sat_azi; ++ el_array[iSatID] = sat_ele; ++ lat_array[iSatID] = sat_lat; ++ long_array[iSatID] = 360.0 - sat_lon; ++ footprint_array[iSatID] = fk; ++ range_array[iSatID] = sat_range; ++ altitude_array[iSatID] = sat_alt; ++ velocity_array[iSatID] = sat_vel; ++ orbitnum_array[iSatID] = rv; ++ doppler[iSatID] = dDoppler; ++ ++ ++ /* Calculate Next Event (AOS/LOS) Times */ ++ if ( iInRange ) ++ nextevent[iSatID] = FindLOS2(); ++ else ++ nextevent[iSatID] = FindAOS(); ++ ++ ++ /* restore... */ ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ return TRUE; ++} ++ + int main(argc,argv) + char argc, *argv[]; + { --- predict-2.2.3.orig/debian/predict-gsat.docs +++ predict-2.2.3/debian/predict-gsat.docs @@ -0,0 +1,4 @@ +clients/gsat-1.1.0/AUTHORS +clients/gsat-1.1.0/NEWS +clients/gsat-1.1.0/README +clients/gsat-1.1.0/Plugin_API --- predict-2.2.3.orig/debian/compat +++ predict-2.2.3/debian/compat @@ -0,0 +1 @@ +7 --- predict-2.2.3.orig/debian/dirs +++ predict-2.2.3/debian/dirs @@ -0,0 +1,7 @@ +etc +usr/bin +usr/lib/predict +usr/share/doc/predict +usr/share/man/man1 +usr/share/man/man5 +usr/share/man/man8 --- predict-2.2.3.orig/debian/kep_reload.1 +++ predict-2.2.3/debian/kep_reload.1 @@ -0,0 +1,31 @@ +.TH KEP_RELOAD 1 "31 August 2003" +.SH NAME +kep_reload \- Update Predict's Keplerian elements +.SH SYNOPSIS +\fB kep_reload\fP +.SH DESCRIPTION +\fBKEP_RELOAD\fP is a simple utility that forces an immediate reload +of PREDICT's Keplerian database through a socket connection while +PREDICT is running in server mode. It is especially useful in +environments where PREDICT runs continuously, and periodic Keplerian +element updates are made outside of PREDICT, such as through scripts +run through a crontab. +.PP +The "kepupdate" script found in this directory is an example of a +Keplerian element update script that can be run on an automated +basis through a crontab. It is designed to be placed in your +home directory under a subdirectory called "cronjobs". It downloads +Keplerian orbital data from www.celestrak.com using the HTTP protocol. +(The "wget" utility, available from the Free Software Foundation, is +required, and is included in many Linux distrubutions.) +.PP +Type crontab -e to edit your crontab. Simply add the following entry: +.PP + 0 8 * * * kepupdate +.PP +and your orbital database will update each morning at 8:00 AM +(provided you have a network connection at that time). +.PP +See the crontab man page for more information on editing your crontab. +.SH AUTHOR +This man page was written by A. Maitland Bottoms, AA4HS, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/predict-earthtrack.docs +++ predict-2.2.3/debian/predict-earthtrack.docs @@ -0,0 +1 @@ +clients/earthtrack/README --- predict-2.2.3.orig/debian/predict-g1yyh.man +++ predict-2.2.3/debian/predict-g1yyh.man @@ -0,0 +1,62 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH PREDICT-G1YYH 1 +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +predict-g1yyh \- satellite tracking program +.SH DESCRIPTION +The +.B predict-g1yyh +program is a variant on the +.B predict +satellite tracking program that includes patches from John Heaton, G1YYH, +that add new functionality. This man page documents only the features that +differ between +.B predict +and +.B predict-g1yyh. +See the +.B predict +man page for information on the features of the program that are not described +here! +.PP +The user may step forwards/backwards through the satellites in the Single-Sat +display using the '+' and '-' keys, and may remove blank entries from the +Selector page. +.PP +MultiSat has been reformatted to display upcoming passes below the satellites +in view. Using the 'i' and 'k' keys you can toggle between distances in +Imperial or Kilometres. +Using the 'l' and 'm' keys you can toggle between displaying the normal +latitude/longitude or Maidenhead locators for the sub-satellite location. +.PP +The SingleSat display allows use of the arrow keys to change the frequency +up/down and to move to the next/previous satellite using left/right arrows. +.PP +A new method of selecting satellites is implemented. Instead of +pressing a character next to a satellite name, a scrolling menu is provided. +This means that the program is now capable of handling a much larget list +of satellites, currently a maximum of 250. +.PP +Finally, the height of the terminal window containing predict can be increased +dynamically if you want to display more information than will fit on an 80x24 +terminal window! +.SH SEE ALSO +.BR predict (1), +.br +.SH AUTHOR +This manual page was written by Bdale Garbee , +for the Debian GNU/Linux system (but may be used by others). --- predict-2.2.3.orig/debian/copyright +++ predict-2.2.3/debian/copyright @@ -0,0 +1,17 @@ +This package was debianized by Bdale Garbee on +Tue, 14 Dec 1999 19:21:47 -0700. + +It was downloaded from ftp://ftp.amsat.org/amsat/software/Linux/ + +Upstream Author: John A. Magliacane, kd2bd@amsat.org + +Copyright: + + PREDICT is copyright 1991-2002 by John A. Magliacane, KD2BD, and licensed + under the terms of the GPL version 2 or later. A complete copy of the GPL + is provided on Debian systems in /usr/share/common-licenses/GPL. + + + +The predict-g1yyh version includes patches offered to me by John Heaton, +G1YYH, that were downloaded from http://voyager.mcc.ac.uk/Predict/. --- predict-2.2.3.orig/debian/changelog +++ predict-2.2.3/debian/changelog @@ -0,0 +1,207 @@ +predict (2.2.3-3.1ubuntu1) quantal; urgency=low + + * Merge from Debian Unstable (LP: #1012006). Remaining Changes: + - debian/patches/fix-R0-conflict.diff: + + Some systems define an enumeration containing R0 in sys/ucontext.h. + Changing the name avoids any conflict.(LP: #645036) + + -- Vibhav Pant Tue, 12 Jun 2012 14:22:34 +0530 + +predict (2.2.3-3.1) unstable; urgency=low + + * Non-maintainer upload. + * Fix "ftbfs with gold or ld --no-add-needed": add patch from Ubuntu / + John T. Nogatch (move -lm to the end of the lines in debian/rules). + Change the order of some more cc invocations. + (Closes: #615766, LP: #770815) + + -- gregor herrmann Tue, 06 Dec 2011 18:17:32 +0100 + +predict (2.2.3-3ubuntu2) oneiric; urgency=low + + * debian/rules: move -lm later in cc command to fix geosat, et al. + Author: John T. Nogatch (LP: #770815) + + -- Daniel Holbach Mon, 12 Sep 2011 17:29:00 +0200 + +predict (2.2.3-3ubuntu1) maverick; urgency=low + + * debian/patches/fix-R0-conflict.diff: + - Some systems define an enumeration containing R0 in + sys/ucontext.h. Changing the name avoids any conflict.(LP: #645036) + + -- Niall Creech Wed, 22 Sep 2010 10:28:53 +0100 + +predict (2.2.3-3) unstable; urgency=low + + * Update for libforms2 (Closes: #583174) + * debian/compat set to 7. + * Bump Standards Version to 3.8.4. + * man page is OK, don't include predict.txt.gz (Closes: #429049) + * Include patches from Ubuntu (Closes: #576087, #576365) + * debian/patched/140_fix-buffer-overflow.diff: Fix buffer + overflow on launching with -s (patch from Norvald H. Ryeng) + * debian/patches/141_buffer_overflow.diff: Fix a buffer overflow that + makes predict-g1yyh crash when printing predictions (p, v, s, n and + o commands). Patch courtesy of Norvald H. Ryeng + * debian/patches/180_reworked_gui.diff: resizes and repositions + widgets after GTK2 changes. Patch courtesy of Norvald H. Ryeng + + -- A. Maitland Bottoms Thu, 27 May 2010 16:46:11 -0400 + +predict (2.2.3-2) unstable; urgency=low + + * Acknowledge NMU - Barry deFreese's change to quilt + and general bug fixing (Closes: #429055, #437790, #515432) + * build gsat with current config.sub and config.guess files + * Lintian fixes, minimize .diff size + + -- A. Maitland Bottoms Sun, 15 Nov 2009 23:13:29 -0500 + +predict (2.2.3-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Add quilt patch system. + + Move existing inline changes to quilt. + * Build with Gtk2. (Closes: #515432). + * Install defaults in proper location. (Closes: #429055). + + Thanks to Timo Lindfors for the fix. + * Don't strip on build. (Closes: #437790). + + Thanks to Timo Lindfors for the fix. + * Make clean not ignore errors. + * Bump debhelper build-dep to >> 5.0.0. + * Move DH_COMPAT from rules to debian/compat and set to 5. + * Bump Standards Version to 3.8.3. + + -- Barry deFreese Thu, 12 Mar 2009 14:52:41 -0400 + +predict (2.2.3-1) unstable; urgency=low + + * New upstream release + * New predict-g1yyh is predict-2.2.1jh4.c + * Acknowledge NMU, fix X build, update standards version + * mention predict-map in description (Closes: #379731) + + -- A. Maitland Bottoms Sat, 5 Aug 2006 20:10:35 -0400 + +predict (2.2.2-6.1) unstable; urgency=low + + * Non-Maintainer Upload to fix Failure to Build From Source due to a change + in the location of forms.h. Thanks to Luca Bruno for the patch. + (Closes: #379495). + + -- Margarita Manterola Mon, 31 Jul 2006 01:54:49 -0300 + +predict (2.2.2-6) unstable; urgency=low + + * Correct errno use in gsat application (Closes: #326399) + * Define _XOPEN_SOURCE for correctly using Unix98 pty support + function ptsname() in fodtrack utility (Closes: #326396) + + -- A. Maitland Bottoms Sun, 11 Sep 2005 16:05:36 -0400 + +predict (2.2.2-5) unstable; urgency=low + + * earthtrack uses the full option name -projection to invoke + xplanet necessary since xplanet 1.1.2 no longer uses -proj + + -- A. Maitland Bottoms Sat, 2 Apr 2005 11:01:09 -0500 + +predict (2.2.2-4) unstable; urgency=low + + * OK. Now the `TERM=none predict -s` daemon functions, too + + -- A. Maitland Bottoms Wed, 31 Dec 2003 02:31:11 -0500 + +predict (2.2.2-3) unstable; urgency=low + + * Extra checks on TERM environment (Closes: #225567) + * No TERM environment or TERM=none will let predict -s be a daemon + + -- A. Maitland Bottoms Wed, 31 Dec 2003 00:33:57 -0500 + +predict (2.2.2-2) unstable; urgency=low + + * Correct path to vocalizer so that it talks again. + + -- A. Maitland Bottoms Mon, 1 Sep 2003 22:40:23 +0000 + +predict (2.2.2-1) unstable; urgency=low + + * New upstream release + * New upstream moontracker application, gsat 1.1.0 update + * reinstate predict-earthtrack with current xplanet support + * add clients/map as predict-map to predict-gsat package + now that xforms is in main + * Example /usr/share/doc/predict/kepupdate for use with cron + * Now Standards-Version 3.6.1.0 + * New maintainer + + -- A. Maitland Bottoms Sun, 31 Aug 2003 10:28:15 -0400 + +predict (2.2.1-2) unstable; urgency=low + + * drop predict-earthtrack package since it needs xearth, which is non-free. + earthtrack claims to support xplanet, but that support is not up to date + and it doesn't work with current versions of xplanet! + * fix from G1YYH for minor display bug in multisat mode in predict-g1yyh + * version the dependency on debhelper + + -- Bdale Garbee Sun, 13 Apr 2003 15:35:35 -0600 + +predict (2.2.1-1) unstable; urgency=low + + * new upstream version + * enable delivery of new kep_reload utility + * split graphical clients into separate packages, closes: #165219 + * fix up the gsat plugins directory path to be consistent and FHS compliant + * build and include as many of the gsat example plugins as will compile + * include an alternate copy of the main predict executable built using + G1YYH's patchset as 'predict-g1yyh' since I like his changes, but don't + want to surprise anyone expecting the 'real' predict, closes: #165914 + + -- Bdale Garbee Wed, 1 Jan 2003 02:27:46 -0700 + +predict (2.1.5-1) unstable; urgency=low + + * new upstream version, closes: #141590 + * depend on netbase (>= 4.07) to get services entry + + -- Bdale Garbee Tue, 9 Apr 2002 20:26:30 -0600 + +predict (2.1.3-1) unstable; urgency=low + + * new upstream version, closes: #81415 + * several new clients, not building 'map' both because it uses non-free xforms + and because it smells like a naming conflict waiting to happen + + -- Bdale Garbee Sat, 6 Jan 2001 17:45:40 -0700 + +predict (2.1.2-1) unstable; urgency=low + + * new upstream version, closes: #68010 + + -- Bdale Garbee Wed, 16 Aug 2000 02:28:28 -0600 + +predict (2.0.0-3) frozen unstable; urgency=low + + * update build dependency on curses to version shipping with slink, + target frozen since this breaks auto building, closes: #55437 + + -- Bdale Garbee Wed, 19 Jan 2000 22:24:00 -0700 + +predict (2.0.0-2) unstable; urgency=low + + * update to latest standards + + -- Bdale Garbee Tue, 14 Dec 1999 19:21:47 -0700 + +predict (2.0.0-1) unstable; urgency=low + + * Initial Release. + * Major hacking to restructure the configure/build/install process to work + well as a Debian package. + + -- Bdale Garbee Tue, 14 Dec 1999 19:21:47 -0700 + + --- predict-2.2.3.orig/debian/moontracker.1 +++ predict-2.2.3/debian/moontracker.1 @@ -0,0 +1,29 @@ +.TH MOONTRACKER 1 "31 August 2003" +.SH NAME +moontracker \- Calculate Az and El to the Moon +.SH SYNOPSIS +\fB moontracker\fP +[ +.I -a +] +[ +.I -a1 +] +[ +.I -q +] +.SH DESCRIPTION +\fBMOONTRACKER\fP is a small program providing +capabilities for automatically aiming an antenna array towards the +Moon (for Moonbounce communications). The +location of the observer is taken from the data files for predict(1). +.PP +Once started, MoonTracker spawns itself as a background process. +.SH OPTIONS + -a serial port (/dev/ttyS0) -- sends data as it changes +.br + -a1 serial port (/dev/ttyS0) -- sends data at one-second intervals +.br + -q alternate qth file (site.qth) +.SH AUTHOR +This man page was written by A. Maitland Bottoms, AA4HS, for Debian GNU/Linux. --- predict-2.2.3.orig/debian/docs +++ predict-2.2.3/debian/docs @@ -0,0 +1,4 @@ +CREDITS +HISTORY +NEWS +README --- predict-2.2.3.orig/debian/patches/010_reboostrap.diff +++ predict-2.2.3/debian/patches/010_reboostrap.diff @@ -0,0 +1,6 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/config.rpath +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ predict-2.2.3/clients/gsat-1.1.0/config.rpath 2009-11-14 09:20:48.000000000 -0500 +@@ -0,0 +1 @@ ++#Empty file for autotools --- predict-2.2.3.orig/debian/patches/120_radio_FT847.diff +++ predict-2.2.3/debian/patches/120_radio_FT847.diff @@ -0,0 +1,259 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/plugins/Makefile +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/plugins/Makefile 2009-11-14 11:37:00.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/plugins/Makefile 2009-11-14 11:38:21.000000000 -0500 +@@ -4,7 +4,7 @@ + # Edit the TARGETS line to contain only the plugins you need + # + +-TARGETS=radio_FT736 radio_ICR10 radio_TMD700 radio_PCR100 radio_print radio_test rotor_print rotor_pictrack ++TARGETS=radio_FT736 radio_FT847 radio_ICR10 radio_TMD700 radio_PCR100 radio_print radio_test rotor_print rotor_pictrack + + PLUGINDIR=/usr/local/lib/gsat/plugins + +@@ -13,14 +13,17 @@ + radio_FT736: + gcc -fPIC -shared radio_FT736.c -o radio_FT736 + ++radio_FT847: radio_FT847.c ++ gcc -Wall -fPIC -shared radio_FT847.c -o radio_FT847 ++ + radio_ICR10: + gcc -fPIC -shared radio_ICR10.c -o radio_ICR10 + + radio_TMD700: +- gcc -fPIC -shared radio_TMD700.c -o radio_TMD700 -lm -lD700 ++ # gcc -fPIC -shared radio_TMD700.c -o radio_TMD700 -lm -lD700 + + radio_PCR100: +- gcc -fPIC -shared radio_PCR100.c -o radio_PCR100 -lpcr100 ++ # gcc -fPIC -shared radio_PCR100.c -o radio_PCR100 -lpcr100 + + radio_print: + gcc -fPIC -shared radio_print.c -o radio_print +@@ -35,7 +38,7 @@ + gcc -fPIC -shared rotor_pictrack.c -o rotor_pictrack + + clean: +- rm *.o *~ $(TARGETS) ++ -rm -f *.o *~ $(TARGETS) + + install: + cp $(TARGETS) $(PLUGINDIR) +Index: predict-2.2.3/clients/gsat-1.1.0/plugins/radio_FT847.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ predict-2.2.3/clients/gsat-1.1.0/plugins/radio_FT847.c 2009-11-14 11:38:11.000000000 -0500 +@@ -0,0 +1,212 @@ ++/* ++ * YAESU FT-847 plugin for gsat ++ * ++ * Copyright (C) 2003 by Ralf Baechle DO1GRB (ralf@linux-mips.org) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * 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. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Look at the README for more information on the program. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int plugin_open_rig(char *config); ++void plugin_close_rig(void); ++void plugin_set_downlink_frequency(double frequency); ++void plugin_set_uplink_frequency(double frequency); ++ ++static int radiofd; ++ ++static void cat_on(int fd) ++{ ++ static const char cmd_buf[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ ++ write(fd, cmd_buf, 5); ++} ++ ++static void cat_off(int fd) ++{ ++ static const char cmd_buf[5] = { 0x00, 0x00, 0x00, 0x00, 0x80 }; ++ ++ write(fd, cmd_buf, 5); ++} ++ ++static void cat_sat_on(int fd) ++{ ++ static const char cmd_buf[5] = { 0x00, 0x00, 0x00, 0x00, 0x4e }; ++ ++ write(fd, cmd_buf, 5); ++} ++ ++static void cat_sat_off(int fd) ++{ ++ static const char cmd_buf[5] = { 0x00, 0x00, 0x00, 0x00, 0x8e }; ++ ++ write(fd, cmd_buf, 5); ++} ++ ++static void cat_send_freq(unsigned int freq, int vfo) ++{ ++ unsigned int bcd0, bcd1; ++ char cmd_buf[5]; ++ ++ /* ++ * CAT only permits setting the frequency with an accuracy of 10Hz, ++ * so we round to the nearest multiple of of 10Hz. ++ */ ++ freq = (freq + 5) / 10 * 10; ++ ++ bcd0 = freq / 100000000; freq -= bcd0 * 100000000; ++ bcd1 = freq / 10000000; freq -= bcd1 * 10000000; ++ cmd_buf[0] = bcd0 << 4 | bcd1; ++ ++ bcd0 = freq / 1000000; freq -= bcd0 * 1000000; ++ bcd1 = freq / 100000; freq -= bcd1 * 100000; ++ cmd_buf[1] = bcd0 << 4 | bcd1; ++ ++ bcd0 = freq / 10000; freq -= bcd0 * 10000; ++ bcd1 = freq / 1000; freq -= bcd1 * 1000; ++ cmd_buf[2] = bcd0 << 4 | bcd1; ++ ++ bcd0 = freq / 100; freq -= bcd0 * 100; ++ bcd1 = freq / 10; freq -= bcd1 * 10; ++ cmd_buf[3] = bcd0 << 4 | bcd1; ++ ++ cmd_buf[4] = vfo; ++ ++ write(radiofd, cmd_buf, 5); ++} ++ ++static void cat_set_freq_sat_rx_vfo(unsigned int freq) ++{ ++ cat_send_freq(freq, 0x11); ++} ++ ++static void cat_set_freq_sat_tx_vfo(unsigned int freq) ++{ ++ cat_send_freq(freq, 0x21); ++} ++ ++char *plugin_info(void) ++{ ++ return "YAESU FT847 V0.1"; ++} ++ ++int plugin_open_rig(char *config) ++{ ++ struct termios cat_termios; ++ speed_t speed = 0; ++ char dumm[64]; ++ char tty[12]; ++ char *ptr, *parm; ++ ++ tty[0] = '\0'; ++ ++ if (config) { ++ strncpy(dumm, config, 64); ++ ++ ptr = dumm; ++ parm = ptr; ++ while (parm != NULL) { ++ parm = strsep(&ptr, ":"); ++ if (parm == NULL) ++ break; ++ if (strlen(parm) != 0) { ++ switch (*parm) { ++ case 'D': /* tty port */ ++ strcpy(tty, parm + 1); ++ break; ++ case 'S': /* Speed */ ++ speed = atoi(parm + 1); ++ break; ++ } ++ } ++ } ++ } ++ ++ if (strlen(tty) == 0) ++ strcpy(tty, "/dev/ttyS0"); ++ ++ /* ++ * If no serial speed or a bad rate was specified fall back to 4800 ++ * which is the factory default for the FT-847. ++ */ ++ if (speed != 4800 && speed != 9600 && speed != 57600) ++ speed = 4800; ++ ++ /* ++ * Open CAT port ++ */ ++ radiofd = open(tty, O_RDWR | O_NOCTTY); ++ if (radiofd == -1) { ++ fprintf(stderr, "can't open %s\n", tty); ++ return 0; ++ } ++ ++ /* ++ * Set line speed to 4800 8N2 ++ */ ++ tcgetattr(radiofd, &cat_termios); ++ ++ cat_termios.c_cflag = CLOCAL | CS8 | CSTOPB | CREAD; ++ //cat_termios.c_cflag = CLOCAL | CS8 | CREAD; ++ ++ /* ++ * ICANON : enable canonical input disable all echo functionality, ++ * and don't send signals to calling program ++ */ ++ cat_termios.c_lflag |= ICANON; ++ cat_termios.c_lflag &= ~(ECHO | ECHOCTL); ++ ++ /* ignore bytes with parity errors */ ++ cat_termios.c_iflag |= IGNPAR; ++ cat_termios.c_iflag &= ~IXON; ++ ++ /* Raw output. */ ++ cat_termios.c_oflag &= ~OPOST; ++ ++ cfsetspeed(&cat_termios, speed); ++ tcsetattr(radiofd, TCSADRAIN, &cat_termios); ++ sleep(1); ++ ++ cat_on(radiofd); ++ cat_sat_on(radiofd); ++ ++ return 1; ++} ++ ++void plugin_close_rig(void) ++{ ++ cat_sat_off(radiofd); ++ cat_off(radiofd); ++ ++ close(radiofd); ++} ++ ++void plugin_set_downlink_frequency(double frequency) ++{ ++ cat_set_freq_sat_rx_vfo((unsigned int)(frequency * 1000.0)); ++} ++ ++void plugin_set_uplink_frequency(double frequency) ++{ ++ cat_set_freq_sat_tx_vfo((unsigned int)(frequency * 1000.0)); ++} --- predict-2.2.3.orig/debian/patches/141_buffer_overflow.diff +++ predict-2.2.3/debian/patches/141_buffer_overflow.diff @@ -0,0 +1,28 @@ +## Description: Extends header line 2 (head2) with an extra byte for the terminating \0 and shortens two strings that were 1 byte too long. +## Origin/Author: Norvald H. Ryeng +## Bug: https://bugs.launchpad.net/ubuntu/+source/predict/+bug/553140 +Index: predict-2.2.3/predict-g1yyh.c +=================================================================== +--- predict-2.2.3.orig/predict-g1yyh.c 2010-04-01 11:03:53.472663321 +0200 ++++ predict-2.2.3/predict-g1yyh.c 2010-04-01 11:11:19.876662739 +0200 +@@ -4018,7 +4018,7 @@ + /* This function buffers and displays orbital predictions + and allows screens to be saved to a disk file. */ + +- char type[20], spaces[80], head1[80], head2[80]; ++ char type[20], spaces[80], head1[80], head2[81]; + int key, ans=0, l, x, t; + static char buffer[5000], lines, quit; + static FILE *fd; +@@ -4068,9 +4068,9 @@ + sprintf(head2," Date Mins/Day Sun Date Mins/Day Sun "); + else { + if (calc_squint) +- sprintf(head2," Date Time El Az Phase %s %s Range Squint ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); ++ sprintf(head2," Date Time El Az Phase %s %s Range Squint ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); + else +- sprintf(head2," Date Time El Az Phase %s %s Range Orbit ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); ++ sprintf(head2," Date Time El Az Phase %s %s Range Orbit ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); + } + } + --- predict-2.2.3.orig/debian/patches/000_build_system.diff +++ predict-2.2.3/debian/patches/000_build_system.diff @@ -0,0 +1,46 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/configure.in +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/configure.in 2009-11-14 11:13:17.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/configure.in 2009-11-14 11:32:53.000000000 -0500 +@@ -9,12 +9,12 @@ + AM_PROG_CC_STDC + AC_HEADER_STDC + +-AM_PATH_GTK(1.2.0, , ++AM_PATH_GTK_2_0(2.0.0, , + AC_MSG_ERROR(Cannot find GTK: Is gtk-config in path?)) + + dnl Add the languages which your application supports here. + ALL_LINGUAS="" +-AM_GNU_GETTEXT ++AM_GNU_GETTEXT([external]) + + dnl Set PACKAGE_LOCALE_DIR in config.h. + if test "x${prefix}" = "xNONE"; then +Index: predict-2.2.3/clients/gsat-1.1.0/Makefile.am +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/Makefile.am 2009-11-14 11:13:17.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/Makefile.am 2009-11-14 11:32:53.000000000 -0500 +@@ -1,6 +1,6 @@ + ## Process this file with automake to produce Makefile.in + +-SUBDIRS = intl po src ++SUBDIRS = po src + + install-data-local: + @$(NORMAL_INSTALL) +Index: predict-2.2.3/clients/gsat-1.1.0/po/Makefile.in.in +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/po/Makefile.in.in 2009-11-14 11:13:17.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/po/Makefile.in.in 2009-11-14 11:32:53.000000000 -0500 +@@ -28,7 +28,9 @@ + + INSTALL = @INSTALL@ + INSTALL_DATA = @INSTALL_DATA@ +-MKINSTALLDIRS = @MKINSTALLDIRS@ ++#Ugly hack but works. ++#MKINSTALLDIRS = @MKINSTALLDIRS@ ++MKINSTALLDIRS = mkinstalldirs + mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(top_builddir)/$(MKINSTALLDIRS)" ;; esac` + + CC = @CC@ --- predict-2.2.3.orig/debian/patches/150_man_predict-g1yhh.diff +++ predict-2.2.3/debian/patches/150_man_predict-g1yhh.diff @@ -0,0 +1,14 @@ +Index: predict-2.2.3/docs/man/predict.man +=================================================================== +--- predict-2.2.3.orig/docs/man/predict.man 2010-05-27 17:13:41.000000000 -0400 ++++ predict-2.2.3/docs/man/predict.man 2010-05-27 17:14:42.000000000 -0400 +@@ -677,6 +677,9 @@ + \fC~/.predict/predict.qth\fR + Default ground station location information + ++.SH SEE ALSO ++.BR predict-g1yhh (1) ++ + .SH AUTHORS + \fBPREDICT\fP was written by John A. Magliacane, KD2BD . + The socket server code was contributed by Ivan Galysh, KD4HBO --- predict-2.2.3.orig/debian/patches/100_gsat_globals_h.diff +++ predict-2.2.3/debian/patches/100_gsat_globals_h.diff @@ -0,0 +1,30 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/src/globals.h +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/src/globals.h 2009-11-14 10:35:56.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/src/globals.h 2009-11-14 10:36:55.000000000 -0500 +@@ -20,13 +20,15 @@ + * Look at the README for more information on the program. + */ + ++#include ++ + /* Global definitions */ + + #define GSATVERSION "1.1.0" + #define WINTITLE(VERS) "gsat #VERS: Real-Time Satellite Tracking Display" + + #ifndef GSATLIBDIR +-#define GSATLIBDIR "/usr/local/lib/gsat" ++#define GSATLIBDIR "/usr/lib/gsat" + #endif + + #define MAXPLUGINS 20 +@@ -55,8 +57,6 @@ + /* Maximum number of dots for drawing az/el graphic */ + #define AZELMAXDOTS AZELSIZEX*2 + +-int errno; +- + /* Network parameters */ + char *predicthost; + char *predictport; --- predict-2.2.3.orig/debian/patches/140_fix-buffer-overflow.diff +++ predict-2.2.3/debian/patches/140_fix-buffer-overflow.diff @@ -0,0 +1,26 @@ +Index: predict/predict-g1yyh.c +=================================================================== +--- predict.orig/predict-g1yyh.c 2010-03-31 11:13:46.314268660 +0100 ++++ predict/predict-g1yyh.c 2010-03-31 11:15:32.262268197 +0100 +@@ -194,7 +194,7 @@ + moon_az, moon_el, moon_dx, moon_ra, moon_dec, moon_gha, moon_dv; + + char qthfile[50], tlefile[50], dbfile[50], temp[80], output[25], +- serial_port[15], resave=0, reload_tle=0, netport[6], ++ serial_port[15], resave=0, reload_tle=0, netport[8], + once_per_second=0, ephem[5], sat_sun_status, findsun, + calc_squint, database=0, xterm, io_lat='N', io_lon='W', maidenstr[9]; + +Index: predict/predict.c +=================================================================== +--- predict.orig/predict.c 2010-03-31 11:13:46.262277416 +0100 ++++ predict/predict.c 2010-03-31 11:15:32.246267071 +0100 +@@ -174,7 +174,7 @@ + moon_az, moon_el, moon_dx, moon_ra, moon_dec, moon_gha, moon_dv; + + char qthfile[50], tlefile[50], dbfile[50], temp[80], output[25], +- serial_port[15], resave=0, reload_tle=0, netport[6], ++ serial_port[15], resave=0, reload_tle=0, netport[8], + once_per_second=0, ephem[5], sat_sun_status, findsun, + calc_squint, database=0, xterm, io_lat='N', io_lon='W'; + --- predict-2.2.3.orig/debian/patches/050_map_main_c.diff +++ predict-2.2.3/debian/patches/050_map_main_c.diff @@ -0,0 +1,22 @@ +Index: predict-2.2.3/clients/map/map_main.c +=================================================================== +--- predict-2.2.3.orig/clients/map/map_main.c 2009-11-14 09:45:50.000000000 -0500 ++++ predict-2.2.3/clients/map/map_main.c 2009-11-14 09:47:15.000000000 -0500 +@@ -19,6 +19,8 @@ + #include "forms.h" + #include "map.h" + #include ++#include ++#include + + extern int connectsock(); + extern void handler(); +@@ -29,7 +31,7 @@ + int main(int argc, char *argv[]) + { + int i, skt, x, y, z; +- char cmd[16], bufr[625], satnamelist[26][26]; ++ char bufr[625], satnamelist[26][26]; + const char *ptrsat; + FD_map *fd_map; + struct timeb tptr; --- predict-2.2.3.orig/debian/patches/121_predict-g1yyh.diff +++ predict-2.2.3/debian/patches/121_predict-g1yyh.diff @@ -0,0 +1,6735 @@ +Index: predict-2.2.3/predict-g1yyh.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ predict-2.2.3/predict-g1yyh.c 2009-11-14 11:02:18.000000000 -0500 +@@ -0,0 +1,6730 @@ ++/***************************************************************************\ ++* PREDICT: A satellite tracking/orbital prediction program * ++* Copyright John A. Magliacane, KD2BD 1991-2002 * ++* Project started: 26-May-1991 * ++* Last update: 14-Oct-2002 * ++***************************************************************************** ++* Network sockets added by Ivan Galysh, KD4HBO 10-Jan-2000 * ++* The network port is 1210. Protocol is UDP. * ++* The pthreads library is required. * ++* The socket server is spawned to operate in the background. * ++***************************************************************************** ++* Code to send live AZ/EL tracking data to the serial port for antenna * ++* tracking was contributed by Vittorio Benvenuti, I3VFJ : 13-Jul-2000 * ++***************************************************************************** ++* SGP4/SDP4 code was derived from Pascal routines originally written by * ++* Dr. TS Kelso, and converted to C by Neoklis Kyriazis, 5B4AZ * ++***************************************************************************** ++* Extended 250 satellite display capability and other cosmetic mods * ++* you need to add '-lmenu' to the build file to link in the menu * ++* handling code. Should work with CygWIN too... * ++* John Heaton, G1YYH : 1-Oct-2005 * ++***************************************************************************** ++* * ++* This program is free software; you can redistribute it and/or modify it * ++* under the terms of the GNU General Public License as published by the * ++* Free Software Foundation; either version 2 of the License or any later * ++* version. * ++* * ++* 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. See the GNU * ++* General Public License for more details. * ++* * ++\***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "predict.h" ++ ++#define maxsats 250 ++#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) ++#define halfdelaytime 10 ++ ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ); ++ ++/* Constants used by SGP4/SDP4 code */ ++ ++#define km2mi 0.621371 /* km to miles */ ++#define deg2rad 1.745329251994330E-2 /* Degrees to radians */ ++#define pi 3.14159265358979323846 /* Pi */ ++#define pio2 1.57079632679489656 /* Pi/2 */ ++#define x3pio2 4.71238898038468967 /* 3*Pi/2 */ ++#define twopi 6.28318530717958623 /* 2*Pi */ ++#define e6a 1.0E-6 ++#define tothrd 6.6666666666666666E-1 /* 2/3 */ ++#define xj2 1.0826158E-3 /* J2 Harmonic (WGS '72) */ ++#define xj3 -2.53881E-6 /* J3 Harmonic (WGS '72) */ ++#define xj4 -1.65597E-6 /* J4 Harmonic (WGS '72) */ ++#define xke 7.43669161E-2 ++#define xkmper 6.378137E3 /* WGS 84 Earth radius km */ ++#define xmnpda 1.44E3 /* Minutes per day */ ++#define ae 1.0 ++#define ck2 5.413079E-4 ++#define ck4 6.209887E-7 ++#define f 3.35281066474748E-3 /* Flattening factor */ ++#define ge 3.986008E5 /* Earth gravitational constant (WGS '72) */ ++#define s 1.012229 ++#define qoms2t 1.880279E-09 ++#define secday 8.6400E4 /* Seconds per day */ ++#define omega_E 1.00273790934 /* Earth rotations/siderial day */ ++#define omega_ER 6.3003879 /* Earth rotations, rads/siderial day */ ++#define zns 1.19459E-5 ++#define c1ss 2.9864797E-6 ++#define zes 1.675E-2 ++#define znl 1.5835218E-4 ++#define c1l 4.7968065E-7 ++#define zel 5.490E-2 ++#define zcosis 9.1744867E-1 ++#define zsinis 3.9785416E-1 ++#define zsings -9.8088458E-1 ++#define zcosgs 1.945905E-1 ++#define zcoshs 1 ++#define zsinhs 0 ++#define q22 1.7891679E-6 ++#define q31 2.1460748E-6 ++#define q33 2.2123015E-7 ++#define g22 5.7686396 ++#define g32 9.5240898E-1 ++#define g44 1.8014998 ++#define g52 1.0508330 ++#define g54 4.4108898 ++#define root22 1.7891679E-6 ++#define root32 3.7393792E-7 ++#define root44 7.3636953E-9 ++#define root52 1.1428639E-7 ++#define root54 2.1765803E-9 ++#define thdt 4.3752691E-3 ++#define rho 1.5696615E-1 ++#define mfactor 7.292115E-5 ++#define sr 6.96000E5 /* Solar radius - km (IAU 76) */ ++#define AU 1.49597870691E8 /* Astronomical unit - km (IAU 76) */ ++ ++/* Entry points of Deep() */ ++ ++#define dpinit 1 /* Deep-space initialization code */ ++#define dpsec 2 /* Deep-space secular code */ ++#define dpper 3 /* Deep-space periodic code */ ++ ++/* Flow control flag definitions */ ++ ++#define ALL_FLAGS -1 ++#define SGP_INITIALIZED_FLAG 0x000001 /* not used */ ++#define SGP4_INITIALIZED_FLAG 0x000002 ++#define SDP4_INITIALIZED_FLAG 0x000004 ++#define SGP8_INITIALIZED_FLAG 0x000008 /* not used */ ++#define SDP8_INITIALIZED_FLAG 0x000010 /* not used */ ++#define SIMPLE_FLAG 0x000020 ++#define DEEP_SPACE_EPHEM_FLAG 0x000040 ++#define LUNAR_TERMS_DONE_FLAG 0x000080 ++#define NEW_EPHEMERIS_FLAG 0x000100 /* not used */ ++#define DO_LOOP_FLAG 0x000200 ++#define RESONANCE_FLAG 0x000400 ++#define SYNCHRONOUS_FLAG 0x000800 ++#define EPOCH_RESTART_FLAG 0x001000 ++#define VISIBLE_FLAG 0x002000 ++#define SAT_ECLIPSED_FLAG 0x004000 ++ ++struct { char line1[70]; ++ char line2[70]; ++ char name[25]; ++ long catnum; ++ long setnum; ++ char designator[10]; ++ int year; ++ double refepoch; ++ double incl; ++ double raan; ++ double eccn; ++ double argper; ++ double meanan; ++ double meanmo; ++ double drag; ++ double nddot6; ++ double bstar; ++ long orbitnum; ++ } sat[maxsats]; ++ ++struct { char callsign[17]; ++ double stnlat; ++ double stnlong; ++ int stnalt; ++ int tzoffset; ++ } qth; ++ ++struct { char name[25]; ++ long catnum; ++ char squintflag; ++ double alat; ++ double alon; ++ unsigned char transponders; ++ char transponder_name[10][80]; ++ double uplink_start[10]; ++ double uplink_end[10]; ++ double downlink_start[10]; ++ double downlink_end[10]; ++ unsigned char dayofweek[10]; ++ int phase_start[10]; ++ int phase_end[10]; ++ } sat_db[maxsats]; ++ ++/* Global variables for sharing data among functions... */ ++ ++double tsince, jul_epoch, jul_utc, eclipse_depth=0, ++ sat_azi, sat_ele, sat_range, sat_range_rate, ++ sat_lat, sat_lon, sat_alt, sat_vel, phase, ++ sun_azi, sun_ele, daynum, fm, fk, age, aostime, ++ lostime, ax, ay, az, rx, ry, rz, squint, alat, alon, ++ sun_ra, sun_dec, sun_lat, sun_lon, sun_range, sun_range_rate, ++ moon_az, moon_el, moon_dx, moon_ra, moon_dec, moon_gha, moon_dv; ++ ++char qthfile[50], tlefile[50], dbfile[50], temp[80], output[25], ++ serial_port[15], resave=0, reload_tle=0, netport[6], ++ once_per_second=0, ephem[5], sat_sun_status, findsun, ++ calc_squint, database=0, xterm, io_lat='N', io_lon='W', maidenstr[9]; ++ ++int indx, antfd, iaz, iel, ma256, isplat, isplong, socket_flag=0, ++ Flags=0, totalsats=0; ++ ++long rv, irk; ++ ++unsigned char val[256]; ++ ++/* The following variables are used by the socket server. They ++ are updated in the MultiTrack() and SingleTrack() functions. */ ++ ++char visibility_array[maxsats], tracking_mode[30]; ++ ++float az_array[maxsats], el_array[maxsats], long_array[maxsats], lat_array[maxsats], ++ footprint_array[maxsats], range_array[maxsats], altitude_array[maxsats], ++ velocity_array[maxsats], eclipse_depth_array[maxsats], phase_array[maxsats], ++squint_array[maxsats]; ++ ++double doppler[maxsats], nextevent[maxsats]; ++ ++long aos_array[maxsats], orbitnum_array[maxsats]; ++ ++unsigned short portbase=0; ++ ++/** Type definitions **/ ++ ++/* Two-line-element satellite orbital data ++ structure used directly by the SGP4/SDP4 code. */ ++ ++typedef struct { ++ double epoch, xndt2o, xndd6o, bstar, xincl, ++ xnodeo, eo, omegao, xmo, xno; ++ int catnr, elset, revnum; ++ char sat_name[25], idesg[9]; ++ } tle_t; ++ ++/* Geodetic position structure used by SGP4/SDP4 code. */ ++ ++typedef struct { ++ double lat, lon, alt, theta; ++ } geodetic_t; ++ ++/* General three-dimensional vector structure used by SGP4/SDP4 code. */ ++ ++typedef struct { ++ double x, y, z, w; ++ } vector_t; ++ ++/* Common arguments between deep-space functions used by SGP4/SDP4 code. */ ++ ++typedef struct { ++ /* Used by dpinit part of Deep() */ ++ double eosq, sinio, cosio, betao, aodp, theta2, ++ sing, cosg, betao2, xmdot, omgdot, xnodot, xnodp; ++ ++ /* Used by dpsec and dpper parts of Deep() */ ++ double xll, omgadf, xnode, em, xinc, xn, t; ++ ++ /* Used by thetg and Deep() */ ++ double ds50; ++ } deep_arg_t; ++ ++/* Global structure used by SGP4/SDP4 code. */ ++ ++geodetic_t obs_geodetic; ++ ++/* Two-line Orbital Elements for the satellite used by SGP4/SDP4 code. */ ++ ++tle_t tle; ++ ++/* Functions for testing and setting/clearing flags used in SGP4/SDP4 code */ ++ ++int isFlagSet(int flag) ++{ ++ return (Flags&flag); ++} ++ ++int isFlagClear(int flag) ++{ ++ return (~Flags&flag); ++} ++ ++void SetFlag(int flag) ++{ ++ Flags|=flag; ++} ++ ++void ClearFlag(int flag) ++{ ++ Flags&=~flag; ++} ++ ++/* Remaining SGP4/SDP4 code follows... */ ++ ++int Sign(double arg) ++{ ++ /* Returns sign of a double */ ++ ++ if (arg>0) ++ return 1; ++ else if (arg<0) ++ return -1; ++ else ++ return 0; ++} ++ ++double Sqr(double arg) ++{ ++ /* Returns square of a double */ ++ return (arg*arg); ++} ++ ++double Cube(double arg) ++{ ++ /* Returns cube of a double */ ++ return (arg*arg*arg); ++} ++ ++double Radians(double arg) ++{ ++ /* Returns angle in radians from argument in degrees */ ++ return (arg*deg2rad); ++} ++ ++double Degrees(double arg) ++{ ++ /* Returns angle in degrees from argument in radians */ ++ return (arg/deg2rad); ++} ++ ++double ArcSin(double arg) ++{ ++ /* Returns the arcsine of the argument */ ++ ++ if (fabs(arg)>=1.0) ++ return(Sign(arg)*pio2); ++ else ++ ++ return(atan(arg/sqrt(1.0-arg*arg))); ++} ++ ++double ArcCos(double arg) ++{ ++ /* Returns arccosine of argument */ ++ return(pio2-ArcSin(arg)); ++} ++ ++void Magnitude(vector_t *v) ++{ ++ /* Calculates scalar magnitude of a vector_t argument */ ++ v->w=sqrt(Sqr(v->x)+Sqr(v->y)+Sqr(v->z)); ++} ++ ++void Vec_Add(vector_t *v1, vector_t *v2, vector_t *v3) ++{ ++ /* Adds vectors v1 and v2 together to produce v3 */ ++ v3->x=v1->x+v2->x; ++ v3->y=v1->y+v2->y; ++ v3->z=v1->z+v2->z; ++ Magnitude(v3); ++} ++ ++void Vec_Sub(vector_t *v1, vector_t *v2, vector_t *v3) ++{ ++ /* Subtracts vector v2 from v1 to produce v3 */ ++ v3->x=v1->x-v2->x; ++ v3->y=v1->y-v2->y; ++ v3->z=v1->z-v2->z; ++ Magnitude(v3); ++} ++ ++void Scalar_Multiply(double k, vector_t *v1, vector_t *v2) ++{ ++ /* Multiplies the vector v1 by the scalar k to produce the vector v2 */ ++ v2->x=k*v1->x; ++ v2->y=k*v1->y; ++ v2->z=k*v1->z; ++ v2->w=fabs(k)*v1->w; ++} ++ ++void Scale_Vector(double k, vector_t *v) ++{ ++ /* Multiplies the vector v1 by the scalar k */ ++ v->x*=k; ++ v->y*=k; ++ v->z*=k; ++ Magnitude(v); ++} ++ ++double Dot(vector_t *v1, vector_t *v2) ++{ ++ /* Returns the dot product of two vectors */ ++ return (v1->x*v2->x+v1->y*v2->y+v1->z*v2->z); ++} ++ ++double Angle(vector_t *v1, vector_t *v2) ++{ ++ /* Calculates the angle between vectors v1 and v2 */ ++ Magnitude(v1); ++ Magnitude(v2); ++ return(ArcCos(Dot(v1,v2)/(v1->w*v2->w))); ++} ++ ++void Cross(vector_t *v1, vector_t *v2 ,vector_t *v3) ++{ ++ /* Produces cross product of v1 and v2, and returns in v3 */ ++ v3->x=v1->y*v2->z-v1->z*v2->y; ++ v3->y=v1->z*v2->x-v1->x*v2->z; ++ v3->z=v1->x*v2->y-v1->y*v2->x; ++ Magnitude(v3); ++} ++ ++void Normalize(vector_t *v) ++{ ++ /* Normalizes a vector */ ++ v->x/=v->w; ++ v->y/=v->w; ++ v->z/=v->w; ++} ++ ++double AcTan(double sinx, double cosx) ++{ ++ /* Four-quadrant arctan function */ ++ ++ if (cosx==0.0) { ++ if (sinx>0.0) ++ return (pio2); ++ else ++ return (x3pio2); ++ } else { ++ if (cosx>0.0) { ++ if (sinx>0.0) ++ return (atan(sinx/cosx)); ++ else ++ return (twopi+atan(sinx/cosx)); ++ } else ++ return (pi+atan(sinx/cosx)); ++ } ++} ++ ++double FMod2p(double x) ++{ ++ /* Returns mod 2PI of argument */ ++ ++ int i; ++ double ret_val; ++ ++ ret_val=x; ++ i=ret_val/twopi; ++ ret_val-=i*twopi; ++ ++ if (ret_val<0.0) ++ ret_val+=twopi; ++ ++ return ret_val; ++} ++ ++double Modulus(double arg1, double arg2) ++{ ++ /* Returns arg1 mod arg2 */ ++ ++ int i; ++ double ret_val; ++ ++ ret_val=arg1; ++ i=ret_val/arg2; ++ ret_val-=i*arg2; ++ ++ if (ret_val<0.0) ++ ret_val+=arg2; ++ ++ return ret_val; ++} ++ ++double Frac(double arg) ++{ ++ /* Returns fractional part of double argument */ ++ return(arg-floor(arg)); ++} ++ ++int Round(double arg) ++{ ++ /* Returns argument rounded up to nearest integer */ ++ return((int)floor(arg+0.5)); ++} ++ ++double Int(double arg) ++{ ++ /* Returns the floor integer of a double arguement, as double */ ++ return(floor(arg)); ++} ++ ++void Convert_Sat_State(vector_t *pos, vector_t *vel) ++{ ++ /* Converts the satellite's position and velocity */ ++ /* vectors from normalized values to km and km/sec */ ++ Scale_Vector(xkmper, pos); ++ Scale_Vector(xkmper*xmnpda/secday, vel); ++} ++ ++double Julian_Date_of_Year(double year) ++{ ++ /* The function Julian_Date_of_Year calculates the Julian Date */ ++ /* of Day 0.0 of {year}. This function is used to calculate the */ ++ /* Julian Date of any date by using Julian_Date_of_Year, DOY, */ ++ /* and Fraction_of_Day. */ ++ ++ /* Astronomical Formulae for Calculators, Jean Meeus, */ ++ /* pages 23-25. Calculate Julian Date of 0.0 Jan year */ ++ ++ long A, B, i; ++ double jdoy; ++ ++ year=year-1; ++ i=year/100; ++ A=i; ++ i=A/4; ++ B=2-A+i; ++ i=365.25*year; ++ i+=30.6001*14; ++ jdoy=i+1720994.5+B; ++ ++ return jdoy; ++} ++ ++double Julian_Date_of_Epoch(double epoch) ++{ ++ /* The function Julian_Date_of_Epoch returns the Julian Date of */ ++ /* an epoch specified in the format used in the NORAD two-line */ ++ /* element sets. It has been modified to support dates beyond */ ++ /* the year 1999 assuming that two-digit years in the range 00-56 */ ++ /* correspond to 2000-2056. Until the two-line element set format */ ++ /* is changed, it is only valid for dates through 2056 December 31. */ ++ ++ double year, day; ++ ++ /* Modification to support Y2K */ ++ /* Valid 1957 through 2056 */ ++ ++ day=modf(epoch*1E-3, &year)*1E3; ++ ++ if (year<57) ++ year=year+2000; ++ else ++ year=year+1900; ++ ++ return (Julian_Date_of_Year(year)+day); ++} ++ ++int DOY (int yr, int mo, int dy) ++{ ++ /* The function DOY calculates the day of the year for the specified */ ++ /* date. The calculation uses the rules for the Gregorian calendar */ ++ /* and is valid from the inception of that calendar system. */ ++ ++ const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ++ int i, day; ++ ++ day=0; ++ ++ for (i=0; i2)) ++ day++; ++ ++ return day; ++} ++ ++double Fraction_of_Day(int hr, int mi, double se) ++{ ++ /* Fraction_of_Day calculates the fraction of */ ++ /* a day passed at the specified input time. */ ++ ++ double dhr, dmi; ++ ++ dhr=(double)hr; ++ dmi=(double)mi; ++ ++ return ((dhr+(dmi+se/60.0)/60.0)/24.0); ++} ++ ++double Julian_Date(struct tm *cdate) ++{ ++ /* The function Julian_Date converts a standard calendar */ ++ /* date and time to a Julian Date. The procedure Date_Time */ ++ /* performs the inverse of this function. */ ++ ++ double julian_date; ++ ++ julian_date=Julian_Date_of_Year(cdate->tm_year)+DOY(cdate->tm_year,cdate->tm_mon,cdate->tm_mday)+Fraction_of_Day(cdate->tm_hour,cdate->tm_min,cdate->tm_sec)+5.787037e-06; /* Round up to nearest 1 sec */ ++ ++ return julian_date; ++} ++ ++void Date_Time(double julian_date, struct tm *cdate) ++{ ++ /* The function Date_Time() converts a Julian Date to ++ standard calendar date and time. The function ++ Julian_Date() performs the inverse of this function. */ ++ ++ time_t jtime; ++ ++ jtime=(julian_date-2440587.5)*86400.0; ++ *cdate=*gmtime(&jtime); ++} ++ ++double Delta_ET(double year) ++{ ++ /* The function Delta_ET has been added to allow calculations on */ ++ /* the position of the sun. It provides the difference between UT */ ++ /* (approximately the same as UTC) and ET (now referred to as TDT).*/ ++ /* This function is based on a least squares fit of data from 1950 */ ++ /* to 1991 and will need to be updated periodically. */ ++ ++ /* Values determined using data from 1950-1991 in the 1990 ++ Astronomical Almanac. See DELTA_ET.WQ1 for details. */ ++ ++ double delta_et; ++ ++ delta_et=26.465+0.747622*(year-1950)+1.886913*sin(twopi*(year-1975)/33); ++ ++ return delta_et; ++} ++ ++double ThetaG(double epoch, deep_arg_t *deep_arg) ++{ ++ /* The function ThetaG calculates the Greenwich Mean Sidereal Time */ ++ /* for an epoch specified in the format used in the NORAD two-line */ ++ /* element sets. It has now been adapted for dates beyond the year */ ++ /* 1999, as described above. The function ThetaG_JD provides the */ ++ /* same calculation except that it is based on an input in the */ ++ /* form of a Julian Date. */ ++ ++ /* Reference: The 1992 Astronomical Almanac, page B6. */ ++ ++ double year, day, UT, jd, TU, GMST, ThetaG; ++ ++ /* Modification to support Y2K */ ++ /* Valid 1957 through 2056 */ ++ ++ day=modf(epoch*1E-3,&year)*1E3; ++ ++ if (year<57) ++ year+=2000; ++ else ++ year+=1900; ++ ++ UT=modf(day,&day); ++ jd=Julian_Date_of_Year(year)+day; ++ TU=(jd-2451545.0)/36525; ++ GMST=24110.54841+TU*(8640184.812866+TU*(0.093104-TU*6.2E-6)); ++ GMST=Modulus(GMST+secday*omega_E*UT,secday); ++ ThetaG=twopi*GMST/secday; ++ deep_arg->ds50=jd-2433281.5+UT; ++ ThetaG=FMod2p(6.3003880987*deep_arg->ds50+1.72944494); ++ ++ return ThetaG; ++} ++ ++double ThetaG_JD(double jd) ++{ ++ /* Reference: The 1992 Astronomical Almanac, page B6. */ ++ ++ double UT, TU, GMST; ++ ++ UT=Frac(jd+0.5); ++ jd=jd-UT; ++ TU=(jd-2451545.0)/36525; ++ GMST=24110.54841+TU*(8640184.812866+TU*(0.093104-TU*6.2E-6)); ++ GMST=Modulus(GMST+secday*omega_E*UT,secday); ++ ++ return (twopi*GMST/secday); ++} ++ ++void Calculate_Solar_Position(double time, vector_t *solar_vector) ++{ ++ /* Calculates solar position vector */ ++ ++ double mjd, year, T, M, L, e, C, O, Lsa, nu, R, eps; ++ ++ mjd=time-2415020.0; ++ year=1900+mjd/365.25; ++ T=(mjd+Delta_ET(year)/secday)/36525.0; ++ M=Radians(Modulus(358.47583+Modulus(35999.04975*T,360.0)-(0.000150+0.0000033*T)*Sqr(T),360.0)); ++ L=Radians(Modulus(279.69668+Modulus(36000.76892*T,360.0)+0.0003025*Sqr(T),360.0)); ++ e=0.01675104-(0.0000418+0.000000126*T)*T; ++ C=Radians((1.919460-(0.004789+0.000014*T)*T)*sin(M)+(0.020094-0.000100*T)*sin(2*M)+0.000293*sin(3*M)); ++ O=Radians(Modulus(259.18-1934.142*T,360.0)); ++ Lsa=Modulus(L+C-Radians(0.00569-0.00479*sin(O)),twopi); ++ nu=Modulus(M+C,twopi); ++ R=1.0000002*(1.0-Sqr(e))/(1.0+e*cos(nu)); ++ eps=Radians(23.452294-(0.0130125+(0.00000164-0.000000503*T)*T)*T+0.00256*cos(O)); ++ R=AU*R; ++ solar_vector->x=R*cos(Lsa); ++ solar_vector->y=R*sin(Lsa)*cos(eps); ++ solar_vector->z=R*sin(Lsa)*sin(eps); ++ solar_vector->w=R; ++} ++ ++int Sat_Eclipsed(vector_t *pos, vector_t *sol, double *depth) ++{ ++ /* Calculates stellite's eclipse status and depth */ ++ ++ double sd_sun, sd_earth, delta; ++ vector_t Rho, earth; ++ ++ /* Determine partial eclipse */ ++ ++ sd_earth=ArcSin(xkmper/pos->w); ++ Vec_Sub(sol,pos,&Rho); ++ sd_sun=ArcSin(sr/Rho.w); ++ Scalar_Multiply(-1,pos,&earth); ++ delta=Angle(sol,&earth); ++ *depth=sd_earth-sd_sun-delta; ++ ++ if (sd_earth=0) ++ return 1; ++ else ++ return 0; ++} ++ ++void select_ephemeris(tle_t *tle) ++{ ++ /* Selects the apropriate ephemeris type to be used */ ++ /* for predictions according to the data in the TLE */ ++ /* It also processes values in the tle set so that */ ++ /* they are apropriate for the sgp4/sdp4 routines */ ++ ++ double ao, xnodp, dd1, dd2, delo, temp, a1, del1, r1; ++ ++ /* Preprocess tle set */ ++ tle->xnodeo*=deg2rad; ++ tle->omegao*=deg2rad; ++ tle->xmo*=deg2rad; ++ tle->xincl*=deg2rad; ++ temp=twopi/xmnpda/xmnpda; ++ tle->xno=tle->xno*temp*xmnpda; ++ tle->xndt2o*=temp; ++ tle->xndd6o=tle->xndd6o*temp/xmnpda; ++ tle->bstar/=ae; ++ ++ /* Period > 225 minutes is deep space */ ++ dd1=(xke/tle->xno); ++ dd2=tothrd; ++ a1=pow(dd1,dd2); ++ r1=cos(tle->xincl); ++ dd1=(1.0-tle->eo*tle->eo); ++ temp=ck2*1.5f*(r1*r1*3.0-1.0)/pow(dd1,1.5); ++ del1=temp/(a1*a1); ++ ao=a1*(1.0-del1*(tothrd*.5+del1*(del1*1.654320987654321+1.0))); ++ delo=temp/(ao*ao); ++ xnodp=tle->xno/(delo+1.0); ++ ++ /* Select a deep-space/near-earth ephemeris */ ++ if (twopi/xnodp/xmnpda>=0.15625) ++ SetFlag(DEEP_SPACE_EPHEM_FLAG); ++ else ++ ClearFlag(DEEP_SPACE_EPHEM_FLAG); ++} ++ ++void SGP4(double tsince, tle_t * tle, vector_t * pos, vector_t * vel) ++{ ++ /* This function is used to calculate the position and velocity */ ++ /* of near-earth (period < 225 minutes) satellites. tsince is */ ++ /* time since epoch in minutes, tle is a pointer to a tle_t */ ++ /* structure with Keplerian orbital elements and pos and vel */ ++ /* are vector_t structures returning ECI satellite position and */ ++ /* velocity. Use Convert_Sat_State() to convert to km and km/s. */ ++ ++ static double aodp, aycof, c1, c4, c5, cosio, d2, d3, d4, delmo, ++ omgcof, eta, omgdot, sinio, xnodp, sinmo, t2cof, t3cof, t4cof, ++ t5cof, x1mth2, x3thm1, x7thm1, xmcof, xmdot, xnodcf, xnodot, xlcof; ++ ++ double cosuk, sinuk, rfdotk, vx, vy, vz, ux, uy, uz, xmy, xmx, cosnok, ++ sinnok, cosik, sinik, rdotk, xinck, xnodek, uk, rk, cos2u, sin2u, ++ u, sinu, cosu, betal, rfdot, rdot, r, pl, elsq, esine, ecose, epw, ++ cosepw, x1m5th, xhdot1, tfour, sinepw, capu, ayn, xlt, aynl, xll, ++ axn, xn, beta, xl, e, a, tcube, delm, delomg, templ, tempe, tempa, ++ xnode, tsq, xmp, omega, xnoddf, omgadf, xmdf, a1, a3ovk2, ao, ++ betao, betao2, c1sq, c2, c3, coef, coef1, del1, delo, eeta, eosq, ++ etasq, perigee, pinvsq, psisq, qoms24, s4, temp, temp1, temp2, ++ temp3, temp4, temp5, temp6, theta2, theta4, tsi; ++ ++ int i; ++ ++ /* Initialization */ ++ ++ if (isFlagClear(SGP4_INITIALIZED_FLAG)) { ++ SetFlag(SGP4_INITIALIZED_FLAG); ++ ++ /* Recover original mean motion (xnodp) and */ ++ /* semimajor axis (aodp) from input elements. */ ++ ++ a1=pow(xke/tle->xno,tothrd); ++ cosio=cos(tle->xincl); ++ theta2=cosio*cosio; ++ x3thm1=3*theta2-1.0; ++ eosq=tle->eo*tle->eo; ++ betao2=1.0-eosq; ++ betao=sqrt(betao2); ++ del1=1.5*ck2*x3thm1/(a1*a1*betao*betao2); ++ ao=a1*(1.0-del1*(0.5*tothrd+del1*(1.0+134.0/81.0*del1))); ++ delo=1.5*ck2*x3thm1/(ao*ao*betao*betao2); ++ xnodp=tle->xno/(1.0+delo); ++ aodp=ao/(1.0-delo); ++ ++ /* For perigee less than 220 kilometers, the "simple" */ ++ /* flag is set and the equations are truncated to linear */ ++ /* variation in sqrt a and quadratic variation in mean */ ++ /* anomaly. Also, the c3 term, the delta omega term, and */ ++ /* the delta m term are dropped. */ ++ ++ if ((aodp*(1-tle->eo)/ae)<(220/xkmper+ae)) ++ SetFlag(SIMPLE_FLAG); ++ else ++ ClearFlag(SIMPLE_FLAG); ++ ++ /* For perigees below 156 km, the */ ++ /* values of s and qoms2t are altered. */ ++ ++ s4=s; ++ qoms24=qoms2t; ++ perigee=(aodp*(1-tle->eo)-ae)*xkmper; ++ ++ if (perigee<156.0) { ++ if (perigee<=98.0) ++ s4=20; ++ else ++ s4=perigee-78.0; ++ ++ qoms24=pow((120-s4)*ae/xkmper,4); ++ s4=s4/xkmper+ae; ++ } ++ ++ pinvsq=1/(aodp*aodp*betao2*betao2); ++ tsi=1/(aodp-s4); ++ eta=aodp*tle->eo*tsi; ++ etasq=eta*eta; ++ eeta=tle->eo*eta; ++ psisq=fabs(1-etasq); ++ coef=qoms24*pow(tsi,4); ++ coef1=coef/pow(psisq,3.5); ++ c2=coef1*xnodp*(aodp*(1+1.5*etasq+eeta*(4+etasq))+0.75*ck2*tsi/psisq*x3thm1*(8+3*etasq*(8+etasq))); ++ c1=tle->bstar*c2; ++ sinio=sin(tle->xincl); ++ a3ovk2=-xj3/ck2*pow(ae,3); ++ c3=coef*tsi*a3ovk2*xnodp*ae*sinio/tle->eo; ++ x1mth2=1-theta2; ++ ++ c4=2*xnodp*coef1*aodp*betao2*(eta*(2+0.5*etasq)+tle->eo*(0.5+2*etasq)-2*ck2*tsi/(aodp*psisq)*(-3*x3thm1*(1-2*eeta+etasq*(1.5-0.5*eeta))+0.75*x1mth2*(2*etasq-eeta*(1+etasq))*cos(2*tle->omegao))); ++ c5=2*coef1*aodp*betao2*(1+2.75*(etasq+eeta)+eeta*etasq); ++ ++ theta4=theta2*theta2; ++ temp1=3*ck2*pinvsq*xnodp; ++ temp2=temp1*ck2*pinvsq; ++ temp3=1.25*ck4*pinvsq*pinvsq*xnodp; ++ xmdot=xnodp+0.5*temp1*betao*x3thm1+0.0625*temp2*betao*(13-78*theta2+137*theta4); ++ x1m5th=1-5*theta2; ++ omgdot=-0.5*temp1*x1m5th+0.0625*temp2*(7-114*theta2+395*theta4)+temp3*(3-36*theta2+49*theta4); ++ xhdot1=-temp1*cosio; ++ xnodot=xhdot1+(0.5*temp2*(4-19*theta2)+2*temp3*(3-7*theta2))*cosio; ++ omgcof=tle->bstar*c3*cos(tle->omegao); ++ xmcof=-tothrd*coef*tle->bstar*ae/eeta; ++ xnodcf=3.5*betao2*xhdot1*c1; ++ t2cof=1.5*c1; ++ xlcof=0.125*a3ovk2*sinio*(3+5*cosio)/(1+cosio); ++ aycof=0.25*a3ovk2*sinio; ++ delmo=pow(1+eta*cos(tle->xmo),3); ++ sinmo=sin(tle->xmo); ++ x7thm1=7*theta2-1; ++ ++ if (isFlagClear(SIMPLE_FLAG)) { ++ c1sq=c1*c1; ++ d2=4*aodp*tsi*c1sq; ++ temp=d2*tsi*c1/3; ++ d3=(17*aodp+s4)*temp; ++ d4=0.5*temp*aodp*tsi*(221*aodp+31*s4)*c1; ++ t3cof=d2+2*c1sq; ++ t4cof=0.25*(3*d3+c1*(12*d2+10*c1sq)); ++ t5cof=0.2*(3*d4+12*c1*d3+6*d2*d2+15*c1sq*(2*d2+c1sq)); ++ } ++ } ++ ++ /* Update for secular gravity and atmospheric drag. */ ++ xmdf=tle->xmo+xmdot*tsince; ++ omgadf=tle->omegao+omgdot*tsince; ++ xnoddf=tle->xnodeo+xnodot*tsince; ++ omega=omgadf; ++ xmp=xmdf; ++ tsq=tsince*tsince; ++ xnode=xnoddf+xnodcf*tsq; ++ tempa=1-c1*tsince; ++ tempe=tle->bstar*c4*tsince; ++ templ=t2cof*tsq; ++ ++ if (isFlagClear(SIMPLE_FLAG)) { ++ delomg=omgcof*tsince; ++ delm=xmcof*(pow(1+eta*cos(xmdf),3)-delmo); ++ temp=delomg+delm; ++ xmp=xmdf+temp; ++ omega=omgadf-temp; ++ tcube=tsq*tsince; ++ tfour=tsince*tcube; ++ tempa=tempa-d2*tsq-d3*tcube-d4*tfour; ++ tempe=tempe+tle->bstar*c5*(sin(xmp)-sinmo); ++ templ=templ+t3cof*tcube+tfour*(t4cof+tsince*t5cof); ++ } ++ ++ a=aodp*pow(tempa,2); ++ e=tle->eo-tempe; ++ xl=xmp+omega+xnode+xnodp*templ; ++ beta=sqrt(1-e*e); ++ xn=xke/pow(a,1.5); ++ ++ /* Long period periodics */ ++ axn=e*cos(omega); ++ temp=1/(a*beta*beta); ++ xll=temp*xlcof*axn; ++ aynl=temp*aycof; ++ xlt=xl+xll; ++ ayn=e*sin(omega)+aynl; ++ ++ /* Solve Kepler's Equation */ ++ capu=FMod2p(xlt-xnode); ++ temp2=capu; ++ i=0; ++ ++ do { ++ sinepw=sin(temp2); ++ cosepw=cos(temp2); ++ temp3=axn*sinepw; ++ temp4=ayn*cosepw; ++ temp5=axn*cosepw; ++ temp6=ayn*sinepw; ++ epw=(capu-temp4+temp3-temp2)/(1-temp5-temp6)+temp2; ++ ++ if (fabs(epw-temp2)<= e6a) ++ break; ++ ++ temp2=epw; ++ ++ } while (i++<10); ++ ++ /* Short period preliminary quantities */ ++ ecose=temp5+temp6; ++ esine=temp3-temp4; ++ elsq=axn*axn+ayn*ayn; ++ temp=1-elsq; ++ pl=a*temp; ++ r=a*(1-ecose); ++ temp1=1/r; ++ rdot=xke*sqrt(a)*esine*temp1; ++ rfdot=xke*sqrt(pl)*temp1; ++ temp2=a*temp1; ++ betal=sqrt(temp); ++ temp3=1/(1+betal); ++ cosu=temp2*(cosepw-axn+ayn*esine*temp3); ++ sinu=temp2*(sinepw-ayn-axn*esine*temp3); ++ u=AcTan(sinu,cosu); ++ sin2u=2*sinu*cosu; ++ cos2u=2*cosu*cosu-1; ++ temp=1/pl; ++ temp1=ck2*temp; ++ temp2=temp1*temp; ++ ++ /* Update for short periodics */ ++ rk=r*(1-1.5*temp2*betal*x3thm1)+0.5*temp1*x1mth2*cos2u; ++ uk=u-0.25*temp2*x7thm1*sin2u; ++ xnodek=xnode+1.5*temp2*cosio*sin2u; ++ xinck=tle->xincl+1.5*temp2*cosio*sinio*cos2u; ++ rdotk=rdot-xn*temp1*x1mth2*sin2u; ++ rfdotk=rfdot+xn*temp1*(x1mth2*cos2u+1.5*x3thm1); ++ ++ /* Orientation vectors */ ++ sinuk=sin(uk); ++ cosuk=cos(uk); ++ sinik=sin(xinck); ++ cosik=cos(xinck); ++ sinnok=sin(xnodek); ++ cosnok=cos(xnodek); ++ xmx=-sinnok*cosik; ++ xmy=cosnok*cosik; ++ ux=xmx*sinuk+cosnok*cosuk; ++ uy=xmy*sinuk+sinnok*cosuk; ++ uz=sinik*sinuk; ++ vx=xmx*cosuk-cosnok*sinuk; ++ vy=xmy*cosuk-sinnok*sinuk; ++ vz=sinik*cosuk; ++ ++ /* Position and velocity */ ++ pos->x=rk*ux; ++ pos->y=rk*uy; ++ pos->z=rk*uz; ++ vel->x=rdotk*ux+rfdotk*vx; ++ vel->y=rdotk*uy+rfdotk*vy; ++ vel->z=rdotk*uz+rfdotk*vz; ++ ++ /* Phase in radians */ ++ phase=xlt-xnode-omgadf+twopi; ++ ++ if (phase<0.0) ++ phase+=twopi; ++ ++ phase=FMod2p(phase); ++} ++ ++void Deep(int ientry, tle_t * tle, deep_arg_t * deep_arg) ++{ ++ /* This function is used by SDP4 to add lunar and solar */ ++ /* perturbation effects to deep-space orbit objects. */ ++ ++ static double thgr, xnq, xqncl, omegaq, zmol, zmos, savtsn, ee2, e3, ++ xi2, xl2, xl3, xl4, xgh2, xgh3, xgh4, xh2, xh3, sse, ssi, ssg, xi3, ++ se2, si2, sl2, sgh2, sh2, se3, si3, sl3, sgh3, sh3, sl4, sgh4, ssl, ++ ssh, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433, del1, ++ del2, del3, fasx2, fasx4, fasx6, xlamo, xfact, xni, atime, stepp, ++ stepn, step2, preep, pl, sghs, xli, d2201, d2211, sghl, sh1, pinc, ++ pe, shs, zsingl, zcosgl, zsinhl, zcoshl, zsinil, zcosil; ++ ++ double a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ainv2, alfdp, aqnv, ++ sgh, sini2, sinis, sinok, sh, si, sil, day, betdp, dalf, bfact, c, ++ cc, cosis, cosok, cosq, ctem, f322, zx, zy, dbet, dls, eoc, eq, f2, ++ f220, f221, f3, f311, f321, xnoh, f330, f441, f442, f522, f523, ++ f542, f543, g200, g201, g211, pgh, ph, s1, s2, s3, s4, s5, s6, s7, ++ se, sel, ses, xls, g300, g310, g322, g410, g422, g520, g521, g532, ++ g533, gam, sinq, sinzf, sis, sl, sll, sls, stem, temp, temp1, x1, ++ x2, x2li, x2omi, x3, x4, x5, x6, x7, x8, xl, xldot, xmao, xnddt, ++ xndot, xno2, xnodce, xnoi, xomi, xpidot, z1, z11, z12, z13, z2, ++ z21, z22, z23, z3, z31, z32, z33, ze, zf, zm, zmo, zn, zsing, ++ zsinh, zsini, zcosg, zcosh, zcosi, delt=0, ft=0; ++ ++ switch (ientry) { ++ case dpinit: /* Entrance for deep space initialization */ ++ thgr=ThetaG(tle->epoch,deep_arg); ++ eq=tle->eo; ++ xnq=deep_arg->xnodp; ++ aqnv=1/deep_arg->aodp; ++ xqncl=tle->xincl; ++ xmao=tle->xmo; ++ xpidot=deep_arg->omgdot+deep_arg->xnodot; ++ sinq=sin(tle->xnodeo); ++ cosq=cos(tle->xnodeo); ++ omegaq=tle->omegao; ++ ++ /* Initialize lunar solar terms */ ++ day=deep_arg->ds50+18261.5; /* Days since 1900 Jan 0.5 */ ++ ++ if (day!=preep) { ++ preep=day; ++ xnodce=4.5236020-9.2422029E-4*day; ++ stem=sin(xnodce); ++ ctem=cos(xnodce); ++ zcosil=0.91375164-0.03568096*ctem; ++ zsinil=sqrt(1-zcosil*zcosil); ++ zsinhl=0.089683511*stem/zsinil; ++ zcoshl=sqrt(1-zsinhl*zsinhl); ++ c=4.7199672+0.22997150*day; ++ gam=5.8351514+0.0019443680*day; ++ zmol=FMod2p(c-gam); ++ zx=0.39785416*stem/zsinil; ++ zy=zcoshl*ctem+0.91744867*zsinhl*stem; ++ zx=AcTan(zx,zy); ++ zx=gam+zx-xnodce; ++ zcosgl=cos(zx); ++ zsingl=sin(zx); ++ zmos=6.2565837+0.017201977*day; ++ zmos=FMod2p(zmos); ++ } ++ ++ /* Do solar terms */ ++ savtsn=1E20; ++ zcosg=zcosgs; ++ zsing=zsings; ++ zcosi=zcosis; ++ zsini=zsinis; ++ zcosh=cosq; ++ zsinh= sinq; ++ cc=c1ss; ++ zn=zns; ++ ze=zes; ++ zmo=zmos; ++ xnoi=1/xnq; ++ ++ /* Loop breaks when Solar terms are done a second */ ++ /* time, after Lunar terms are initialized */ ++ ++ for (;;) { ++ /* Solar terms done again after Lunar terms are done */ ++ a1=zcosg*zcosh+zsing*zcosi*zsinh; ++ a3=-zsing*zcosh+zcosg*zcosi*zsinh; ++ a7=-zcosg*zsinh+zsing*zcosi*zcosh; ++ a8=zsing*zsini; ++ a9=zsing*zsinh+zcosg*zcosi*zcosh; ++ a10=zcosg*zsini; ++ a2=deep_arg->cosio*a7+deep_arg->sinio*a8; ++ a4=deep_arg->cosio*a9+deep_arg->sinio*a10; ++ a5=-deep_arg->sinio*a7+deep_arg->cosio*a8; ++ a6=-deep_arg->sinio*a9+deep_arg->cosio*a10; ++ x1=a1*deep_arg->cosg+a2*deep_arg->sing; ++ x2=a3*deep_arg->cosg+a4*deep_arg->sing; ++ x3=-a1*deep_arg->sing+a2*deep_arg->cosg; ++ x4=-a3*deep_arg->sing+a4*deep_arg->cosg; ++ x5=a5*deep_arg->sing; ++ x6=a6*deep_arg->sing; ++ x7=a5*deep_arg->cosg; ++ x8=a6*deep_arg->cosg; ++ z31=12*x1*x1-3*x3*x3; ++ z32=24*x1*x2-6*x3*x4; ++ z33=12*x2*x2-3*x4*x4; ++ z1=3*(a1*a1+a2*a2)+z31*deep_arg->eosq; ++ z2=6*(a1*a3+a2*a4)+z32*deep_arg->eosq; ++ z3=3*(a3*a3+a4*a4)+z33*deep_arg->eosq; ++ z11=-6*a1*a5+deep_arg->eosq*(-24*x1*x7-6*x3*x5); ++ z12=-6*(a1*a6+a3*a5)+deep_arg->eosq*(-24*(x2*x7+x1*x8)-6*(x3*x6+x4*x5)); ++ z13=-6*a3*a6+deep_arg->eosq*(-24*x2*x8-6*x4*x6); ++ z21=6*a2*a5+deep_arg->eosq*(24*x1*x5-6*x3*x7); ++ z22=6*(a4*a5+a2*a6)+deep_arg->eosq*(24*(x2*x5+x1*x6)-6*(x4*x7+x3*x8)); ++ z23=6*a4*a6+deep_arg->eosq*(24*x2*x6-6*x4*x8); ++ z1=z1+z1+deep_arg->betao2*z31; ++ z2=z2+z2+deep_arg->betao2*z32; ++ z3=z3+z3+deep_arg->betao2*z33; ++ s3=cc*xnoi; ++ s2=-0.5*s3/deep_arg->betao; ++ s4=s3*deep_arg->betao; ++ s1=-15*eq*s4; ++ s5=x1*x3+x2*x4; ++ s6=x2*x3+x1*x4; ++ s7=x2*x4-x1*x3; ++ se=s1*zn*s5; ++ si=s2*zn*(z11+z13); ++ sl=-zn*s3*(z1+z3-14-6*deep_arg->eosq); ++ sgh=s4*zn*(z31+z33-6); ++ sh=-zn*s2*(z21+z23); ++ ++ if (xqncl<5.2359877E-2) ++ sh=0; ++ ++ ee2=2*s1*s6; ++ e3=2*s1*s7; ++ xi2=2*s2*z12; ++ xi3=2*s2*(z13-z11); ++ xl2=-2*s3*z2; ++ xl3=-2*s3*(z3-z1); ++ xl4=-2*s3*(-21-9*deep_arg->eosq)*ze; ++ xgh2=2*s4*z32; ++ xgh3=2*s4*(z33-z31); ++ xgh4=-18*s4*ze; ++ xh2=-2*s2*z22; ++ xh3=-2*s2*(z23-z21); ++ ++ if (isFlagSet(LUNAR_TERMS_DONE_FLAG)) ++ break; ++ ++ /* Do lunar terms */ ++ sse=se; ++ ssi=si; ++ ssl=sl; ++ ssh=sh/deep_arg->sinio; ++ ssg=sgh-deep_arg->cosio*ssh; ++ se2=ee2; ++ si2=xi2; ++ sl2=xl2; ++ sgh2=xgh2; ++ sh2=xh2; ++ se3=e3; ++ si3=xi3; ++ sl3=xl3; ++ sgh3=xgh3; ++ sh3=xh3; ++ sl4=xl4; ++ sgh4=xgh4; ++ zcosg=zcosgl; ++ zsing=zsingl; ++ zcosi=zcosil; ++ zsini=zsinil; ++ zcosh=zcoshl*cosq+zsinhl*sinq; ++ zsinh=sinq*zcoshl-cosq*zsinhl; ++ zn=znl; ++ cc=c1l; ++ ze=zel; ++ zmo=zmol; ++ SetFlag(LUNAR_TERMS_DONE_FLAG); ++ } ++ ++ sse=sse+se; ++ ssi=ssi+si; ++ ssl=ssl+sl; ++ ssg=ssg+sgh-deep_arg->cosio/deep_arg->sinio*sh; ++ ssh=ssh+sh/deep_arg->sinio; ++ ++ /* Geopotential resonance initialization for 12 hour orbits */ ++ ClearFlag(RESONANCE_FLAG); ++ ClearFlag(SYNCHRONOUS_FLAG); ++ ++ if (!((xnq<0.0052359877) && (xnq>0.0034906585))) { ++ if ((xnq<0.00826) || (xnq>0.00924)) ++ return; ++ ++ if (eq<0.5) ++ return; ++ ++ SetFlag(RESONANCE_FLAG); ++ eoc=eq*deep_arg->eosq; ++ g201=-0.306-(eq-0.64)*0.440; ++ ++ if (eq<=0.65) { ++ g211=3.616-13.247*eq+16.290*deep_arg->eosq; ++ g310=-19.302+117.390*eq-228.419*deep_arg->eosq+156.591*eoc; ++ g322=-18.9068+109.7927*eq-214.6334*deep_arg->eosq+146.5816*eoc; ++ g410=-41.122+242.694*eq-471.094*deep_arg->eosq+313.953*eoc; ++ g422=-146.407+841.880*eq-1629.014*deep_arg->eosq+1083.435 * eoc; ++ g520=-532.114+3017.977*eq-5740*deep_arg->eosq+3708.276*eoc; ++ } else { ++ g211=-72.099+331.819*eq-508.738*deep_arg->eosq+266.724*eoc; ++ g310=-346.844+1582.851*eq-2415.925*deep_arg->eosq+1246.113*eoc; ++ g322=-342.585+1554.908*eq-2366.899*deep_arg->eosq+1215.972*eoc; ++ g410=-1052.797+4758.686*eq-7193.992*deep_arg->eosq+3651.957*eoc; ++ g422=-3581.69+16178.11*eq-24462.77*deep_arg->eosq+12422.52*eoc; ++ ++ if (eq<=0.715) ++ g520=1464.74-4664.75*eq+3763.64*deep_arg->eosq; ++ else ++ g520=-5149.66+29936.92*eq-54087.36*deep_arg->eosq+31324.56*eoc; ++ } ++ ++ if (eq<0.7) { ++ g533=-919.2277+4988.61*eq-9064.77*deep_arg->eosq+5542.21*eoc; ++ g521=-822.71072+4568.6173*eq-8491.4146*deep_arg->eosq+5337.524*eoc; ++ g532=-853.666+4690.25*eq-8624.77*deep_arg->eosq+5341.4*eoc; ++ } else { ++ g533=-37995.78+161616.52*eq-229838.2*deep_arg->eosq+109377.94*eoc; ++ g521 =-51752.104+218913.95*eq-309468.16*deep_arg->eosq+146349.42*eoc; ++ g532 =-40023.88+170470.89*eq-242699.48*deep_arg->eosq+115605.82*eoc; ++ } ++ ++ sini2=deep_arg->sinio*deep_arg->sinio; ++ f220=0.75*(1+2*deep_arg->cosio+deep_arg->theta2); ++ f221=1.5*sini2; ++ f321=1.875*deep_arg->sinio*(1-2*deep_arg->cosio-3*deep_arg->theta2); ++ f322=-1.875*deep_arg->sinio*(1+2*deep_arg->cosio-3*deep_arg->theta2); ++ f441=35*sini2*f220; ++ f442=39.3750*sini2*sini2; ++ f522=9.84375*deep_arg->sinio*(sini2*(1-2*deep_arg->cosio-5*deep_arg->theta2)+0.33333333*(-2+4*deep_arg->cosio+6*deep_arg->theta2)); ++ f523=deep_arg->sinio*(4.92187512*sini2*(-2-4*deep_arg->cosio+10*deep_arg->theta2)+6.56250012*(1+2*deep_arg->cosio-3*deep_arg->theta2)); ++ f542=29.53125*deep_arg->sinio*(2-8*deep_arg->cosio+deep_arg->theta2*(-12+8*deep_arg->cosio+10*deep_arg->theta2)); ++ f543=29.53125*deep_arg->sinio*(-2-8*deep_arg->cosio+deep_arg->theta2*(12+8*deep_arg->cosio-10*deep_arg->theta2)); ++ xno2=xnq*xnq; ++ ainv2=aqnv*aqnv; ++ temp1=3*xno2*ainv2; ++ temp=temp1*root22; ++ d2201=temp*f220*g201; ++ d2211=temp*f221*g211; ++ temp1=temp1*aqnv; ++ temp=temp1*root32; ++ d3210=temp*f321*g310; ++ d3222=temp*f322*g322; ++ temp1=temp1*aqnv; ++ temp=2*temp1*root44; ++ d4410=temp*f441*g410; ++ d4422=temp*f442*g422; ++ temp1=temp1*aqnv; ++ temp=temp1*root52; ++ d5220=temp*f522*g520; ++ d5232=temp*f523*g532; ++ temp=2*temp1*root54; ++ d5421=temp*f542*g521; ++ d5433=temp*f543*g533; ++ xlamo=xmao+tle->xnodeo+tle->xnodeo-thgr-thgr; ++ bfact=deep_arg->xmdot+deep_arg->xnodot+deep_arg->xnodot-thdt-thdt; ++ bfact=bfact+ssl+ssh+ssh; ++ } else { ++ SetFlag(RESONANCE_FLAG); ++ SetFlag(SYNCHRONOUS_FLAG); ++ ++ /* Synchronous resonance terms initialization */ ++ g200=1+deep_arg->eosq*(-2.5+0.8125*deep_arg->eosq); ++ g310=1+2*deep_arg->eosq; ++ g300=1+deep_arg->eosq*(-6+6.60937*deep_arg->eosq); ++ f220=0.75*(1+deep_arg->cosio)*(1+deep_arg->cosio); ++ f311=0.9375*deep_arg->sinio*deep_arg->sinio*(1+3*deep_arg->cosio)-0.75*(1+deep_arg->cosio); ++ f330=1+deep_arg->cosio; ++ f330=1.875*f330*f330*f330; ++ del1=3*xnq*xnq*aqnv*aqnv; ++ del2=2*del1*f220*g200*q22; ++ del3=3*del1*f330*g300*q33*aqnv; ++ del1=del1*f311*g310*q31*aqnv; ++ fasx2=0.13130908; ++ fasx4=2.8843198; ++ fasx6=0.37448087; ++ xlamo=xmao+tle->xnodeo+tle->omegao-thgr; ++ bfact=deep_arg->xmdot+xpidot-thdt; ++ bfact=bfact+ssl+ssg+ssh; ++ } ++ ++ xfact=bfact-xnq; ++ ++ /* Initialize integrator */ ++ xli=xlamo; ++ xni=xnq; ++ atime=0; ++ stepp=720; ++ stepn=-720; ++ step2=259200; ++ ++ return; ++ ++ case dpsec: /* Entrance for deep space secular effects */ ++ deep_arg->xll=deep_arg->xll+ssl*deep_arg->t; ++ deep_arg->omgadf=deep_arg->omgadf+ssg*deep_arg->t; ++ deep_arg->xnode=deep_arg->xnode+ssh*deep_arg->t; ++ deep_arg->em=tle->eo+sse*deep_arg->t; ++ deep_arg->xinc=tle->xincl+ssi*deep_arg->t; ++ ++ if (deep_arg->xinc<0) { ++ deep_arg->xinc=-deep_arg->xinc; ++ deep_arg->xnode=deep_arg->xnode+pi; ++ deep_arg->omgadf=deep_arg->omgadf-pi; ++ } ++ ++ if (isFlagClear(RESONANCE_FLAG)) ++ return; ++ ++ do { ++ if ((atime==0) || ((deep_arg->t>=0) && (atime<0)) || ((deep_arg->t<0) && (atime>=0))) { ++ /* Epoch restart */ ++ ++ if (deep_arg->t>=0) ++ delt=stepp; ++ else ++ delt=stepn; ++ ++ atime=0; ++ xni=xnq; ++ xli=xlamo; ++ } else { ++ if (fabs(deep_arg->t)>=fabs(atime)) { ++ if (deep_arg->t>0) ++ delt=stepp; ++ else ++ delt=stepn; ++ } ++ } ++ ++ do { ++ if (fabs(deep_arg->t-atime)>=stepp) { ++ SetFlag(DO_LOOP_FLAG); ++ ClearFlag(EPOCH_RESTART_FLAG); ++ } else { ++ ft=deep_arg->t-atime; ++ ClearFlag(DO_LOOP_FLAG); ++ } ++ ++ if (fabs(deep_arg->t)t>=0) ++ delt=stepn; ++ else ++ delt=stepp; ++ ++ SetFlag(DO_LOOP_FLAG | EPOCH_RESTART_FLAG); ++ } ++ ++ /* Dot terms calculated */ ++ if (isFlagSet(SYNCHRONOUS_FLAG)) { ++ xndot=del1*sin(xli-fasx2)+del2*sin(2*(xli-fasx4))+del3*sin(3*(xli-fasx6)); ++ xnddt=del1*cos(xli-fasx2)+2*del2*cos(2*(xli-fasx4))+3*del3*cos(3*(xli-fasx6)); ++ } else { ++ xomi=omegaq+deep_arg->omgdot*atime; ++ x2omi=xomi+xomi; ++ x2li=xli+xli; ++ xndot=d2201*sin(x2omi+xli-g22)+d2211*sin(xli-g22)+d3210*sin(xomi+xli-g32)+d3222*sin(-xomi+xli-g32)+d4410*sin(x2omi+x2li-g44)+d4422*sin(x2li-g44)+d5220*sin(xomi+xli-g52)+d5232*sin(-xomi+xli-g52)+d5421*sin(xomi+x2li-g54)+d5433*sin(-xomi+x2li-g54); ++ xnddt=d2201*cos(x2omi+xli-g22)+d2211*cos(xli-g22)+d3210*cos(xomi+xli-g32)+d3222*cos(-xomi+xli-g32)+d5220*cos(xomi+xli-g52)+d5232*cos(-xomi+xli-g52)+2*(d4410*cos(x2omi+x2li-g44)+d4422*cos(x2li-g44)+d5421*cos(xomi+x2li-g54)+d5433*cos(-xomi+x2li-g54)); ++ } ++ ++ xldot=xni+xfact; ++ xnddt=xnddt*xldot; ++ ++ if (isFlagSet(DO_LOOP_FLAG)) { ++ xli=xli+xldot*delt+xndot*step2; ++ xni=xni+xndot*delt+xnddt*step2; ++ atime=atime+delt; ++ } ++ } while (isFlagSet(DO_LOOP_FLAG) && isFlagClear(EPOCH_RESTART_FLAG)); ++ } while (isFlagSet(DO_LOOP_FLAG) && isFlagSet(EPOCH_RESTART_FLAG)); ++ ++ deep_arg->xn=xni+xndot*ft+xnddt*ft*ft*0.5; ++ xl=xli+xldot*ft+xndot*ft*ft*0.5; ++ temp=-deep_arg->xnode+thgr+deep_arg->t*thdt; ++ ++ if (isFlagClear(SYNCHRONOUS_FLAG)) ++ deep_arg->xll=xl+temp+temp; ++ else ++ deep_arg->xll=xl-deep_arg->omgadf+temp; ++ ++ return; ++ ++ case dpper: /* Entrance for lunar-solar periodics */ ++ sinis=sin(deep_arg->xinc); ++ cosis=cos(deep_arg->xinc); ++ ++ if (fabs(savtsn-deep_arg->t)>=30) { ++ savtsn=deep_arg->t; ++ zm=zmos+zns*deep_arg->t; ++ zf=zm+2*zes*sin(zm); ++ sinzf=sin(zf); ++ f2=0.5*sinzf*sinzf-0.25; ++ f3=-0.5*sinzf*cos(zf); ++ ses=se2*f2+se3*f3; ++ sis=si2*f2+si3*f3; ++ sls=sl2*f2+sl3*f3+sl4*sinzf; ++ sghs=sgh2*f2+sgh3*f3+sgh4*sinzf; ++ shs=sh2*f2+sh3*f3; ++ zm=zmol+znl*deep_arg->t; ++ zf=zm+2*zel*sin(zm); ++ sinzf=sin(zf); ++ f2=0.5*sinzf*sinzf-0.25; ++ f3=-0.5*sinzf*cos(zf); ++ sel=ee2*f2+e3*f3; ++ sil=xi2*f2+xi3*f3; ++ sll=xl2*f2+xl3*f3+xl4*sinzf; ++ sghl=xgh2*f2+xgh3*f3+xgh4*sinzf; ++ sh1=xh2*f2+xh3*f3; ++ pe=ses+sel; ++ pinc=sis+sil; ++ pl=sls+sll; ++ } ++ ++ pgh=sghs+sghl; ++ ph=shs+sh1; ++ deep_arg->xinc=deep_arg->xinc+pinc; ++ deep_arg->em=deep_arg->em+pe; ++ ++ if (xqncl>=0.2) { ++ /* Apply periodics directly */ ++ ph=ph/deep_arg->sinio; ++ pgh=pgh-deep_arg->cosio*ph; ++ deep_arg->omgadf=deep_arg->omgadf+pgh; ++ deep_arg->xnode=deep_arg->xnode+ph; ++ deep_arg->xll=deep_arg->xll+pl; ++ } else { ++ /* Apply periodics with Lyddane modification */ ++ sinok=sin(deep_arg->xnode); ++ cosok=cos(deep_arg->xnode); ++ alfdp=sinis*sinok; ++ betdp=sinis*cosok; ++ dalf=ph*cosok+pinc*cosis*sinok; ++ dbet=-ph*sinok+pinc*cosis*cosok; ++ alfdp=alfdp+dalf; ++ betdp=betdp+dbet; ++ deep_arg->xnode=FMod2p(deep_arg->xnode); ++ xls=deep_arg->xll+deep_arg->omgadf+cosis*deep_arg->xnode; ++ dls=pl+pgh-pinc*deep_arg->xnode*sinis; ++ xls=xls+dls; ++ xnoh=deep_arg->xnode; ++ deep_arg->xnode=AcTan(alfdp,betdp); ++ ++ /* This is a patch to Lyddane modification */ ++ /* suggested by Rob Matson. */ ++ ++ if (fabs(xnoh-deep_arg->xnode)>pi) { ++ if (deep_arg->xnodexnode+=twopi; ++ else ++ deep_arg->xnode-=twopi; ++ } ++ ++ deep_arg->xll=deep_arg->xll+pl; ++ deep_arg->omgadf=xls-deep_arg->xll-cos(deep_arg->xinc)*deep_arg->xnode; ++ } ++ return; ++ } ++} ++ ++void SDP4(double tsince, tle_t * tle, vector_t * pos, vector_t * vel) ++{ ++ /* This function is used to calculate the position and velocity */ ++ /* of deep-space (period > 225 minutes) satellites. tsince is */ ++ /* time since epoch in minutes, tle is a pointer to a tle_t */ ++ /* structure with Keplerian orbital elements and pos and vel */ ++ /* are vector_t structures returning ECI satellite position and */ ++ /* velocity. Use Convert_Sat_State() to convert to km and km/s. */ ++ ++ int i; ++ ++ static double x3thm1, c1, x1mth2, c4, xnodcf, t2cof, xlcof, ++ aycof, x7thm1; ++ ++ double a, axn, ayn, aynl, beta, betal, capu, cos2u, cosepw, cosik, ++ cosnok, cosu, cosuk, ecose, elsq, epw, esine, pl, theta4, rdot, ++ rdotk, rfdot, rfdotk, rk, sin2u, sinepw, sinik, sinnok, sinu, ++ sinuk, tempe, templ, tsq, u, uk, ux, uy, uz, vx, vy, vz, xinck, xl, ++ xlt, xmam, xmdf, xmx, xmy, xnoddf, xnodek, xll, a1, a3ovk2, ao, c2, ++ coef, coef1, x1m5th, xhdot1, del1, r, delo, eeta, eta, etasq, ++ perigee, psisq, tsi, qoms24, s4, pinvsq, temp, tempa, temp1, ++ temp2, temp3, temp4, temp5, temp6, bx, by, bz, cx, cy, cz; ++ ++ static deep_arg_t deep_arg; ++ ++ /* Initialization */ ++ ++ if (isFlagClear(SDP4_INITIALIZED_FLAG)) { ++ SetFlag(SDP4_INITIALIZED_FLAG); ++ ++ /* Recover original mean motion (xnodp) and */ ++ /* semimajor axis (aodp) from input elements. */ ++ ++ a1=pow(xke/tle->xno,tothrd); ++ deep_arg.cosio=cos(tle->xincl); ++ deep_arg.theta2=deep_arg.cosio*deep_arg.cosio; ++ x3thm1=3*deep_arg.theta2-1; ++ deep_arg.eosq=tle->eo*tle->eo; ++ deep_arg.betao2=1-deep_arg.eosq; ++ deep_arg.betao=sqrt(deep_arg.betao2); ++ del1=1.5*ck2*x3thm1/(a1*a1*deep_arg.betao*deep_arg.betao2); ++ ao=a1*(1-del1*(0.5*tothrd+del1*(1+134/81*del1))); ++ delo=1.5*ck2*x3thm1/(ao*ao*deep_arg.betao*deep_arg.betao2); ++ deep_arg.xnodp=tle->xno/(1+delo); ++ deep_arg.aodp=ao/(1-delo); ++ ++ /* For perigee below 156 km, the values */ ++ /* of s and qoms2t are altered. */ ++ ++ s4=s; ++ qoms24=qoms2t; ++ perigee=(deep_arg.aodp*(1-tle->eo)-ae)*xkmper; ++ ++ if (perigee<156.0) { ++ if (perigee<=98.0) ++ s4=20.0; ++ else ++ s4=perigee-78.0; ++ ++ qoms24=pow((120-s4)*ae/xkmper,4); ++ s4=s4/xkmper+ae; ++ } ++ ++ pinvsq=1/(deep_arg.aodp*deep_arg.aodp*deep_arg.betao2*deep_arg.betao2); ++ deep_arg.sing=sin(tle->omegao); ++ deep_arg.cosg=cos(tle->omegao); ++ tsi=1/(deep_arg.aodp-s4); ++ eta=deep_arg.aodp*tle->eo*tsi; ++ etasq=eta*eta; ++ eeta=tle->eo*eta; ++ psisq=fabs(1-etasq); ++ coef=qoms24*pow(tsi,4); ++ coef1=coef/pow(psisq,3.5); ++ c2=coef1*deep_arg.xnodp*(deep_arg.aodp*(1+1.5*etasq+eeta*(4+etasq))+0.75*ck2*tsi/psisq*x3thm1*(8+3*etasq*(8+etasq))); ++ c1=tle->bstar*c2; ++ deep_arg.sinio=sin(tle->xincl); ++ a3ovk2=-xj3/ck2*pow(ae,3); ++ x1mth2=1-deep_arg.theta2; ++ c4=2*deep_arg.xnodp*coef1*deep_arg.aodp*deep_arg.betao2*(eta*(2+0.5*etasq)+tle->eo*(0.5+2*etasq)-2*ck2*tsi/(deep_arg.aodp*psisq)*(-3*x3thm1*(1-2*eeta+etasq*(1.5-0.5*eeta))+0.75*x1mth2*(2*etasq-eeta*(1+etasq))*cos(2*tle->omegao))); ++ theta4=deep_arg.theta2*deep_arg.theta2; ++ temp1=3*ck2*pinvsq*deep_arg.xnodp; ++ temp2=temp1*ck2*pinvsq; ++ temp3=1.25*ck4*pinvsq*pinvsq*deep_arg.xnodp; ++ deep_arg.xmdot=deep_arg.xnodp+0.5*temp1*deep_arg.betao*x3thm1+0.0625*temp2*deep_arg.betao*(13-78*deep_arg.theta2+137*theta4); ++ x1m5th=1-5*deep_arg.theta2; ++ deep_arg.omgdot=-0.5*temp1*x1m5th+0.0625*temp2*(7-114*deep_arg.theta2+395*theta4)+temp3*(3-36*deep_arg.theta2+49*theta4); ++ xhdot1=-temp1*deep_arg.cosio; ++ deep_arg.xnodot=xhdot1+(0.5*temp2*(4-19*deep_arg.theta2)+2*temp3*(3-7*deep_arg.theta2))*deep_arg.cosio; ++ xnodcf=3.5*deep_arg.betao2*xhdot1*c1; ++ t2cof=1.5*c1; ++ xlcof=0.125*a3ovk2*deep_arg.sinio*(3+5*deep_arg.cosio)/(1+deep_arg.cosio); ++ aycof=0.25*a3ovk2*deep_arg.sinio; ++ x7thm1=7*deep_arg.theta2-1; ++ ++ /* initialize Deep() */ ++ ++ Deep(dpinit,tle,&deep_arg); ++ } ++ ++ /* Update for secular gravity and atmospheric drag */ ++ xmdf=tle->xmo+deep_arg.xmdot*tsince; ++ deep_arg.omgadf=tle->omegao+deep_arg.omgdot*tsince; ++ xnoddf=tle->xnodeo+deep_arg.xnodot*tsince; ++ tsq=tsince*tsince; ++ deep_arg.xnode=xnoddf+xnodcf*tsq; ++ tempa=1-c1*tsince; ++ tempe=tle->bstar*c4*tsince; ++ templ=t2cof*tsq; ++ deep_arg.xn=deep_arg.xnodp; ++ ++ /* Update for deep-space secular effects */ ++ deep_arg.xll=xmdf; ++ deep_arg.t=tsince; ++ ++ Deep(dpsec, tle, &deep_arg); ++ ++ xmdf=deep_arg.xll; ++ a=pow(xke/deep_arg.xn,tothrd)*tempa*tempa; ++ deep_arg.em=deep_arg.em-tempe; ++ xmam=xmdf+deep_arg.xnodp*templ; ++ ++ /* Update for deep-space periodic effects */ ++ deep_arg.xll=xmam; ++ ++ Deep(dpper,tle,&deep_arg); ++ ++ xmam=deep_arg.xll; ++ xl=xmam+deep_arg.omgadf+deep_arg.xnode; ++ beta=sqrt(1-deep_arg.em*deep_arg.em); ++ deep_arg.xn=xke/pow(a,1.5); ++ ++ /* Long period periodics */ ++ axn=deep_arg.em*cos(deep_arg.omgadf); ++ temp=1/(a*beta*beta); ++ xll=temp*xlcof*axn; ++ aynl=temp*aycof; ++ xlt=xl+xll; ++ ayn=deep_arg.em*sin(deep_arg.omgadf)+aynl; ++ ++ /* Solve Kepler's Equation */ ++ capu=FMod2p(xlt-deep_arg.xnode); ++ temp2=capu; ++ i=0; ++ ++ do { ++ sinepw=sin(temp2); ++ cosepw=cos(temp2); ++ temp3=axn*sinepw; ++ temp4=ayn*cosepw; ++ temp5=axn*cosepw; ++ temp6=ayn*sinepw; ++ epw=(capu-temp4+temp3-temp2)/(1-temp5-temp6)+temp2; ++ ++ if (fabs(epw-temp2)<=e6a) ++ break; ++ ++ temp2=epw; ++ ++ } while (i++<10); ++ ++ /* Short period preliminary quantities */ ++ ecose=temp5+temp6; ++ esine=temp3-temp4; ++ elsq=axn*axn+ayn*ayn; ++ temp=1-elsq; ++ pl=a*temp; ++ r=a*(1-ecose); ++ temp1=1/r; ++ rdot=xke*sqrt(a)*esine*temp1; ++ rfdot=xke*sqrt(pl)*temp1; ++ temp2=a*temp1; ++ betal=sqrt(temp); ++ temp3=1/(1+betal); ++ cosu=temp2*(cosepw-axn+ayn*esine*temp3); ++ sinu=temp2*(sinepw-ayn-axn*esine*temp3); ++ u=AcTan(sinu,cosu); ++ sin2u=2*sinu*cosu; ++ cos2u=2*cosu*cosu-1; ++ temp=1/pl; ++ temp1=ck2*temp; ++ temp2=temp1*temp; ++ ++ /* Update for short periodics */ ++ rk=r*(1-1.5*temp2*betal*x3thm1)+0.5*temp1*x1mth2*cos2u; ++ uk=u-0.25*temp2*x7thm1*sin2u; ++ xnodek=deep_arg.xnode+1.5*temp2*deep_arg.cosio*sin2u; ++ xinck=deep_arg.xinc+1.5*temp2*deep_arg.cosio*deep_arg.sinio*cos2u; ++ rdotk=rdot-deep_arg.xn*temp1*x1mth2*sin2u; ++ rfdotk=rfdot+deep_arg.xn*temp1*(x1mth2*cos2u+1.5*x3thm1); ++ ++ /* Orientation vectors */ ++ sinuk=sin(uk); ++ cosuk=cos(uk); ++ sinik=sin(xinck); ++ cosik=cos(xinck); ++ sinnok=sin(xnodek); ++ cosnok=cos(xnodek); ++ xmx=-sinnok*cosik; ++ xmy=cosnok*cosik; ++ ux=xmx*sinuk+cosnok*cosuk; ++ uy=xmy*sinuk+sinnok*cosuk; ++ uz=sinik*sinuk; ++ vx=xmx*cosuk-cosnok*sinuk; ++ vy=xmy*cosuk-sinnok*sinuk; ++ vz=sinik*cosuk; ++ ++ /* Position and velocity */ ++ pos->x=rk*ux; ++ pos->y=rk*uy; ++ pos->z=rk*uz; ++ vel->x=rdotk*ux+rfdotk*vx; ++ vel->y=rdotk*uy+rfdotk*vy; ++ vel->z=rdotk*uz+rfdotk*vz; ++ ++ /* Calculations for squint angle begin here... */ ++ ++ if (calc_squint) { ++ bx=cos(alat)*cos(alon+deep_arg.omgadf); ++ by=cos(alat)*sin(alon+deep_arg.omgadf); ++ bz=sin(alat); ++ cx=bx; ++ cy=by*cos(xinck)-bz*sin(xinck); ++ cz=by*sin(xinck)+bz*cos(xinck); ++ ax=cx*cos(xnodek)-cy*sin(xnodek); ++ ay=cx*sin(xnodek)+cy*cos(xnodek); ++ az=cz; ++ } ++ ++ /* Phase in radians */ ++ phase=xlt-deep_arg.xnode-deep_arg.omgadf+twopi; ++ ++ if (phase<0.0) ++ phase+=twopi; ++ ++ phase=FMod2p(phase); ++} ++ ++void Calculate_User_PosVel(double time, geodetic_t *geodetic, vector_t *obs_pos, vector_t *obs_vel) ++{ ++ /* Calculate_User_PosVel() passes the user's geodetic position ++ and the time of interest and returns the ECI position and ++ velocity of the observer. The velocity calculation assumes ++ the geodetic position is stationary relative to the earth's ++ surface. */ ++ ++ /* Reference: The 1992 Astronomical Almanac, page K11. */ ++ ++ double c, sq, achcp; ++ ++ geodetic->theta=FMod2p(ThetaG_JD(time)+geodetic->lon); /* LMST */ ++ c=1/sqrt(1+f*(f-2)*Sqr(sin(geodetic->lat))); ++ sq=Sqr(1-f)*c; ++ achcp=(xkmper*c+geodetic->alt)*cos(geodetic->lat); ++ obs_pos->x=achcp*cos(geodetic->theta); /* kilometers */ ++ obs_pos->y=achcp*sin(geodetic->theta); ++ obs_pos->z=(xkmper*sq+geodetic->alt)*sin(geodetic->lat); ++ obs_vel->x=-mfactor*obs_pos->y; /* kilometers/second */ ++ obs_vel->y=mfactor*obs_pos->x; ++ obs_vel->z=0; ++ Magnitude(obs_pos); ++ Magnitude(obs_vel); ++} ++ ++void Calculate_LatLonAlt(double time, vector_t *pos, geodetic_t *geodetic) ++{ ++ /* Procedure Calculate_LatLonAlt will calculate the geodetic */ ++ /* position of an object given its ECI position pos and time. */ ++ /* It is intended to be used to determine the ground track of */ ++ /* a satellite. The calculations assume the earth to be an */ ++ /* oblate spheroid as defined in WGS '72. */ ++ ++ /* Reference: The 1992 Astronomical Almanac, page K12. */ ++ ++ double r, e2, phi, c; ++ ++ geodetic->theta=AcTan(pos->y,pos->x); /* radians */ ++ geodetic->lon=FMod2p(geodetic->theta-ThetaG_JD(time)); /* radians */ ++ r=sqrt(Sqr(pos->x)+Sqr(pos->y)); ++ e2=f*(2-f); ++ geodetic->lat=AcTan(pos->z,r); /* radians */ ++ ++ do { ++ phi=geodetic->lat; ++ c=1/sqrt(1-e2*Sqr(sin(phi))); ++ geodetic->lat=AcTan(pos->z+xkmper*c*e2*sin(phi),r); ++ ++ } while (fabs(geodetic->lat-phi)>=1E-10); ++ ++ geodetic->alt=r/cos(geodetic->lat)-xkmper*c; /* kilometers */ ++ ++ if (geodetic->lat>pio2) ++ geodetic->lat-=twopi; ++} ++ ++double reduce(value,rangeMin,rangeMax) ++double value, rangeMin, rangeMax; ++{ ++ double range, rangeFrac, fullRanges, retval; ++ ++ range = rangeMax - rangeMin; ++ rangeFrac = (rangeMax - value) / range; ++ ++ modf(rangeFrac,&fullRanges); ++ ++ retval = value + fullRanges * range; ++ ++ if (retval > rangeMax) ++ retval -= range; ++ ++ return(retval); ++} ++ ++void getMaidenHead(mLtd,mLng,mStr) ++double mLtd, mLng; ++char *mStr; ++{ ++ int i, j, k, l, m, n; ++ ++ mLng = reduce(180.0 - mLng, 0.0, 360.0); ++ mLtd = reduce(90.0 + mLtd, 0.0, 360.0); ++ ++ i = (int) (mLng / 20.0); ++ j = (int) (mLtd / 10.0); ++ ++ mLng -= (double) i * 20.0; ++ mLtd -= (double) j * 10.0; ++ ++ k = (int) (mLng / 2.0); ++ l = (int) (mLtd / 1.0); ++ ++ mLng -= (double) k * 2.0; ++ mLtd -= (double) l * 1.0; ++ ++ m = (int) (mLng * 12.0); ++ n = (int) (mLtd * 24.0); ++ ++ sprintf(mStr,"%c%c%d%d%c%c", ++ 'A' + (char) i, ++ 'A' + (char) j, ++ k, l, ++ tolower('A' + (char) m), ++ tolower('A' + (char) n)); ++ ++ return; ++} ++ ++void Calculate_Obs(double time, vector_t *pos, vector_t *vel, geodetic_t *geodetic, vector_t *obs_set) ++{ ++ /* The procedures Calculate_Obs and Calculate_RADec calculate */ ++ /* the *topocentric* coordinates of the object with ECI position, */ ++ /* {pos}, and velocity, {vel}, from location {geodetic} at {time}. */ ++ /* The {obs_set} returned for Calculate_Obs consists of azimuth, */ ++ /* elevation, range, and range rate (in that order) with units of */ ++ /* radians, radians, kilometers, and kilometers/second, respectively. */ ++ /* The WGS '72 geoid is used and the effect of atmospheric refraction */ ++ /* (under standard temperature and pressure) is incorporated into the */ ++ /* elevation calculation; the effect of atmospheric refraction on */ ++ /* range and range rate has not yet been quantified. */ ++ ++ /* The {obs_set} for Calculate_RADec consists of right ascension and */ ++ /* declination (in that order) in radians. Again, calculations are */ ++ /* based on *topocentric* position using the WGS '72 geoid and */ ++ /* incorporating atmospheric refraction. */ ++ ++ double sin_lat, cos_lat, sin_theta, cos_theta, el, azim, top_s, top_e, top_z; ++ ++ vector_t obs_pos, obs_vel, range, rgvel; ++ ++ Calculate_User_PosVel(time, geodetic, &obs_pos, &obs_vel); ++ ++ range.x=pos->x-obs_pos.x; ++ range.y=pos->y-obs_pos.y; ++ range.z=pos->z-obs_pos.z; ++ ++ /* Save these values globally for calculating squint angles later... */ ++ ++ rx=range.x; ++ ry=range.y; ++ rz=range.z; ++ ++ rgvel.x=vel->x-obs_vel.x; ++ rgvel.y=vel->y-obs_vel.y; ++ rgvel.z=vel->z-obs_vel.z; ++ ++ Magnitude(&range); ++ ++ sin_lat=sin(geodetic->lat); ++ cos_lat=cos(geodetic->lat); ++ sin_theta=sin(geodetic->theta); ++ cos_theta=cos(geodetic->theta); ++ top_s=sin_lat*cos_theta*range.x+sin_lat*sin_theta*range.y-cos_lat*range.z; ++ top_e=-sin_theta*range.x+cos_theta*range.y; ++ top_z=cos_lat*cos_theta*range.x+cos_lat*sin_theta*range.y+sin_lat*range.z; ++ azim=atan(-top_e/top_s); /* Azimuth */ ++ ++ if (top_s>0.0) ++ azim=azim+pi; ++ ++ if (azim<0.0) ++ azim=azim+twopi; ++ ++ el=ArcSin(top_z/range.w); ++ obs_set->x=azim; /* Azimuth (radians) */ ++ obs_set->y=el; /* Elevation (radians) */ ++ obs_set->z=range.w; /* Range (kilometers) */ ++ ++ /* Range Rate (kilometers/second) */ ++ ++ obs_set->w=Dot(&range,&rgvel)/range.w; ++ ++ /* Corrections for atmospheric refraction */ ++ /* Reference: Astronomical Algorithms by Jean Meeus, pp. 101-104 */ ++ /* Correction is meaningless when apparent elevation is below horizon */ ++ ++ /*** Temporary bypass for PREDICT-2.2.0 ***/ ++ ++ /* obs_set->y=obs_set->y+Radians((1.02/tan(Radians(Degrees(el)+10.3/(Degrees(el)+5.11))))/60); */ ++ ++ obs_set->y=el; ++ ++ /**** End bypass ****/ ++ ++ if (obs_set->y>=0.0) ++ SetFlag(VISIBLE_FLAG); ++ else { ++ obs_set->y=el; /* Reset to true elevation */ ++ ClearFlag(VISIBLE_FLAG); ++ } ++} ++ ++void Calculate_RADec(double time, vector_t *pos, vector_t *vel, geodetic_t *geodetic, vector_t *obs_set) ++{ ++ /* Reference: Methods of Orbit Determination by */ ++ /* Pedro Ramon Escobal, pp. 401-402 */ ++ ++ double phi, theta, sin_theta, cos_theta, sin_phi, cos_phi, az, el, ++ Lxh, Lyh, Lzh, Sx, Ex, Zx, Sy, Ey, Zy, Sz, Ez, Zz, Lx, Ly, ++ Lz, cos_delta, sin_alpha, cos_alpha; ++ ++ Calculate_Obs(time,pos,vel,geodetic,obs_set); ++ ++ if (isFlagSet(VISIBLE_FLAG)) { ++ az=obs_set->x; ++ el=obs_set->y; ++ phi=geodetic->lat; ++ theta=FMod2p(ThetaG_JD(time)+geodetic->lon); ++ sin_theta=sin(theta); ++ cos_theta=cos(theta); ++ sin_phi=sin(phi); ++ cos_phi=cos(phi); ++ Lxh=-cos(az)*cos(el); ++ Lyh=sin(az)*cos(el); ++ Lzh=sin(el); ++ Sx=sin_phi*cos_theta; ++ Ex=-sin_theta; ++ Zx=cos_theta*cos_phi; ++ Sy=sin_phi*sin_theta; ++ Ey=cos_theta; ++ Zy=sin_theta*cos_phi; ++ Sz=-cos_phi; ++ Ez=0.0; ++ Zz=sin_phi; ++ Lx=Sx*Lxh+Ex*Lyh+Zx*Lzh; ++ Ly=Sy*Lxh+Ey*Lyh+Zy*Lzh; ++ Lz=Sz*Lxh+Ez*Lyh+Zz*Lzh; ++ obs_set->y=ArcSin(Lz); /* Declination (radians) */ ++ cos_delta=sqrt(1.0-Sqr(Lz)); ++ sin_alpha=Ly/cos_delta; ++ cos_alpha=Lx/cos_delta; ++ obs_set->x=AcTan(sin_alpha,cos_alpha); /* Right Ascension (radians) */ ++ obs_set->x=FMod2p(obs_set->x); ++ } ++} ++ ++void bailout(string) ++char *string; ++{ ++ /* This function quits ncurses, resets and "beeps" ++ the terminal, and displays an error message (string) ++ when we need to bail out of the program in a hurry. */ ++ ++ beep(); ++ curs_set(1); ++ bkgdset(COLOR_PAIR(1)); ++ clear(); ++ refresh(); ++ endwin(); ++ fprintf(stderr,"*** predict: %s!\n",string); ++} ++ ++void TrackDataOut(antfd, elevation, azimuth) ++int antfd; ++double elevation, azimuth; ++{ ++ /* This function sends Azimuth and Elevation data ++ to an antenna tracker connected to the serial port */ ++ ++ int n, port; ++ char message[30]="\n"; ++ ++ port=antfd; ++ ++ sprintf(message, "AZ%3.1f EL%3.1f \x0D\x0A", azimuth,elevation); ++ n=write(port,message,strlen(message)); ++ ++ if (n<0) { ++ bailout("Error Writing To Antenna Port"); ++ exit(-1); ++ } ++} ++ ++int passivesock(char *service, char *protocol, int qlen) ++{ ++ /* This function opens the socket port */ ++ ++ struct servent *pse; ++ struct protoent *ppe; ++ struct sockaddr_in sin; ++ int sd, type; ++ ++ memset((char *)&sin, 0, sizeof(struct sockaddr_in)); ++ sin.sin_family=AF_INET; ++ sin.sin_addr.s_addr=INADDR_ANY; ++ ++ if ((pse=getservbyname(service,protocol))) ++ sin.sin_port=htons(ntohs((unsigned short)pse->s_port)+portbase); ++ ++ else if ((sin.sin_port=htons((unsigned short)atoi(service)))==0) { ++ bailout("Can't get service"); ++ exit(-1); ++ } ++ ++ if ((ppe=getprotobyname(protocol))==0) { ++ bailout("Can't get protocol"); ++ exit(-1); ++ } ++ ++ if (strcmp(protocol,"udp")==0) ++ type=SOCK_DGRAM; ++ else ++ type=SOCK_STREAM; ++ ++ sd=socket(PF_INET,type, ppe->p_proto); ++ ++ if (sd<0) { ++ bailout("Can't open socket"); ++ exit(-1); ++ } ++ ++ if (bind(sd,(struct sockaddr *)&sin,sizeof(sin))<0) { ++ bailout("Can't bind"); ++ exit(-1); ++ } ++ ++ if ((type=SOCK_STREAM && listen(s,qlen))<0) { ++ bailout("Listen fail"); ++ exit(-1); ++ } ++ ++ return sd; ++} ++ ++void socket_server(predict_name) ++char *predict_name; ++{ ++ /* This is the socket server code */ ++ ++ int i, j, n, sock; ++ socklen_t alen; ++ double dLat, dLong; /* parameters for PredictAt */ ++ struct sockaddr_in fsin; ++ char buf[80], buff[1000], satname[50], tempname[30], ok; ++ time_t t; ++ long nxtevt; ++ FILE *fd=NULL; ++ ++ /* Open a socket port at "predict" or netport if defined */ ++ ++ if (netport[0]==0) ++ strncpy(netport,"predict",7); ++ ++ sock=passivesock(netport,"udp",10); ++ alen=sizeof(fsin); ++ ++ /* This is the main loop for monitoring the socket ++ port and sending back replies to clients */ ++ ++ while (1) { ++ /* Get datagram from socket port */ ++ if ((n=recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr *)&fsin,&alen)) < 0) ++ exit (-1); ++ ++ buf[n]=0; ++ ok=0; ++ ++ /* Parse the command in the datagram */ ++ if ((strncmp("GET_SAT",buf,7)==0) && (strncmp("GET_SAT_POS",buf,11)!=0)) { ++ /* Parse "buf" for satellite name */ ++ for (i=0; buf[i]!=32 && buf[i]!=0 && i<39; i++); ++ ++ for (j=++i; buf[j]!='\n' && buf[j]!=0 && (j-i)<25; j++) ++ satname[j-i]=buf[j]; ++ ++ satname[j-i]=0; ++ ++ /* Do a simple search for the matching satellite name */ ++ ++ for (i=0; itwopi) ++ x-=twopi; ++ ++ return x; ++} ++ ++double PrimeAngle(x) ++double x; ++{ ++ /* This function is used in the FindMoon() function. */ ++ ++ x=x-360.0*floor(x/360.0); ++ return x; ++} ++ ++char *SubString(string,start,end) ++char *string, start, end; ++{ ++ /* This function returns a substring based on the starting ++ and ending positions provided. It is used heavily in ++ the AutoUpdate function when parsing 2-line element data. */ ++ ++ unsigned x, y; ++ ++ if (end>=start) { ++ for (x=start, y=0; x<=end && string[x]!=0; x++) ++ if (string[x]!=' ') { ++ temp[y]=string[x]; ++ y++; ++ } ++ ++ temp[y]=0; ++ return temp; ++ } else ++ return NULL; ++} ++ ++void CopyString(source, destination, start, end) ++char *source, *destination, start, end; ++{ ++ /* This function copies elements of the string "source" ++ bounded by "start" and "end" into the string "destination". */ ++ ++ unsigned j, k=0; ++ ++ for (j=start; j<=end; j++) ++ if (source[k]!=0) { ++ destination[j]=source[k]; ++ k++; ++ } ++} ++ ++char *Abbreviate(string,n) ++char *string; ++int n; ++{ ++ /* This function returns an abbreviated substring of the original, ++ including a '~' character if a non-blank character is chopped ++ out of the generated substring. n is the length of the desired ++ substring. It is used for abbreviating satellite names. */ ++ ++ strncpy(temp,(const char *)string,79); ++ ++ if (temp[n]!=0 && temp[n]!=32) { ++ temp[n-2]='~'; ++ temp[n-1]=temp[strlen(temp)-1]; ++ } ++ ++ temp[n]=0; ++ ++ return temp; ++} ++ ++char KepCheck(line1,line2) ++char *line1, *line2; ++{ ++ /* This function scans line 1 and line 2 of a NASA 2-Line element ++ set and returns a 1 if the element set appears to be valid or ++ a 0 if it does not. If the data survives this torture test, ++ it's a pretty safe bet we're looking at a valid 2-line ++ element set and not just some random text that might pass ++ as orbital data based on a simple checksum calculation alone. */ ++ ++ int x; ++ unsigned sum1, sum2; ++ ++ /* Compute checksum for each line */ ++ ++ for (x=0, sum1=0, sum2=0; x<=67; sum1+=val[(int)line1[x]], sum2+=val[(int)line2[x]], x++); ++ ++ /* Perform a "torture test" on the data */ ++ ++ x=(val[(int)line1[68]]^(sum1%10)) | (val[(int)line2[68]]^(sum2%10)) | ++ (line1[0]^'1') | (line1[1]^' ') | (line1[7]^'U') | ++ (line1[8]^' ') | (line1[17]^' ') | (line1[23]^'.') | ++ (line1[32]^' ') | (line1[34]^'.') | (line1[43]^' ') | ++ (line1[52]^' ') | (line1[61]^' ') | (line1[62]^'0') | ++ (line1[63]^' ') | (line2[0]^'2') | (line2[1]^' ') | ++ (line2[7]^' ') | (line2[11]^'.') | (line2[16]^' ') | ++ (line2[20]^'.') | (line2[25]^' ') | (line2[33]^' ') | ++ (line2[37]^'.') | (line2[42]^' ') | (line2[46]^'.') | ++ (line2[51]^' ') | (line2[54]^'.') | (line1[2]^line2[2]) | ++ (line1[3]^line2[3]) | (line1[4]^line2[4]) | ++ (line1[5]^line2[5]) | (line1[6]^line2[6]) | ++ (isdigit(line1[68]) ? 0 : 1) | (isdigit(line2[68]) ? 0 : 1) | ++ (isdigit(line1[18]) ? 0 : 1) | (isdigit(line1[19]) ? 0 : 1) | ++ (isdigit(line2[31]) ? 0 : 1) | (isdigit(line2[32]) ? 0 : 1); ++ ++ return (x ? 0 : 1); ++} ++ ++void InternalUpdate(x) ++int x; ++{ ++ /* Updates data in TLE structure based on ++ line1 and line2 stored in structure. */ ++ ++ double tempnum; ++ ++ strncpy(sat[x].designator,SubString(sat[x].line1,9,16),8); ++ sat[x].designator[9]=0; ++ sat[x].catnum=atol(SubString(sat[x].line1,2,6)); ++ sat[x].year=atoi(SubString(sat[x].line1,18,19)); ++ sat[x].refepoch=atof(SubString(sat[x].line1,20,31)); ++ tempnum=1.0e-5*atof(SubString(sat[x].line1,44,49)); ++ sat[x].nddot6=tempnum/pow(10.0,(sat[x].line1[51]-'0')); ++ tempnum=1.0e-5*atof(SubString(sat[x].line1,53,58)); ++ sat[x].bstar=tempnum/pow(10.0,(sat[x].line1[60]-'0')); ++ sat[x].setnum=atol(SubString(sat[x].line1,64,67)); ++ sat[x].incl=atof(SubString(sat[x].line2,8,15)); ++ sat[x].raan=atof(SubString(sat[x].line2,17,24)); ++ sat[x].eccn=1.0e-07*atof(SubString(sat[x].line2,26,32)); ++ sat[x].argper=atof(SubString(sat[x].line2,34,41)); ++ sat[x].meanan=atof(SubString(sat[x].line2,43,50)); ++ sat[x].meanmo=atof(SubString(sat[x].line2,52,62)); ++ sat[x].drag=atof(SubString(sat[x].line1,33,42)); ++ sat[x].orbitnum=atof(SubString(sat[x].line2,63,67)); ++} ++ ++char *noradEvalue(value) ++double value; ++{ ++ /* Converts numeric values to E notation used in NORAD TLEs */ ++ ++ char string[15]; ++ ++ sprintf(string,"%11.4e",value*10.0); ++ ++ output[0]=string[0]; ++ output[1]=string[1]; ++ output[2]=string[3]; ++ output[3]=string[4]; ++ output[4]=string[5]; ++ output[5]=string[6]; ++ output[6]='-'; ++ output[7]=string[10]; ++ output[8]=0; ++ ++ return output; ++} ++ ++void Data2TLE(x) ++int x; ++{ ++ /* This function converts orbital data held in the numeric ++ portion of the sat tle structure to ASCII TLE format, ++ and places the result in ASCII portion of the structure. */ ++ ++ int i; ++ char string[15], line1[70], line2[70]; ++ unsigned sum; ++ ++ /* Fill lines with blanks */ ++ ++ for (i=0; i<70; line1[i]=32, line2[i]=32, i++); ++ ++ line1[69]=0; ++ line2[69]=0; ++ ++ /* Insert static characters */ ++ ++ line1[0]='1'; ++ line1[7]='U'; /* Unclassified */ ++ line2[0]='2'; ++ ++ line1[62]='0'; /* For publically released TLEs */ ++ ++ /* Insert orbital data */ ++ ++ sprintf(string,"%05ld",sat[x].catnum); ++ CopyString(string,line1,2,6); ++ CopyString(string,line2,2,6); ++ ++ CopyString(sat[x].designator,line1,9,16); ++ ++ sprintf(string,"%02d",sat[x].year); ++ CopyString(string,line1,18,19); ++ ++ sprintf(string,"%12.8f",sat[x].refepoch); ++ CopyString(string,line1,20,32); ++ ++ sprintf(string,"%.9f",fabs(sat[x].drag)); ++ ++ CopyString(string,line1,33,42); ++ ++ if (sat[x].drag<0.0) ++ line1[33]='-'; ++ else ++ line1[33]=32; ++ ++ CopyString(noradEvalue(sat[x].nddot6),line1,44,51); ++ CopyString(noradEvalue(sat[x].bstar),line1,53,60); ++ ++ sprintf(string,"%4lu",sat[x].setnum); ++ CopyString(string,line1,64,67); ++ ++ sprintf(string,"%9.4f",sat[x].incl); ++ CopyString(string,line2,7,15); ++ ++ sprintf(string,"%9.4f",sat[x].raan); ++ CopyString(string,line2,16,24); ++ ++ sprintf(string,"%13.12f",sat[x].eccn); ++ ++ /* Erase eccentricity's decimal point */ ++ ++ for (i=2; i<=9; string[i-2]=string[i], i++); ++ ++ CopyString(string,line2,26,32); ++ ++ sprintf(string,"%9.4f",sat[x].argper); ++ CopyString(string,line2,33,41); ++ ++ sprintf(string,"%9.5f",sat[x].meanan); ++ CopyString(string,line2,43,50); ++ ++ sprintf(string,"%12.9f",sat[x].meanmo); ++ CopyString(string,line2,52,62); ++ ++ sprintf(string,"%5lu",sat[x].orbitnum); ++ CopyString(string,line2,63,67); ++ ++ /* Compute and insert checksum for line 1 and line 2 */ ++ ++ for (i=0, sum=0; i<=67; sum+=val[(int)line1[i]], i++); ++ ++ line1[68]=(sum%10)+'0'; ++ ++ for (i=0, sum=0; i<=67; sum+=val[(int)line2[i]], i++); ++ ++ line2[68]=(sum%10)+'0'; ++ ++ line1[69]=0; ++ line2[69]=0; ++ ++ strcpy(sat[x].line1,line1); ++ strcpy(sat[x].line2,line2); ++} ++ ++double ReadBearing(input) ++char *input; ++{ ++ /* This function takes numeric input in the form of a character ++ string, and returns an equivalent bearing in degrees as a ++ decimal number (double). The input may either be expressed ++ in decimal format (74.2467) or degree, minute, second ++ format (74 14 48). This function also safely handles ++ extra spaces found either leading, trailing, or ++ embedded within the numbers expressed in the ++ input string. Decimal seconds are permitted. */ ++ ++ char string[20]; ++ double bearing=0.0, seconds; ++ int a, b, length, degrees, minutes; ++ ++ /* Copy "input" to "string", and ignore any extra ++ spaces that might be present in the process. */ ++ ++ string[0]=0; ++ length=strlen(input); ++ ++ for (a=0, b=0; a360.0 || bearing<-360.0) ++ bearing=0.0; ++ ++ return bearing; ++} ++ ++char ReadDataFiles() ++{ ++ /* This function reads "predict.qth" and "predict.tle" ++ files into memory. Return values are as follows: ++ ++ 0 : No files were loaded ++ 1 : Only the qth file was loaded ++ 2 : Only the tle file was loaded ++ 3 : Both files were loaded successfully */ ++ ++ FILE *fd; ++ long catnum; ++ unsigned char dayofweek; ++ int x=0, y, entry=0, max_entries=10, transponders=0; ++ char flag=0, match, name[80], line1[80], line2[80]; ++ ++ fd=fopen(qthfile,"r"); ++ ++ if (fd!=NULL) { ++ fgets(qth.callsign,16,fd); ++ qth.callsign[strlen(qth.callsign)-1]=0; ++ fscanf(fd,"%lf", &qth.stnlat); ++ fscanf(fd,"%lf", &qth.stnlong); ++ fscanf(fd,"%d", &qth.stnalt); ++ fscanf(fd,"%d", &qth.tzoffset); ++ fclose(fd); ++ ++ obs_geodetic.lat=qth.stnlat*deg2rad; ++ obs_geodetic.lon=-qth.stnlong*deg2rad; ++ obs_geodetic.alt=((double)qth.stnalt)/1000.0; ++ obs_geodetic.theta=0.0; ++ ++ flag=1; ++ } ++ ++ fd=fopen(tlefile,"r"); ++ ++ if (fd!=NULL) { ++ while (x "); ++ refresh(); ++ wgetnstr(stdscr,filename,49); ++ clear(); ++ curs_set(0); ++ } else ++ strcpy(filename,string); ++ ++ /* Prevent "." and ".." from being used as a ++ filename otherwise strange things happen. */ ++ ++ if (strlen(filename)==0 || strncmp(filename,".",1)==0 || strncmp(filename,"..",2)==0) ++ return 0; ++ ++ fd=fopen(filename,"r"); ++ ++ if (interactive && fd==NULL) { ++ bkgdset(COLOR_PAIR(5)); ++ clear(); ++ move(12,0); ++ ++ for (i=47; i>strlen(filename); i-=2) ++ printw(" "); ++ ++ printw("*** ERROR: File \"%s\" not found! ***\n",filename); ++ beep(); ++ attrset(COLOR_PAIR(7)|A_BOLD); ++ AnyKey(); ++ } ++ ++ if (fd!=NULL) { ++ success=1; ++ ++ fgets(str0,75,fd); ++ fgets(str1,75,fd); ++ fgets(str2,75,fd); ++ ++ do { ++ if (KepCheck(str1,str2)) { ++ /* We found a valid TLE! ++ Copy strings str1 and ++ str2 into line1 and line2 */ ++ ++ strncpy(line1,str1,75); ++ strncpy(line2,str2,75); ++ kepcount++; ++ ++ /* Scan for object number in datafile to see ++ if this is something we're interested in */ ++ ++ for (i=0; (i= epoch in data file ++ so we don't overwrite current data with older ++ data. */ ++ ++ if (tle_epoch>=database_epoch) { ++ if (saveflag==0) { ++ if (interactive) { ++ ++ bkgdset(COLOR_PAIR(3)|A_BOLD); ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Orbital Data : Updating..... "); ++ mvprintw(2,0," "); ++ ++ attrset(COLOR_PAIR(2)); ++ refresh(); ++ move(4,0); ++ } ++ saveflag=1; ++ } ++ ++ if (interactive) { ++ bkgdset(COLOR_PAIR(3)); ++ printw(" %-8s ",sat[i].name); ++ } ++ ++ savecount++; ++ ++ /* Copy TLE data into the sat data structure */ ++ ++ strncpy(sat[i].line1,line1,69); ++ strncpy(sat[i].line2,line2,69); ++ InternalUpdate(i); ++ } ++ } ++ ++ fgets(str0,75,fd); ++ fgets(str1,75,fd); ++ fgets(str2,75,fd); ++ } else { ++ strcpy(str0,str1); ++ strcpy(str1,str2); ++ fgets(str2,75,fd); ++ } ++ ++ } while (feof(fd)==0); ++ ++ fclose(fd); ++ ++ if (interactive) { ++ bkgdset(COLOR_PAIR(2)); ++ ++ if (kepcount==1) ++ mvprintw(LINES-3,2,"Only 1 NASA Two Line Element was found."); ++ else ++ mvprintw(LINES-3,2,"%3u NASA Two Line Elements were read.",kepcount); ++ ++ if (saveflag) { ++ if (savecount==1) ++ mvprintw(LINES-2,2,"Only 1 satellite was updated."); ++ else { ++ if (savecount==totalsats) ++ mvprintw(LINES-2,2,"All satellites were updated!"); ++ else ++ mvprintw(LINES-2,2,"%3u out of %3u satellites were updated.",savecount,totalsats); ++ } ++ } ++ ++ refresh(); ++ } ++ } ++ ++ if (interactive) { ++ noecho(); ++ ++ if (strlen(filename) && fd!=NULL) { ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ AnyKey(); ++ } ++ } ++ ++ if (saveflag) ++ SaveTLE(); ++ } while (success==0 && interactive); ++ ++ return (saveflag ? 0 : -1); ++} ++ ++int Select() ++{ ++ ITEM **my_items; ++ int c; ++ MENU *my_menu; ++ WINDOW *my_menu_win; ++ int n_choices, i, j; ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Satellite Selector "); ++ mvprintw(2,0," "); ++ ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw( 5,46,"Use cursor keys to move up/down"); ++ mvprintw( 6,46,"the list and then select with "); ++ mvprintw( 7,46,"the 'Enter' key."); ++ mvprintw( 9,46,"Press 'q' to return to menu."); ++ ++ if (totalsats >= maxsats) ++ mvprintw(LINES-3,46,"Truncated to %d satellites",maxsats); ++ else ++ mvprintw(LINES-3,46,"%d satellites",totalsats); ++ ++ /* Create items */ ++ n_choices = ARRAY_SIZE(sat); ++ my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *)); ++ for(i = 0; i < n_choices; ++i) ++ my_items[i] = new_item(sat[i].name, sat[i].designator); ++ ++ /* Create menu */ ++ my_menu = new_menu((ITEM **)my_items); ++ ++ /* Set menu option not to show the description */ ++// menu_opts_off(my_menu, O_SHOWDESC); ++ ++ /* Create the window to be associated with the menu */ ++ my_menu_win = newwin(LINES-5, 40, 4, 4); ++ keypad(my_menu_win, TRUE); ++ ++ set_menu_back(my_menu,COLOR_PAIR(1)); ++ set_menu_fore(my_menu,COLOR_PAIR(5)|A_BOLD); ++ ++ wattrset(my_menu_win, COLOR_PAIR(4)); ++ ++ /* Set main window and sub window */ ++ set_menu_win(my_menu, my_menu_win); ++ set_menu_sub(my_menu, derwin(my_menu_win, LINES-7, 38, 2, 1)); ++ set_menu_format(my_menu, LINES-9, 1); ++ ++ /* Set menu mark to the string " * " */ ++ set_menu_mark(my_menu, " * "); ++ ++ /* Print a border around the main window and print a title */ ++#if !defined (__CYGWIN32__) ++ box(my_menu_win, 0, 0); ++#endif ++ ++ /* Post the menu */ ++ post_menu(my_menu); ++ ++ refresh(); ++ wrefresh(my_menu_win); ++ ++ while((c = wgetch(my_menu_win)) != 10) { ++ switch(c) { ++ case 'q': ++ return -1; ++ case KEY_DOWN: ++ menu_driver(my_menu, REQ_DOWN_ITEM); ++ break; ++ case KEY_UP: ++ menu_driver(my_menu, REQ_UP_ITEM); ++ break; ++ case KEY_NPAGE: ++ menu_driver(my_menu, REQ_SCR_DPAGE); ++ break; ++ case KEY_PPAGE: ++ menu_driver(my_menu, REQ_SCR_UPAGE); ++ break; ++ case 10: /* Enter */ ++ pos_menu_cursor(my_menu); ++ break; ++ } ++ wrefresh(my_menu_win); ++ } ++ ++ for (i=0, j=0; i> "); ++ curs_set(1); ++ refresh(); ++ echo(); ++ string[0]=0; ++ wgetnstr(stdscr,string,29); ++ curs_set(0); ++ noecho(); ++ ++ if (strlen(string)!=0) ++ strcpy(line,string); ++ else ++ /* Select `NOW' */ ++ return(CurrentDaynum()); ++ ++ if (strlen(line)==7) { ++ line[7]=' '; ++ line[8]='0'; ++ line[9]='0'; ++ line[10]=':'; ++ line[11]='0'; ++ line[12]='0'; ++ line[13]=':'; ++ line[14]='0'; ++ line[15]='0'; ++ line[16]=0; ++ } ++ ++ /* Check Day */ ++ good = (isdigit(line[0]) && isdigit(line[1])) ? 1 : 0; ++ ++ /* Month */ ++ good = (good && isalpha(line[2]) && isalpha(line[3]) && isalpha(line[4])) ? 1 : 0; ++ ++ /* Year */ ++ good = (good && isdigit(line[5]) && isdigit(line[6]) && (line[7]==' ')) ? 1 : 0; ++ ++ /* Hour */ ++ good = (good && isdigit(line[8]) && isdigit(line[9]) && (line[10]==':')) ? 1 : 0; ++ ++ /* Minute */ ++ good = (good && isdigit(line[11]) && isdigit(line[12]) && (line[13]==':')) ? 1 : 0; ++ ++ /* Seconds */ ++ good = (good && isdigit(line[14]) && isdigit(line[15])) ? 1 : 0; ++ ++ if (good) { ++ /* Decode Day */ ++ dd=10*(line[0]-'0')+line[1]-'0'; ++ ++ /* Decode Month Number */ ++ line[2]=toupper(line[2]); ++ line[3]=tolower(line[3]); ++ line[4]=tolower(line[4]); ++ ++ mon[0]=line[2]; ++ mon[1]=line[3]; ++ mon[2]=line[4]; ++ mon[3]=0; ++ ++ for (mm=0; (mm<12 && strcmp(mon,month[mm])!=0); mm++); ++ ++ mm++; ++ ++ good=(mm>12) ? 0 : 1; ++ } ++ ++ if (good==0) ++ beep(); ++ ++ } while (good==0 && bozo_count<6); ++ ++ if (good==0) { ++ /* If the user can't enter the starting date/time ++ correctly after several attempts, then the user ++ is a "bozo" and obviously can't follow directions. */ ++ ++ bailout("Too Many Errors"); ++ exit(-1); ++ } ++ ++ /* Decode Year */ ++ yy=10*(line[5]-'0')+line[6]-'0'; ++ ++ /* Decode Time */ ++ for (x=8; x<16; x++) ++ string[x-8]=line[x]; ++ ++ string[8]=0; ++ ++ hr=10*(line[8]-'0')+line[9]-'0'; ++ min=10*(line[11]-'0')+line[12]-'0'; ++ sec=10*(line[14]-'0')+line[15]-'0'; ++ ++ return ((double)DayNum(mm,dd,yy)+((hr/24.0)+(min/1440.0)+(sec/86400.0))); ++} ++ ++void FindMoon(daynum) ++double daynum; ++{ ++ /* This function determines the position of the moon, including ++ the azimuth and elevation headings, relative to the latitude ++ and longitude of the tracking station. This code was derived ++ from a Javascript implementation of the Meeus method for ++ determining the exact position of the Moon found at: ++ http://www.geocities.com/s_perona/ingles/poslun.htm. */ ++ ++ double jd, ss, t, t1, t2, t3, d, ff, l1, m, m1, ex, om, l, ++ b, w1, w2, bt, p, lm, h, ra, dec, z, ob, n, e, el, ++ az, teg, th, mm, dv; ++ ++ jd=daynum+2444238.5; ++ ++ t=(jd-2415020.0)/36525.0; ++ t2=t*t; ++ t3=t2*t; ++ l1=270.434164+481267.8831*t-0.001133*t2+0.0000019*t3; ++ m=358.475833+35999.0498*t-0.00015*t2-0.0000033*t3; ++ m1=296.104608+477198.8491*t+0.009192*t2+0.0000144*t3; ++ d=350.737486+445267.1142*t-0.001436*t2+0.0000019*t3; ++ ff=11.250889+483202.0251*t-0.003211*t2-0.0000003*t3; ++ om=259.183275-1934.142*t+0.002078*t2+0.0000022*t3; ++ om=om*deg2rad; ++ ++ /* Additive terms */ ++ ++ l1=l1+0.000233*sin((51.2+20.2*t)*deg2rad); ++ ss=0.003964*sin((346.56+132.87*t-0.0091731*t2)*deg2rad); ++ l1=l1+ss+0.001964*sin(om); ++ m=m-0.001778*sin((51.2+20.2*t)*deg2rad); ++ m1=m1+0.000817*sin((51.2+20.2*t)*deg2rad); ++ m1=m1+ss+0.002541*sin(om); ++ d=d+0.002011*sin((51.2+20.2*t)*deg2rad); ++ d=d+ss+0.001964*sin(om); ++ ff=ff+ss-0.024691*sin(om); ++ ff=ff-0.004328*sin(om+(275.05-2.3*t)*deg2rad); ++ ex=1.0-0.002495*t-0.00000752*t2; ++ om=om*deg2rad; ++ ++ l1=PrimeAngle(l1); ++ m=PrimeAngle(m); ++ m1=PrimeAngle(m1); ++ d=PrimeAngle(d); ++ ff=PrimeAngle(ff); ++ om=PrimeAngle(om); ++ ++ m=m*deg2rad; ++ m1=m1*deg2rad; ++ d=d*deg2rad; ++ ff=ff*deg2rad; ++ ++ /* Ecliptic Longitude */ ++ ++ l=l1+6.28875*sin(m1)+1.274018*sin(2.0*d-m1)+0.658309*sin(2.0*d); ++ l=l+0.213616*sin(2.0*m1)-ex*0.185596*sin(m)-0.114336*sin(2.0*ff); ++ l=l+0.058793*sin(2.0*d-2.0*m1)+ex*0.057212*sin(2.0*d-m-m1)+0.05332*sin(2.0*d+m1); ++ l=l+ex*0.045874*sin(2.0*d-m)+ex*0.041024*sin(m1-m)-0.034718*sin(d); ++ l=l-ex*0.030465*sin(m+m1)+0.015326*sin(2.0*d-2.0*ff)-0.012528*sin(2.0*ff+m1); ++ ++ l=l-0.01098*sin(2.0*ff-m1)+0.010674*sin(4.0*d-m1)+0.010034*sin(3.0*m1); ++ l=l+0.008548*sin(4.0*d-2.0*m1)-ex*0.00791*sin(m-m1+2.0*d)-ex*0.006783*sin(2.0*d+m); ++ ++ l=l+0.005162*sin(m1-d)+ex*0.005*sin(m+d)+ex*0.004049*sin(m1-m+2.0*d); ++ l=l+0.003996*sin(2.0*m1+2.0*d)+0.003862*sin(4.0*d)+0.003665*sin(2.0*d-3.0*m1); ++ ++ l=l+ex*0.002695*sin(2.0*m1-m)+0.002602*sin(m1-2.0*ff-2.0*d)+ex*0.002396*sin(2.0*d-m-2.0*m1); ++ ++ l=l-0.002349*sin(m1+d)+ex*ex*0.002249*sin(2.0*d-2.0*m)-ex*0.002125*sin(2.0*m1+m); ++ ++ l=l-ex*ex*0.002079*sin(2.0*m)+ex*ex*0.002059*sin(2.0*d-m1-2.0*m)-0.001773*sin(m1+2.0*d-2.0*ff); ++ ++ l=l+ex*0.00122*sin(4.0*d-m-m1)-0.00111*sin(2.0*m1+2.0*ff)+0.000892*sin(m1-3.0*d); ++ ++ l=l-ex*0.000811*sin(m+m1+2.0*d)+ex*0.000761*sin(4.0*d-m-2.0*m1)+ex*ex*.000717*sin(m1-2.0*m); ++ ++ l=l+ex*ex*0.000704*sin(m1-2.0*m-2.0*d)+ex*0.000693*sin(m-2.0*m1+2.0*d)+ex*0.000598*sin(2.0*d-m-2.0*ff)+0.00055*sin(m1+4.0*d); ++ ++ l=l+0.000538*sin(4.0*m1)+ex*0.000521*sin(4.0*d-m)+0.000486*sin(2.0*m1-d); ++ ++ l=l-0.001595*sin(2.0*ff+2.0*d); ++ ++ /* Ecliptic latitude */ ++ ++ b=5.128189*sin(ff)+0.280606*sin(m1+ff)+0.277693*sin(m1-ff)+0.173238*sin(2.0*d-ff); ++ b=b+0.055413*sin(2.0*d+ff-m1)+0.046272*sin(2.0*d-ff-m1)+0.032573*sin(2.0*d+ff); ++ ++ b=b+0.017198*sin(2.0*m1+ff)+9.266999e-03*sin(2.0*d+m1-ff)+0.008823*sin(2.0*m1-ff); ++ b=b+ex*0.008247*sin(2.0*d-m-ff)+0.004323*sin(2.0*d-ff-2.0*m1)+0.0042*sin(2.0*d+ff+m1); ++ ++ b=b+ex*0.003372*sin(ff-m-2.0*d)+ex*0.002472*sin(2.0*d+ff-m-m1)+ex*0.002222*sin(2.0*d+ff-m); ++ ++ b=b+0.002072*sin(2.0*d-ff-m-m1)+ex*0.001877*sin(ff-m+m1)+0.001828*sin(4.0*d-ff-m1); ++ ++ b=b-ex*0.001803*sin(ff+m)-0.00175*sin(3.0*ff)+ex*0.00157*sin(m1-m-ff)-0.001487*sin(ff+d)-ex*0.001481*sin(ff+m+m1)+ex*0.001417*sin(ff-m-m1)+ex*0.00135*sin(ff-m)+0.00133*sin(ff-d); ++ ++ b=b+0.001106*sin(ff+3.0*m1)+0.00102*sin(4.0*d-ff)+0.000833*sin(ff+4.0*d-m1); ++ ++ b=b+0.000781*sin(m1-3.0*ff)+0.00067*sin(ff+4.0*d-2.0*m1)+0.000606*sin(2.0*d-3.0*ff); ++ ++ b=b+0.000597*sin(2.0*d+2.0*m1-ff)+ex*0.000492*sin(2.0*d+m1-m-ff)+0.00045*sin(2.0*m1-ff-2.0*d); ++ ++ b=b+0.000439*sin(3.0*m1-ff)+0.000423*sin(ff+2.0*d+2.0*m1)+0.000422*sin(2.0*d-ff-3.0*m1); ++ ++ b=b-ex*0.000367*sin(m+ff+2.0*d-m1)-ex*0.000353*sin(m+ff+2.0*d)+0.000331*sin(ff+4.0*d); ++ ++ b=b+ex*0.000317*sin(2.0*d+ff-m+m1)+ex*ex*0.000306*sin(2.0*d-2.0*m-ff)-0.000283*sin(m1+3.0*ff); ++ ++ w1=0.0004664*cos(om*deg2rad); ++ w2=0.0000754*cos((om+275.05-2.3*t)*deg2rad); ++ bt=b*(1.0-w1-w2); ++ ++ /* Parallax calculations */ ++ ++ p=0.950724+0.051818*cos(m1)+0.009531*cos(2.0*d-m1)+0.007843*cos(2.0*d)+0.002824*cos(2.0*m1)+0.000857*cos(2.0*d+m1)+ex*0.000533*cos(2.0*d-m)+ex*0.000401*cos(2.0*d-m-m1); ++ ++ p=p+0.000173*cos(3.0*m1)+0.000167*cos(4.0*d-m1)-ex*0.000111*cos(m)+0.000103*cos(4.0*d-2.0*m1)-0.000084*cos(2.0*m1-2.0*d)-ex*0.000083*cos(2.0*d+m)+0.000079*cos(2.0*d+2.0*m1); ++ ++ p=p+0.000072*cos(4.0*d)+ex*0.000064*cos(2.0*d-m+m1)-ex*0.000063*cos(2.0*d+m-m1); ++ ++ p=p+ex*0.000041*cos(m+d)+ex*0.000035*cos(2.0*m1-m)-0.000033*cos(3.0*m1-2.0*d); ++ ++ p=p-0.00003*cos(m1+d)-0.000029*cos(2.0*ff-2.0*d)-ex*0.000029*cos(2.0*m1+m); ++ ++ p=p+ex*ex*0.000026*cos(2.0*d-2.0*m)-0.000023*cos(2.0*ff-2.0*d+m1)+ex*0.000019*cos(4.0*d-m-m1); ++ ++ b=bt*deg2rad; ++ lm=l*deg2rad; ++ moon_dx=3.0/(pi*p); ++ ++ /* Semi-diameter calculation */ ++ /* sem=10800.0*asin(0.272488*p*deg2rad)/pi; */ ++ ++ /* Convert ecliptic coordinates to equatorial coordinates */ ++ ++ z=(jd-2415020.5)/365.2422; ++ ob=23.452294-(0.46845*z+5.9e-07*z*z)/3600.0; ++ ob=ob*deg2rad; ++ dec=asin(sin(b)*cos(ob)+cos(b)*sin(ob)*sin(lm)); ++ ra=acos(cos(b)*cos(lm)/cos(dec)); ++ ++ if (lm>pi) ++ ra=twopi-ra; ++ ++ /* ra = right ascension */ ++ /* dec = declination */ ++ ++ n=qth.stnlat*deg2rad; /* North latitude of tracking station */ ++ e=-qth.stnlong*deg2rad; /* East longitude of tracking station */ ++ ++ /* Find siderial time in radians */ ++ ++ t=(jd-2451545.0)/36525.0; ++ teg=280.46061837+360.98564736629*(jd-2451545.0)+(0.000387933*t-t*t/38710000.0)*t; ++ ++ while (teg>360.0) ++ teg-=360.0; ++ ++ th=FixAngle((teg-qth.stnlong)*deg2rad); ++ h=th-ra; ++ ++ az=atan2(sin(h),cos(h)*sin(n)-tan(dec)*cos(n))+pi; ++ el=asin(sin(n)*sin(dec)+cos(n)*cos(dec)*cos(h)); ++ ++ moon_az=az/deg2rad; ++ moon_el=el/deg2rad; ++ ++ attrset(COLOR_PAIR(4)|A_REVERSE|A_BOLD); ++ mvprintw(20,70," Moon "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ if (moon_el > 0.0) ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ else ++ attrset(COLOR_PAIR(2)); ++ mvprintw(21,70,"%-7.2fAz",moon_az); ++ mvprintw(22,70,"%+-6.2f El",moon_el); ++ ++ /* Radial velocity approximation. This code was derived ++ from "Amateur Radio Software", by John Morris, GM4ANB, ++ published by the RSGB in 1985. */ ++ ++ mm=FixAngle(1.319238+daynum*0.228027135); /* mean moon position */ ++ t2=0.10976; ++ t1=mm+t2*sin(mm); ++ dv=0.01255*moon_dx*moon_dx*sin(t1)*(1.0+t2*cos(mm)); ++ dv=dv*4449.0; ++ t1=6378.0; ++ t2=384401.0; ++ t3=t1*t2*(cos(dec)*cos(n)*sin(h)); ++ t3=t3/sqrt(t2*t2-t2*t1*sin(el)); ++ moon_dv=dv+t3*0.0753125; ++ ++ moon_dec=dec/deg2rad; ++ moon_ra=ra/deg2rad; ++ moon_gha=teg-moon_ra; ++ ++ if (moon_gha<0.0) ++ moon_gha+=360.0; ++} ++ ++void FindSun(daynum) ++double daynum; ++{ ++ /* This function finds the position of the Sun */ ++ ++ /* Zero vector for initializations */ ++ vector_t zero_vector={0,0,0,0}; ++ ++ /* Solar ECI position vector */ ++ vector_t solar_vector=zero_vector; ++ ++ /* Solar observed azi and ele vector */ ++ vector_t solar_set=zero_vector; ++ ++ /* Solar right ascension and declination vector */ ++ vector_t solar_rad=zero_vector; ++ ++ /* Solar lat, long, alt vector */ ++ geodetic_t solar_latlonalt; ++ ++ jul_utc=daynum+2444238.5; ++ ++ Calculate_Solar_Position(jul_utc, &solar_vector); ++ Calculate_Obs(jul_utc, &solar_vector, &zero_vector, &obs_geodetic, &solar_set); ++ sun_azi=Degrees(solar_set.x); ++ sun_ele=Degrees(solar_set.y); ++ sun_range=1.0+((solar_set.z-AU)/AU); ++ sun_range_rate=1000.0*solar_set.w; ++ ++ Calculate_LatLonAlt(jul_utc, &solar_vector, &solar_latlonalt); ++ ++ sun_lat=Degrees(solar_latlonalt.lat); ++ sun_lon=360.0-Degrees(solar_latlonalt.lon); ++ ++ Calculate_RADec(jul_utc, &solar_vector, &zero_vector, &obs_geodetic, &solar_rad); ++ ++ sun_ra=Degrees(solar_rad.x); ++ sun_dec=Degrees(solar_rad.y); ++} ++ ++void PreCalc(x) ++int x; ++{ ++ /* This function copies TLE data from PREDICT's sat structure ++ to the SGP4/SDP4's single dimensioned tle structure, and ++ prepares the tracking code for the update. */ ++ ++ strcpy(tle.sat_name,sat[x].name); ++ strcpy(tle.idesg,sat[x].designator); ++ tle.catnr=sat[x].catnum; ++ tle.epoch=(1000.0*(double)sat[x].year)+sat[x].refepoch; ++ tle.xndt2o=sat[x].drag; ++ tle.xndd6o=sat[x].nddot6; ++ tle.bstar=sat[x].bstar; ++ tle.xincl=sat[x].incl; ++ tle.xnodeo=sat[x].raan; ++ tle.eo=sat[x].eccn; ++ tle.omegao=sat[x].argper; ++ tle.xmo=sat[x].meanan; ++ tle.xno=sat[x].meanmo; ++ tle.revnum=sat[x].orbitnum; ++ ++ if (sat_db[x].squintflag) { ++ calc_squint=1; ++ alat=deg2rad*sat_db[x].alat; ++ alon=deg2rad*sat_db[x].alon; ++ } else ++ calc_squint=0; ++ ++ /* Clear all flags */ ++ ++ ClearFlag(ALL_FLAGS); ++ ++ /* Select ephemeris type. This function will set or clear the ++ DEEP_SPACE_EPHEM_FLAG depending on the TLE parameters of the ++ satellite. It will also pre-process tle members for the ++ ephemeris functions SGP4 or SDP4, so this function must ++ be called each time a new tle set is used. */ ++ ++ select_ephemeris(&tle); ++} ++ ++void Calc() ++{ ++ /* This is the stuff we need to do repetitively... */ ++ ++ /* Zero vector for initializations */ ++ vector_t zero_vector={0,0,0,0}; ++ ++ /* Satellite position and velocity vectors */ ++ vector_t vel=zero_vector; ++ vector_t pos=zero_vector; ++ ++ /* Satellite Az, El, Range, Range rate */ ++ vector_t obs_set; ++ ++ /* Solar ECI position vector */ ++ vector_t solar_vector=zero_vector; ++ ++ /* Solar observed azi and ele vector */ ++ vector_t solar_set; ++ ++ /* Satellite's predicted geodetic position */ ++ geodetic_t sat_geodetic; ++ ++ jul_utc=daynum+2444238.5; ++ ++ /* Convert satellite's epoch time to Julian */ ++ /* and calculate time since epoch in minutes */ ++ ++ jul_epoch=Julian_Date_of_Epoch(tle.epoch); ++ tsince=(jul_utc-jul_epoch)*xmnpda; ++ age=jul_utc-jul_epoch; ++ ++ /* Copy the ephemeris type in use to ephem string. */ ++ ++ if (isFlagSet(DEEP_SPACE_EPHEM_FLAG)) ++ strcpy(ephem,"SDP4"); ++ else ++ strcpy(ephem,"SGP4"); ++ ++ /* Call NORAD routines according to deep-space flag. */ ++ ++ if (isFlagSet(DEEP_SPACE_EPHEM_FLAG)) ++ SDP4(tsince, &tle, &pos, &vel); ++ else ++ SGP4(tsince, &tle, &pos, &vel); ++ ++ /* Scale position and velocity vectors to km and km/sec */ ++ ++ Convert_Sat_State(&pos, &vel); ++ ++ /* Calculate velocity of satellite */ ++ ++ Magnitude(&vel); ++ sat_vel=vel.w; ++ ++ /** All angles in rads. Distance in km. Velocity in km/s **/ ++ /* Calculate satellite Azi, Ele, Range and Range-rate */ ++ ++ Calculate_Obs(jul_utc, &pos, &vel, &obs_geodetic, &obs_set); ++ ++ /* Calculate satellite Lat North, Lon East and Alt. */ ++ ++ Calculate_LatLonAlt(jul_utc, &pos, &sat_geodetic); ++ ++ /* Calculate squint angle */ ++ ++ if (calc_squint) ++ squint=(acos(-(ax*rx+ay*ry+az*rz)/obs_set.z))/deg2rad; ++ ++ /* Calculate solar position and satellite eclipse depth. */ ++ /* Also set or clear the satellite eclipsed flag accordingly. */ ++ ++ Calculate_Solar_Position(jul_utc, &solar_vector); ++ Calculate_Obs(jul_utc, &solar_vector, &zero_vector, &obs_geodetic, &solar_set); ++ ++ if (Sat_Eclipsed(&pos, &solar_vector, &eclipse_depth)) ++ SetFlag(SAT_ECLIPSED_FLAG); ++ else ++ ClearFlag(SAT_ECLIPSED_FLAG); ++ ++ if (isFlagSet(SAT_ECLIPSED_FLAG)) ++ sat_sun_status=0; /* Eclipse */ ++ else ++ sat_sun_status=1; /* In sunlight */ ++ ++ /* Convert satellite and solar data */ ++ sat_azi=Degrees(obs_set.x); ++ sat_ele=Degrees(obs_set.y); ++ sat_range=obs_set.z; ++ sat_range_rate=obs_set.w; ++ sat_lat=Degrees(sat_geodetic.lat); ++ sat_lon=Degrees(sat_geodetic.lon); ++ sat_alt=sat_geodetic.alt; ++ ++ fk=12756.33*acos(xkmper/(xkmper+sat_alt)); ++ fm=fk/1.609344; ++ ++ rv=(long)floor((tle.xno*xmnpda/twopi+age*tle.bstar*ae)*age+tle.xmo/twopi)+tle.revnum; ++ ++ sun_azi=Degrees(solar_set.x); ++ sun_ele=Degrees(solar_set.y); ++ ++ irk=(long)rint(sat_range); ++ isplat=(int)rint(sat_lat); ++ isplong=(int)rint(360.0-sat_lon); ++ iaz=(int)rint(sat_azi); ++ iel=(int)rint(sat_ele); ++ ma256=(int)rint(256.0*(phase/twopi)); ++ ++ if (sat_sun_status) { ++ if (sun_ele<=-12.0 && rint(sat_ele)>=0.0) ++ findsun='+'; ++ else ++ findsun='*'; ++ } else ++ findsun=' '; ++} ++ ++char AosHappens(x) ++int x; ++{ ++ /* This function returns a 1 if the satellite pointed to by ++ "x" can ever rise above the horizon of the ground station. */ ++ ++ double lin, sma, apogee; ++ ++ if (sat[x].meanmo==0.0) ++ return 0; ++ else { ++ lin=sat[x].incl; ++ ++ if (lin>=90.0) ++ lin=180.0-lin; ++ ++ sma=331.25*exp(log(1440.0/sat[x].meanmo)*(2.0/3.0)); ++ apogee=sma*(1.0+sat[x].eccn)-xkmper; ++ ++ if ((acos(xkmper/(apogee+xkmper))+(lin*deg2rad)) > fabs(qth.stnlat*deg2rad)) ++ return 1; ++ else ++ return 0; ++ } ++} ++ ++char Decayed(x,time) ++int x; ++double time; ++{ ++ /* This function returns a 1 if it appears that the ++ satellite pointed to by 'x' has decayed at the ++ time of 'time'. If 'time' is 0.0, then the ++ current date/time is used. */ ++ ++ double satepoch; ++ ++ if (time==0.0) ++ time=CurrentDaynum(); ++ ++ satepoch=DayNum(1,0,sat[x].year)+sat[x].refepoch; ++ ++ if (satepoch+((16.666666-sat[x].meanmo)/(10.0*fabs(sat[x].drag))) < time) ++ return 1; ++ else ++ return 0; ++} ++ ++char Geostationary(x) ++int x; ++{ ++ /* This function returns a 1 if the satellite pointed ++ to by "x" appears to be in a geostationary orbit */ ++ ++ if (fabs(sat[x].meanmo-1.0027)<0.0002) ++ ++ return 1; ++ else ++ return 0; ++} ++ ++double FindAOS() ++{ ++ /* This function finds and returns the time of AOS (aostime). */ ++ ++ aostime=0.0; ++ ++ if (AosHappens(indx) && Geostationary(indx)==0 && Decayed(indx,daynum)==0) { ++ Calc(); ++ ++ /* Get the satellite in range */ ++ ++ while (sat_ele<-1.0) { ++ daynum-=0.00035*(sat_ele*((sat_alt/8400.0)+0.46)-2.0); ++ Calc(); ++ } ++ ++ /* Find AOS */ ++ ++ while (aostime==0.0) { ++ if (fabs(sat_ele)<0.03) ++ aostime=daynum; ++ else { ++ daynum-=sat_ele*sqrt(sat_alt)/530000.0; ++ Calc(); ++ } ++ } ++ } ++ ++ return aostime; ++} ++ ++double FindLOS() ++{ ++ lostime=0.0; ++ ++ if (Geostationary(indx)==0 && AosHappens(indx)==1 && Decayed(indx,daynum)==0) { ++ Calc(); ++ ++ do { ++ daynum+=sat_ele*sqrt(sat_alt)/502500.0; ++ Calc(); ++ ++ if (fabs(sat_ele) < 0.03) ++ lostime=daynum; ++ ++ } while (lostime==0.0); ++ } ++ ++ return lostime; ++} ++ ++double FindLOS2() ++{ ++ /* This function steps through the pass to find LOS. ++ FindLOS() is called to "fine tune" and return the result. */ ++ ++ do { ++ daynum+=cos((sat_ele-1.0)*deg2rad)*sqrt(sat_alt)/25000.0; ++ Calc(); ++ ++ } while (sat_ele>=0.0); ++ ++ return(FindLOS()); ++} ++ ++double NextAOS() ++{ ++ /* This function finds and returns the time of the next ++ AOS for a satellite that is currently in range. */ ++ ++ aostime=0.0; ++ ++ if (AosHappens(indx) && Geostationary(indx)==0 && Decayed(indx,daynum)==0) ++ daynum=FindLOS2()+0.014; /* Move to LOS + 20 minutes */ ++ ++ return (FindAOS()); ++} ++ ++int Print(string,mode) ++char *string, mode; ++{ ++ /* This function buffers and displays orbital predictions ++ and allows screens to be saved to a disk file. */ ++ ++ char type[20], spaces[80], head1[80], head2[80]; ++ int key, ans=0, l, x, t; ++ static char buffer[5000], lines, quit; ++ static FILE *fd; ++ ++ /* Pass a NULL string to initialize the buffer, counter, and flags */ ++ ++ if (string[0]==0) { ++ lines=0; ++ quit=0; ++ buffer[0]=0; ++ fd=NULL; ++ } else { ++ if (mode=='p') ++ strcpy(type,"Satellite Passes"); ++ ++ if (mode=='v') ++ strcpy(type,"Visual"); ++ ++ if (mode=='s') ++ strcpy(type,"Solar Illumination"); ++ ++ if (mode=='m') { ++ strcpy(type,"Moon"); ++ } ++ ++ if (mode=='o') { ++ strcpy(type,"Sun"); ++ } ++ ++ if (mode=='m' || mode=='o') { ++ sprintf(head1," %s's Orbit Calendar for the %s",qth.callsign,type); ++ sprintf(head2," Date Time El Az RA Dec GHA Vel Range "); ++ } ++ ++ if (mode!='m' && mode!='o') { ++ ++ l=strlen(qth.callsign)+strlen(sat[indx].name)+strlen(type); ++ ++ spaces[0]=0; ++ ++ for (x=l; x<60; x+=2) ++ strcat(spaces," "); ++ ++ sprintf(head1,"%s%s's %s Calendar for %s", spaces, qth.callsign, type, sat[indx].name); ++ ++ if (mode=='s') ++ sprintf(head2," Date Mins/Day Sun Date Mins/Day Sun "); ++ else { ++ if (calc_squint) ++ sprintf(head2," Date Time El Az Phase %s %s Range Squint ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); ++ else ++ sprintf(head2," Date Time El Az Phase %s %s Range Orbit ",(io_lat=='N'?"LatN":"LatS"),(io_lon=='W'?"LonW":"LonE")); ++ } ++ } ++ ++ strcat(buffer,string); ++ lines++; ++//JHJHJH ++ if (lines==(LINES-8)) { ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Calendar : "); ++ mvprintw(1,21,"%-24s", type); ++ if (mode == 'p' || mode == 'v' || mode == 's') { ++ mvprintw(1,60, "%s (%d)", sat[indx].name, sat[indx].catnum); ++ } ++ mvprintw(2,0," "); ++ attrset(COLOR_PAIR(2)|A_REVERSE); ++ mvprintw(3,0,head2); ++ ++ attrset(COLOR_PAIR(2)); ++ mvprintw(4,0,"\n"); ++ ++ addstr(buffer); ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ ++ if (buffer[0]=='\n') ++ printw("\n"); ++ ++ if (fd==NULL) ++ mvprintw(LINES-2,63," "); ++ else ++ mvprintw(LINES-2,63,"Log = ON"); ++ ++ mvprintw(LINES-2,6,"More? [y/n] >> "); ++ curs_set(1); ++ refresh(); ++ ++ while (ans==0) { ++ key=toupper(getch()); ++ ++ if (key=='Y' || key=='\n' || key==' ') { ++ key='Y'; ++ ans=1; ++ quit=0; ++ } ++ ++ if (key=='N' || key=='Q' || key==27) { ++ key='N'; ++ ans=1; ++ quit=1; ++ } ++ ++ /* 'L' logs output to "satname.txt" */ ++ ++ if (key=='L' && fd==NULL && buffer[0]) { ++ sprintf(temp,"%s.txt",sat[indx].name); ++ ++ l=strlen(temp)-4; ++ ++ for (x=0; x3) || (plus>2 && asterisk>2)) ++ visible=1; ++ } ++ ++ if (visible) { ++ /* Dump buffer to Print() line by line */ ++ ++ for (x=0, y=0; buffer[x]!=0 && quit==0; x++) { ++ line[y]=buffer[x]; ++ ++ if (line[y]=='\n') { ++ line[y+1]=0; ++ quit=Print(line,'v'); ++ line[0]=0; ++ y=0; ++ } else ++ y++; ++ } ++ } ++ ++ buffer[0]=0; ++ } ++ } ++ ++ return quit; ++} ++ ++void Predict(mode) ++char mode; ++{ ++ /* This function predicts satellite passes. It displays ++ output through the Print() function if mode=='p' (show ++ all passes), or through the PrintVisible() function if ++ mode=='v' (show only visible passes). */ ++ ++ int quit=0, lastel=0, breakout=0; ++ char string[80], type[10]; ++ ++ PreCalc(indx); ++ daynum=GetStartTime(0); ++ clear(); ++ ++ /* Trap geostationary orbits and passes that cannot occur. */ ++ ++ if (AosHappens(indx) && Geostationary(indx)==0 && Decayed(indx,daynum)==0) { ++ if (xterm) { ++ strcpy(type,"Orbit"); /* Default */ ++ ++ if (mode=='v') ++ strcpy(type,"Visual"); ++ ++ fprintf(stderr,"\033]0;PREDICT: %s's %s Calendar For %s\007",qth.callsign, type, sat[indx].name); ++ } ++ ++ do { ++ daynum=FindAOS(); ++ ++ /* Display the pass */ ++ ++ while (iel>=0 && quit==0) { ++ if (calc_squint) ++ sprintf(string," %s%4d %4d %4d %4d %4d %6ld %4.0f %c\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,(io_lat=='N'?+1:-1)*isplat,(io_lon=='W'?isplong:360-isplong),irk,squint,findsun); ++ else ++ sprintf(string," %s%4d %4d %4d %4d %4d %6ld %6ld %c\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,(io_lat=='N'?+1:-1)*isplat,(io_lon=='W'?isplong:360-isplong),irk,rv,findsun); ++ ++ lastel=iel; ++ ++ if (mode=='p') ++ quit=Print(string,'p'); ++ ++ if (mode=='v') { ++ nodelay(stdscr,TRUE); ++ attrset(COLOR_PAIR(4)); ++ mvprintw(LINES - 2,6," Calculating... Press [ESC] To Quit"); ++ ++ /* Allow a way out if this ++ should continue forever... */ ++ ++ if (getch()==27) ++ breakout=1; ++ ++ nodelay(stdscr,FALSE); ++ ++ quit=PrintVisible(string); ++ } ++ ++ daynum+=cos((sat_ele-1.0)*deg2rad)*sqrt(sat_alt)/25000.0; ++ Calc(); ++ } ++ ++ if (lastel!=0) { ++ daynum=FindLOS(); ++ Calc(); ++ ++ if (calc_squint) ++ sprintf(string," %s%4d %4d %4d %4d %4d %6ld %4.0f %c\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,(io_lat=='N'?+1:-1)*isplat,(io_lon=='W'?isplong:360-isplong),irk,squint,findsun); ++ else ++ sprintf(string," %s%4d %4d %4d %4d %4d %6ld %6ld %c\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,(io_lat=='N'?+1:-1)*isplat,(io_lon=='W'?isplong:360-isplong),irk,rv,findsun); ++ ++ if (mode=='p') ++ quit=Print(string,'p'); ++ ++ if (mode=='v') ++ quit=PrintVisible(string); ++ } ++ ++ if (mode=='p') ++ quit=Print("\n",'p'); ++ ++ if (mode=='v') ++ quit=PrintVisible("\n"); ++ ++ /* Move to next orbit */ ++ daynum=NextAOS(); ++ ++ } while (quit==0 && breakout==0 && AosHappens(indx) && Decayed(indx,daynum)==0); ++ } else { ++ bkgdset(COLOR_PAIR(5)|A_BOLD); ++ clear(); ++ ++ if (AosHappens(indx)==0 || Decayed(indx,daynum)==1) ++ mvprintw(12,5,"*** Passes for %s cannot occur for your ground station! ***\n",sat[indx].name); ++ ++ if (Geostationary(indx)==1) ++ mvprintw(12,3,"*** Orbital predictions cannot be made for a geostationary satellite! ***\n"); ++ ++ beep(); ++ bkgdset(COLOR_PAIR(7)|A_BOLD); ++ AnyKey(); ++ refresh(); ++ } ++} ++ ++void PredictMoon() ++{ ++ /* This function predicts "passes" of the Moon */ ++ ++ int iaz, iel, lastel=0; ++ char string[80], quit=0; ++ double lastdaynum, moonrise=0.0; ++ ++ daynum=GetStartTime('m'); ++ clear(); ++ ++ if (xterm) ++ fprintf(stderr,"\033]0;PREDICT: %s's Orbit Calendar for the Moon\007",qth.callsign); ++ ++ do { ++ /* Determine moonrise */ ++ ++ FindMoon(daynum); ++ ++ while (moonrise==0.0) { ++ if (fabs(moon_el)<0.03) ++ moonrise=daynum; ++ else { ++ daynum-=(0.004*moon_el); ++ FindMoon(daynum); ++ } ++ } ++ ++ FindMoon(moonrise); ++ daynum=moonrise; ++ iaz=(int)rint(moon_az); ++ iel=(int)rint(moon_el); ++ ++ do { ++ /* Display pass of the moon */ ++ ++ sprintf(string," %s%4d %4d %5.1f %5.1f %5.1f %6.1f%7.3f\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"), iel, iaz, moon_ra, moon_dec, moon_gha, moon_dv, moon_dx); ++ quit=Print(string,'m'); ++ lastel=iel; ++ lastdaynum=daynum; ++ daynum+=0.04*(cos(deg2rad*(moon_el+0.5))); ++ FindMoon(daynum); ++ iaz=(int)rint(moon_az); ++ iel=(int)rint(moon_el); ++ ++ } while (iel>3 && quit==0); ++ ++ while (lastel!=0 && quit==0) { ++ daynum=lastdaynum; ++ ++ do { ++ /* Determine setting time */ ++ ++ daynum+=0.004*(sin(deg2rad*(moon_el+0.5))); ++ FindMoon(daynum); ++ iaz=(int)rint(moon_az); ++ iel=(int)rint(moon_el); ++ ++ } while (iel>0); ++ ++ /* Print moonset */ ++ ++ sprintf(string," %s%4d %4d %5.1f %5.1f %5.1f %6.1f%7.3f\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"), iel, iaz, moon_ra, moon_dec, moon_gha, moon_dv, moon_dx); ++ quit=Print(string,'m'); ++ lastel=iel; ++ } ++ ++ quit=Print("\n",'m'); ++ daynum+=0.4; ++ moonrise=0.0; ++ ++ } while (quit==0); ++} ++ ++void PredictSun() ++{ ++ /* This function predicts "passes" of the Sun. */ ++ ++ int iaz, iel, lastel=0; ++ char string[80], quit=0; ++ double lastdaynum, sunrise=0.0; ++ ++ daynum=GetStartTime('o'); ++ clear(); ++ ++ if (xterm) ++ fprintf(stderr,"\033]0;PREDICT: %s's Orbit Calendar for the Sun\007",qth.callsign); ++ ++ do { ++ /* Determine sunrise */ ++ ++ FindSun(daynum); ++ ++ while (sunrise==0.0) { ++ if (fabs(sun_ele)<0.03) ++ sunrise=daynum; ++ else { ++ daynum-=(0.004*sun_ele); ++ FindSun(daynum); ++ } ++ } ++ ++ FindSun(sunrise); ++ daynum=sunrise; ++ iaz=(int)rint(sun_azi); ++ iel=(int)rint(sun_ele); ++ ++ /* Print time of sunrise */ ++ ++ do { ++ /* Display pass of the sun */ ++ ++ sprintf(string," %s%4d %4d %5.1f %5.1f %5.1f %6.1f%7.3f\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"), iel, iaz, sun_ra, sun_dec, sun_lon, sun_range_rate, sun_range); ++ quit=Print(string,'o'); ++ lastel=iel; ++ lastdaynum=daynum; ++ daynum+=0.04*(cos(deg2rad*(sun_ele+0.5))); ++ FindSun(daynum); ++ iaz=(int)rint(sun_azi); ++ iel=(int)rint(sun_ele); ++ ++ } while (iel>3 && quit==0); ++ ++ while (lastel!=0 && quit==0) { ++ daynum=lastdaynum; ++ ++ do { ++ /* Find sun set */ ++ ++ daynum+=0.004*(sin(deg2rad*(sun_ele+0.5))); ++ FindSun(daynum); ++ iaz=(int)rint(sun_azi); ++ iel=(int)rint(sun_ele); ++ ++ } while (iel>0); ++ ++ /* Print time of sunset */ ++ ++ sprintf(string," %s%4d %4d %5.1f %5.1f %5.1f %6.1f%7.3f\n",Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"), iel, iaz, sun_ra, sun_dec, sun_lon, sun_range_rate, sun_range); ++ quit=Print(string,'o'); ++ lastel=iel; ++ } ++ ++ quit=Print("\n",'o'); ++ daynum+=0.4; ++ sunrise=0.0; ++ ++ } while (quit==0); ++} ++ ++char KbEdit(x,y) ++int x,y; ++{ ++ /* This function is used when editing QTH ++ and orbital data via the keyboard. */ ++ ++ char need2save=0, input[25]; ++ ++ echo(); ++ move(y-1,x-1); ++ wgetnstr(stdscr,input,24); ++ ++ if (strlen(input)!=0) { ++ need2save=1; /* Save new data to variables */ ++ resave=1; /* Save new data to disk files */ ++ strncpy(temp,input,24); ++ } ++ ++ mvprintw(y-1,x-1,"%-25s",temp); ++ ++ refresh(); ++ noecho(); ++ ++ return need2save; ++} ++ ++void ShowOrbitData() ++{ ++ /* This function permits displays a satellite's orbital ++ data. The age of the satellite data is also provided. */ ++ ++ int c, x, namelength, age; ++ double an_period, no_period, sma, c1, e2, satepoch; ++ char days[5]; ++ ++ x=Select(); ++ ++ while (x!=-1) { ++ if (sat[x].meanmo!=0.0) { ++ bkgdset(COLOR_PAIR(2)|A_BOLD); ++ clear(); ++ sma=331.25*exp(log(1440.0/sat[x].meanmo)*(2.0/3.0)); ++ an_period=1440.0/sat[x].meanmo; ++ c1=cos(sat[x].incl*deg2rad); ++ e2=1.0-(sat[x].eccn*sat[x].eccn); ++ no_period=(an_period*360.0)/(360.0+(4.97*pow((xkmper/sma),3.5)*((5.0*c1*c1)-1.0)/(e2*e2))/sat[x].meanmo); ++ satepoch=DayNum(1,0,sat[x].year)+sat[x].refepoch; ++ age=(int)rint(CurrentDaynum()-satepoch); ++ ++ if (age==1) ++ strcpy(days,"day"); ++ else ++ strcpy(days,"days"); ++ ++ namelength=strlen(sat[x].name); ++ ++ printw("\n"); ++ ++ for (c=41; c>namelength; c-=2) ++ printw(" "); ++ ++ bkgdset(COLOR_PAIR(3)|A_BOLD); ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Orbital Data "); ++ mvprintw(2,0," "); ++ ++ mvprintw(1,25,"(%ld) %s", sat[x].catnum, sat[x].name); ++ ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ mvprintw( 4, 4,"Data Issued : "); ++ mvprintw( 5, 4,"Reference Epoch : "); ++ mvprintw( 6, 4,"Inclination : "); ++ mvprintw( 7, 4,"RAAN : "); ++ mvprintw( 8, 4,"Eccentricity : "); ++ mvprintw( 9, 4,"Arg of Perigee : "); ++ mvprintw(10, 4,"Mean Anomaly : "); ++ mvprintw(11, 4,"Mean Motion : "); ++ mvprintw(12, 4,"Decay Rate : "); ++ mvprintw(13, 4,"Nddot/6 Drag : "); ++ mvprintw(14, 4,"Bstar Drag Factor : "); ++ mvprintw(15, 4,"Semi-Major Axis : "); ++ mvprintw(16, 4,"Apogee Altitude : "); ++ mvprintw(17, 4,"Perigee Altitude : "); ++ mvprintw(18, 4,"Anomalistic Period : "); ++ mvprintw(19, 4,"Nodal Period : "); ++ mvprintw(20, 4,"Orbit Number : "); ++ mvprintw(21, 4,"Element Set Number : "); ++ ++ attrset(COLOR_PAIR(2)|A_BOLD); ++ mvprintw( 4,25,"%d %s ago",age,days); ++ mvprintw( 5,25,"%02d %.8f",sat[x].year,sat[x].refepoch); ++ mvprintw( 6,25,"%.4f deg",sat[x].incl); ++ mvprintw( 7,25,"%.4f deg",sat[x].raan); ++ mvprintw( 8,25,"%g",sat[x].eccn); ++ mvprintw( 9,25,"%.4f deg",sat[x].argper); ++ mvprintw(10,25,"%.4f deg",sat[x].meanan); ++ mvprintw(11,25,"%.8f rev/day",sat[x].meanmo); ++ mvprintw(12,25,"%g rev/day/day",sat[x].drag); ++ mvprintw(13,25,"%g rev/day/day/day",sat[x].nddot6); ++ mvprintw(14,25,"%g 1/earth radii",sat[x].bstar); ++ mvprintw(15,25,"%.4f km",sma); ++ mvprintw(16,25,"%.4f km",sma*(1.0+sat[x].eccn)-xkmper); ++ mvprintw(17,25,"%.4f km",sma*(1.0-sat[x].eccn)-xkmper); ++ mvprintw(18,25,"%.4f mins",an_period); ++ mvprintw(19,25,"%.4f mins",no_period); ++ mvprintw(20,25,"%ld",sat[x].orbitnum); ++ mvprintw(21,25,"%ld",sat[x].setnum); ++ ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ refresh(); ++ AnyKey(); ++ } ++ x=Select(); ++ }; ++} ++ ++void KepEdit() ++{ ++ /* This function permits keyboard editing of the orbital database. */ ++ ++ int x; ++ ++ do { ++ x=Select(); ++ ++ if (x!=-1) { ++ bkgdset(COLOR_PAIR(3)|A_BOLD); ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Orbital Database Editing "); ++ mvprintw(2,0," "); ++ ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ ++ mvprintw( 7,20,"Spacecraft Name :"); ++ mvprintw( 8,20,"Catalog Number :"); ++ mvprintw( 9,20,"Designator :"); ++ mvprintw(10,20,"Reference Epoch :"); ++ mvprintw(11,20,"Inclination :"); ++ mvprintw(12,20,"RAAN :"); ++ mvprintw(13,20,"Eccentricity :"); ++ mvprintw(14,20,"Arg of Perigee :"); ++ mvprintw(15,20,"Mean Anomaly :"); ++ mvprintw(16,20,"Mean Motion :"); ++ mvprintw(17,20,"Decay Rate :"); ++ mvprintw(18,20,"Nddot/6 :"); ++ mvprintw(19,20,"Bstar Drag Term :"); ++ mvprintw(20,20,"Orbit Number :"); ++ mvprintw(21,20,"Element Set No. :"); ++ ++ attrset(COLOR_PAIR(2)|A_BOLD); ++ ++ mvprintw( 7,38,"%s",sat[x].name); ++ mvprintw( 8,38,"%ld",sat[x].catnum); ++ mvprintw( 9,38,"%s",sat[x].designator); ++ mvprintw(10,38,"%02d %.8f",sat[x].year,sat[x].refepoch); ++ mvprintw(11,38,"%.4f",sat[x].incl); ++ mvprintw(12,38,"%.4f",sat[x].raan); ++ mvprintw(13,38,"%g",sat[x].eccn); ++ mvprintw(14,38,"%.4f",sat[x].argper); ++ mvprintw(15,38,"%.4f",sat[x].meanan); ++ mvprintw(16,38,"%.8f",sat[x].meanmo); ++ mvprintw(17,38,"%g",sat[x].drag); ++ mvprintw(18,38,"%g",sat[x].nddot6); ++ mvprintw(19,38,"%g",sat[x].bstar); ++ mvprintw(20,38,"%ld",sat[x].orbitnum); ++ mvprintw(21,38,"%ld",sat[x].setnum); ++ ++ curs_set(1); ++ refresh(); ++ ++ sprintf(temp,"%s",sat[x].name); ++ ++ if (KbEdit(39,8)) ++ strncpy(sat[x].name,temp,24); ++ ++ sprintf(temp,"%ld",sat[x].catnum); ++ ++ if (KbEdit(39,9)) ++ sscanf(temp,"%ld",&sat[x].catnum); ++ ++ sprintf(temp,"%s",sat[x].designator); ++ ++ if (KbEdit(39,10)) ++ sscanf(temp,"%s",sat[x].designator); ++ ++ sprintf(temp,"%02d %4.8f",sat[x].year,sat[x].refepoch); ++ ++ if (KbEdit(39,11)) ++ sscanf(temp,"%d %lf",&sat[x].year,&sat[x].refepoch); ++ ++ sprintf(temp,"%4.4f",sat[x].incl); ++ ++ if (KbEdit(39,12)) ++ sscanf(temp,"%lf",&sat[x].incl); ++ ++ sprintf(temp,"%4.4f",sat[x].raan); ++ ++ if (KbEdit(39,13)) ++ sscanf(temp,"%lf",&sat[x].raan); ++ ++ sprintf(temp,"%g",sat[x].eccn); ++ ++ if (KbEdit(39,14)) ++ sscanf(temp,"%lf",&sat[x].eccn); ++ ++ sprintf(temp,"%4.4f",sat[x].argper); ++ ++ if (KbEdit(39,15)) ++ sscanf(temp,"%lf",&sat[x].argper); ++ ++ sprintf(temp,"%4.4f",sat[x].meanan); ++ ++ if (KbEdit(39,16)) ++ sscanf(temp,"%lf",&sat[x].meanan); ++ ++ sprintf(temp,"%4.8f",sat[x].meanmo); ++ ++ if (KbEdit(39,17)) ++ sscanf(temp,"%lf",&sat[x].meanmo); ++ ++ sprintf(temp,"%g",sat[x].drag); ++ ++ if (KbEdit(39,18)) ++ sscanf(temp,"%lf",&sat[x].drag); ++ ++ sprintf(temp,"%g",sat[x].nddot6); ++ ++ if (KbEdit(39,19)) ++ sscanf(temp,"%lf",&sat[x].nddot6); ++ ++ sprintf(temp,"%g",sat[x].bstar); ++ ++ if (KbEdit(39,20)) ++ sscanf(temp,"%lf",&sat[x].bstar); ++ ++ sprintf(temp,"%ld",sat[x].orbitnum); ++ ++ if (KbEdit(39,21)) ++ sscanf(temp,"%ld",&sat[x].orbitnum); ++ ++ sprintf(temp,"%ld",sat[x].setnum); ++ ++ if (KbEdit(39,22)) ++ sscanf(temp,"%ld",&sat[x].setnum); ++ ++ curs_set(0); ++ } ++ ++ } while (x!=-1); ++ ++ if (resave) { ++ SaveTLE(); ++ resave=0; ++ } ++} ++ ++void QthEdit() ++{ ++ /* This function permits keyboard editing of ++ the ground station's location information. */ ++ ++ bkgdset(COLOR_PAIR(3)|A_BOLD); ++ clear(); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Ground Station Location "); ++ mvprintw(2,0," "); ++ ++ curs_set(1); ++ ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ mvprintw(11,20,"Station Callsign : "); ++ mvprintw(12,20,"Station Latitude : "); ++ mvprintw(13,20,"Station Longitude : "); ++ mvprintw(14,20,"Station Altitude : "); ++ mvprintw(15,20,"Timezone Offset : "); ++ ++ attrset(COLOR_PAIR(2)|A_BOLD); ++ mvprintw(11,43,"%s",qth.callsign); ++ if (io_lat=='N') ++ mvprintw(12,43,"%g [DegN]",+qth.stnlat); ++ else ++ mvprintw(12,43,"%g [DegS]",-qth.stnlat); ++ if (io_lon=='W') ++ mvprintw(13,43,"%g [DegW]",+qth.stnlong); ++ else ++ mvprintw(13,43,"%g [DegE]",-qth.stnlong); ++ mvprintw(14,43,"%d",qth.stnalt); ++ mvprintw(15,43,"%d",qth.tzoffset); ++ ++ refresh(); ++ ++ sprintf(temp,"%s",qth.callsign); ++ mvprintw(18,15, " Enter the callsign of your ground station"); ++ if (KbEdit(44,12)) ++ strncpy(qth.callsign,temp,16); ++ ++ if (io_lat=='N') ++ sprintf(temp,"%g [DegN]",+qth.stnlat); ++ else ++ sprintf(temp,"%g [DegS]",-qth.stnlat); ++ if (io_lat=='N') ++ mvprintw(18,15," Enter your latitude in degrees NORTH "); ++ else ++ mvprintw(18,15," Enter your latitude in degrees SOUTH "); ++ mvprintw(19,15," Decimal (74.2467) or DMS (74 14 48) format allowed"); ++ if (KbEdit(44,13)) { ++ if (io_lat=='N') ++ qth.stnlat=+ReadBearing(temp); ++ else ++ qth.stnlat=-ReadBearing(temp); ++ } ++ ++ if (io_lon=='W') ++ sprintf(temp,"%g [DegW]",+qth.stnlong); ++ else ++ sprintf(temp,"%g [DegE]",-qth.stnlong); ++ ++ if (io_lon=='W') ++ mvprintw(18,15," Enter your longitude in degrees WEST "); ++ else ++ mvprintw(18,15," Enter your longitude in degrees EAST "); ++ ++ if (KbEdit(44,14)) { ++ if (io_lon=='W') ++ qth.stnlong=+ReadBearing(temp); ++ else ++ qth.stnlong=-ReadBearing(temp); ++ } ++ move(19,15); ++ clrtoeol(); ++ ++ mvprintw(18,15," Enter your altitude above sea level (in meters) "); ++ sprintf(temp,"%d",qth.stnalt); ++ if (KbEdit(44,15)) ++ sscanf(temp,"%d",&qth.stnalt); ++ ++ sprintf(temp,"%d",qth.tzoffset); ++ mvprintw(18,15," Enter your timezone offset from GMT (hours) "); ++ if (KbEdit(44,16)) ++ sscanf(temp,"%d",&qth.tzoffset); ++ ++ if (resave) { ++ SaveQTH(); ++ resave=0; ++ } ++} ++ ++void SingleTrack(x,speak) ++int x; ++char speak; ++{ ++ /* This function tracks a single satellite in real-time ++ until 'Q' or ESC is pressed. x represents the index ++ of the satellite being tracked. If speak=='T', then ++ the speech routines are enabled. */ ++ ++ int ans, oldaz=0, oldel=0, length, xponder=0, ++ polarity=0, tshift, bshift; ++ char approaching=0, command[80], comsat, aos_alarm=0, ++ geostationary=0, aoshappens=0, decayed=0, eclipse_alarm=0, ++ visibility=0, old_visibility=0, los_alarm=0; ++ double oldtime=0.0, nextaos=0.0, lostime=0.0, aoslos=0.0, ++ downlink=0.0, uplink=0.0, downlink_start=0.0, ++ downlink_end=0.0, uplink_start=0.0, uplink_end=0.0, ++ dopp, doppler100=0.0, delay, loss, shift; ++ long newtime, lasttime=0; ++ ++ do { ++ PreCalc(x); ++ indx=x; ++ ++ if (sat_db[x].transponders>0) { ++ comsat=1; ++ tshift=0; ++ bshift=0; ++ } else { ++ comsat=0; ++ tshift=2; ++ bshift=-2; ++ } ++ ++ if (comsat) { ++ downlink_start=sat_db[x].downlink_start[xponder]; ++ downlink_end=sat_db[x].downlink_end[xponder]; ++ uplink_start=sat_db[x].uplink_start[xponder]; ++ uplink_end=sat_db[x].uplink_end[xponder]; ++ ++ if (downlink_start>downlink_end) ++ polarity=-1; ++ ++ if (downlink_start=0.0) ++ visibility_array[indx]='V'; ++ else ++ visibility_array[indx]='D'; ++ } else ++ visibility_array[indx]='N'; ++ ++ visibility=visibility_array[indx]; ++ ++ if (comsat) { ++ if (downlink!=0.0) ++ mvprintw(12,11,"%11.5f MHz",downlink); ++ else ++ mvprintw(12,11," "); ++ ++ if (uplink!=0.0) ++ mvprintw(11,11,"%11.5f MHz",uplink); ++ else ++ mvprintw(11,11," "); ++ } ++ ++ if (antfd!=-1) { ++ if (sat_ele>=0.0) ++ mvprintw(17,67," Active "); ++ else ++ mvprintw(17,67,"Standing By"); ++ } else ++ mvprintw(18,67,"Not Enabled"); ++ ++ if (calc_squint) ++ mvprintw(18,52,"%+6.2f",squint); ++ else ++ mvprintw(18,54,"N/A"); ++ ++ doppler100=-100.0e06*((sat_range_rate*1000.0)/299792458.0); ++ delay=1000.0*((1000.0*sat_range)/299792458.0); ++ ++ if (sat_ele>=0.0) { ++ if (aos_alarm==0) { ++ beep(); ++ aos_alarm=1; ++ } ++ ++ if (comsat) { ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ ++ if (fabs(sat_range_rate)<0.1) ++ mvprintw(13,34," TCA "); ++ else { ++ if (sat_range_rate<0.0) ++ mvprintw(13,34,"Approaching"); ++ ++ if (sat_range_rate>0.0) ++ mvprintw(13,34," Receding "); ++ } ++ ++ attrset(COLOR_PAIR(2)|A_BOLD); ++ ++ if (downlink!=0.0) { ++ dopp=1.0e-08*(doppler100*downlink); ++ mvprintw(12,32,"%11.5f MHz",downlink+dopp); ++ loss=32.4+(20.0*log10(downlink))+(20.0*log10(sat_range)); ++ mvprintw(12,67,"%7.3f dB",loss); ++ mvprintw(13,13,"%7.3f ms",delay); ++ } else { ++ mvprintw(13,32," "); ++ mvprintw(13,67," "); ++ mvprintw(14,13," "); ++ } ++ ++ if (uplink!=0.0) { ++ dopp=1.0e-08*(doppler100*uplink); ++ mvprintw(11,32,"%11.5f MHz",uplink-dopp); ++ loss=32.4+(20.0*log10(uplink))+(20.0*log10(sat_range)); ++ mvprintw(11,67,"%7.3f dB",loss); ++ } else { ++ mvprintw(12,32," "); ++ mvprintw(12,67," "); ++ } ++ ++ if (uplink!=0.0 && downlink!=0.0) ++ mvprintw(13,67,"%7.3f ms",2.0*delay); ++ else ++ mvprintw(14,67," "); ++ } ++ ++ if (speak=='T' && soundcard) { ++ if (eclipse_alarm==0 && fabs(eclipse_depth)<0.015) { ++ /* ~1 deg */ ++ /* Hold off regular announcements if ++ eclipse depth is within +/- 1 deg. */ ++ ++ oldtime=CurrentDaynum(); ++ ++ if ((old_visibility=='V' || old_visibility=='D') && visibility=='N') { ++ sprintf(command,"%svocalizer/vocalizer eclipse &",predictpath); ++ system(command); ++ eclipse_alarm=1; ++ oldtime-=0.000015*sqrt(sat_alt); ++ } ++ ++ if (old_visibility=='N' && (visibility=='V' || visibility=='D')) { ++ sprintf(command,"%svocalizer/vocalizer sunlight &",predictpath); ++ system(command); ++ eclipse_alarm=1; ++ oldtime-=0.000015*sqrt(sat_alt); ++ } ++ } ++ ++ if ((CurrentDaynum()-oldtime)>(0.00003*sqrt(sat_alt))) { ++ ++ if (sat_range_rate<0.0) ++ approaching='+'; ++ ++ if (sat_range_rate>0.0) ++ approaching='-'; ++ ++ sprintf(command,"%svocalizer/vocalizer %.0f %.0f %c %c &",predictpath,sat_azi,sat_ele,approaching,visibility); ++ system(command); ++ oldtime=CurrentDaynum(); ++ old_visibility=visibility; ++ } ++ ++ if (sat_ele<=1.0 && approaching=='-') { ++ /* Suspend regular announcements ++ as we approach LOS. */ ++ ++ oldtime=CurrentDaynum(); ++ } ++ } ++ } else { ++ lostime=0.0; ++ aos_alarm=0; ++ los_alarm=0; ++ eclipse_alarm=0; ++ ++ if (comsat) { ++ mvprintw(11,32," "); ++ mvprintw(11,67," "); ++ mvprintw(12,32," "); ++ mvprintw(12,67," "); ++ mvprintw(13,13," "); ++ mvprintw(13,34," "); ++ mvprintw(13,67," "); ++ } ++ } ++ ++ mvprintw(5,42,"%0.f ",fm); ++ mvprintw(6,42,"%0.f ",fk); ++ ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ ++ mvprintw(20,1,"Orbit Number: %ld",rv); ++ ++ /* Send data to serial port antenna tracker ++ either as needed (when it changes), or ++ once per second. */ ++ ++ if (sat_ele>=0.0 && antfd!=-1) { ++ newtime=(long)time(NULL); ++ ++ if ((oldel!=iel || oldaz!=iaz) || (once_per_second && newtime>lasttime)) { ++ TrackDataOut(antfd,(float)iel,(float)iaz); ++ oldel=iel; ++ oldaz=iaz; ++ lasttime=newtime; ++ } ++ } ++ ++ mvprintw(22,1,"Spacecraft is currently "); ++ ++ if (visibility=='V') ++ mvprintw(22,25,"visible "); ++ ++ if (visibility=='D') ++ mvprintw(22,25,"in sunlight"); ++ ++ if (visibility=='N') ++ mvprintw(22,25,"in eclipse "); ++ ++ attrset(COLOR_PAIR(4)|A_REVERSE|A_BOLD); ++ mvprintw(20,55," Sun "); ++ if (sun_ele > 0.0) ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ else ++ attrset(COLOR_PAIR(2)); ++ mvprintw(21,55,"%-7.2fAz",sun_azi); ++ mvprintw(22,55,"%+-6.2f El",sun_ele); ++ ++ FindMoon(daynum); ++ ++ if (geostationary==1 && sat_ele>=0.0) { ++ mvprintw(21,1,"Satellite orbit is geostationary"); ++ aoslos=-3651.0; ++ } ++ ++ if (geostationary==1 && sat_ele<0.0) { ++ mvprintw(21,1,"This satellite never reaches AOS"); ++ aoslos=-3651.0; ++ } ++ ++ if (aoshappens==0 || decayed==1) { ++ mvprintw(21,1,"This satellite never reaches AOS"); ++ aoslos=-3651.0; ++ } ++ ++ if (sat_ele>=0.0 && geostationary==0 && decayed==0 && daynum>lostime) { ++ lostime=FindLOS2(); ++ mvprintw(21,1,"LOS at: %s %s ",Daynum2String(lostime,24,"%a %d%b%y %j.%H:%M:%S"),(qth.tzoffset==0) ? "GMT" : "Local"); ++ aoslos=lostime; ++ } else if (sat_ele<0.0 && geostationary==0 && decayed==0 && aoshappens==1 && daynum>aoslos) { ++ daynum+=0.003; /* Move ahead slightly... */ ++ nextaos=FindAOS(); ++ mvprintw(21,1,"Next AOS: %s %s",Daynum2String(nextaos,24,"%a %d%b%y %j.%H:%M:%S"),(qth.tzoffset==0) ? "GMT" : "Local"); ++ aoslos=nextaos; ++ ++ if (oldtime!=0.0 && speak=='T' && soundcard) { ++ /* Announce LOS */ ++ ++ sprintf(command,"%svocalizer/vocalizer los &",predictpath); ++ system(command); ++ } ++ } ++ ++ /* This is where the variables for the socket server are updated. */ ++ ++ if (socket_flag) { ++ az_array[indx]=sat_azi; ++ el_array[indx]=sat_ele; ++ lat_array[indx]=sat_lat; ++ long_array[indx]=360.0-sat_lon; ++ footprint_array[indx]=fk; ++ range_array[indx]=sat_range; ++ altitude_array[indx]=sat_alt; ++ velocity_array[indx]=sat_vel; ++ orbitnum_array[indx]=rv; ++ doppler[indx]=doppler100; ++ nextevent[indx]=aoslos; ++ eclipse_depth_array[indx]=eclipse_depth/deg2rad; ++ phase_array[indx]=360.0*(phase/twopi); ++ ++ if (calc_squint) ++ squint_array[indx]=squint; ++ else ++ squint_array[indx]=360.0; ++ ++ FindSun(daynum); ++ ++ sprintf(tracking_mode, "%s\n%c",sat[indx].name,0); ++ } ++ ++ /* Get input from keyboard */ ++ ++ ans=tolower(getch()); ++ ++ /* We can force PREDICT to speak by pressing 'T' */ ++ ++ if (ans=='t') ++ oldtime=0.0; ++ ++ /* If we receive a RELOAD_TLE command through the ++ socket connection or an 'r' through the keyboard, ++ reload the TLE file. */ ++ ++ if (reload_tle || ans=='r') { ++ ReadDataFiles(); ++ reload_tle=0; ++ } ++ ++ if (comsat) { ++ if (ans==' ' && sat_db[x].transponders>1) { ++ xponder++; ++ ++ if (xponder>=sat_db[x].transponders) ++ xponder=0; ++ ++ move(9,1); ++ clrtoeol(); ++ ++ downlink_start=sat_db[x].downlink_start[xponder]; ++ downlink_end=sat_db[x].downlink_end[xponder]; ++ uplink_start=sat_db[x].uplink_start[xponder]; ++ uplink_end=sat_db[x].uplink_end[xponder]; ++ ++ if (downlink_start>downlink_end) ++ polarity=-1; ++ ++ if (downlink_start' || ans=='.') { ++ if (ans==KEY_UP || ans=='>') ++ shift=0.001; /* 1 kHz */ ++ else ++ shift=0.0001; /* 100 Hz */ ++ ++ /* Raise uplink frequency */ ++ ++ uplink+=shift*(double)abs(polarity); ++ downlink=downlink+(shift*(double)polarity); ++ ++ if (uplink>uplink_end) { ++ uplink=uplink_start; ++ downlink=downlink_start; ++ } ++ } ++ ++ if (ans==KEY_DOWN || ans=='<' || ans== ',') { ++ if (ans==KEY_DOWN || ans=='<') ++ shift=0.001; /* 1 kHz */ ++ else ++ shift=0.0001; /* 100 Hz */ ++ ++ /* Lower uplink frequency */ ++ ++ uplink-=shift*(double)abs(polarity); ++ downlink=downlink-(shift*(double)polarity); ++ ++ if (uplink0)) x--; ++ ++ } while (ans!='q' && ans!=17); ++ ++ cbreak(); ++ sprintf(tracking_mode, "NONE\n%c",0); ++} ++ ++void MultiColours(scrk, scel) ++double scrk, scel; ++{ ++ if (scrk < 8000) ++ if (scrk < 4000) ++ if (scrk < 2000) ++ if (scrk < 1000) ++ if (scel > 10) ++ attrset(COLOR_PAIR(6)|A_REVERSE); /* red */ ++ else ++ attrset(COLOR_PAIR(3)|A_REVERSE); /* yellow */ ++ else ++ if (scel > 20) ++ attrset(COLOR_PAIR(3)|A_REVERSE); /* yellow */ ++ else ++ attrset(COLOR_PAIR(4)|A_REVERSE); /* cyan */ ++ else ++ if (scel > 40) ++ attrset(COLOR_PAIR(4)|A_REVERSE); /* cyan */ ++ else ++ attrset(COLOR_PAIR(1)|A_REVERSE); /* white */ ++ else ++ attrset(COLOR_PAIR(1)|A_REVERSE); /* white */ ++ else ++ attrset(COLOR_PAIR(2)|A_REVERSE); /* reverse */ ++} ++ ++void MultiTrack(multitype,disttype) ++char multitype, disttype; ++{ ++ /* This function tracks all satellites in the program's ++ database simultaneously until 'Q' or ESC is pressed. ++ Satellites in range are HIGHLIGHTED. Coordinates ++ for the Sun and Moon are also displayed. */ ++ ++ int w, x, y, z, ans, siv; ++ ++ unsigned char satindex[maxsats], inrange[maxsats], sunstat=0, ++ ok2predict[maxsats]; ++ ++ double aos[maxsats], ++ nextcalctime=0.0, los[maxsats], aoslos[maxsats]; ++ ++ if (xterm) ++ fprintf(stderr,"\033]0;PREDICT: Multi-Satellite Tracking Mode\007"); ++ ++ curs_set(0); ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ clear(); ++ ++ mvprintw(0,0," "); ++ mvprintw(1,0," PREDICT Real-Time Multi-Tracking "); ++ mvprintw(2,0," "); ++ ++ attrset(COLOR_PAIR(2)|A_REVERSE); ++ ++ mvprintw(3,0," Satellite Azim Elev Lat Long Alt Range Next AOS/LOS "); ++ ++ attrset(COLOR_PAIR(4)|A_REVERSE|A_BOLD); ++ mvprintw(5,70," QTH "); ++ attrset(COLOR_PAIR(2)); ++ mvprintw(6,70,"%9s",Abbreviate(qth.callsign,9)); ++ getMaidenHead(qth.stnlat,qth.stnlong,maidenstr); ++ mvprintw(7,70,"%9s",maidenstr); ++ ++ for (x=0; x= 0.0) { ++ MultiColours(sat_range, sat_ele); ++ inrange[indx]=1; ++ } else { ++ inrange[indx]=0; ++ } ++ ++ if (sat_sun_status) { ++ if (sun_ele<=-12.0 && sat_ele>=0.0) ++ sunstat='V'; ++ else ++ sunstat='D'; ++ } else ++ sunstat='N'; ++ ++ if (sat_ele >= 0.0) { ++ getMaidenHead(sat_lat,sat_lon,maidenstr); ++ if (multitype=='m') { ++ mvprintw(y+5,1, ++ ((strlen(sat[indx].name)>12) ++ ? " #%-12d%5.1f %5.1f %7s %6.0f %6.0f %c %8s " ++ : " %-13s%5.1f %5.1f %7s %6.0f %6.0f %c %8s "), ++ ((strlen(sat[indx].name)>12) ++ ? (const char *)sat[indx].catnum ++ : sat[indx].name), ++ sat_azi, sat_ele, maidenstr, ++ ((disttype=='i') ? sat_alt*km2mi : sat_alt), ++ ((disttype=='i') ? sat_range*km2mi : sat_range), ++ sunstat, Daynum2String(los[indx]-daynum,8,"%H:%M:%S")); ++ ++ } else { ++ mvprintw(y+5,1, ++ ((strlen(sat[indx].name)>12) ++ ? " #%-12d%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %8s " ++ : " %-13s%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %8s "), ++ ((strlen(sat[indx].name)>12) ++ ? (const char *)sat[indx].catnum ++ : sat[indx].name), ++ sat_azi, sat_ele, sat_lat, 360.0-sat_lon, ++ ((disttype=='i') ? sat_alt*km2mi : sat_alt), ++ ((disttype=='i') ? sat_range*km2mi : sat_range), ++ sunstat, Daynum2String(los[indx]-daynum,8,"%H:%M:%S")); ++ } ++ ++ if (fabs(sat_range_rate)<0.1) ++ mvprintw(y+5,54,"="); ++ else { ++ if (sat_range_rate<0.0) ++ mvprintw(y+5,54,"/"); ++ if (sat_range_rate>0.0) ++ mvprintw(y+5,54,"\\"); ++ } ++ ++ attrset(COLOR_PAIR(2)); ++ mvprintw(y+6,1, " "); ++ ++ y++; ++ siv++; ++ } ++ ++ if (socket_flag) { ++ az_array[indx]=sat_azi; ++ el_array[indx]=sat_ele; ++ lat_array[indx]=sat_lat; ++ long_array[indx]=360.0-sat_lon; ++ footprint_array[indx]=fk; ++ range_array[indx]=sat_range; ++ altitude_array[indx]=sat_alt; ++ velocity_array[indx]=sat_vel; ++ orbitnum_array[indx]=rv; ++ visibility_array[indx]=sunstat; ++ eclipse_depth_array[indx]=eclipse_depth/deg2rad; ++ phase_array[indx]=360.0*(phase/twopi); ++ ++ doppler[indx]=-100e06*((sat_range_rate*1000.0)/299792458.0); ++ ++ if (calc_squint) ++ squint_array[indx]=squint; ++ else ++ squint_array[indx]=360.0; ++ ++ FindSun(daynum); ++ sprintf(tracking_mode,"MULTI\n%c",0); ++ ++ } ++ ++ attrset(COLOR_PAIR(4)|A_REVERSE|A_BOLD); ++ mvprintw(16,70," Sun "); ++ if (sun_ele > 0.0) ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ else ++ attrset(COLOR_PAIR(2)); ++ mvprintw(17,70,"%-7.2fAz",sun_azi); ++ mvprintw(18,70,"%+-6.2f El",sun_ele); ++ ++ FindMoon(daynum); ++ ++ /* Calculate Next Event (AOS/LOS) Times */ ++ ++ if (ok2predict[indx] && daynum>los[indx] && inrange[indx]) ++ los[indx]=FindLOS2(); ++ ++ if (ok2predict[indx] && daynum>aos[indx]) { ++ if (inrange[indx]) ++ aos[indx]=NextAOS(); ++ else ++ aos[indx]=FindAOS(); ++ } ++ ++ if (inrange[indx]) ++ aoslos[indx]=los[indx]; ++ else ++ aoslos[indx]=aos[indx]; ++ ++ if (socket_flag) { ++ if (ok2predict[indx]) ++ nextevent[indx]=aoslos[indx]; ++ else ++ nextevent[indx]=-3651.0; ++ } ++ ++ } ++ ++ if (Decayed(indx,0.0)) { ++ attrset(COLOR_PAIR(2)); ++ mvprintw(y+5,1,"%-10s---------- Decayed ---------", Abbreviate(sat[indx].name,9)); ++ ++ if (socket_flag) { ++ az_array[indx]=0.0; ++ el_array[indx]=0.0; ++ lat_array[indx]=0.0; ++ long_array[indx]=0.0; ++ footprint_array[indx]=0.0; ++ range_array[indx]=0.0; ++ altitude_array[indx]=0.0; ++ velocity_array[indx]=0.0; ++ orbitnum_array[indx]=0L; ++ visibility_array[indx]='N'; ++ eclipse_depth_array[indx]=0.0; ++ phase_array[indx]=0.0; ++ doppler[indx]=0.0; ++ squint_array[indx]=0.0; ++ nextevent[indx]=-3651.0; ++ } ++ } ++ } while (y<=(LINES-6) && z++aos[satindex[y+1]]) { ++ x=satindex[y]; ++ satindex[y]=satindex[y+1]; ++ satindex[y+1]=x; ++ } ++ ++/* Below Horizon */ ++ ++ w=siv+(siv==0 ? 5 : 6); y=0; z=0; ++ do { ++ indx=z; ++ ++ if (sat[(int)satindex[indx]].meanmo!=0.0 ++ && Decayed((int)satindex[indx],0.0)!=1 ++ && (indx < totalsats)) ++ { ++ daynum=CurrentDaynum(); ++ PreCalc((int)satindex[indx]); ++ Calc(); ++ ++ inrange[(int)satindex[indx]]=0; ++ ++ if (sat_sun_status) { ++ if (sun_ele<=-12.0 && sat_ele>=0.0) ++ sunstat='V'; ++ else ++ sunstat='D'; ++ } else ++ sunstat='N'; ++ ++ if ((sat_ele < 0.0) && ok2predict[(int)satindex[indx]]) { ++ getMaidenHead(sat_lat,sat_lon,maidenstr); ++ if ((aos[(int)satindex[indx]]-daynum) < 0.00694) ++ attrset(COLOR_PAIR(2)); ++ else ++ attrset(COLOR_PAIR(4)); ++ if (multitype=='m') ++ mvprintw(w+y,1, ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? " #%-12d%5.1f %5.1f %7s %6.0f %6.0f %c %12s " ++ : " %-13s%5.1f %5.1f %7s %6.0f %6.0f %c %12s ", ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? (const char *)sat[(int)satindex[indx]].catnum ++ : sat[(int)satindex[indx]].name, ++ sat_azi, sat_ele, maidenstr, ++ (disttype=='i') ? sat_alt*km2mi : sat_alt, ++ (disttype=='i') ? sat_range*km2mi : sat_range, ++ sunstat, ++ ((aos[(int)satindex[indx]]-daynum) < 0.0069) ++ ? Daynum2String(aos[(int)satindex[indx]]-daynum,12," %M:%S") ++ : Daynum2String(aos[(int)satindex[indx]],12,"%j.%H:%M:%S")); ++ else ++ mvprintw(w+y,1, ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? " #%-12d%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %12s " ++ : " %-13s%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %12s ", ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? (const char *)sat[(int)satindex[indx]].catnum ++ : sat[(int)satindex[indx]].name, ++ sat_azi, sat_ele, sat_lat, 360.0-sat_lon, ++ (disttype=='i') ? sat_alt*km2mi : sat_alt, ++ (disttype=='i') ? sat_range*km2mi : sat_range, ++ sunstat, ++ ((aos[(int)satindex[indx]]-daynum) < 0.0069) ++ ? Daynum2String(aos[(int)satindex[indx]]-daynum,12," %M:%S") ++ : Daynum2String(aos[(int)satindex[indx]],12,"%j.%H:%M:%S")); ++ ++ if (fabs(sat_range_rate)<0.1) ++ mvprintw(w+y,54,"="); ++ else ++ if (sat_range_rate<0.0) ++ mvprintw(w+y,54,"/"); ++ if (sat_range_rate>0.0) ++ mvprintw(w+y,54,"\\"); ++ y++; ++ } ++ } ++ } while ((w+y)<=(LINES-2) && z++<(totalsats)); ++ ++/* Geostationary / Never reaches AOS */ ++ ++ w=w+y; y=0; z=0; ++ if (w<=(LINES-2)) ++ do { ++ indx=z; ++ ++ if (sat[(int)satindex[indx]].meanmo!=0.0 && Decayed((int)satindex[indx],0.0)!=1) { ++ daynum=CurrentDaynum(); ++ PreCalc((int)satindex[indx]); ++ Calc(); ++ ++ if (sat_ele >= 0.0) ++ inrange[(int)satindex[indx]]=1; ++ else ++ inrange[(int)satindex[indx]]=0; ++ ++ if (sat_sun_status) { ++ if (sun_ele<=-12.0 && sat_ele>=0.0) ++ sunstat='V'; ++ else ++ sunstat='D'; ++ } else ++ sunstat='N'; ++ ++ if (!ok2predict[(int)satindex[indx]]) { ++ getMaidenHead(sat_lat,sat_lon,maidenstr); ++ attrset(COLOR_PAIR(3)); ++ if (multitype=='m') ++ mvprintw(w+y,1, ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? " #%-12d%5.1f %5.1f %7s %6.0f %6.0f %c %12s " ++ : " %-13s%5.1f %5.1f %7s %6.0f %6.0f %c %12s ", ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? (const char *)sat[(int)satindex[indx]].catnum ++ : sat[(int)satindex[indx]].name, ++ sat_azi, sat_ele, maidenstr, ++ (disttype=='i') ? sat_alt*km2mi : sat_alt, ++ (disttype=='i') ? sat_range*km2mi : sat_range, ++ sunstat, "*GeoS-NoAOS*"); ++ else ++ mvprintw(w+y,1, ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? " #%-12d%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %12s " ++ : " %-13s%5.1f %5.1f %3.0f %3.0f %6.0f %6.0f %c %12s ", ++ (strlen(sat[(int)satindex[indx]].name)>12) ++ ? (const char *)sat[(int)satindex[indx]].catnum ++ : sat[(int)satindex[indx]].name, ++ sat_azi, sat_ele, sat_lat, 360.0-sat_lon, ++ (disttype=='i') ? sat_alt*km2mi : sat_alt, ++ (disttype=='i') ? sat_range*km2mi : sat_range, ++ sunstat, "*GeoS-NoAOS*"); ++ ++ if (fabs(sat_range_rate)<0.1) ++ mvprintw(w+y,54,"="); ++ else ++ if (sat_range_rate<0.0) ++ mvprintw(w+y,54,"/"); ++ if (sat_range_rate>0.0) ++ mvprintw(w+y,54,"\\"); ++ y++; ++ } ++ } ++ } while ((w+y)<=(LINES-2) && z++<(totalsats)); ++ ++ mvprintw(w+y ,1," "); ++ mvprintw(w+y+1,1," "); ++ mvprintw(w+y+2,1," "); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ ++ daynum=CurrentDaynum(); ++ mvprintw(1,54,"%s",Daynum2String(daynum,24,"%a %d%b%y %j.%H:%M:%S")); ++ ++ mvprintw(1,35,"(%d/%d in view) ", siv,totalsats); ++ ++ refresh(); ++ halfdelay(halfdelaytime); /* Increase if CPU load is too high */ ++ ans=tolower(getch()); ++ ++ if (ans=='m') multitype='m'; ++ if (ans=='l') multitype='l'; ++ if (ans=='k') disttype ='k'; ++ if (ans=='i') disttype ='i'; ++ ++ /* If we receive a RELOAD_TLE command through the ++ socket connection, or an 'r' through the keyboard, ++ reload the TLE file. */ ++ ++ if (reload_tle || ans=='r') { ++ ReadDataFiles(); ++ reload_tle=0; ++ nextcalctime=0.0; ++ } ++ ++ } while (ans!='q' && ans!=27); ++ ++ cbreak(); ++ sprintf(tracking_mode, "NONE\n%c",0); ++} ++ ++void Illumination() ++{ ++ double startday, oneminute, sunpercent; ++ int eclipses, minutes, quit, breakout=0; ++ char string1[40], string[80], datestring[25], count; ++ ++ oneminute=1.0/(24.0*60.0); ++ ++ PreCalc(indx); ++ daynum=floor(GetStartTime(0)); ++ startday=daynum; ++ count=0; ++ ++ curs_set(0); ++ clear(); ++ ++ if (xterm) ++ fprintf(stderr,"\033]0;PREDICT: %s's Solar Illumination Calendar For %s\007",qth.callsign, sat[indx].name); ++ ++ ++ do { ++ attrset(COLOR_PAIR(4)); ++ mvprintw(LINES - 2,6," Calculating... Press [ESC] To Quit"); ++ refresh(); ++ ++ count++; ++ daynum=startday; ++ ++ for (minutes=0, eclipses=0; minutes<1440; minutes++) { ++ Calc(); ++ ++ if (sat_sun_status==0) ++ eclipses++; ++ ++ daynum=startday+(oneminute*(double)minutes); ++ } ++ ++ sunpercent=((double)eclipses)/((double)minutes); ++ sunpercent=100.0-(sunpercent*100.0); ++ ++ strcpy(datestring,Daynum2String(startday,20,"%a %d%b%y %H:%M:%S")); ++ datestring[11]=0; ++ sprintf(string1," %s %4d %6.2f%c",datestring,1440-eclipses,sunpercent,37); ++ ++ /* Allow a quick way out */ ++ ++ nodelay(stdscr,TRUE); ++ ++ if (getch()==27) ++ breakout=1; ++ ++ nodelay(stdscr,FALSE); ++ ++ startday+= (LINES-8); ++ ++ daynum=startday; ++ ++ for (minutes=0, eclipses=0; minutes<1440; minutes++) { ++ Calc(); ++ ++ if (sat_sun_status==0) ++ eclipses++; ++ ++ daynum=startday+(oneminute*(double)minutes); ++ } ++ ++ sunpercent=((double)eclipses)/((double)minutes); ++ sunpercent=100.0-(sunpercent*100.0); ++ ++ strcpy(datestring,Daynum2String(startday,20,"%a %d%b%y %H:%M:%S")); ++ datestring[11]=0; ++ sprintf(string,"%s\t %s %4d %6.2f%c\n",string1,datestring,1440-eclipses,sunpercent,37); ++ quit=Print(string,'s'); ++ ++ /* Allow a quick way out */ ++ ++ nodelay(stdscr,TRUE); ++ ++ if (getch()==27) ++ breakout=1; ++ ++ nodelay(stdscr,FALSE); ++ ++ if (count< (LINES-8)) ++ startday-= (LINES-9); ++ else { ++ count=0; ++ startday+=1.0; ++ } ++ } ++ while (quit!=1 && breakout!=1 && Decayed(indx,daynum)==0); ++} ++ ++void MainMenu() ++{ ++ /* Start-up menu. Your wish is my command. :-) */ ++ ++ Banner(); ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw( 9,2," P "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw( 9,6," Predict Satellite Passes"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(11,2," V "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(11,6," Predict Visible Passes"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(13,2," S "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(13,6," Solar Illumination Predictions"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(15,2," N "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(15,6," Lunar Pass Predictions"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(17,2," O "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(17,6," Solar Pass Predictions"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(19,2," T "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(19,6," Single Satellite Tracking Mode"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(21,2," M "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(21,6," Multi-Satellite Tracking Mode"); ++ ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw( 9,41," I "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw( 9,45," Program Information"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(11,41," G "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(11,45," Edit Ground Station Information"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(13,41," D "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(13,45," Display Satellite Orbital Data"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(15,41," U "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(15,45," Update Sat Elements From File"); ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(17,41," E "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(17,45," Manually Edit Orbital Database"); ++ ++ ++ attrset(COLOR_PAIR(6)|A_REVERSE|A_BOLD); ++ mvprintw(21,41," Q "); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ mvprintw(21,45," Exit PREDICT"); ++ ++ if (socket_flag) { ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ mvprintw( 1, 1,"Server Mode"); ++ } ++ ++ refresh(); ++ ++ if (xterm) ++ fprintf(stderr,"\033]0;PREDICT: Version %s\007",version); ++} ++ ++void ProgramInfo() ++{ ++ Banner(); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ ++ printw("\n\n\n\n\n\t\tPREDICT version : %s\n",version); ++ printw("\t\tQTH file loaded : %s\n",qthfile); ++ printw("\t\tTLE file loaded : %s\n",tlefile); ++ printw("\t\tDatabase file : "); ++ ++ if (database) ++ printw("Loaded\n"); ++ else ++ printw("Not loaded\n"); ++ ++ if (antfd!=-1) { ++ printw("\t\tAutoTracking : Sending data to %s",serial_port); ++ ++ if (once_per_second) ++ printw(" every second"); ++ ++ printw("\n"); ++ } else ++ printw("\t\tAutoTracking : Not enabled\n"); ++ ++ printw("\t\tRunning Mode : "); ++ ++ if (socket_flag) ++ printw("Network server on port \"%s\"\n",netport); ++ else ++ printw("Standalone\n"); ++ ++ printw("\t\tVocalizer : "); ++ ++ if (soundcard) ++ printw("Soundcard present"); ++ else ++ printw("No soundcard available"); ++ ++ refresh(); ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ AnyKey(); ++} ++ ++void NewUser() ++{ ++#if !defined (__CYGWIN32__) ++ int *mkdir(); ++#endif ++ ++ Banner(); ++ attrset(COLOR_PAIR(3)|A_BOLD); ++ ++ mvprintw(12,2,"WELCOME to PREDICT! Since you are a new user to the program, default\n"); ++ printw(" orbital data and ground station location information was copied into\n"); ++ printw(" your home directory to get you going. Please select option [G] from\n"); ++ printw(" PREDICT's main menu to edit your ground station information, and update\n"); ++ printw(" your orbital database using option [U] or [E]. Enjoy the program! :-)"); ++ refresh(); ++ ++ /* Make "~/.predict" subdirectory */ ++ ++ sprintf(temp,"%s/.predict",getenv("HOME")); ++ mkdir(temp,0777); ++ ++ /* Copy default files into ~/.predict directory */ ++ ++ sprintf(temp,"%sdefault/predict.tle",predictpath); ++ ++ CopyFile(temp,tlefile); ++ ++ sprintf(temp,"%sdefault/predict.db",predictpath); ++ ++ CopyFile(temp,dbfile); ++ ++ sprintf(temp,"%sdefault/predict.qth",predictpath); ++ ++ CopyFile(temp,qthfile); ++ ++ attrset(COLOR_PAIR(4)|A_BOLD); ++ AnyKey(); ++} ++ ++int QuickFind(string, outputfile) ++char *string, *outputfile; ++{ ++ int x, y, z, step=1; ++ long start, now, end, count; ++ char satname[50], startstr[20], endstr[20]; ++ time_t t; ++ FILE *fd; ++ ++ if (outputfile[0]) ++ fd=fopen(outputfile,"w"); ++ else ++ fd=stdout; ++ ++ startstr[0]=0; ++ endstr[0]=0; ++ ++ ReadDataFiles(); ++ ++ for (x=0; x<48 && string[x]!=0 && string[x]!='\n'; x++) ++ satname[x]=string[x]; ++ ++ satname[x]=0; ++ x++; ++ ++ for (y=0; string[x+y]!=0 && string[x+y]!='\n'; y++) ++ startstr[y]=string[x+y]; ++ ++ startstr[y]=0; ++ y++; ++ ++ for (z=0; string[x+y+z]!=0 && string[x+y+z]!='\n'; z++) ++ endstr[z]=string[x+y+z]; ++ ++ endstr[z]=0; ++ ++ /* Do a simple search for the matching satellite name */ ++ ++ for (z=0; z86400) { ++ start=now; ++ end=now-1; ++ } ++ } ++ ++ if ((start>=now-31557600) && (start<=now+31557600) && end==0) { ++ /* Start must be one year from now */ ++ /* Display a single position */ ++ daynum=((start/86400.0)-3651.0); ++ PreCalc(indx); ++ Calc(); ++ ++ if (Decayed(indx,daynum)==0) ++ fprintf(fd,"%ld %s %4d %4d %4d %4d %4d %6ld %6ld %c\n",start,Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,isplat,isplong,irk,rv,findsun); ++ break; ++ } else { ++ /* Display a whole list */ ++ for (count=start; count<=end; count+=step) { ++ daynum=((count/86400.0)-3651.0); ++ PreCalc(indx); ++ Calc(); ++ ++ if (Decayed(indx,daynum)==0) ++ fprintf(fd,"%ld %s %4d %4d %4d %4d %4d %6ld %6ld %c\n",count,Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,isplat,isplong,irk,rv,findsun); ++ } ++ break; ++ } ++ } ++ } ++ ++ if (outputfile[0]) ++ fclose(fd); ++ ++ return 0; ++} ++ ++int QuickPredict(string, outputfile) ++char *string, *outputfile; ++{ ++ int x, y, z, lastel=0; ++ long start, now; ++ char satname[50], startstr[20]; ++ time_t t; ++ FILE *fd; ++ ++ if (outputfile[0]) ++ fd=fopen(outputfile,"w"); ++ else ++ fd=stdout; ++ ++ startstr[0]=0; ++ ++ ReadDataFiles(); ++ ++ for (x=0; x<48 && string[x]!=0 && string[x]!='\n'; x++) ++ satname[x]=string[x]; ++ ++ satname[x]=0; ++ x++; ++ ++ for (y=0; string[x+y]!=0 && string[x+y]!='\n'; y++) ++ startstr[y]=string[x+y]; ++ ++ startstr[y]=0; ++ y++; ++ ++ /* Do a simple search for the matching satellite name */ ++ ++ for (z=0; z=now-31557600) && (start<=now+31557600)) { ++ /* Start must within one year of now */ ++ daynum=((start/86400.0)-3651.0); ++ PreCalc(indx); ++ Calc(); ++ ++ if (AosHappens(indx) && Geostationary(indx)==0 && Decayed(indx,daynum)==0) { ++ /* Make Predictions */ ++ daynum=FindAOS(); ++ ++ /* Display the pass */ ++ ++ while (iel>=0) { ++ fprintf(fd,"%.0f %s %4d %4d %4d %4d %4d %6ld %6ld %c\n",floor(86400.0*(3651.0+daynum)),Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,isplat,isplong,irk,rv,findsun); ++ lastel=iel; ++ daynum+=cos((sat_ele-1.0)*deg2rad)*sqrt(sat_alt)/25000.0; ++ Calc(); ++ } ++ ++ if (lastel!=0) { ++ daynum=FindLOS(); ++ Calc(); ++ fprintf(fd,"%.0f %s %4d %4d %4d %4d %4d %6ld %6ld %c\n",floor(86400.0*(3651.0+daynum)),Daynum2String(daynum,20,"%a %d%b%y %H:%M:%S"),iel,iaz,ma256,isplat,isplong,irk,rv,findsun); ++ } ++ } ++ break; ++ } ++ } ++ } ++ ++ if (outputfile[0]) ++ fclose(fd); ++ ++ return 0; ++} ++ ++double GetDayNum ( struct timeval *tv ) ++{ ++ /* used by PredictAt */ ++ return ( ( ( (double) (tv->tv_sec) - 0.000001 * ( (double) (tv->tv_usec) ) ) / 86400.0) - 3651.0 ); ++} ++ ++/* ++ void PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++ ++ Computes the satellites possition at the given time... ++ ... so that we can report it via a socket. ++ ++ Returns: ++ TRUE if successful. ++ ++ Author/Editor: ++ February 2003 ++ Glenn Richardson ++ glenn@spacequest.com ++*/ ++ ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++{ ++ double dDayNum; /* time of prediction */ ++ double dOldRange, dOldClock; /* range / time of pre-prediction position */ ++ double dDoppler = 0.0; /* doppler calculation */ ++ double dDeltaTime, dDeltaPos; /* used in doppler calc */ ++ double dQLat, dQLong; /* remember the groundstation lat/long */ ++ int iInRange; /* is the satellite in view? */ ++ struct timeval tv; /* time structure... */ ++ ++ /* remember... */ ++ dQLat = qth.stnlat; ++ dQLong = qth.stnlong; ++ qth.stnlat = dLat; ++ qth.stnlong = dLong; ++ ++ /* are the keps ok? */ ++ if ( ( sat[iSatID].meanmo == 0.0) || ( Decayed ( iSatID, 0.0 ) == 1 ) || ( Geostationary ( iSatID ) ) || !( AosHappens ( iSatID ) ) ) ++ { ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ /* !!!! NOTE: we only compute LEOs !!!! */ ++ /* syslog ( LOG_INFO, "PredictAT() can't do this one..."); */ ++ return FALSE; ++ } ++ ++ /* syslog ( LOG_INFO, "PredictAT: ttDayNum... %ld, %s", (unsigned long) ttDayNum, ctime ( &ttDayNum ) ); */ ++ /* first, prepare for doppler by computing pos 5 sec ago */ ++ indx = iSatID; ++ tv.tv_sec = ttDayNum - 5; ++ tv.tv_usec = 0; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dOldClock = 86400.0 * daynum; ++ dOldRange = sat_range * 1000.0; ++ ++ /* now, recompute at current position */ ++ tv.tv_sec = ttDayNum; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dDayNum = daynum; ++ ++ /* setup for doppler... */ ++ dDeltaTime = dDayNum * 86400.0 - dOldClock; ++ dDeltaPos = (sat_range * 1000.0) - dOldRange; ++ ++ if ( sat_azi >= 0.0 ) ++ { ++ iInRange = 1; ++ ++ /* compute the doppler */ ++ dDoppler = - ( ( dDeltaPos / dDeltaTime ) / 299792458.0 ); ++ dDoppler = dDoppler * 100.0e6; ++ } ++ else ++ { ++ /* compute the doppler */ ++ iInRange = 0; ++ } ++ ++ /* printf ("InRange? %d, doppler: %f, Az: %f, El: %f, %s", ++ iInRange, dDoppler, azimuth, elevation, ctime ( &ttDayNum ) ); */ ++ /* remember values for socket connection... */ ++ az_array[iSatID] = sat_azi; ++ el_array[iSatID] = sat_ele; ++ lat_array[iSatID] = sat_lat; ++ long_array[iSatID] = 360.0 - sat_lon; ++ footprint_array[iSatID] = fk; ++ range_array[iSatID] = sat_range; ++ altitude_array[iSatID] = sat_alt; ++ velocity_array[iSatID] = sat_vel; ++ orbitnum_array[iSatID] = rv; ++ doppler[iSatID] = dDoppler; ++ ++ ++ /* Calculate Next Event (AOS/LOS) Times */ ++ if ( iInRange ) ++ nextevent[iSatID] = FindLOS2(); ++ else ++ nextevent[iSatID] = FindAOS(); ++ ++ ++ /* restore... */ ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ return TRUE; ++} ++ ++int main(argc,argv) ++char argc, *argv[]; ++{ ++ int x, y, z, key=0; ++ char updatefile[80], quickfind=0, quickpredict=0, ++ quickstring[40], outputfile[42], ++ tle_cli[50], qth_cli[50], interactive=0; ++ struct termios oldtty, newtty; ++ pthread_t thread; ++ char *env=NULL; ++ FILE *db; ++ ++ /* Set up translation table for computing TLE checksums */ ++ ++ for (x=0; x<=255; val[x]=0, x++); ++ for (x='0'; x<='9'; val[x]=x-'0', x++); ++ ++ val['-']=1; ++ ++ updatefile[0]=0; ++ quickstring[0]=0; ++ outputfile[0]=0; ++ temp[0]=0; ++ tle_cli[0]=0; ++ qth_cli[0]=0; ++ dbfile[0]=0; ++ netport[0]=0; ++ serial_port[0]=0; ++ once_per_second=0; ++ ++ y=argc-1; ++ antfd=-1; ++ ++ for (x=1; x<=y; x++) { ++ if (strcmp(argv[x],"-f")==0) { ++ quickfind=1; ++ z=x+1; ++ while (z<=y && argv[z][0] && argv[z][0]!='-') { ++ if ((strlen(quickstring)+strlen(argv[z]))<37) { ++ strncat(quickstring,argv[z],15); ++ strcat(quickstring,"\n"); ++ z++; ++ } ++ } ++ z--; ++ } ++ ++ if (strcmp(argv[x],"-p")==0) { ++ quickpredict=1; ++ z=x+1; ++ while (z<=y && argv[z][0] && argv[z][0]!='-') { ++ if ((strlen(quickstring)+strlen(argv[z]))<37) { ++ strncat(quickstring,argv[z],15); ++ strcat(quickstring,"\n"); ++ z++; ++ } ++ } ++ z--; ++ } ++ ++ if (strcmp(argv[x],"-u")==0) { ++ z=x+1; ++ while (z<=y && argv[z][0] && argv[z][0]!='-') { ++ if ((strlen(updatefile)+strlen(argv[z]))<75) { ++ strncat(updatefile,argv[z],75); ++ strcat(updatefile,"\n"); ++ z++; ++ } ++ } ++ z--; ++ } ++ ++ if (strcmp(argv[x],"-t")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(tle_cli,argv[z],48); ++ } ++ ++ if (strcmp(argv[x],"-q")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(qth_cli,argv[z],48); ++ } ++ ++ if (strcmp(argv[x],"-a")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(serial_port,argv[z],13); ++ } ++ ++ if (strcmp(argv[x],"-a1")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(serial_port,argv[z],13); ++ once_per_second=1; ++ } ++ ++ if (strcmp(argv[x],"-o")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(outputfile,argv[z],40); ++ } ++ ++ if (strcmp(argv[x],"-n")==0) { ++ z=x+1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') ++ strncpy(netport,argv[z],5); ++ } ++ ++ if (strcmp(argv[x],"-s")==0) ++ socket_flag=1; ++ ++ if (strcmp(argv[x],"-north")==0) /* Default */ ++ io_lat='N'; ++ ++ if (strcmp(argv[x],"-south")==0) ++ io_lat='S'; ++ ++ if (strcmp(argv[x],"-west")==0) /* Default */ ++ io_lon='W'; ++ ++ if (strcmp(argv[x],"-east")==0) ++ io_lon='E'; ++ } ++ ++ /* We're done scanning command-line arguments */ ++ ++ /* If no command-line (-t or -q) arguments have been passed ++ to PREDICT, create qth and tle filenames based on the ++ default ($HOME) directory. */ ++ ++ env=getenv("HOME"); ++ ++ if (qth_cli[0]==0) ++ sprintf(qthfile,"%s/.predict/predict.qth",env); ++ else ++ sprintf(qthfile,"%s%c",qth_cli,0); ++ ++ if (tle_cli[0]==0) ++ sprintf(tlefile,"%s/.predict/predict.tle",env); ++ else ++ sprintf(tlefile,"%s%c",tle_cli,0); ++ ++ /* Test for interactive/non-interactive mode of operation ++ based on command-line arguments given to PREDICT. */ ++ ++ if (updatefile[0] || quickfind || quickpredict) ++ interactive=0; ++ else ++ interactive=1; ++ ++ if (interactive) { ++ sprintf(dbfile,"%s/.predict/predict.db",env); ++ ++ /* If the transponder database file doesn't already ++ exist under $HOME/.predict, and a working environment ++ is available, place a default copy from the PREDICT ++ distribution under $HOME/.predict. */ ++ ++ db=fopen(dbfile,"r"); ++ ++ if (db==NULL) { ++ sprintf(temp,"%sdefault/predict.db",predictpath); ++ CopyFile(temp,dbfile); ++ } else ++ fclose(db); ++ } ++ ++ x=ReadDataFiles(); ++ ++ if (x>1) /* TLE file was loaded successfully */ { ++ if (updatefile[0]) { ++ y=0; ++ z=0; ++ temp[0]=0; ++ ++ while (updatefile[y]!=0) { ++ while (updatefile[y]!='\n' && updatefile[y]!=0 && y<79) { ++ temp[z]=updatefile[y]; ++ z++; ++ y++; ++ } ++ ++ temp[z]=0; ++ ++ if (temp[0]) { ++ AutoUpdate(temp); ++ temp[0]=0; ++ z=0; ++ y++; ++ } ++ } ++ exit(0); ++ } ++ } ++ ++ if (x==3) /* Both TLE and QTH files were loaded successfully */ { ++ if (quickfind) ++ exit(QuickFind(quickstring,outputfile)); ++ ++ if (quickpredict) ++ exit(QuickPredict(quickstring,outputfile)); ++ } else { ++ if (tle_cli[0] || qth_cli[0]) { ++ /* "Houston, we have a problem..." */ ++ ++ printf("\n%c",7); ++ ++ if (x^1) ++ printf("*** ERROR! Your QTH file \"%s\" could not be loaded!\n",qthfile); ++ ++ if (x^2) ++ printf("*** ERROR! Your TLE file \"%s\" could not be loaded!\n",tlefile); ++ ++ printf("\n"); ++ ++ exit(-1); ++ } ++ } ++ ++ if (interactive) { ++ /* We're in interactive mode. Prepare the screen */ ++ ++ /* Are we running under an xterm or equivalent? */ ++ ++ env=getenv("TERM"); ++ ++ if (env!=NULL && strncmp(env,"xterm",5)==0) ++ xterm=1; ++ else ++ xterm=0; ++ ++ /* Start ncurses */ ++ ++ initscr(); ++ keypad(stdscr, TRUE); ++ start_color(); ++ cbreak(); ++ noecho(); ++ scrollok(stdscr,TRUE); ++ curs_set(0); ++ ++ init_pair(1,COLOR_WHITE,COLOR_BLACK); ++ init_pair(2,COLOR_WHITE,COLOR_BLUE); ++ init_pair(3,COLOR_YELLOW,COLOR_BLUE); ++ init_pair(4,COLOR_CYAN,COLOR_BLUE); ++ init_pair(5,COLOR_WHITE,COLOR_RED); ++ init_pair(6,COLOR_RED,COLOR_WHITE); ++ init_pair(7,COLOR_CYAN,COLOR_RED); ++ ++ if (x<3) { ++ NewUser(); ++ x=ReadDataFiles(); ++ QthEdit(); ++ } ++ } ++ ++ if (x==3) { ++ /* Open serial port to send data to ++ the antenna tracker if present. */ ++ ++ if (serial_port[0]!=0) { ++ /* Make sure there's no trailing '/' */ ++ ++ x=strlen(serial_port); ++ ++ if (serial_port[x-1]=='/') ++ serial_port[x-1]=0; ++ ++ antfd=open(serial_port, O_WRONLY|O_NOCTTY); ++ ++ if (antfd!=-1) { ++ /* Set up serial port */ ++ ++ tcgetattr(antfd, &oldtty); ++ memset(&newtty, 0, sizeof(newtty)); ++ ++ /* 9600 baud, 8-bits, no parity, ++ 1-stop bit, no handshaking */ ++ ++ newtty.c_cflag=B9600|CS8|CLOCAL; ++ newtty.c_iflag=IGNPAR; ++ newtty.c_oflag=0; ++ newtty.c_lflag=0; ++ ++ tcflush(antfd, TCIFLUSH); ++ tcsetattr(antfd, TCSANOW, &newtty); ++ } else { ++ bailout("Unable To Open Antenna Port"); ++ exit(-1); ++ } ++ } ++ ++ /* Socket activated here. Remember that ++ the socket data is updated only when ++ running in the real-time tracking modes. */ ++ ++ if (socket_flag) { ++ pthread_create(&thread,NULL,(void *)socket_server,(void *)argv[0]); ++ bkgdset(COLOR_PAIR(3)); ++ MultiTrack('m','i'); ++ } ++ ++ MainMenu(); ++ ++ do { ++ key=getch(); ++ ++ if (key!='T') ++ key=tolower(key); ++ ++ switch (key) { ++ case 'p': ++ case 'v': ++ Print("",0); ++ PrintVisible(""); ++ indx=Select(); ++ ++ if (indx!=-1 && sat[indx].meanmo!=0.0 && Decayed(indx,0.0)==0) ++ Predict(key); ++ ++ MainMenu(); ++ break; ++ ++ case 'n': ++ Print("",0); ++ PredictMoon(); ++ MainMenu(); ++ break; ++ ++ case 'o': ++ Print("",0); ++ PredictSun(); ++ MainMenu(); ++ break; ++ ++ case 'u': ++ AutoUpdate(""); ++ MainMenu(); ++ break; ++ ++ case 'e': ++ KepEdit(); ++ MainMenu(); ++ break; ++ ++ case 'd': ++ ShowOrbitData(); ++ MainMenu(); ++ break; ++ ++ case 'g': ++ QthEdit(); ++ MainMenu(); ++ break; ++ ++ case 't': ++ case 'T': ++ indx=Select(); ++ ++ if (indx!=-1 && sat[indx].meanmo!=0.0 && Decayed(indx,0.0)==0) ++ SingleTrack(indx,key); ++ ++ MainMenu(); ++ break; ++ ++ case 'm': ++ case 'l': ++ MultiTrack(key,'i'); ++ MainMenu(); ++ break; ++ ++ case 'i': ++ ProgramInfo(); ++ MainMenu(); ++ break; ++ ++ case 's': ++ indx=Select(); ++ if (indx!=-1 && sat[indx].meanmo!=0.0 && Decayed(indx,0.0)==0) { ++ Print("",0); ++ Illumination(); ++ } ++ MainMenu(); ++ break; ++ } ++ ++ } while (key!='q' && key!=27); ++ ++ if (antfd!=-1) { ++ tcsetattr(antfd,TCSANOW,&oldtty); ++ close(antfd); ++ } ++ ++ curs_set(1); ++ bkgdset(COLOR_PAIR(1)); ++ clear(); ++ refresh(); ++ endwin(); ++ } ++ ++ exit(0); ++} --- predict-2.2.3.orig/debian/patches/series +++ predict-2.2.3/debian/patches/series @@ -0,0 +1,20 @@ +000_build_system.diff +010_reboostrap.diff +020_predict_h.diff +030_predict_c.diff +040_fodtrack_c.diff +050_map_main_c.diff +060_map_c.diff +070_map_cb_c.diff +080_earthtrack_c.diff +090_gsat_README.diff +100_gsat_globals_h.diff +110_vocalizer_c.diff +120_radio_FT847.diff +121_predict-g1yyh.diff +130_gtk2.diff +140_fix-buffer-overflow.diff +141_buffer_overflow.diff +150_man_predict-g1yhh.diff +180_reworked_gui.diff +fix-R0-conflict.diff --- predict-2.2.3.orig/debian/patches/130_gtk2.diff +++ predict-2.2.3/debian/patches/130_gtk2.diff @@ -0,0 +1,34 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/src/interface.c +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/src/interface.c 2009-11-14 11:13:16.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/src/interface.c 2009-11-14 11:35:45.000000000 -0500 +@@ -347,7 +347,8 @@ + gtk_widget_set_usize (maparea, 700, 350); + gtk_widget_set_sensitive (maparea, FALSE); + +- toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_TEXT); ++/* toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_TEXT); */ ++ toolbar = gtk_toolbar_new (); + gtk_widget_set_name (toolbar, "toolbar"); + gtk_widget_ref (toolbar); + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "toolbar", toolbar, +@@ -357,8 +358,8 @@ + gtk_widget_set_uposition (toolbar, 0, 0); + gtk_widget_set_usize (toolbar, 696, 24); + gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5); +- gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar), 10); +- gtk_toolbar_set_space_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_SPACE_LINE); ++/* gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar), 10); */ ++/* gtk_toolbar_set_space_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_SPACE_LINE); */ + gtk_toolbar_set_tooltips (GTK_TOOLBAR (toolbar), FALSE); + + cb_connect = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), +@@ -1751,7 +1752,7 @@ + GtkWidget *lb_azel_elevation; + GtkWidget *lb_azel_azimuth; + +- dialog_azel_graph = gtk_window_new (GTK_WINDOW_DIALOG); ++ dialog_azel_graph = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (dialog_azel_graph, "dialog_azel_graph"); + gtk_object_set_data (GTK_OBJECT (dialog_azel_graph), "dialog_azel_graph", dialog_azel_graph); + gtk_window_set_title (GTK_WINDOW (dialog_azel_graph), _("gsat - AZ/EL tracking")); --- predict-2.2.3.orig/debian/patches/070_map_cb_c.diff +++ predict-2.2.3/debian/patches/070_map_cb_c.diff @@ -0,0 +1,43 @@ +Index: predict-2.2.3/clients/map/map_cb.c +=================================================================== +--- predict-2.2.3.orig/clients/map/map_cb.c 2009-11-14 09:48:53.000000000 -0500 ++++ predict-2.2.3/clients/map/map_cb.c 2009-11-14 09:51:07.000000000 -0500 +@@ -18,9 +18,11 @@ + *****************************************************************************/ + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -39,7 +41,7 @@ + /* This function implements the arccosine function, + returning a value between 0 and two pi. */ + +- double result, fraction; ++ double result=0.0, fraction; + + fraction=x/y; + +@@ -76,7 +78,7 @@ + bzero((char *)&sin,sizeof(struct sockaddr_in)); + sin.sin_family = AF_INET; + +- if (pse=getservbyname(service,protocol)) ++ if ((pse=getservbyname(service,protocol))) + sin.sin_port=pse->s_port; + + else if ((sin.sin_port=htons((unsigned short)atoi(service)))==0) +@@ -85,7 +87,7 @@ + return -1; + } + +- if (phe=gethostbyname(host)) ++ if ((phe=gethostbyname(host))) + bcopy(phe->h_addr,(char *)&sin.sin_addr,phe->h_length); + + else if ((sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE) --- predict-2.2.3.orig/debian/patches/090_gsat_README.diff +++ predict-2.2.3/debian/patches/090_gsat_README.diff @@ -0,0 +1,13 @@ +Index: predict-2.2.3/clients/gsat-1.1.0/README +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/README 2009-11-14 10:27:34.000000000 -0500 ++++ predict-2.2.3/clients/gsat-1.1.0/README 2009-11-14 10:28:21.000000000 -0500 +@@ -39,7 +39,7 @@ + ABOUT PLUGINS + ------------- + +-gsat can do automatic doppler correction and rotor control via plugins. Plugins are placed in the /usr/local/lib/gsat/plugins directory by default. You can override this setting the GSATPLUGINSDIR environment variable. Plugin's name must begin by "radio_" for the radio plugins and "rotor_" for the rotor plugins. Once you have the plugins installed, you can select it in the preferences window, pass it a config string and activate it in the doppler section of the main window. ++gsat can do automatic doppler correction and rotor control via plugins. Plugins are placed in the /usr/lib/gsat/plugins directory by default. You can override this setting the GSATPLUGINSDIR environment variable. Plugin's name must begin by "radio_" for the radio plugins and "rotor_" for the rotor plugins. Once you have the plugins installed, you can select it in the preferences window, pass it a config string and activate it in the doppler section of the main window. + There is a file called Plugin_API with the info to program a custom plugin. There are some examples in the plugins subdir. + Please note that not all the plugins in the plugins directory of this package are in a working state. I'm working on some of them and it is possible that even some refuse to compile. I include them to show some examples of plugin programming. + --- predict-2.2.3.orig/debian/patches/110_vocalizer_c.diff +++ predict-2.2.3/debian/patches/110_vocalizer_c.diff @@ -0,0 +1,13 @@ +Index: predict-2.2.3/vocalizer/vocalizer.c +=================================================================== +--- predict-2.2.3.orig/vocalizer/vocalizer.c 2009-11-14 10:38:16.000000000 -0500 ++++ predict-2.2.3/vocalizer/vocalizer.c 2009-11-14 10:39:24.000000000 -0500 +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include "vocalizer.h" ++char *path={"/usr/lib/predict/"}; + + int dsp; + char numstr[20][10]; --- predict-2.2.3.orig/debian/patches/080_earthtrack_c.diff +++ predict-2.2.3/debian/patches/080_earthtrack_c.diff @@ -0,0 +1,146 @@ +Index: predict-2.2.3/clients/earthtrack/earthtrack.c +=================================================================== +--- predict-2.2.3.orig/clients/earthtrack/earthtrack.c 2009-11-14 11:04:01.000000000 -0500 ++++ predict-2.2.3/clients/earthtrack/earthtrack.c 2009-11-14 11:06:02.000000000 -0500 +@@ -350,17 +350,22 @@ + char argc, *argv[]; + { + int x, y, z, updateinterval, satnum=0, radius=50, sleeptime=20; ++ int background=0; + char buf[128], command[255], satlist[625], satname[26], + satnamelist[26][26], callsign[15], markerfile[50], + greatarcfile[50], configfile[50], sat2track[30], +- hostname[50], color[35], xtra[50], xplanet=0, ++ outfname[250]="", ++ screenpos[10]="200,200", ++ hostname[50], color[35], xtra[50],proj[25], xplanet=1, ++ backimage[26]="~/.predict/background.jpg ", ++ earthpref[25]="~/.predict/earth_", + xearth=0, visibility, circledrawn=0, zoom=0; +- float az, el, slat, slong, qthlat, ++ float az, el, slat, slong, qthlat, magn=0.8, + qthlong, footprint, range, altitude, + velocity, mapcenterlat, mapcenterlong; + long next_event_time, orbitnum, starttime, endtime, current_time; + time_t t; +- FILE *fd=NULL; ++ FILE *fd=NULL,*xplanetfd=NULL; + + /* Parse command-line arguments */ + +@@ -371,39 +376,41 @@ + + buf[y]=0; + +- if (strncmp(buf,"arthtrack2",10)==0) ++#ifdef notdef ++ if (strncmp(buf,"earthtrack2",10)==0) + xplanet=1; + + if (strncmp(buf,"earthtrack",10)==0) + xearth=1; + ++#else ++ /* for Debian, always use xplanet since xearth is non-free! */ ++ xplanet=1; ++#endif + y=argc-1; + xtra[0]=0; + hostname[0]=0; + sat2track[0]=0; + updateinterval=0; ++ strcpy(proj,"ortho "); /* default */ + + for (x=1; x<=y; x++) + { + if (strcmp(argv[x],"-h")==0) + { + /* Hostname */ +- + z=x+1; +- + if (z<=y && argv[z][0] && argv[z][0]!='-') + strncpy(hostname,argv[z],50); ++ x++; + } + + if (strcmp(argv[x],"-c")==0 || strcmp(argv[x],"-C")==0) + { + /* Center map on this satellite */ +- + z=x+1; +- + if (z<=y && argv[z][0] && argv[z][0]!='-') + strncpy(sat2track,argv[z],30); +- + if (argv[x][1]=='C') + zoom=1; + } +@@ -411,21 +418,49 @@ + if (strcmp(argv[x],"-u")==0) + { + /* Screen update interval */ +- + z=x+1; +- + if (z<=y && argv[z][0] && argv[z][0]!='-') + sscanf(argv[z],"%d",&updateinterval); ++ x++; ++ } ++ ++ if (strcmp(argv[x],"-o")==0) { ++ /* outfile */ ++ xplanet=1; ++ strcpy(outfname," -output /tmp/xplanet.png "); /* default */ ++ if (argv[x+1][0] != '-') { /* Oh, a file name, not another switch? */ ++ sprintf(outfname," -output %s ",argv[x+1]); /* use that instead */ ++ x++; ++ } ++ } ++ ++ if (strcmp(argv[x],"-p")==0) { ++ /* projection */ ++ if (argv[x+1][0]!='-') { ++ strcpy(proj,argv[x+1]); /* override default */ ++ magn=1.0; ++ x++; ++ } ++ } ++ ++ if (strcmp(argv[x],"-g")==0) { ++ /* X display Geometery, Screen position */ ++ z=x+1; ++ background=1; ++ if (z<=y && argv[z][0] && argv[z][0]!='-') { ++ strncpy(screenpos,argv[z],10); ++ x++; ++ } ++ + } + + if (strcmp(argv[x],"-x")==0) + { + /* Extra commands to pass to xplanet or xearth */ +- + z=x+1; +- + if (z<=y && argv[z][0]) + strncpy(xtra,argv[z],50); ++ x++; + } + } + +@@ -528,6 +563,13 @@ + markerfd=fopen(markerfile,"w"); + greatarcfd=fopen(greatarcfile,"w"); + ++ /* ++ xplanetfd=fopen(configfile,"w"); ++ fprintf(xplanetfd,"[earth]\nmarker_file=%s\n", ++ markerfile); ++ fclose(xplanetfd); ++ */ ++ + fprintf(markerfd,"%8.3f %8.3f %c%s%c\n",qthlat,qthlong,34,callsign,34); + + for (z=0; z + #include + #include "map.h" + #include "world_fill.h" --- predict-2.2.3.orig/debian/patches/fix-R0-conflict.diff +++ predict-2.2.3/debian/patches/fix-R0-conflict.diff @@ -0,0 +1,150 @@ +Author: Niall Creech +Description: Some systems define an enumeration containing R0 in + sys/ucontext.h. Changing the name avoids any conflict. +Ubuntu-Bug: https://bugs.edge.launchpad.net/ubuntu/+source/predict/+bug/645036 +Index: predict-2.2.3/clients/earthtrack/earthtrack.c +=================================================================== +--- predict-2.2.3.orig/clients/earthtrack/earthtrack.c 2010-09-22 12:16:33.819222073 +0100 ++++ predict-2.2.3/clients/earthtrack/earthtrack.c 2010-09-22 12:16:34.143211509 +0100 +@@ -49,7 +49,7 @@ + #endif + + char string[625], error; +-double R0=6378.16, TWOPI=6.283185307179586, ++double LOCAL_R0=6378.16, TWOPI=6.283185307179586, + HALFPI=1.570796326794896, deg2rad=1.74532925199e-02; + FILE *markerfd=NULL, *greatarcfd=NULL; + +@@ -259,7 +259,7 @@ + + ssplat=ssplat*deg2rad; + ssplong=ssplong*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + for (azi=0; azi<360; azi++) + { +@@ -612,7 +612,7 @@ + circledrawn=1; + + if (zoom) +- radius=(int)(100.0*(R0/footprint)); ++ radius=(int)(100.0*(LOCAL_R0/footprint)); + else + radius=50; + +Index: predict-2.2.3/clients/earthtrack/earthtrack-old.c +=================================================================== +--- predict-2.2.3.orig/clients/earthtrack/earthtrack-old.c 2010-09-22 12:17:07.406126820 +0100 ++++ predict-2.2.3/clients/earthtrack/earthtrack-old.c 2010-09-22 12:17:41.189025221 +0100 +@@ -46,7 +46,7 @@ + #endif + + char string[625], error; +-double R0=6378.16, TWOPI=6.283185307179586, HALFPI=1.570796326794896, ++double LOCAL_R0=6378.16, TWOPI=6.283185307179586, HALFPI=1.570796326794896, + deg2rad=1.74532925199e-02; + FILE *markerfd=NULL, *greatarcfd=NULL; + +@@ -256,7 +256,7 @@ + + ssplat=ssplat*deg2rad; + ssplong=ssplong*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + for (azi=0; azi<360; azi++) + { +@@ -496,7 +496,7 @@ + circledrawn=1; + + if (zoom) +- radius=(int)(100.0*(R0/footprint)); ++ radius=(int)(100.0*(LOCAL_R0/footprint)); + else + radius=50; + +Index: predict-2.2.3/clients/earthtrack/earthtrack-really-old.c +=================================================================== +--- predict-2.2.3.orig/clients/earthtrack/earthtrack-really-old.c 2010-09-22 12:17:45.516884101 +0100 ++++ predict-2.2.3/clients/earthtrack/earthtrack-really-old.c 2010-09-22 12:18:05.740224680 +0100 +@@ -46,7 +46,7 @@ + #endif + + char string[625], error; +-double R0=6378.16, TWOPI=6.283185307179586, HALFPI=1.570796326794896, ++double LOCAL_R0=6378.16, TWOPI=6.283185307179586, HALFPI=1.570796326794896, + deg2rad=1.74532925199e-02; + FILE *markerfd=NULL, *greatarcfd=NULL; + +@@ -256,7 +256,7 @@ + + ssplat=ssplat*deg2rad; + ssplong=ssplong*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + for (azi=0; azi<360; azi++) + { +@@ -486,7 +486,7 @@ + circledrawn=1; + + if (zoom) +- radius=(int)(100.0*(R0/footprint)); ++ radius=(int)(100.0*(LOCAL_R0/footprint)); + else + radius=50; + +Index: predict-2.2.3/clients/gsat-1.1.0/src/comms.c +=================================================================== +--- predict-2.2.3.orig/clients/gsat-1.1.0/src/comms.c 2010-09-22 12:18:56.302576067 +0100 ++++ predict-2.2.3/clients/gsat-1.1.0/src/comms.c 2010-09-22 12:19:16.733909923 +0100 +@@ -326,7 +326,7 @@ + dopplershiftup, dopplershiftdown, dopplershiftbeacon, + rangelat, rangelong, azimuth, ssplat, + ssplong, TWOPI, HALFPI, deg2rad=1.74532925199e-02, +- R0=6378.16, beta, num, dem; ++ LOCAL_R0=6378.16, beta, num, dem; + GdkRectangle updatewin; + gint sx, sy; + GdkPoint footprintdots[360], qthfootprintdots[360]; +@@ -676,7 +676,7 @@ + if( satfootprint ) { + ssplat=slat*deg2rad; + ssplong=slong*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + for (azi=0; azi<360; azi++) + { +@@ -734,7 +734,7 @@ + if( qthfootprint ) { + ssplat=qthlat*deg2rad; + ssplong=qthlong*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + for (azi=0; azi<360; azi++) + { +Index: predict-2.2.3/clients/map/map_cb.c +=================================================================== +--- predict-2.2.3.orig/clients/map/map_cb.c 2010-09-22 12:18:27.539513892 +0100 ++++ predict-2.2.3/clients/map/map_cb.c 2010-09-22 12:18:44.390964444 +0100 +@@ -156,7 +156,7 @@ + struct tm gmt, *ptr_gmt; + + double rangelat, rangelong, azimuth, ssplat, ssplong, TWOPI, +- HALFPI, deg2rad=1.74532925199e-02, R0=6378.16, beta, num, dem; ++ HALFPI, deg2rad=1.74532925199e-02, LOCAL_R0=6378.16, beta, num, dem; + + TWOPI=2.0*PI; + HALFPI=PI/2.0; +@@ -237,7 +237,7 @@ + + ssplat=latitude*deg2rad; + ssplong=longitude*deg2rad; +- beta=(0.5*footprint)/R0; ++ beta=(0.5*footprint)/LOCAL_R0; + + fl_drawmode(GXxor); + fl_points(xa,360,FL_WHITE); --- predict-2.2.3.orig/debian/patches/040_fodtrack_c.diff +++ predict-2.2.3/debian/patches/040_fodtrack_c.diff @@ -0,0 +1,12 @@ +Index: predict-2.2.3/utils/fodtrack-0.1/fodtrack.c +=================================================================== +--- predict-2.2.3.orig/utils/fodtrack-0.1/fodtrack.c 2009-11-14 09:44:49.000000000 -0500 ++++ predict-2.2.3/utils/fodtrack-0.1/fodtrack.c 2009-11-14 09:45:06.000000000 -0500 +@@ -3,6 +3,7 @@ + */ + + #define __USE_GNU ++#define _XOPEN_SOURCE + + #include + #include --- predict-2.2.3.orig/debian/patches/180_reworked_gui.diff +++ predict-2.2.3/debian/patches/180_reworked_gui.diff @@ -0,0 +1,739 @@ +## Description: resizes and repositions widgets after GTK2 changes. +## Origin/Author: Norvald H. Ryeng +## Bug: https://bugs.launchpad.net/ubuntu/+source/predict/+bug/555706 +--- a/clients/gsat-1.1.0/src/interface.c ++++ b/clients/gsat-1.1.0/src/interface.c +@@ -18,6 +18,15 @@ + #include "interface.h" + #include "support.h" + ++void set_font (GtkWidget *widget, gpointer data) ++{ ++ PangoFontDescription *font = (PangoFontDescription *) data; ++ if (GTK_IS_WIDGET (widget)) ++ gtk_widget_modify_font (widget, font); ++ if (GTK_IS_CONTAINER (widget)) ++ gtk_container_forall(GTK_CONTAINER (widget), &set_font, data); ++} ++ + GtkWidget* + create_mainwindow (void) + { +@@ -94,6 +103,7 @@ + GtkWidget *lb_velocity; + GtkWidget *lb_ma; + GtkWidget *lb_squint; ++ PangoFontDescription *font_desc; + + mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (mainwindow, "mainwindow"); +@@ -331,8 +341,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "drawingframe", drawingframe, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (drawingframe); +- gtk_fixed_put (GTK_FIXED (fixed), drawingframe, 0, 24); +- gtk_widget_set_uposition (drawingframe, 0, 24); ++ gtk_fixed_put (GTK_FIXED (fixed), drawingframe, 0, 30); ++ gtk_widget_set_uposition (drawingframe, 0, 30); + gtk_widget_set_usize (drawingframe, 704, 354); + gtk_container_set_border_width (GTK_CONTAINER (drawingframe), 2); + gtk_frame_set_shadow_type (GTK_FRAME (drawingframe), GTK_SHADOW_ETCHED_OUT); +@@ -349,14 +359,15 @@ + + /* toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_TEXT); */ + toolbar = gtk_toolbar_new (); ++ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT); + gtk_widget_set_name (toolbar, "toolbar"); + gtk_widget_ref (toolbar); + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "toolbar", toolbar, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (toolbar); +- gtk_fixed_put (GTK_FIXED (fixed), toolbar, 0, 0); +- gtk_widget_set_uposition (toolbar, 0, 0); +- gtk_widget_set_usize (toolbar, 696, 24); ++ gtk_fixed_put (GTK_FIXED (fixed), toolbar, -12, -12); ++ gtk_widget_set_uposition (toolbar, -12, -12); ++ gtk_widget_set_usize (toolbar, 720, 48); + gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5); + /* gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar), 10); */ + /* gtk_toolbar_set_space_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_SPACE_LINE); */ +@@ -568,8 +579,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_downlink", lb_downlink, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_downlink); +- gtk_fixed_put (GTK_FIXED (fixed), lb_downlink, 8, 500); +- gtk_widget_set_uposition (lb_downlink, 8, 500); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_downlink, 4, 500); ++ gtk_widget_set_uposition (lb_downlink, 4, 500); + gtk_widget_set_usize (lb_downlink, 0, 0); + + lb_beacon = gtk_label_new (_("Beacon Frequency")); +@@ -578,8 +589,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_beacon", lb_beacon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_beacon); +- gtk_fixed_put (GTK_FIXED (fixed), lb_beacon, 8, 524); +- gtk_widget_set_uposition (lb_beacon, 8, 524); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_beacon, 4, 524); ++ gtk_widget_set_uposition (lb_beacon, 4, 524); + gtk_widget_set_usize (lb_beacon, 0, 0); + + lb_satellite = gtk_label_new (_("Satellite")); +@@ -588,8 +599,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_satellite", lb_satellite, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_satellite); +- gtk_fixed_put (GTK_FIXED (fixed), lb_satellite, 8, 388); +- gtk_widget_set_uposition (lb_satellite, 8, 388); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_satellite, 4, 388); ++ gtk_widget_set_uposition (lb_satellite, 4, 388); + gtk_widget_set_usize (lb_satellite, 0, 0); + + lb_uplink = gtk_label_new (_("Uplink Frequency")); +@@ -598,8 +609,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_uplink", lb_uplink, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_uplink); +- gtk_fixed_put (GTK_FIXED (fixed), lb_uplink, 8, 476); +- gtk_widget_set_uposition (lb_uplink, 8, 476); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_uplink, 4, 476); ++ gtk_widget_set_uposition (lb_uplink, 4, 476); + gtk_widget_set_usize (lb_uplink, 0, 0); + + lb_latitude = gtk_label_new (_("Latitude")); +@@ -608,8 +619,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_latitude", lb_latitude, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_latitude); +- gtk_fixed_put (GTK_FIXED (fixed), lb_latitude, 8, 416); +- gtk_widget_set_uposition (lb_latitude, 8, 416); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_latitude, 4, 416); ++ gtk_widget_set_uposition (lb_latitude, 4, 416); + gtk_widget_set_usize (lb_latitude, 0, 0); + + lb_longitude = gtk_label_new (_("Longitude")); +@@ -618,8 +629,8 @@ + gtk_object_set_data_full (GTK_OBJECT (mainwindow), "lb_longitude", lb_longitude, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_longitude); +- gtk_fixed_put (GTK_FIXED (fixed), lb_longitude, 8, 444); +- gtk_widget_set_uposition (lb_longitude, 8, 444); ++ gtk_fixed_put (GTK_FIXED (fixed), lb_longitude, 4, 444); ++ gtk_widget_set_uposition (lb_longitude, 4, 444); + gtk_widget_set_usize (lb_longitude, 0, 0); + + lb_orbit = gtk_label_new (_("Orbit")); +@@ -955,6 +966,13 @@ + + gtk_widget_grab_focus (combo_tx_satname); + gtk_widget_grab_default (combo_tx_satname); ++ ++ font_desc = gtk_widget_get_style (mainwindow)->font_desc; ++ pango_font_description_set_absolute_size (font_desc, 10 * PANGO_SCALE); ++ set_font (mainwindow, font_desc); ++ pango_font_description_set_absolute_size (font_desc, 9 * PANGO_SCALE); ++ set_font (toolbar, font_desc); ++ + return mainwindow; + } + +@@ -1071,8 +1089,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_downpluginconfig", tx_downpluginconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_downpluginconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), tx_downpluginconfig, 104, 40); +- gtk_widget_set_uposition (tx_downpluginconfig, 104, 40); ++ gtk_fixed_put (GTK_FIXED (fixed3), tx_downpluginconfig, 420, 70); ++ gtk_widget_set_uposition (tx_downpluginconfig, 420, 70); + gtk_widget_set_usize (tx_downpluginconfig, 160, 24); + + tx_uppluginconfig = gtk_entry_new (); +@@ -1081,8 +1099,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_uppluginconfig", tx_uppluginconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_uppluginconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), tx_uppluginconfig, 104, 112); +- gtk_widget_set_uposition (tx_uppluginconfig, 104, 112); ++ gtk_fixed_put (GTK_FIXED (fixed3), tx_uppluginconfig, 420, 142); ++ gtk_widget_set_uposition (tx_uppluginconfig, 420, 142); + gtk_widget_set_usize (tx_uppluginconfig, 160, 24); + + tx_beaconpluginconfig = gtk_entry_new (); +@@ -1091,8 +1109,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_beaconpluginconfig", tx_beaconpluginconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_beaconpluginconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), tx_beaconpluginconfig, 104, 184); +- gtk_widget_set_uposition (tx_beaconpluginconfig, 104, 184); ++ gtk_fixed_put (GTK_FIXED (fixed3), tx_beaconpluginconfig, 420, 214); ++ gtk_widget_set_uposition (tx_beaconpluginconfig, 420, 214); + gtk_widget_set_usize (tx_beaconpluginconfig, 160, 24); + + lb_prefs_upconfig = gtk_label_new (_("Plugin Config")); +@@ -1101,8 +1119,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_upconfig", lb_prefs_upconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_upconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_upconfig, 0, 112); +- gtk_widget_set_uposition (lb_prefs_upconfig, 0, 112); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_upconfig, 310, 142); ++ gtk_widget_set_uposition (lb_prefs_upconfig, 310, 142); + gtk_widget_set_usize (lb_prefs_upconfig, 96, 24); + + lb_prefs_beacon = gtk_label_new (_("Beacon plugin")); +@@ -1111,8 +1129,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_beacon", lb_prefs_beacon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_beacon); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_beacon, 0, 152); +- gtk_widget_set_uposition (lb_prefs_beacon, 0, 152); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_beacon, 310, 182); ++ gtk_widget_set_uposition (lb_prefs_beacon, 310, 182); + gtk_widget_set_usize (lb_prefs_beacon, 96, 24); + + lb_prefs_beaconconfig = gtk_label_new (_("Plugin Config")); +@@ -1121,8 +1139,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_beaconconfig", lb_prefs_beaconconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_beaconconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_beaconconfig, 0, 184); +- gtk_widget_set_uposition (lb_prefs_beaconconfig, 0, 184); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_beaconconfig, 310, 214); ++ gtk_widget_set_uposition (lb_prefs_beaconconfig, 310, 214); + gtk_widget_set_usize (lb_prefs_beaconconfig, 96, 24); + + combo_downplugin = gtk_combo_new (); +@@ -1131,8 +1149,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "combo_downplugin", combo_downplugin, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_downplugin); +- gtk_fixed_put (GTK_FIXED (fixed3), combo_downplugin, 104, 8); +- gtk_widget_set_uposition (combo_downplugin, 104, 8); ++ gtk_fixed_put (GTK_FIXED (fixed3), combo_downplugin, 420, 38); ++ gtk_widget_set_uposition (combo_downplugin, 420, 38); + gtk_widget_set_usize (combo_downplugin, 160, 24); + + entry_downplugin = GTK_COMBO (combo_downplugin)->entry; +@@ -1149,8 +1167,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "combo_beaconplugin", combo_beaconplugin, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_beaconplugin); +- gtk_fixed_put (GTK_FIXED (fixed3), combo_beaconplugin, 104, 152); +- gtk_widget_set_uposition (combo_beaconplugin, 104, 152); ++ gtk_fixed_put (GTK_FIXED (fixed3), combo_beaconplugin, 420, 182); ++ gtk_widget_set_uposition (combo_beaconplugin, 420, 182); + gtk_widget_set_usize (combo_beaconplugin, 160, 24); + + entry_beaconplugin = GTK_COMBO (combo_beaconplugin)->entry; +@@ -1167,9 +1185,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_downlink", lb_prefs_downlink, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_downlink); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_downlink, 0, 8); +- gtk_widget_set_uposition (lb_prefs_downlink, 0, 8); +- gtk_widget_set_usize (lb_prefs_downlink, 96, 24); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_downlink, 310, 38); ++ gtk_widget_set_uposition (lb_prefs_downlink, 310, 38); ++ gtk_widget_set_usize (lb_prefs_downlink, 106, 24); + + lb_prefs_downconfig = gtk_label_new (_("Plugin Config")); + gtk_widget_set_name (lb_prefs_downconfig, "lb_prefs_downconfig"); +@@ -1177,8 +1195,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_downconfig", lb_prefs_downconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_downconfig); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_downconfig, 0, 40); +- gtk_widget_set_uposition (lb_prefs_downconfig, 0, 40); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_downconfig, 310, 70); ++ gtk_widget_set_uposition (lb_prefs_downconfig, 310, 70); + gtk_widget_set_usize (lb_prefs_downconfig, 96, 24); + + lb_prefs_uplink = gtk_label_new (_("Uplink plugin")); +@@ -1187,8 +1205,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_uplink", lb_prefs_uplink, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_uplink); +- gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_uplink, 0, 80); +- gtk_widget_set_uposition (lb_prefs_uplink, 0, 80); ++ gtk_fixed_put (GTK_FIXED (fixed3), lb_prefs_uplink, 310, 110); ++ gtk_widget_set_uposition (lb_prefs_uplink, 310, 110); + gtk_widget_set_usize (lb_prefs_uplink, 96, 24); + + combo_upplugin = gtk_combo_new (); +@@ -1197,8 +1215,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "combo_upplugin", combo_upplugin, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_upplugin); +- gtk_fixed_put (GTK_FIXED (fixed3), combo_upplugin, 104, 80); +- gtk_widget_set_uposition (combo_upplugin, 104, 80); ++ gtk_fixed_put (GTK_FIXED (fixed3), combo_upplugin, 420, 110); ++ gtk_widget_set_uposition (combo_upplugin, 420, 110); + gtk_widget_set_usize (combo_upplugin, 160, 24); + + entry_upplugin = GTK_COMBO (combo_upplugin)->entry; +@@ -1234,8 +1252,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_rotorpluginconfig", tx_rotorpluginconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_rotorpluginconfig); +- gtk_fixed_put (GTK_FIXED (fixed8), tx_rotorpluginconfig, 96, 40); +- gtk_widget_set_uposition (tx_rotorpluginconfig, 96, 40); ++ gtk_fixed_put (GTK_FIXED (fixed8), tx_rotorpluginconfig, 420, 310); ++ gtk_widget_set_uposition (tx_rotorpluginconfig, 420, 310); + gtk_widget_set_usize (tx_rotorpluginconfig, 160, 24); + + lb_prefs_rotor = gtk_label_new (_("Rotor plugin")); +@@ -1244,8 +1262,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_rotor", lb_prefs_rotor, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_rotor); +- gtk_fixed_put (GTK_FIXED (fixed8), lb_prefs_rotor, 0, 8); +- gtk_widget_set_uposition (lb_prefs_rotor, 0, 8); ++ gtk_fixed_put (GTK_FIXED (fixed8), lb_prefs_rotor, 310, 278); ++ gtk_widget_set_uposition (lb_prefs_rotor, 310, 278); + gtk_widget_set_usize (lb_prefs_rotor, 96, 24); + + lb_prefs_rotorpluginconfig = gtk_label_new (_("Plugin Config")); +@@ -1254,8 +1272,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_rotorpluginconfig", lb_prefs_rotorpluginconfig, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_rotorpluginconfig); +- gtk_fixed_put (GTK_FIXED (fixed8), lb_prefs_rotorpluginconfig, 0, 40); +- gtk_widget_set_uposition (lb_prefs_rotorpluginconfig, 0, 40); ++ gtk_fixed_put (GTK_FIXED (fixed8), lb_prefs_rotorpluginconfig, 310, 310); ++ gtk_widget_set_uposition (lb_prefs_rotorpluginconfig, 310, 310); + gtk_widget_set_usize (lb_prefs_rotorpluginconfig, 96, 24); + + combo_rotorplugin = gtk_combo_new (); +@@ -1264,8 +1282,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "combo_rotorplugin", combo_rotorplugin, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_rotorplugin); +- gtk_fixed_put (GTK_FIXED (fixed8), combo_rotorplugin, 96, 8); +- gtk_widget_set_uposition (combo_rotorplugin, 96, 8); ++ gtk_fixed_put (GTK_FIXED (fixed8), combo_rotorplugin, 420, 278); ++ gtk_widget_set_uposition (combo_rotorplugin, 420, 278); + gtk_widget_set_usize (combo_rotorplugin, 160, 24); + + entry_rotorplugin = GTK_COMBO (combo_rotorplugin)->entry; +@@ -1301,8 +1319,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_aoscommand", tx_aoscommand, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_aoscommand); +- gtk_fixed_put (GTK_FIXED (fixed2), tx_aoscommand, 104, 216); +- gtk_widget_set_uposition (tx_aoscommand, 104, 216); ++ gtk_fixed_put (GTK_FIXED (fixed2), tx_aoscommand, 126, 278); ++ gtk_widget_set_uposition (tx_aoscommand, 126, 278); + gtk_widget_set_usize (tx_aoscommand, 160, 24); + + tx_loscommand = gtk_entry_new (); +@@ -1311,8 +1329,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "tx_loscommand", tx_loscommand, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_loscommand); +- gtk_fixed_put (GTK_FIXED (fixed2), tx_loscommand, 104, 264); +- gtk_widget_set_uposition (tx_loscommand, 104, 264); ++ gtk_fixed_put (GTK_FIXED (fixed2), tx_loscommand, 126, 310); ++ gtk_widget_set_uposition (tx_loscommand, 126, 310); + gtk_widget_set_usize (tx_loscommand, 160, 24); + + lb_prefs_time = gtk_label_new (_("Time format")); +@@ -1321,9 +1339,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_time", lb_prefs_time, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_time); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_time, 8, 48); +- gtk_widget_set_uposition (lb_prefs_time, 8, 48); +- gtk_widget_set_usize (lb_prefs_time, 88, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_time, 16, 70); ++ gtk_widget_set_uposition (lb_prefs_time, 16, 70); ++ gtk_widget_set_usize (lb_prefs_time, 84, 24); + + rd_prefs_local = gtk_radio_button_new_with_label (timeprefs_group, _("Local time")); + timeprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_local)); +@@ -1332,9 +1350,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_local", rd_prefs_local, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_local); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_local, 104, 48); +- gtk_widget_set_uposition (rd_prefs_local, 104, 48); +- gtk_widget_set_usize (rd_prefs_local, 64, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_local, 146, 70); ++ gtk_widget_set_uposition (rd_prefs_local, 146, 70); ++ gtk_widget_set_usize (rd_prefs_local, 94, 24); + + rd_prefs_utc = gtk_radio_button_new_with_label (timeprefs_group, _("UTC time")); + timeprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_utc)); +@@ -1343,9 +1361,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_utc", rd_prefs_utc, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_utc); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_utc, 176, 48); +- gtk_widget_set_uposition (rd_prefs_utc, 176, 48); +- gtk_widget_set_usize (rd_prefs_utc, 64, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_utc, 146, 90); ++ gtk_widget_set_uposition (rd_prefs_utc, 146, 90); ++ gtk_widget_set_usize (rd_prefs_utc, 94, 24); + + lb_prefs_grid = gtk_label_new (_("Map grid")); + gtk_widget_set_name (lb_prefs_grid, "lb_prefs_grid"); +@@ -1353,9 +1371,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_grid", lb_prefs_grid, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_grid); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_grid, 8, 16); +- gtk_widget_set_uposition (lb_prefs_grid, 8, 16); +- gtk_widget_set_usize (lb_prefs_grid, 88, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_grid, 16, 38); ++ gtk_widget_set_uposition (lb_prefs_grid, 16, 38); ++ gtk_widget_set_usize (lb_prefs_grid, 58, 24); + + rd_prefs_gridon = gtk_radio_button_new_with_label (gridprefs_group, _("On")); + gridprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_gridon)); +@@ -1364,8 +1382,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_gridon", rd_prefs_gridon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_gridon); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_gridon, 104, 16); +- gtk_widget_set_uposition (rd_prefs_gridon, 104, 16); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_gridon, 146, 38); ++ gtk_widget_set_uposition (rd_prefs_gridon, 146, 38); + gtk_widget_set_usize (rd_prefs_gridon, 48, 24); + + rd_prefs_gridoff = gtk_radio_button_new_with_label (gridprefs_group, _("Off")); +@@ -1375,8 +1393,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_gridoff", rd_prefs_gridoff, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_gridoff); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_gridoff, 152, 16); +- gtk_widget_set_uposition (rd_prefs_gridoff, 152, 16); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_gridoff, 194, 38); ++ gtk_widget_set_uposition (rd_prefs_gridoff, 194, 38); + gtk_widget_set_usize (rd_prefs_gridoff, 48, 24); + + lb_prefs_fpsat = gtk_label_new (_("Satellite footprint")); +@@ -1385,9 +1403,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_fpsat", lb_prefs_fpsat, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_fpsat); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_fpsat, 8, 80); +- gtk_widget_set_uposition (lb_prefs_fpsat, 8, 80); +- gtk_widget_set_usize (lb_prefs_fpsat, 88, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_fpsat, 16, 122); ++ gtk_widget_set_uposition (lb_prefs_fpsat, 16, 122); ++ gtk_widget_set_usize (lb_prefs_fpsat, 114, 24); + + rd_prefs_fpsaton = gtk_radio_button_new_with_label (fpsatprefs_group, _("On")); + fpsatprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_fpsaton)); +@@ -1396,8 +1414,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_fpsaton", rd_prefs_fpsaton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_fpsaton); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpsaton, 104, 80); +- gtk_widget_set_uposition (rd_prefs_fpsaton, 104, 80); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpsaton, 146, 122); ++ gtk_widget_set_uposition (rd_prefs_fpsaton, 146, 122); + gtk_widget_set_usize (rd_prefs_fpsaton, 48, 24); + + rd_prefs_fpsatoff = gtk_radio_button_new_with_label (fpsatprefs_group, _("Off")); +@@ -1407,8 +1425,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_fpsatoff", rd_prefs_fpsatoff, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_fpsatoff); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpsatoff, 152, 80); +- gtk_widget_set_uposition (rd_prefs_fpsatoff, 152, 80); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpsatoff, 194, 122); ++ gtk_widget_set_uposition (rd_prefs_fpsatoff, 194, 122); + gtk_widget_set_usize (rd_prefs_fpsatoff, 48, 24); + + lb_prefs_fpqth = gtk_label_new (_("Station footprint")); +@@ -1417,9 +1435,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_fpqth", lb_prefs_fpqth, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_fpqth); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_fpqth, 8, 112); +- gtk_widget_set_uposition (lb_prefs_fpqth, 8, 112); +- gtk_widget_set_usize (lb_prefs_fpqth, 88, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_fpqth, 16, 154); ++ gtk_widget_set_uposition (lb_prefs_fpqth, 16, 154); ++ gtk_widget_set_usize (lb_prefs_fpqth, 108, 24); + + rd_prefs_fpqthon = gtk_radio_button_new_with_label (fpqthprefs_group, _("On")); + fpqthprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_fpqthon)); +@@ -1428,8 +1446,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_fpqthon", rd_prefs_fpqthon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_fpqthon); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpqthon, 104, 112); +- gtk_widget_set_uposition (rd_prefs_fpqthon, 104, 112); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpqthon, 146, 154); ++ gtk_widget_set_uposition (rd_prefs_fpqthon, 146, 154); + gtk_widget_set_usize (rd_prefs_fpqthon, 48, 24); + + rd_prefs_fpqthoff = gtk_radio_button_new_with_label (fpqthprefs_group, _("Off")); +@@ -1439,8 +1457,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_fpqthoff", rd_prefs_fpqthoff, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_fpqthoff); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpqthoff, 152, 112); +- gtk_widget_set_uposition (rd_prefs_fpqthoff, 152, 112); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_fpqthoff, 194, 154); ++ gtk_widget_set_uposition (rd_prefs_fpqthoff, 194, 154); + gtk_widget_set_usize (rd_prefs_fpqthoff, 48, 24); + + lb_prefs_track = gtk_label_new (_("Ground Track")); +@@ -1449,8 +1467,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_track", lb_prefs_track, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_track); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_track, 8, 144); +- gtk_widget_set_uposition (lb_prefs_track, 8, 144); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_track, 16, 186); ++ gtk_widget_set_uposition (lb_prefs_track, 16, 186); + gtk_widget_set_usize (lb_prefs_track, 88, 24); + + rd_prefs_trackon = gtk_radio_button_new_with_label (trackprefs_group, _("On")); +@@ -1460,8 +1478,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_trackon", rd_prefs_trackon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_trackon); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_trackon, 104, 144); +- gtk_widget_set_uposition (rd_prefs_trackon, 104, 144); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_trackon, 146, 186); ++ gtk_widget_set_uposition (rd_prefs_trackon, 146, 186); + gtk_widget_set_usize (rd_prefs_trackon, 48, 24); + + rd_prefs_trackoff = gtk_radio_button_new_with_label (trackprefs_group, _("Off")); +@@ -1471,8 +1489,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_trackoff", rd_prefs_trackoff, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_trackoff); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_trackoff, 152, 144); +- gtk_widget_set_uposition (rd_prefs_trackoff, 152, 144); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_trackoff, 194, 186); ++ gtk_widget_set_uposition (rd_prefs_trackoff, 194, 186); + gtk_widget_set_usize (rd_prefs_trackoff, 48, 24); + + lb_prefs_autofreq = gtk_label_new (_("Auto Frequency")); +@@ -1481,9 +1499,9 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_autofreq", lb_prefs_autofreq, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_autofreq); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_autofreq, 8, 176); +- gtk_widget_set_uposition (lb_prefs_autofreq, 8, 176); +- gtk_widget_set_usize (lb_prefs_autofreq, 88, 24); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_autofreq, 16, 218); ++ gtk_widget_set_uposition (lb_prefs_autofreq, 16, 218); ++ gtk_widget_set_usize (lb_prefs_autofreq, 108, 24); + + rd_prefs_autofreqon = gtk_radio_button_new_with_label (autofreqprefs_group, _("On")); + autofreqprefs_group = gtk_radio_button_group (GTK_RADIO_BUTTON (rd_prefs_autofreqon)); +@@ -1492,8 +1510,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_autofreqon", rd_prefs_autofreqon, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_autofreqon); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_autofreqon, 104, 176); +- gtk_widget_set_uposition (rd_prefs_autofreqon, 104, 176); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_autofreqon, 146, 218); ++ gtk_widget_set_uposition (rd_prefs_autofreqon, 146, 218); + gtk_widget_set_usize (rd_prefs_autofreqon, 48, 24); + + rd_prefs_autofreqoff = gtk_radio_button_new_with_label (autofreqprefs_group, _("Off")); +@@ -1503,8 +1521,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "rd_prefs_autofreqoff", rd_prefs_autofreqoff, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (rd_prefs_autofreqoff); +- gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_autofreqoff, 152, 176); +- gtk_widget_set_uposition (rd_prefs_autofreqoff, 152, 176); ++ gtk_fixed_put (GTK_FIXED (fixed2), rd_prefs_autofreqoff, 194, 218); ++ gtk_widget_set_uposition (rd_prefs_autofreqoff, 194, 218); + gtk_widget_set_usize (rd_prefs_autofreqoff, 48, 24); + + lb_prefs_aoscommand = gtk_label_new (_("AOS command")); +@@ -1513,8 +1531,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_aoscommand", lb_prefs_aoscommand, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_aoscommand); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_aoscommand, 8, 216); +- gtk_widget_set_uposition (lb_prefs_aoscommand, 8, 216); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_aoscommand, 16, 278); ++ gtk_widget_set_uposition (lb_prefs_aoscommand, 16, 278); + gtk_widget_set_usize (lb_prefs_aoscommand, 96, 24); + + lb_prefs_loscommand = gtk_label_new (_("LOS command")); +@@ -1523,8 +1541,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_preferences), "lb_prefs_loscommand", lb_prefs_loscommand, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_prefs_loscommand); +- gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_loscommand, 8, 264); +- gtk_widget_set_uposition (lb_prefs_loscommand, 8, 264); ++ gtk_fixed_put (GTK_FIXED (fixed2), lb_prefs_loscommand, 16, 310); ++ gtk_widget_set_uposition (lb_prefs_loscommand, 16, 310); + gtk_widget_set_usize (lb_prefs_loscommand, 96, 24); + + dialog_action_area1 = GTK_DIALOG (dialog_preferences)->action_area; +@@ -1817,8 +1835,7 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_azel_graph), "tx_azel_sat", tx_azel_sat, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_azel_sat); +- gtk_fixed_put (GTK_FIXED (fixed7), tx_azel_sat, 96, 8); +- gtk_widget_set_uposition (tx_azel_sat, 96, 8); ++ gtk_fixed_put (GTK_FIXED (fixed7), tx_azel_sat, 112, 8); + gtk_widget_set_usize (tx_azel_sat, 80, 16); + gtk_entry_set_editable (GTK_ENTRY (tx_azel_sat), FALSE); + +@@ -1829,7 +1846,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_azel_azimuth); + gtk_fixed_put (GTK_FIXED (fixed7), tx_azel_azimuth, 64, 32); +- gtk_widget_set_uposition (tx_azel_azimuth, 64, 32); + gtk_widget_set_usize (tx_azel_azimuth, 48, 16); + GTK_WIDGET_UNSET_FLAGS (tx_azel_azimuth, GTK_CAN_FOCUS); + gtk_entry_set_editable (GTK_ENTRY (tx_azel_azimuth), FALSE); +@@ -1840,8 +1856,7 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_azel_graph), "tx_azel_elevation", tx_azel_elevation, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_azel_elevation); +- gtk_fixed_put (GTK_FIXED (fixed7), tx_azel_elevation, 184, 32); +- gtk_widget_set_uposition (tx_azel_elevation, 184, 32); ++ gtk_fixed_put (GTK_FIXED (fixed7), tx_azel_elevation, 200, 32); + gtk_widget_set_usize (tx_azel_elevation, 48, 16); + GTK_WIDGET_UNSET_FLAGS (tx_azel_elevation, GTK_CAN_FOCUS); + gtk_entry_set_editable (GTK_ENTRY (tx_azel_elevation), FALSE); +@@ -1852,9 +1867,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_azel_graph), "lb_azel_sat", lb_azel_sat, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_azel_sat); +- gtk_fixed_put (GTK_FIXED (fixed7), lb_azel_sat, 48, 8); +- gtk_widget_set_uposition (lb_azel_sat, 48, 8); +- gtk_widget_set_usize (lb_azel_sat, 48, 16); ++ gtk_fixed_put (GTK_FIXED (fixed7), lb_azel_sat, 38, 8); ++ gtk_widget_set_usize (lb_azel_sat, 58, 16); + + lb_azel_elevation = gtk_label_new (_("Elevation")); + gtk_widget_set_name (lb_azel_elevation, "lb_azel_elevation"); +@@ -1863,8 +1877,7 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_azel_elevation); + gtk_fixed_put (GTK_FIXED (fixed7), lb_azel_elevation, 128, 32); +- gtk_widget_set_uposition (lb_azel_elevation, 128, 32); +- gtk_widget_set_usize (lb_azel_elevation, 48, 16); ++ gtk_widget_set_usize (lb_azel_elevation, 64, 16); + + lb_azel_azimuth = gtk_label_new (_("Azimuth")); + gtk_widget_set_name (lb_azel_azimuth, "lb_azel_azimuth"); +@@ -1872,9 +1885,8 @@ + gtk_object_set_data_full (GTK_OBJECT (dialog_azel_graph), "lb_azel_azimuth", lb_azel_azimuth, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_azel_azimuth); +- gtk_fixed_put (GTK_FIXED (fixed7), lb_azel_azimuth, 16, 32); +- gtk_widget_set_uposition (lb_azel_azimuth, 16, 32); +- gtk_widget_set_usize (lb_azel_azimuth, 40, 16); ++ gtk_fixed_put (GTK_FIXED (fixed7), lb_azel_azimuth, 0, 32); ++ gtk_widget_set_usize (lb_azel_azimuth, 58, 16); + + gtk_signal_connect (GTK_OBJECT (dialog_azel_graph), "delete_event", + GTK_SIGNAL_FUNC (on_dialog_azel_graph_delete_event), +@@ -2020,7 +2032,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_dbsat); + gtk_fixed_put (GTK_FIXED (fixed10), tx_dbsat, 8, 24); +- gtk_widget_set_uposition (tx_dbsat, 8, 24); + gtk_widget_set_usize (tx_dbsat, 80, 20); + + tx_dbuplink = gtk_entry_new (); +@@ -2030,7 +2041,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_dbuplink); + gtk_fixed_put (GTK_FIXED (fixed10), tx_dbuplink, 144, 24); +- gtk_widget_set_uposition (tx_dbuplink, 144, 24); + gtk_widget_set_usize (tx_dbuplink, 76, 20); + + tx_dbdownlink = gtk_entry_new (); +@@ -2040,7 +2050,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_dbdownlink); + gtk_fixed_put (GTK_FIXED (fixed10), tx_dbdownlink, 228, 24); +- gtk_widget_set_uposition (tx_dbdownlink, 228, 24); + gtk_widget_set_usize (tx_dbdownlink, 76, 20); + + tx_dbbeacon = gtk_entry_new (); +@@ -2050,7 +2059,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_dbbeacon); + gtk_fixed_put (GTK_FIXED (fixed10), tx_dbbeacon, 312, 24); +- gtk_widget_set_uposition (tx_dbbeacon, 312, 24); + gtk_widget_set_usize (tx_dbbeacon, 76, 20); + + bt_dbadd = gtk_button_new_with_label (_("Add")); +@@ -2060,7 +2068,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (bt_dbadd); + gtk_fixed_put (GTK_FIXED (fixed10), bt_dbadd, 16, 56); +- gtk_widget_set_uposition (bt_dbadd, 16, 56); + gtk_widget_set_usize (bt_dbadd, 64, 24); + + bt_dbupdate = gtk_button_new_with_label (_("Update")); +@@ -2070,7 +2077,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (bt_dbupdate); + gtk_fixed_put (GTK_FIXED (fixed10), bt_dbupdate, 167, 56); +- gtk_widget_set_uposition (bt_dbupdate, 167, 56); + gtk_widget_set_usize (bt_dbupdate, 64, 24); + + bt_dbdelete = gtk_button_new_with_label (_("Delete")); +@@ -2080,7 +2086,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (bt_dbdelete); + gtk_fixed_put (GTK_FIXED (fixed10), bt_dbdelete, 317, 56); +- gtk_widget_set_uposition (bt_dbdelete, 317, 56); + gtk_widget_set_usize (bt_dbdelete, 64, 24); + + lb_dbsat = gtk_label_new (_("Satellite")); +@@ -2090,7 +2095,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_dbsat); + gtk_fixed_put (GTK_FIXED (fixed10), lb_dbsat, 8, 6); +- gtk_widget_set_uposition (lb_dbsat, 8, 6); + gtk_widget_set_usize (lb_dbsat, 80, 16); + + lb_dbmode = gtk_label_new (_("Mode")); +@@ -2100,7 +2104,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_dbmode); + gtk_fixed_put (GTK_FIXED (fixed10), lb_dbmode, 96, 6); +- gtk_widget_set_uposition (lb_dbmode, 96, 6); + gtk_widget_set_usize (lb_dbmode, 40, 16); + + tx_dbmode = gtk_entry_new (); +@@ -2110,7 +2113,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (tx_dbmode); + gtk_fixed_put (GTK_FIXED (fixed10), tx_dbmode, 96, 24); +- gtk_widget_set_uposition (tx_dbmode, 96, 24); + gtk_widget_set_usize (tx_dbmode, 40, 20); + + lb_dbuplink = gtk_label_new (_("Uplink")); +@@ -2120,7 +2122,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_dbuplink); + gtk_fixed_put (GTK_FIXED (fixed10), lb_dbuplink, 144, 6); +- gtk_widget_set_uposition (lb_dbuplink, 144, 6); + gtk_widget_set_usize (lb_dbuplink, 76, 16); + + lb_dbdownlink = gtk_label_new (_("Downlink")); +@@ -2130,7 +2131,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_dbdownlink); + gtk_fixed_put (GTK_FIXED (fixed10), lb_dbdownlink, 228, 6); +- gtk_widget_set_uposition (lb_dbdownlink, 228, 6); + gtk_widget_set_usize (lb_dbdownlink, 76, 16); + + lb_dbbeacon = gtk_label_new (_("Beacon")); +@@ -2140,7 +2140,6 @@ + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lb_dbbeacon); + gtk_fixed_put (GTK_FIXED (fixed10), lb_dbbeacon, 312, 6); +- gtk_widget_set_uposition (lb_dbbeacon, 312, 6); + gtk_widget_set_usize (lb_dbbeacon, 76, 16); + + gtk_signal_connect (GTK_OBJECT (dialog_dbedit), "delete_event", --- predict-2.2.3.orig/debian/patches/030_predict_c.diff +++ predict-2.2.3/debian/patches/030_predict_c.diff @@ -0,0 +1,507 @@ +Index: predict-2.2.3/predict.c +=================================================================== +--- predict-2.2.3.orig/predict.c 2009-11-14 09:37:36.000000000 -0500 ++++ predict-2.2.3/predict.c 2009-11-14 09:40:09.000000000 -0500 +@@ -34,8 +34,10 @@ + #include + #include + #include ++#include + + #include "predict.h" ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ); + + /* Constants used by SGP4/SDP4 code */ + +@@ -2041,6 +2043,7 @@ + + int i, j, n, sock; + socklen_t alen; ++ double dLat, dLong; /* parameters for PredictAt */ + struct sockaddr_in fsin; + char buf[80], buff[1000], satname[50], tempname[30], ok; + time_t t; +@@ -2239,6 +2242,34 @@ + ok=1; + } + ++ // calculate the satellite position at a given moment in time... ++ if ( strncmp ( "GET_SAT_AT", buf, 10 ) == 0 ) { ++ // get the parameters... ++ sscanf ( &buf[10], "%s %ld %lf %lf", satname, (unsigned long *) &t, &dLat, &dLong ); ++ ++ // find the satellite id ++ for ( i=0; i<24; i++ ) { ++ if ( strcmp ( sat[i].name, satname ) == 0) { ++ //syslog ( LOG_INFO, "%s | %ld\n", sat[i].name, (unsigned long) t ); ++ ++ // get the position ++ PredictAt ( i, t, dLat, dLong ); ++ ++ // print out the info... ++ sprintf ( buff, "GOT_SAT_AT %ld %f %f %f %f %ld %f %f\n", \ ++ (unsigned long)t, \ ++ long_array[i], \ ++ lat_array[i], \ ++ az_array[i], \ ++ el_array[i], \ ++ aos_array[i], \ ++ range_array[i], \ ++ doppler[i] ); ++ sendto(sock,buff,strlen(buff),0,(struct sockaddr *)&fsin,sizeof(fsin)); ++ } ++ } ++ } ++ + if (strncmp("GET_SAT_POS",buf,11)==0) + { + /* Parse "buf" for satellite name and arguments */ +@@ -5128,7 +5159,7 @@ + + if ((old_visibility=='V' || old_visibility=='D') && visibility=='N') + { +- sprintf(command,"%svocalizer/vocalizer eclipse &",predictpath); ++ sprintf(command,"%s/vocalizer eclipse &",predictpath); + system(command); + eclipse_alarm=1; + oldtime-=0.000015*sqrt(sat_alt); +@@ -5136,7 +5167,7 @@ + + if (old_visibility=='N' && (visibility=='V' || visibility=='D')) + { +- sprintf(command,"%svocalizer/vocalizer sunlight &",predictpath); ++ sprintf(command,"%s/vocalizer sunlight &",predictpath); + system(command); + eclipse_alarm=1; + oldtime-=0.000015*sqrt(sat_alt); +@@ -5151,7 +5182,7 @@ + if (sat_range_rate>0.0) + approaching='-'; + +- sprintf(command,"%svocalizer/vocalizer %.0f %.0f %c %c &",predictpath,sat_azi,sat_ele,approaching,visibility); ++ sprintf(command,"%s/vocalizer %.0f %.0f %c %c &",predictpath,sat_azi,sat_ele,approaching,visibility); + system(command); + oldtime=CurrentDaynum(); + old_visibility=visibility; +@@ -5273,7 +5304,7 @@ + { + /* Announce LOS */ + +- sprintf(command,"%svocalizer/vocalizer los &",predictpath); ++ sprintf(command,"%s/vocalizer los &",predictpath); + system(command); + } + } +@@ -5664,6 +5695,241 @@ + sprintf(tracking_mode, "NONE\n%c",0); + } + ++void ++time_to_die( int why ) ++{ ++ /* syslog ( LOG_INFO, "Time_to_Die called (%d)\n", why ); */ ++ exit ( -1 ); ++} ++ ++void MultiTrackDaemon() ++{ ++ /* This function tracks all satellites in the program's ++ database simultaneously until 'Q' or ESC is pressed. ++ Satellites in range are HIGHLIGHTED. Coordinates ++ for the Sun and Moon are also displayed. */ ++ ++ int x, y, z; ++ pid_t pid; ++ pthread_t thread; ++ ++ unsigned char satindex[24], inrange[24], sunstat=0, ok2predict[24]; ++ ++ double aos[24], aos2[24], temptime, ++ nextcalctime=0.0, los[24], aoslos[24]; ++ ++ /* openlog ( "predict", LOG_PID, LOG_USER ); ++ syslog ( LOG_INFO, "Starting the satellite Prediction server." ); */ ++ signal ( SIGQUIT, time_to_die ); ++ signal ( SIGINT, time_to_die ); ++ ++ if ( ( pid = fork ( ) ) < 0 ) ++ return; ++ else if ( pid != 0 ) ++ exit ( 0 ); // Parent goes bye-bye ++ ++ /* syslog ( LOG_INFO, "Forking daemon..." ); */ ++ ++ // Child continues ++ setsid(); // become session leader ++ ++ pthread_create(&thread,NULL,(void *)socket_server,(void *)"predict"); ++ ++ for (x=0; x<24; x++) ++ { ++ if (Geostationary(x)==0 && AosHappens(x)==1 && Decayed(x,0.0)!=1) ++ ok2predict[x]=1; ++ else ++ ok2predict[x]=0; ++ ++ aoslos[x]=0.0; ++ los[x]=0.0; ++ aos[x]=0.0; ++ aos2[x]=0.0; ++ } ++ ++ do ++ { ++ for (z=0; z<24; z++) ++ { ++ y=z/2; ++ ++ if (z%2) ++ { ++ x=41; ++ indx=y+12; ++ } ++ ++ else ++ { ++ x=1; ++ indx=y; ++ } ++ ++ if (sat[indx].meanmo!=0.0 && Decayed(indx,0.0)!=1) ++ { ++ daynum=CurrentDaynum(); ++ PreCalc(indx); ++ Calc(); ++ ++ if (sat_ele>=0.0) ++ { ++ inrange[indx]=1; ++ } ++ ++ else ++ { ++ inrange[indx]=0; ++ } ++ ++ if (sat_sun_status) ++ { ++ if (sun_ele<=-12.0 && sat_ele>=0.0) ++ sunstat='V'; ++ else ++ sunstat='D'; ++ } ++ ++ else ++ sunstat='N'; ++ ++ if (socket_flag) ++ { ++ az_array[indx]=sat_azi; ++ el_array[indx]=sat_ele; ++ lat_array[indx]=sat_lat; ++ long_array[indx]=360.0-sat_lon; ++ footprint_array[indx]=fk; ++ range_array[indx]=sat_range; ++ altitude_array[indx]=sat_alt; ++ velocity_array[indx]=sat_vel; ++ orbitnum_array[indx]=rv; ++ visibility_array[indx]=sunstat; ++ eclipse_depth_array[indx]=eclipse_depth/deg2rad; ++ phase_array[indx]=360.0*(phase/twopi); ++ ++ if (inrange[indx]) ++ doppler[indx]=-100e06*((sat_range_rate*1000.0)/299792458.0); ++ else ++ doppler[indx]=0.0; ++ ++ if (calc_squint) ++ squint_array[indx]=squint; ++ else ++ squint_array[indx]=360.0; ++ ++ FindSun(daynum); ++ sprintf(tracking_mode,"MULTI\n%c",0); ++ } ++ ++ FindMoon(daynum); ++ ++ /* Calculate Next Event (AOS/LOS) Times */ ++ ++ if (ok2predict[indx] && daynum>los[indx] && inrange[indx]) ++ los[indx]=FindLOS2(); ++ ++ if (ok2predict[indx] && daynum>aos[indx]) ++ { ++ if (inrange[indx]) ++ aos[indx]=NextAOS(); ++ else ++ aos[indx]=FindAOS(); ++ } ++ ++ if (inrange[indx]) ++ aoslos[indx]=los[indx]; ++ else ++ aoslos[indx]=aos[indx]; ++ ++ if (socket_flag) ++ { ++ if (ok2predict[indx]) ++ nextevent[indx]=aoslos[indx]; ++ else ++ nextevent[indx]=-3651.0; ++ } ++ ++ aos2[indx]=aos[indx]; ++ satindex[indx]=indx; ++ } ++ ++ if (Decayed(indx,0.0)) ++ { ++ if (socket_flag) ++ { ++ az_array[indx]=0.0; ++ el_array[indx]=0.0; ++ lat_array[indx]=0.0; ++ long_array[indx]=0.0; ++ footprint_array[indx]=0.0; ++ range_array[indx]=0.0; ++ altitude_array[indx]=0.0; ++ velocity_array[indx]=0.0; ++ orbitnum_array[indx]=0L; ++ visibility_array[indx]='N'; ++ eclipse_depth_array[indx]=0.0; ++ phase_array[indx]=0.0; ++ doppler[indx]=0.0; ++ squint_array[indx]=0.0; ++ nextevent[indx]=-3651.0; ++ } ++ } ++ } ++ ++ daynum=CurrentDaynum(); ++ ++ if (daynum>nextcalctime) ++ { ++ /* Bubble sort the AOS times */ ++ ++ for (z=22; z>=0; z--) ++ for (y=0; y<=z; y++) ++ if (aos2[y]>=aos2[y+1]) ++ { ++ temptime=aos2[y]; ++ aos2[y]=aos2[y+1]; ++ aos2[y+1]=temptime; ++ ++ x=satindex[y]; ++ satindex[y]=satindex[y+1]; ++ satindex[y+1]=x; ++ } ++ ++ for (x=0, y=0, z=-1; x<21 && y!=3; x++) ++ { ++ if (ok2predict[satindex[x]] && aos2[x]!=0.0) ++ { ++ mvprintw(y+21,19,"%10s on %s UTC",Abbreviate(sat[(int)satindex[x]].name,9),Daynum2String(aos2[x])); ++ ++ if (z==-1) ++ z=x; ++ y++; ++ } ++ } ++ ++ if (z!=-1) ++ nextcalctime=aos2[z]; ++ } ++ ++ sleep(1); /* Increase if CPU load is too high */ ++ ++ /* If we receive a RELOAD_TLE command through the ++ socket connection, or an 'r' through the keyboard, ++ reload the TLE file. */ ++ ++ if (reload_tle) ++ { ++ ReadDataFiles(); ++ reload_tle=0; ++ nextcalctime=0.0; ++ } ++ ++ } while (1); ++ ++ sprintf(tracking_mode, "NONE\n%c",0); ++} ++ + void Illumination() + { + double startday, oneminute, sunpercent; +@@ -6099,6 +6365,121 @@ + return 0; + } + ++double GetDayNum ( struct timeval *tv ) ++{ ++ /* used by PredictAt */ ++ return ( ( ( (double) (tv->tv_sec) - 0.000001 * ( (double) (tv->tv_usec) ) ) / 86400.0) - 3651.0 ); ++} ++ ++/* ++ void PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++ ++ Computes the satellites possition at the given time... ++ ... so that we can report it via a socket. ++ ++ Returns: ++ TRUE if successful. ++ ++ Author/Editor: ++ February 2003 ++ Glenn Richardson ++ glenn@spacequest.com ++*/ ++ ++int PredictAt ( int iSatID, time_t ttDayNum, double dLat, double dLong ) ++{ ++ double dDayNum; /* time of prediction */ ++ double dOldRange, dOldClock; /* range / time of pre-prediction position */ ++ double dDoppler = 0.0; /* doppler calculation */ ++ double dDeltaTime, dDeltaPos; /* used in doppler calc */ ++ double dQLat, dQLong; /* remember the groundstation lat/long */ ++ int iInRange; /* is the satellite in view? */ ++ struct timeval tv; /* time structure... */ ++ ++ /* remember... */ ++ dQLat = qth.stnlat; ++ dQLong = qth.stnlong; ++ qth.stnlat = dLat; ++ qth.stnlong = dLong; ++ ++ /* are the keps ok? */ ++ if ( ( sat[iSatID].meanmo == 0.0) || ( Decayed ( iSatID, 0.0 ) == 1 ) || ( Geostationary ( iSatID ) ) || !( AosHappens ( iSatID ) ) ) ++ { ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ /* !!!! NOTE: we only compute LEOs !!!! */ ++ /* syslog ( LOG_INFO, "PredictAT() can't do this one..."); */ ++ return FALSE; ++ } ++ ++ /* syslog ( LOG_INFO, "PredictAT: ttDayNum... %ld, %s", (unsigned long) ttDayNum, ctime ( &ttDayNum ) ); */ ++ /* first, prepare for doppler by computing pos 5 sec ago */ ++ indx = iSatID; ++ tv.tv_sec = ttDayNum - 5; ++ tv.tv_usec = 0; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dOldClock = 86400.0 * daynum; ++ dOldRange = sat_range * 1000.0; ++ ++ /* now, recompute at current position */ ++ tv.tv_sec = ttDayNum; ++ daynum = GetDayNum ( &tv ); ++ PreCalc ( iSatID ); ++ Calc (); ++ ++ dDayNum = daynum; ++ ++ /* setup for doppler... */ ++ dDeltaTime = dDayNum * 86400.0 - dOldClock; ++ dDeltaPos = (sat_range * 1000.0) - dOldRange; ++ ++ if ( sat_azi >= 0.0 ) ++ { ++ iInRange = 1; ++ ++ /* compute the doppler */ ++ dDoppler = - ( ( dDeltaPos / dDeltaTime ) / 299792458.0 ); ++ dDoppler = dDoppler * 100.0e6; ++ } ++ else ++ { ++ /* compute the doppler */ ++ iInRange = 0; ++ } ++ ++ /* printf ("InRange? %d, doppler: %f, Az: %f, El: %f, %s", ++ iInRange, dDoppler, azimuth, elevation, ctime ( &ttDayNum ) ); */ ++ /* remember values for socket connection... */ ++ az_array[iSatID] = sat_azi; ++ el_array[iSatID] = sat_ele; ++ lat_array[iSatID] = sat_lat; ++ long_array[iSatID] = 360.0 - sat_lon; ++ footprint_array[iSatID] = fk; ++ range_array[iSatID] = sat_range; ++ altitude_array[iSatID] = sat_alt; ++ velocity_array[iSatID] = sat_vel; ++ orbitnum_array[iSatID] = rv; ++ doppler[iSatID] = dDoppler; ++ ++ ++ /* Calculate Next Event (AOS/LOS) Times */ ++ if ( iInRange ) ++ nextevent[iSatID] = FindLOS2(); ++ else ++ nextevent[iSatID] = FindAOS(); ++ ++ ++ /* restore... */ ++ qth.stnlat = dQLat; ++ qth.stnlong = dQLong; ++ ++ return TRUE; ++} ++ + int main(argc,argv) + char argc, *argv[]; + { +@@ -6365,10 +6746,20 @@ + if (env!=NULL && strncmp(env,"xterm",5)==0) + xterm=1; + else +- xterm=0; ++ xterm=0; + + /* Start ncurses */ + ++ /* Are we running under an xterm or equivalent? */ ++ ++ if (getenv("TERM") && strncmp(getenv("TERM"),"xterm",5)==0) ++ xterm=1; ++ else ++ xterm=0; ++ ++ if (!getenv("TERM") || strncmp(getenv("TERM"),"none",4)==0) { ++ /* NO-OP */; ++ } else { + initscr(); + start_color(); + cbreak(); +@@ -6445,9 +6836,13 @@ + + if (socket_flag) + { +- pthread_create(&thread,NULL,(void *)socket_server,(void *)argv[0]); +- bkgdset(COLOR_PAIR(3)); +- MultiTrack(); ++ if (!getenv("TERM") || strncmp(getenv("TERM"),"none",4)==0) { ++ MultiTrackDaemon(); ++ } else { ++ pthread_create(&thread,NULL,(void *)socket_server,(void *)argv[0]); ++ bkgdset(COLOR_PAIR(3)); ++ MultiTrack(); ++ } + } + + MainMenu(); +@@ -6555,7 +6950,6 @@ + refresh(); + endwin(); + } +- +- exit(0); ++ } ++ exit(0); + } +- --- predict-2.2.3.orig/debian/patches/020_predict_h.diff +++ predict-2.2.3/debian/patches/020_predict_h.diff @@ -0,0 +1,6 @@ +Index: predict-2.2.3/predict.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ predict-2.2.3/predict.h 2009-11-14 09:35:52.000000000 -0500 +@@ -0,0 +1 @@ ++char *predictpath={"/usr/lib/predict/"}, soundcard=1, *version={"2.2.3"};