You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
gpligc/perl/GPLIGC.pl

6687 lines
246 KiB

#!/usr/bin/perl -w
# version and copyleft
my $version='1.10.1';
my $copyright_years="2000-2016";
my $copyright="(c) $copyright_years by Hannes Krueger";
# new version welcome message
my $new_version_message=<<ENDE;
News for version $version
- some bugs fixed
for details see ChangeLog and read the Manual
If you're using GPLIGC/ogie on a regular basis,
please consider to subscribe to the gpligc-announce
mailinglist (see menu 'about')
* to get rid of this message, choose 'save configuration'
from menu 'options' *
ENDE
# set default configuration settings (configuration-hash...)
# needs some order ? alphabetic/functional groups?
my %config = ();
$config{'new_version_message_shown'}="0.1";
$config{'photos'}=1; #use photos?
$config{'photo_path'}="none";
$config{'picture_viewer'} = "internal"; #internal, or ext app
$config{'mm_player'} = "mplayer"; #multimedia
$config{'skip_check'} = 1; #show gaps in track?
$config{'skip_limit_minutes'} = 1.0; #actually, these are minutes now! 0.1 = 6sec
$config{'skip_del_first_after'}=1; #first fix after skip will be deleted!
$config{'terminal'}="xterm -hold -e";
$config{'garmin_download'}="sudo gpspoint -dt -p /dev/ttyUSB2";
$config{'gpsbabel_tdownload'}="sudo gpsbabel -t -i garmin -f /dev/ttyUSB2 -o igc -F ";
$config{'geotag_force_overwrite'}= 0;
$config{'mm_mountpoint'}="/mnt/sdC";
$config{'mm_download_dirs'}="Aufnahmen Fotos Videoclips";
$config{'browser'} = "/usr/bin/firefox";
$config{'gnuplot_win_exec'} = "wgnuplot.exe";
$config{'gnuplot_major_version'} = 4;
$config{'gnuplot_4_terminal'} = 0;
$config{'gnuplot_terminal_app'} = "xterm -e";
$config{'gnuplot_3d_rotx'} = 30; # values for gnuplot 3d-view
$config{'gnuplot_3d_rotz'} = 330;
$config{'te_vario_fallback'} = 1; # calculate TE vario from groundspeed?
$config{'te_warning'}=0; # set to 0 to avoid TE from groundspeed warning
$config{'wind_analysis'} = 1; # wind analysis with f7 stat
$config{'optimizer_cycles_mmc'} = 20;
$config{'optimizer_cycles_sa'} = 5;
$config{'optimizer_method'}="mmc";
$config{'optimizer_mmc'}=" -m 1000 -mmc 25000 -devisor 3 -refine 2 ";
$config{'optimizer_sa'}= " -sima -m 1000 -sacycles 500 -saexp -sapara 15.0 -saparb 0.03 -devisor 3 -refine 2 ";
$config{'optimizer_verbose'} = 0;
$config{'optimizer_debug'} = 0;
$config{'maps'} = "1";
$config{'map_type'}= "osm";
$config{'map_gms_v'}=130; # as of 12/2013 v132 seems to be the lowest number
$config{'maps_zoomlevel'}= 8;
$config{'map_max_scalesize'}=750;
$config{'map_max_tiles'}=30;
# set path for slippery map tiles cache
if ($^O eq "MSWin32") {
if (defined $ENV{'GPLIGCHOME'}) {
$config{'map_path'} = $ENV{'GPLIGCHOME'}."/map/";
} else {
$config{'map_path'} = "C:/GPLIGC/map/";
}
} else {
$config{'map_path'} = "$ENV{'HOME'}/.gpligc/map/";
}
$config{'vertical_speed_unit_name'} = "m/s"; # to add more units edit the options-menu
$config{'vertical_speed_unit_factor'} = 1.0;
$config{'speed_unit_name'} ="km/h";
$config{'speed_unit_factor'} = 1.0;
$config{'altitude_unit_name'} ="m";
$config{'altitude_unit_factor'} = 1.0;
$config{'distance_unit_name'} ="km";
$config{'distance_unit_factor'} = 1.0;
$config{'waypoint_linewidth'} = 3.0;
$config{'cylinder_linewidth'} = 3.0;
$config{'task_linewidth'} = 3.0;
$config{'marker_linewidth'} = 3.0;
$config{'fvw_grid'}='yes';
$config{'fvw_baro_grid'}='yes';
$config{'fvw_baro_fraction'}=3;
$config{'open_additional_info'} = 0; # open the additional info window automatically, if no gpi file exists
$config{'integrate_over'} = 10; # how many data-points are averaged for integration of...
$config{'vario_histo_intervall'} = 0.5;
$config{'speed_histo_intervall'} = 5;
$config{'baro_histo_intervall'} = 50;
$config{'baro_grid_small'} = 500;
$config{'baro_grid_large'} = 1000;
$config{'draw_task'}=0;
$config{'draw_wpcyl'}=0;
$config{'draw_accuracy'}=1;
$config{'viewclick_res'}=1;
$config{'timezone'} = "0"; # timzone offset from UTC to camera-time (and localtime?)
$config{'libdir'} = "zzLIBDIRzz"; # LIBDIR PATH will be changed by the installation
$config{'datadir'} = "zzDATADIRzz"; # DATADIR PATH will be changed by the installation
$config{'gnuplot_draw_style'}="with lines";
$config{'gnuplot_grid_state'}='set grid';
$config{'gnuplot_terminal'}="x11";
$config{'zylinder_radius'}=0.5; # now in km (09/2015)
$config{'zylinder_wp_type'}="both";
$config{'starting_line'}=10; # starting line length
$config{'zylinder_names'}=1;
$config{'zoom_sidelength'}="10"; # in km
$config{'ENL_noise_limit'}=500;
$config{'coordinate_print_format'}="igch"; # igch, zanh, deg
$config{'DEBUG'} = 0;
$config{'window_height'}=500; #this is initial height/width of frame_canvas
$config{'window_width'}=900;
my $text=<<ENDE;
GPLIGC Version $version Copyright (c) $copyright_years by
Hannes Krueger <Hannes.Krueger\@gmail.com> and Jan MW Krueger
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 3 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, see <http://www.gnu.org/licenses/>.
ENDE
### Global variables
my $altmode = 'baro';
my $filestat='closed';
my $file='No file opened';
#my $sigusr2flag=0;
my $optimized_for = "none";
my $zoom = 0;
my $cut_track = 0;
my $hide_mm = 0; # if 1 hide pictures and mm
my $delta_photo_time = 0; # offset between GPS time and camera clock
my $savname = 'no'; # not set
my $zl = 0;
my $tiles = 0;
my $map_reload = 0;
# flag for Tk::JPEG module
my $have_jpeg = 0;
# flag for Image:ExifTool
my $have_EXIF = 0;
# flag for Imager
my $have_imager = 0;
my $have_png = 0;
# Temporary directory
my $pfadftmp;
my $map_gms_v_min=10000;
my $map_gms_v_max=$config{'map_gms_v'};
my %gpi;
$gpi{'qnh'} = 1013.25; # just to avoid an error if the pressure plot is issued without igc file
# all temp-files to be cleaned later
# these are the data files used for Gnuplot
my @clearlist=qw(zyl.dat speed.dat press.dat plot.bat vario.dat gpsvario.dat deltah.dat
baro.dat gpsalt.dat 3d.dat lonproj.dat latproj.dat befehl.dat
km.dat lonlat.dat enl.dat ias.dat tas.dat iashisto.dat tashisto.dat shisto.dat vhisto.dat
vhistogps.dat plot.gpl plot.bat barohisto.dat gpshisto.dat wind.dat sat.dat tmp.png);
# More stuff that's not properly passed around.
my $FDR;
my $task_state;
my $wpcyl_state;
# ===16=== is this all needed... socket connection!!!
# this is used for Communication with openGLIGCexplorer
# use IPC::SysV qw(IPC_RMID IPC_CREAT S_IRWXU ftok);
# use SysVIPC on non-windows platforms only
# BEGIN {} is executed at compile time...
# OLD CODE...
BEGIN {
if ($^O ne "MSWin32") {
# require IPC::SysV;
# import IPC::SysV qw(IPC_RMID IPC_CREAT S_IRWXU ftok);
} else {
require Win32;
import Win32 qw(GetOSName);
}
}
# Tk-Module is needed!
use Tk;
# here we load the config (.gpligcrc) for the first time!
# later, we need to load it another time, because all defaults will be set
# while building the menus in FlightView()
load_config(1);
# check for Tk::JPEG module
# since Tk804.026 jpeg should be available
my $test_jpeg = eval{ require Tk::JPEG; };
if (defined $test_jpeg && $test_jpeg == 1) {
$have_jpeg = 1;
print "Tk::JPEG module found ;-) !\n" if ($config{'DEBUG'});
} else {
print "Perl module: Tk::JPEG not available :,-( !\n";# if ($config{'DEBUG'});
}
my $test_png = eval{require Tk::PNG;};
if (defined $test_png && $test_png == 1) {
$have_png = 1;
print "PNG module found ;-) !\n" if ($config{'DEBUG'});
} else {
print "Perl module: Tk::PNG not available :,-( !\n";# if ($config{'DEBUG'});
}
my $test_imager = eval{require Imager;};
if (defined $test_imager && $test_imager == 1) {
$have_imager = 1;
print "Imager module found ;-) !\n" if ($config{'DEBUG'});
} else {
print "Perl module: Imager not available :,-( !\n";# if ($config{'DEBUG'});
}
# check for the Image::ExifTool module.
my $test_EXIF = eval{ require Image::ExifTool; };
if (defined $test_EXIF && $test_EXIF == 1) {
$have_EXIF = 1;
print "Image::ExifTool module found ;-) !\n" if ($config{'DEBUG'});
} else {
print "Perl module: Image::ExifTool not available :,-( !\n";# if ($config{'DEBUG'});
}
# check environment vars on win
if ($^O eq "MSWin32") {
if (defined $ENV{'GPLIGCHOME'}) {
$config{'libdir'} = $ENV{'GPLIGCHOME'}."/";
$config{'datadir'} = $ENV{'GPLIGCHOME'}."/";
} else {
$config{'libdir'} = ".";
$config{'datadir'} = ".";
print "GPLIGCHOME is not defined !!!\n";
}
# workaround for old buggy win32 tk module < 800.23 ?
if (!defined $ENV{'HOME'}) {
$ENV{'HOME'} = "C:\\";
}
} else { # Unix-case: allow overriding libdir by GPLIGCHOME
if (defined $ENV{'GPLIGCHOME'}) {
print "GPLIGCHOME is defined: $ENV{'GPLIGCHOME'}\n";
print "previous content of $config{'libdir'}="."$config{'libdir'} will be overridden.\n";
$config{'libdir'} = $ENV{'GPLIGCHOME'}."/";
$config{'datadir'} = $ENV{'GPLIGCHOME'}."/";
}
}
# add libdir to infotext
$text .= "Library path: $config{'libdir'}\n";
$text .= "Data path: $config{'datadir'}\n";
use File::Spec;
my $curdir = File::Spec->curdir;
use File::Basename;
my $scriptpath = File::Basename::dirname($0)."/";
if ($config{'DEBUG'}) {
print "$scriptpath $0\n";
print "libdir: $config{'libdir'} \n";
print "datadir: $config{'datadir'} \n";
print "curdir: $curdir \n";
print "scriptpath: $scriptpath \n";
}
# define $config{'working_directory'} the starting path for open,save,etc.
if ($^O eq "MSWin32") {
if (defined $ENV{'GPLIGCHOME'}) {
$config{'working_directory'} = $ENV{'GPLIGCHOME'};
} else {
$config{'working_directory'} = "C:\\";
}
} else {
if (defined $ENV{'HOME'}) {
$config{'working_directory'} = $ENV{'HOME'};
} else {
$config{'working_directory'} = "/";
}
}
unshift (@INC, $curdir, $scriptpath, $config{'libdir'});
# path seperator
my $ps;
if ($^O eq "MSWin32") { $ps =";";} else {$ps=":";}
$ENV{'PATH'} = "$ENV{'PATH'}$ps$curdir$ps$config{'libdir'}$ps$scriptpath";
#catch some signals for controlled shutdown.
$SIG{'INT'} = \&gpligcexit;
$SIG{'QUIT'} = \&gpligcexit;
$SIG{'TERM'} = \&gpligcexit;
require GPLIGCfunctions;
if ($^O eq "MSWin32") {
my ($osname, $edition) = Win32::GetOSName();
$text .= "Windows version: $osname - $edition\n";
}
$text .= "Platform: ".$^O." Perl: ".$]." Tk: ".$Tk::VERSION."\n";
# additional modules version info ######################
if ($have_imager) {
$text .= "Imager: ".$Imager::VERSION." ";
} else {
$text .= "Imager: not inst. ";
}
if ($have_EXIF) {
$text .= "Image::ExifTool: ".$Image::ExifTool::VERSION." ";
} else {
$text .= "Image::ExifTool: not inst. ";
}
if ($have_jpeg) {
$text .= "Tk::JPEG: ".$Tk::JPEG::VERSION." ";
} else {
$text .= "Tk::JPEG: not inst. ";
}
if ($have_png) {
$text .= "Tk::PNG: ".$Tk::PNG::VERSION."\n";
} else {
$text .= "Tk::PNG: not inst.\n";
}
########################################################
# /B Option for windows (DOS) command "start" to start the new DOS-window minimized
# not available on all systems
my $start_parameter;
if ($^O eq "MSWin32") {
$start_parameter = "/b";
my ($osname, $edition) = Win32::GetOSName();
# if $osname contains one of the list-entries, delete the /B option
my @noB_OSlist = qw(Win95 Win98 WinME); #these OS's dont know the /B option for start-command
foreach (@noB_OSlist) {
if ($osname =~ /$_/i) {
$start_parameter = "";
}
}
}
# CREATE TMP-DIR
# Make a temporary directory, only if it does not exist already
# (|| will only get evaluated if it does _not_ exist yet.)
if ($^O ne "MSWin32") {
$pfadftmp="/tmp/GPLIGC-$$/";
-d $pfadftmp || mkdir $pfadftmp;
} else {
$pfadftmp = $ENV{'TMP'}."\\GPLIGC-$$\\";
-d $pfadftmp || mkdir $pfadftmp;
}
# ================ CREATE MAIN WINDOW ========================
FlightView();
# load configuration if available
# second time. after defaults were set in FlightView
load_config();
print "config loaded 2nd time\n" if ($config{'DEBUG'});
$map_gms_v_min=10000;
$map_gms_v_max=$config{'map_gms_v'};
if ($config{'maps'} && !($have_imager && $have_png)) {
Errorbox("The config{'maps'} is set, but imager and/or png modules are not available. I'll disable maps\n");
$config{'maps'}=0;
}
$zl = $config{'maps_zoomlevel'};
# a timezone in config should be copied to gpi, before loading any files
$gpi{'timezone'}=$config{'timezone'};
# show new version welcome message
if ($config{'new_version_message_shown'} ne $version) {
Errorbox($new_version_message);
$config{'new_version_message_shown'} = $version;
}
if (!-d $config{'working_directory'}) {
Errorbox("Working directory $config{'working_directory'} doesnt exits! Will be changed to $curdir\n");
$config{'working_directory'} = $curdir;
}
if ($config{'skip_limit_minutes'} <= 0.017) {
Errorbox("skip_limit_minutes is smaller than 0.017! That doesnt make sense! See manual. I'll set it to 0.1 now!");
$config{'skip_limit_minutes'}=0.1;
}
# final check of configuration
check_config();
# check for a file on commandline and load it
# OR load "splash" image/text
if($#ARGV == 0 ){
$file = $ARGV[0];
oeffnen($file);
updateFVW('i');
} else {
FVWsetInfo();
}
### Main Event Loop
MainLoop;
###
### Subroutines follow
###
###############################################################################
# Global state
my ($FlightView, $canvas, $WPPlotWindow, $barocanvas);
my ($minlat, $minlon, $dxp, $dyp);
my @introtext;
my @trackplot;
my @mapplot;
my @baroplot;
my @baroplot_task;
my @wpcyl_lines;
my @acc_lines;
my @task_lines;
my @marks_lines;
sub updateCyl {
if (Exists($FlightView)) {
if ($wpcyl_state == 1) {wpcyldraw(0); wpcyldraw(1);}
}
}
sub updateZoom {
if ($zoom == 1) { zoom(); zoom(); }
}
# update flight view window
sub updateFVW {
#if (Exists($FlightView)) {
my $initflag='u'; # update or initial //mapplot braucht das flag irgendwie beim erstem mal 'i'
if ($#_ != -1) { ## no parameters?
$initflag='i' if (shift eq 'i') ;
if (@introtext) {$canvas->delete(@introtext);}
}
# task and cylinder have to be erased first! (fix for bug #6)
if ($task_state == 1) {taskdraw(0);}
if ($wpcyl_state == 1) {wpcyldraw(0);}
mapplot($dxp, $dyp, $minlat, $minlon, $initflag);
trackplot($dxp, $dyp, $minlat, $minlon);
marksdraw();
baroplot();
if ($wpcyl_state == 1) {wpcyldraw(1);}
if ($task_state == 1) {taskdraw(1);}
FVWausg();
}
sub updateCoor {
FVWausg();
if (Exists($WPPlotWindow)) {WPPlotUpdate();}
}
# More global crap..
my @DECLAT;
my @DECTIME;
my @DECLON;
my @FIX;
my @FIXb;
my @LAT;
my @LON;
my @IAS;
my @TAS;
my @SIU;
my @FXA;
my @VXA;
my @RPM;
my @KMY;
my @KMX;
my @ENL;
my @BARO;
my @TIME;
my @GPSALT;
my @TASK;
my @TASK_info;
my @HEADER;
my @IVARIO;
my @IVARIOGPS;
my @ASPEED;
my @WPNAME;
my @WPLAT;
my @WPLON;
my @WPRADFAC;
my @WPIGCLAT;
my @WPIGCLON;
my @nonIVARIO;
my @nonIVARIOGPS;
my @nonISPEED;
my @compVARIO;
my $VXAEXISTS;
my $RPMEXISTS;
my $TASKEXISTS;
my $FXAEXISTS;
my $SIUEXISTS;
my $ENLEXISTS;
my $TASEXISTS;
my $IASEXISTS;
my ($BARO_max, $BARO_min);
my ($GPSALT_max, $GPSALT_min);
my ($IAS_max, $IAS_min);
my ($TAS_max, $TAS_min);
my ($nonIVARIO_max, $nonIVARIO_min);
my ($nonIVARIOGPS_max, $nonIVARIOGPS_min);
my ($nonISPEED_max, $nonISPEED_min);
my $busy;
my ($task_start_time_index, $task_finish_time_index);
my ($xmin, $xmax, $zmin, $zmax, $ymin, $ymax);
my ($AKTWP, $MAXWP, $freeWP);
my ($com1, $com2);
my ($nr, $offset);
my ($liftsexist);
my ($stat_start, $stat_end);
sub oeffnen { ### open a File
my $backup=$file;
$file=shift; ### Filename wird vom Fileselektor uebernommen (file=global)
if ($file eq '') {$file=$backup; return;} ### Kein Filename -> zurueck
my $length=length($file);
my $test=substr($file, $length-3 ,3); ### Fileendung in $test
# check for igc-file (only file-ending...)
if ($test ne 'igc' && $test ne 'IGC') {
Errorbox("The file does not have igc or IGC ending. Trying to open anyway.");
}
if (! -r $file) {
Errorbox("Can't open $file");$file='No file opened'; return;
}
#if (Exists($initpic)) {$initpic->destroy;}
#reset alt-mode
$altmode = "baro";
$liftsexist=0;
#reset some variables (this was at prog-start in 1.6)
$xmin='';
$xmax='';
$ymin='';
$ymax='';
$zmin='0';
$zmax='';
$AKTWP=1;
$freeWP=1;
$offset=0; #elevation offset, used as openGLIGCexplorer option... after using elevation calibration of FVW!
$nr = 0;
# reset additional info in gpi-data
$gpi{'month'}="00";
$gpi{'day'}="00";
$gpi{'year'}="2009";
$gpi{'timezone'}=$config{'timezone'};
$gpi{'qnh'}=1013.25; # (this is also set in the beginning)
$gpi{'altitude_calibration_ref_press'}=0;
$gpi{'altitude_calibration_type'}="none";
$gpi{'altitude_calibration_point'}=0;
$gpi{'altitude_calibration_point_alt'}=0;
$gpi{'pilot'}="";
$gpi{'copilot'}="";
$gpi{'glider'}="";
$gpi{'callsign'}="";
$gpi{'airfield'}="";
$gpi{'logger'}="";
$gpi{'remarks'}="";
$gpi{'remarks2'}="";
$gpi{'remarks3'}="";
open(FILE,"<$file") || return; ### wie fehlermeldung und return?????
($gpi{'year'}, $gpi{'month'}, $gpi{'day'}) = GPLIGCfunctions::guessdatefromfilename($file);
### Einsaugen der IGC-Datei von File
my @file=<FILE>; ###global! file fuer alle!!!
close (FILE);
$filestat='open'; ### Status : File geoeffnet
# reset some variables
$AKTWP=1;
###alle array werden definiert!
@DECLON=();
@DECLAT=();
@DECTIME=();
@BARO=();
$BARO_max=-20000;
$BARO_min=100000;
@GPSALT=();
$GPSALT_max=-20000;
$GPSALT_min=100000;
@TIME=();
@LAT=();
@LON=();
@FIX=();
@FIXb=();
@HEADER=();
@TASK=();
@ENL=(); #noise level
@IAS=(); #indicated airspeed
@TAS=(); #true airspeed
@SIU=(); # satellites in used
@FXA=(); # hor/vertical accuracy
@VXA=();
@RPM=();
$IAS_max=-10000;
$IAS_min=100000;
$TAS_max=-10000;
$TAS_min=100000;
@ASPEED=();
@compVARIO=();
@nonIVARIO=();
$nonIVARIO_max=-100;
$nonIVARIO_min=100;
@nonIVARIOGPS=();
$nonIVARIOGPS_max=-100;
$nonIVARIOGPS_min=100;
@IVARIO=();
@IVARIOGPS=();
@nonISPEED=();
$nonISPEED_max=-200000;
$nonISPEED_min=2000000;
@TASK_info=();
@WPIGCLAT=0;
@WPIGCLON=0;
@WPNAME=();
@WPLAT=();
@WPLON=();
@WPRADFAC=(); # WP radius factor (for cylinder/barrel)
# I-extensions to the B-record
$IASEXISTS = "no";
my $IASSTART = 0;
my $IASLENGTH = 0;
$TASEXISTS = "no";
my $TASSTART = 0;
my $TASLENGTH = 0;
$ENLEXISTS = "no";
my $ENLSTART = 0;
my $ENLLENGTH = 0;
$SIUEXISTS = "no";
my $SIUSTART = 0;
my $SIULENGTH = 0;
$FXAEXISTS = "no";
my $FXASTART = 0;
my $FXALENGTH = 0;
$VXAEXISTS = "no";
my $VXASTART = 0;
my $VXALENGTH = 0;
$RPMEXISTS = "no";
my $RPMSTART = 0;
my $RPMLENGTH = 0;
$TASKEXISTS = "no";
## Trigonometric distances from some reference point
## Skewed because we are on the surface of a sphere, but our
## flown distances are a lot << than that very sphere we are on...
@KMY = ();
@KMX = ();
$busy=$FlightView->Busy;
### Schleife ueber alle Zeilen und Selektierung der Eintraege nach A H C B
foreach my $zeile (@file) {
if ($zeile=~/^A(.+)\S?/) {$FDR=$1;}
if ($zeile=~/^H(.+)\S?/) {push(@HEADER , $1."\n");}
if ($zeile=~/^C(.+)\S?/) {
$TASKEXISTS="yes";
push(@TASK , $1."\n");
}
if ($zeile=~/^B(.+)\S?/) {push(@FIXb , $1."\n");}
# check for I_extensions to the Brecords (more here to be added SIU, FXA etc)
if ($zeile=~/^I(.+)\S?/) {
my $izeile=$1;
if ($izeile =~/(\d{2})(\d{2})ENL/) {
$ENLSTART = $1 - 2;
$ENLLENGTH = $2 -$1 +1;
#$ENLEND = $2;
$ENLEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})RPM/) {
$RPMSTART = $1 - 2;
$RPMLENGTH = $2 -$1 +1;
#$ENLEND = $2;
$RPMEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})IAS/) {
$IASSTART = $1 - 2;
$IASLENGTH = $2 - $1 +1;
$IASEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})SIU/) {
$SIUSTART = $1 - 2;
$SIULENGTH = $2 - $1 +1;
$SIUEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})FXA/) {
$FXASTART = $1 - 2;
$FXALENGTH = $2 - $1 +1;
$FXAEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})VXA/) {
$VXASTART = $1 - 2;
$VXALENGTH = $2 - $1 +1;
$VXAEXISTS = "yes";
}
if ($izeile =~/(\d{2})(\d{2})TAS/) {
$TASSTART = $1 - 2;
$TASLENGTH = $2 -$1 +1;
$TASEXISTS = "yes";
}
}
}
# grep all "safe" position fixes (if 24th character is V == unsafe)
@FIX = grep { (substr($_,23,1) ne 'V'); } @FIXb;
# emergency Fallback, if no "A's" available
if ($#FIX == -1) {
Errorbox("No valid (A) position fixes found. Trying to use position fixes marked as invalid (V)");
@FIX = @FIXb;
}
# no fixes avaiilable? no safe ones and no unsafe ones... sorry, nothing to do
if ($#FIX == -1) {
Errorbox("No position fixes found - invalid igc-file!");
gpligcexit (1);
}
my $alterr=0;
### read @BARO @GPSALT @TIME @LAT @LON from fixes-lines
for (my $z=0; $z<= $#FIX; $z++) {
my $skip=0;
if ($config{'skip_check'} && $config{'skip_del_first_after'} && !$z<1) {
if (GPLIGCfunctions::time2dec(substr($FIX[$z],0,6))-GPLIGCfunctions::time2dec(substr($FIX[$z-1],0,6)) > $config{'skip_limit_minutes'}/60 ) {$skip =1;}
}
if (! $skip) {
my $alt = substr($FIX[$z], 24,5);
my $gpsa = substr($FIX[$z], 29,5);
if ($alt > 20000) {$alt = 0; $alterr=1;}
if ($gpsa >20000) {$gpsa = 0; $alterr=1;}
push(@BARO, $alt);
push(@GPSALT, $gpsa);
push(@TIME, substr($FIX[$z], 0,6));
push(@LAT, substr($FIX[$z], 6, 8));
push(@LON, substr($FIX[$z], 14, 9));
if ($ENLEXISTS eq "yes") {
push(@ENL, substr($FIX[$z], $ENLSTART, $ENLLENGTH));
} else {
push(@ENL, "0");
}
if ($RPMEXISTS eq "yes") {
push(@RPM, substr($FIX[$z], $RPMSTART, $RPMLENGTH));
} else {
push(@RPM, "0");
}
if ($IASEXISTS eq "yes") {
push(@IAS, substr($FIX[$z], $IASSTART, $IASLENGTH));
} else {
push(@IAS, "0");
}
if ($TASEXISTS eq "yes") {
push(@TAS, substr($FIX[$z], $TASSTART, $TASLENGTH));
} else {
push(@TAS, "0");
}
if ($SIUEXISTS eq "yes") {
push(@SIU, substr($FIX[$z], $SIUSTART, $SIULENGTH));
} else {
push(@SIU, "0");
}
if ($FXAEXISTS eq "yes") {
push(@FXA, substr($FIX[$z], $FXASTART, $FXALENGTH));
} else {
push(@FXA, "0");
}
if ($VXAEXISTS eq "yes") {
push(@VXA, substr($FIX[$z], $VXASTART, $VXALENGTH));
} else {
push(@VXA, "0");
}
}
}
if ($alterr) {
Errorbox("Very weird altitudes found! (>20.000m) They are set to 0. Check your igc-file.");
}
# convert time to decimal
foreach (@TIME) {
my $tmptime=GPLIGCfunctions::time2dec($_);
push(@DECTIME, $tmptime);
}
# convert coordinates to decimal degrees
foreach (@LAT) {
push(@DECLAT, GPLIGCfunctions::igc2dec($_));
}
foreach (@LON) {
push(@DECLON, GPLIGCfunctions::igc2dec($_));
}
# Find reference point (center between max and min lat/lon)
my ($maxlat, $minlat)=GPLIGCfunctions::MaxKoor(\@DECLAT);
my ($maxlon, $minlon)=GPLIGCfunctions::MaxKoor(\@DECLON);
my $centrex = ($minlon + $maxlon)/2;
my $centrey = ($minlat + $maxlat)/2;
print "OEFFNEN: init maxlat minlat maxlon minlon: $maxlat $minlat $maxlon $minlon\n" if ($config{'DEBUG'});
# KMY and KMX are km distances in X ynd Y from refernece point
for (my $i=0; $i<=$#DECLAT; $i++){
my $dist=GPLIGCfunctions::dist($centrey,$DECLON[$i],$DECLAT[$i],$DECLON[$i]);
if($centrey>$DECLAT[$i]){
$dist = -$dist;
}
#print "$i $dist\n";
push(@KMY, $dist);
}
for (my $i=0; $i<=$#DECLON; $i++){
my $dist=GPLIGCfunctions::dist($DECLAT[$i],$centrex,$DECLAT[$i],$DECLON[$i]);
if($centrex>$DECLON[$i]){
$dist = -$dist;
}
push(@KMX, $dist);
}
# average speed, vario, gpsvario (averaged by $config{'integrate_over'} position fixes)
for (my $i=0; $i<=$#DECLAT; $i++){
if ($i >= $config{'integrate_over'}) {
my $dist=GPLIGCfunctions::dist($DECLAT[$i-$config{'integrate_over'}],$DECLON[$i-$config{'integrate_over'}],$DECLAT[$i],$DECLON[$i]);
push(@ASPEED, ($dist/($DECTIME[$i]-$DECTIME[$i-$config{'integrate_over'}])));
push(@IVARIO, (($BARO[$i]-$BARO[$i-$config{'integrate_over'}])/(($DECTIME[$i]-$DECTIME[$i-$config{'integrate_over'}])*3600)) );
push(@IVARIOGPS, (($GPSALT[$i]-$GPSALT[$i-$config{'integrate_over'}])/(($DECTIME[$i]-$DECTIME[$i-$config{'integrate_over'}])*3600)) );
} else {
push(@ASPEED, 0);
push(@IVARIO, 0);
push(@IVARIOGPS, 0);
}
}
# non averaged speed, vario. gpsvario TE vario(compVARIO)
for (my $i=0; $i<=$#DECLAT; $i++) {
if ($i >= 1) {# && $i <$#DECLAT) {
my $dist=GPLIGCfunctions::dist($DECLAT[$i-1],$DECLON[$i-1],$DECLAT[$i],$DECLON[$i]);
my $delta_time=$DECTIME[$i]-$DECTIME[$i-1];
#my $delta_time_next=$DECTIME[$i+1]-$DECTIME[$i];
# WORKAROUND to avoid div by zero, if we have two identic B-records
if ($delta_time == 0) {$delta_time=0.00000001;Errorbox("Identical B records! check IGC file at ".GPLIGCfunctions::dec2time($DECTIME[$i])) }
#if ($delta_time_next == 0) {$delta_time_next=0.00000001;}
# check for time reversals!
# exception is 24:00->0:00 with a small window
# might be problematic for large interval files... :-(
my $trc=0; #time reversal count
my $firsttrcat=999; #first trc
my $nn; #n-1
if ($DECTIME[$i] < $DECTIME[$i-1] && !( $DECTIME[$i]<=0.2
&& $DECTIME[$i]>=0
&& $DECTIME[$i-1]<=24
&& $DECTIME[$i-1]>=23.8 )) {
# ??? why this? $DECTIME[$i] = $DECTIME[$i-1] + 0.000014; # a half a second!
print " $DECTIME[$i] $DECTIME[$i-1] \n" if ($config{'DEBUG'});
if ($firsttrcat == 999) {
$firsttrcat = $DECTIME[$i];
$nn = $DECTIME[$i-1];
}
$trc++;
}
if ($trc > 0) {
Errorbox("$trc time reversal(s) found. between ".GPLIGCfunctions::dec2time($nn)."-".GPLIGCfunctions::dec2time($firsttrcat)."! Check your IGC file!");
}
# filter abnormal values....
#my $nonispeed = (($dist/$delta_time)+($distn/$delta_time_next))/2.0;
my $nonispeed = ($dist/$delta_time);
if ($nonispeed < 1200) {
push(@nonISPEED, $nonispeed);
} else {
push(@nonISPEED, 0);
}
# my $nonivario = ((($BARO[$i]-$BARO[$i-1])/($delta_time*3600)) + (($BARO[$i+1]-$BARO[$i])/($delta_time_next*3600)))/2.0 ;
my $nonivario = ($BARO[$i]-$BARO[$i-1])/($delta_time*3600);
if (abs($nonivario) < 60) {
push(@nonIVARIO,$nonivario);
} else {
push(@nonIVARIO,0);
}
if ($IASEXISTS eq "yes") {
my $compvario = ( ($BARO[$i]-$BARO[$i-1]) -
( ( (($IAS[$i-1]/3.6)**2) - ($IAS[$i]/3.6)**2) / 19.62) ) / ($delta_time*3600);
push(@compVARIO,$compvario);
} elsif ($TASEXISTS eq "yes") { ## XXX is this necessary for TAS?
my $compvario = ( ($BARO[$i]-$BARO[$i-1]) -
( ( (($TAS[$i-1]/3.6)**2) - ($TAS[$i]/3.6)**2) / 19.62) ) / ($delta_time*3600);
push(@compVARIO,$compvario);
} elsif ($config{'te_vario_fallback'}) { # ist das hier die richtige speed?
my $compvario = ( ($BARO[$i]-$BARO[$i-1]) -
( ( (($nonISPEED[$i-1]/3.6)**2) - ($nonISPEED[$i]/3.6)**2) / 19.62) ) / ($delta_time*3600);
push(@compVARIO,$compvario);
}
else {push(@compVARIO,0);}
#my $gpsvario = ((($GPSALT[$i]-$GPSALT[$i-1])/($delta_time*3600))+ (($GPSALT[$i+1]-$GPSALT[$i])/($delta_time_next*3600)))/2.0 ;
my $gpsvario = ($GPSALT[$i]-$GPSALT[$i-1])/($delta_time*3600);
if (abs($gpsvario) < 60) {
push(@nonIVARIOGPS,$gpsvario);
} else {
push(@nonIVARIOGPS,0);
}
} else { # this can be only calculated from the second data record. for the first record they will be set to zero
push(@nonISPEED, 0);
push(@nonIVARIO, 0);
push(@nonIVARIOGPS, 0);
if ($IASEXISTS eq "yes" || $TASEXISTS eq "yes" || $config{'te_vario_fallback'} == 1) {
push(@compVARIO,0);
}
}
}
# warning
if (($IASEXISTS ne "yes" && $TASEXISTS ne "yes") && $config{'te_vario_fallback'} == 1 && $config{'te_warning'})
{Errorbox("total energy compensation was calculated from gps groundspeed!\nTo turn off this warning set te_warning = 0.\nAlso see te_vario_fallback");}
# Maximum/minimum height:
my ($maxbaro, $minbaro)=GPLIGCfunctions::MaxKoor(\@BARO);
my ($maxgpsalt, $mingpsalt)=GPLIGCfunctions::MaxKoor(\@GPSALT);
# write tmp-files
tmpfileout();
sub tmpfileout {
open (BARO,">${pfadftmp}baro.dat");
open (GPSALT,">${pfadftmp}gpsalt.dat");
open (PRESS,">${pfadftmp}press.dat");
open (SPACE,">${pfadftmp}3d.dat");
open (LATPROJ,">${pfadftmp}latproj.dat");
open (LONPROJ,">${pfadftmp}lonproj.dat");
open (DELTAH,">${pfadftmp}deltah.dat");
open (VARIO,">${pfadftmp}vario.dat");
open (GPSVARIO,">${pfadftmp}gpsvario.dat");
open (SPEED,">${pfadftmp}speed.dat");
open (LONLAT,">${pfadftmp}lonlat.dat");
open (KM,">${pfadftmp}km.dat");
open (ENL, ">${pfadftmp}enl.dat");
open (IAS, ">${pfadftmp}ias.dat");
open (TAS, ">${pfadftmp}tas.dat");
open (SAT, ">${pfadftmp}sat.dat");
# ----------------- LOOP over all data-records (fixes) --------------------
# writing tmp-files
for (my $i=0; $i<=$#DECTIME; $i++) { # DECTIME nicht FIX!
# processing of decimal time.....
# check if we pass the 24:00
if ($i > 0) { # not in first cycle
# if time goes backwards 24:00 -> 0:00
if ($DECTIME[$i] < $DECTIME[$i-1]) {
print "2400 -> 0000 detected, altering DECTIME...\n" if ($config{'DEBUG'});
print " $#DECTIME, dect,,,,, $#FIX fix...\n" if ($config{'DEBUG'});
# alter all time-points after this one... + 24
for (my $z=$i; $z<=$#DECTIME; $z++) {
$DECTIME[$z] = $DECTIME[$z] + 24;
}
}
}
print KM $KMX[$i]," ",$KMY[$i]," ",$BARO[$i],"\n";
print LONLAT $i," ",$LON[$i]," ",$LAT[$i],"\n";
print BARO $DECTIME[$i]," ",$BARO[$i],"\n";
print PRESS $DECTIME[$i]," ",GPLIGCfunctions::pressure($BARO[$i],$gpi{'qnh'}),"\n";
if ($VXAEXISTS eq "no") {
print GPSALT $DECTIME[$i]," ",$GPSALT[$i],"\n";
} else {
print GPSALT $DECTIME[$i]," ",$GPSALT[$i]," ", $VXA[$i],"\n";
}
print ENL $DECTIME[$i], " ", $ENL[$i], " ", $RPM[$i], "\n";
print IAS $DECTIME[$i], " ", $IAS[$i],"\n";
print TAS $DECTIME[$i], " ", $TAS[$i],"\n";
print SPACE $DECLON[$i]," ",$DECLAT[$i]," ",$BARO[$i]," ",$GPSALT[$i],"\n";
print LATPROJ $DECLAT[$i]," ",$BARO[$i]," ",$GPSALT[$i],"\n";
print LONPROJ $DECLON[$i]," ",$BARO[$i]," ",$GPSALT[$i],"\n";
print DELTAH $DECTIME[$i]," ",$BARO[$i]-$GPSALT[$i],"\n";
# averaged vario, speed, gps-vario
print VARIO $DECTIME[$i]," ",$IVARIO[$i],"\n";
print GPSVARIO $DECTIME[$i]," ",$IVARIOGPS[$i],"\n";
print SPEED $DECTIME[$i]," ",$ASPEED[$i],"\n";
print SAT $DECTIME[$i]," ",$SIU[$i]," ",$FXA[$i]," ", $VXA[$i],"\n";
# getting extrema of some values;
$BARO_max = $BARO[$i] if ($BARO[$i] > $BARO_max);
$BARO_min = $BARO[$i] if ($BARO[$i] < $BARO_min);
$GPSALT_max = $GPSALT[$i] if ($GPSALT[$i] > $GPSALT_max);
$GPSALT_min = $GPSALT[$i] if ($GPSALT[$i] < $GPSALT_min);
$nonISPEED_max = $nonISPEED[$i] if ($nonISPEED[$i] > $nonISPEED_max);
$nonISPEED_min = $nonISPEED[$i] if ($nonISPEED[$i] < $nonISPEED_min);
$IAS_max = $IAS[$i] if ($IAS[$i] > $IAS_max);
$IAS_min = $IAS[$i] if ($IAS[$i] < $IAS_min);
$TAS_max = $TAS[$i] if ($TAS[$i] > $TAS_max);
$TAS_min = $TAS[$i] if ($TAS[$i] < $TAS_min);
$nonIVARIO_max = $nonIVARIO[$i] if ($nonIVARIO[$i] > $nonIVARIO_max);
$nonIVARIO_min = $nonIVARIO[$i] if ($nonIVARIO[$i] < $nonIVARIO_min);
$nonIVARIOGPS_max = $nonIVARIOGPS[$i] if ($nonIVARIOGPS[$i] > $nonIVARIOGPS_max);
$nonIVARIOGPS_min = $nonIVARIOGPS[$i] if ($nonIVARIOGPS[$i] < $nonIVARIOGPS_min);
}
#rounding vario-extrema
$nonIVARIO_max = sprintf("%.4f",$nonIVARIO_max);
$nonIVARIO_min = sprintf("%.4f",$nonIVARIO_min);
$nonIVARIOGPS_max = sprintf("%.4f",$nonIVARIOGPS_max);
$nonIVARIOGPS_min = sprintf("%.4f",$nonIVARIOGPS_min);
# closing files
close (BARO);
close (GPSALT);
close (SPACE);
close (LATPROJ);
close (LONPROJ);
close (DELTAH);
close (VARIO);
close (SPEED);
close (LONLAT);
close (ENL);
close (IAS);
close (TAS);
close (KM);
close (SAT);
}
if ($config{'DEBUG'}) {
print "Debugging in Oeffnen: max and min values\n";
print "baro $BARO_max \n";#= $BARO[$i] if ($BARO[$i] > $BARO_max);
print " $BARO_min \n";#= $BARO[$i] if ($BARO[$i] < $BARO_min);
print "gps $GPSALT_max \n";#= $GPSALT[$i] if ($GPSALT[$i] > $GPSALT_max);
print " $GPSALT_min \n";#= $GPSALT[$i] if ($GPSALT[$i] < $GPSALT_min);
print "nISp $nonISPEED_max \n";#= $nonISPEED[$i] if ($nonISPEED[$i] > $nonISPEED_max);
print " $nonISPEED_min \n";#= $nonISPEED[$i] if ($nonISPEED[$i] < $nonISPEED_min);
print "IAS $IAS_max \n";#= $IAS[$i] if ($IAS[$i] > $IAS_max);
print " $IAS_min \n";#= $IAS[$i] if ($IAS[$i] < $IAS_min);
print "TAS $TAS_max \n";#= $TAS[$i] if ($TAS[$i] > $TAS_max);
print " $TAS_min \n";#= $TAS[$i] if ($TAS[$i] < $TAS_min);
print "nIV $nonIVARIO_max \n";#= $nonIVARIO[$i] if ($nonIVARIO[$i] > $nonIVARIO_max);
print " $nonIVARIO_min \n";#= $nonIVARIO[$i] if ($nonIVARIO[$i] < $nonIVARIO_min);
print "nIVgps $nonIVARIOGPS_max \n";#= $nonIVARIOGPS[$i] if ($nonIVARIOGPS[$i] > $nonIVARIOGPS_max);
print " $nonIVARIOGPS_min \n";#= $nonIVARIOGPS[$i] if ($nonIVARIOGPS[$i] < $nonIVARIOGPS_min);
}
# Generating HISTOGRAMS
# we need the decimal flighttime!
my $starttimeindex=GPLIGCfunctions::takeoff_detect(\@nonISPEED, 's');
my $landtimeindex=GPLIGCfunctions::takeoff_detect(\@nonISPEED, 'l');
my $decflighttime=$DECTIME[$landtimeindex]-$DECTIME[$starttimeindex];
# histogram intervals for vario
my $histo_intervall_vario = $config{'vario_histo_intervall'};#0.2;
# histogram intervals and limits for speed
my $histo_intervall = $config{'speed_histo_intervall'};#2.5;
### GROUND SPEED HISTOGRAM
# initialize arrays for speed histogram
my @speedBEREICH=();
my @speedHISTO=();
my $i = 0;
for (my $bereich=$nonISPEED_min; $bereich <= $nonISPEED_max; $bereich+=$histo_intervall) {
push(@speedHISTO,0);
push(@speedBEREICH,$bereich);
}
# summarize the intervals
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($nonISPEED[$z] - $nonISPEED_min ) / $histo_intervall);
#print "$index \n";
if ($index >= 0 && $index < (($nonISPEED_max-$nonISPEED_min)/$histo_intervall)) {
#print "if $index\n";
$speedHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (SHISTO,">${pfadftmp}shisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#speedHISTO; $z++) {
#print "$z $#speedHISTO \n";
print SHISTO $speedBEREICH[$z]+($histo_intervall/2)." ".(($speedHISTO[$z]/$decflighttime)*100)."\n";
}
close (SHISTO);
### AIRSPEED HISTOGRAM
# initialize arrays
@speedBEREICH=();
@speedHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$IAS_min; $bereich <= $IAS_max; $bereich+=$histo_intervall) {
push(@speedHISTO,0);
push(@speedBEREICH,$bereich);
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($IAS[$z] - $IAS_min ) / $histo_intervall);
#print "$index \n";
if ($index >= 0 && $index < (($IAS_max-$IAS_min)/$histo_intervall)) {
#print "if $index\n";
$speedHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (ASHISTO,">${pfadftmp}iashisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#speedHISTO; $z++) {
#print "$z $#speedHISTO \n";
print ASHISTO $speedBEREICH[$z]+($histo_intervall/2)." ".(($speedHISTO[$z]/$decflighttime)*100)."\n";
}
close (ASHISTO);
### AIRSPEED HISTOGRAM
# initialize arrays
@speedBEREICH=();
@speedHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$TAS_min; $bereich <= $TAS_max; $bereich+=$histo_intervall) {
push(@speedHISTO,0);
push(@speedBEREICH,$bereich);
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($TAS[$z] - $TAS_min ) / $histo_intervall);
#print "$index \n";
if ($index >= 0 && $index < (($TAS_max-$TAS_min)/$histo_intervall)) {
#print "if $index\n";
$speedHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (ASHISTO,">${pfadftmp}tashisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#speedHISTO; $z++) {
#print "$z $#speedHISTO \n";
print ASHISTO $speedBEREICH[$z]+($histo_intervall/2)." ".(($speedHISTO[$z]/$decflighttime)*100)."\n";
}
close (ASHISTO);
### VARIO HISTO BARO
my @varioBEREICH=();
my @varioHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$nonIVARIO_min; $bereich <= $nonIVARIO_max; $bereich+=$histo_intervall_vario) {
push(@varioHISTO,0);
push(@varioBEREICH,$bereich);
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($nonIVARIO[$z] - $nonIVARIO_min ) / $histo_intervall_vario);
#print "$index \n";
if ($index >= 0 && $index < (($nonIVARIO_max-$nonIVARIO_min)/$histo_intervall_vario)) {
#print "if $index\n";
$varioHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (VHISTO,">${pfadftmp}vhisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#varioHISTO; $z++) {
print VHISTO $varioBEREICH[$z]+($histo_intervall_vario/2)." ".(($varioHISTO[$z]/$decflighttime)*100)."\n";
}
close (VHISTO);
### VARIO HISTO GPS
@varioBEREICH=();
@varioHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$nonIVARIOGPS_min; $bereich <= $nonIVARIOGPS_max; $bereich+=$histo_intervall_vario) {
push(@varioHISTO,0);
push(@varioBEREICH,$bereich);
#print "$bereich ..\n";
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int((($nonIVARIOGPS[$z] - $nonIVARIOGPS_min ) / $histo_intervall_vario)+.5);
#print "$nonIVARIOGPS[$z] \n";
if ($index >= 0 && $index < (($nonIVARIOGPS_max-$nonIVARIOGPS_min)/$histo_intervall_vario)) {
#print "if $index\n";
$varioHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (VHISTOGPS,">${pfadftmp}vhistogps.dat");
#output in % of flighttime!
for (my $z=0; $z < $#varioHISTO; $z++) {
print VHISTOGPS $varioBEREICH[$z]+($histo_intervall_vario/2)." ".(($varioHISTO[$z]/$decflighttime)*100)."\n";
}
close (VHISTOGPS);
### BARO HISTO
my @baroBEREICH=();
my @baroHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$BARO_min; $bereich <= $BARO_max; $bereich+=$config{'baro_histo_intervall'}) {
push(@baroHISTO,0);
push(@baroBEREICH,$bereich);
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($BARO[$z] - $BARO_min ) / $config{'baro_histo_intervall'});
#print "$index \n";
if ($index >= 0 && $index < (($BARO_max-$BARO_min)/$config{'baro_histo_intervall'})) {
#print "if $index\n";
$baroHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (BAROHISTO,">${pfadftmp}barohisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#baroHISTO; $z++) {
print BAROHISTO $baroBEREICH[$z]+($config{'baro_histo_intervall'}/2)." ".(($baroHISTO[$z]/$decflighttime)*100)."\n";
}
close (BAROHISTO);
### GPS HISTO
@baroBEREICH=();
@baroHISTO=();
$i = 0;
# initialize the histo-arrays
for (my $bereich=$GPSALT_min; $bereich <= $GPSALT_max; $bereich+=$config{'baro_histo_intervall'}) {
push(@baroHISTO,0);
push(@baroBEREICH,$bereich);
}
# summieren der intervalle
for (my $z=$starttimeindex ; $z < $landtimeindex; $z++) {
my $index = int(($GPSALT[$z] - $GPSALT_min ) / $config{'baro_histo_intervall'});
#print "$index \n";
if ($index >= 0 && $index < (($GPSALT_max-$GPSALT_min)/$config{'baro_histo_intervall'})) {
#print "if $index\n";
$baroHISTO[$index]+= $DECTIME[$z+1]-$DECTIME[$z];
}
}
#output
open (BAROHISTO,">${pfadftmp}gpshisto.dat");
#output in % of flighttime!
for (my $z=0; $z < $#baroHISTO; $z++) {
print BAROHISTO $baroBEREICH[$z]+($config{'baro_histo_intervall'}/2)." ".(($baroHISTO[$z]/$decflighttime)*100)."\n";
}
close (BAROHISTO);
##################
# This is a work-around for files without pressure altitude...
# hell knows how that can happen, but I have seen such.
my $dybaro = ($maxbaro - $minbaro);
if($dybaro == 0){ #some sick files only have GPS altitude...
Errorbox("Work-around enabled! NO PRESSURE ALTITUDE FOUND IN FILE! USING GPS ALTITUDE");
$minbaro = $mingpsalt;
$maxbaro = $maxgpsalt;
@BARO = @GPSALT;
@nonIVARIO = @nonIVARIOGPS;
@IVARIO = @IVARIOGPS;
$altmode = "gps";
}
#################
# evaluation of @TASK
my $z=0;
$MAXWP=0;
my $j=1;
# this is the new and better task scan-function
foreach (@TASK) {
if (substr($_,7,1) ne 'N' && substr($_,7,1) ne 'S') {
# $_ is a task-definition !
my $TASK_ID=substr($_,18,4);
my $zwisch_date=GPLIGCfunctions::time2human(substr($_,0,6),'d');
my $zwisch_zeit=GPLIGCfunctions::time2human(substr($_,6,6),'t');
my $TASK_TIME=$zwisch_date." ".$zwisch_zeit;
my $TASK_DATE=GPLIGCfunctions::time2human(substr($_,12,6),'d');
my $TASK_WPs=substr($_,22,2);
#$MAXWP=$MAXWP+($TASK_WPs+4); # + start, abflug, finish, landing
push(@TASK_info, "------------");
push(@TASK_info, "Task ID: $TASK_ID");
push(@TASK_info, "Task set time: $TASK_TIME");
push(@TASK_info, "Task date: $TASK_DATE");
push(@TASK_info, "#WPs : $TASK_WPs");
} else {
#only if different from last one (avoid the doubled entries)
if ( (substr($_,0,8) ne $WPIGCLAT[$j-1] && substr($_,8,9) ne $WPIGCLON[$j-1]) &&
!( substr($_,0,7) eq "0000000" && substr($_,8,8) eq "00000000" ) # ignore 0/0 coordinates (invalid WPs) Bug #4
) {
$WPIGCLAT[$j]=substr($_,0,8);
$WPIGCLON[$j]=substr($_,8,9);
$WPNAME[$j]=substr($_,17);
$WPRADFAC[$j]=1.0;
chop($WPNAME[$j]); #cut CR
chop($WPNAME[$j]); #cut LF
my $formlat=GPLIGCfunctions::coorconvert(GPLIGCfunctions::igc2dec($WPIGCLAT[$j]),'lat','igch');
my $formlon=GPLIGCfunctions::coorconvert(GPLIGCfunctions::igc2dec($WPIGCLON[$j]),'lon','igch');
#push(@TASK_info, "$WPIGCLAT[$j] $WPIGCLON[$j] $WPNAME[$j]");
push(@TASK_info, "$formlat $formlon $WPNAME[$j]");
$j++;
$MAXWP++;
} else { # if doubled, put in TASK_info trotzdem
my $wpname=substr($_,17);
my $wplat=substr($_,0,8);
my $wplon=substr($_,8,9);
chop($wpname); #cut CR
chop($wpname); #cut LF
my $formlat=GPLIGCfunctions::coorconvert(GPLIGCfunctions::igc2dec($wplat),'lat','igch');
my $formlon=GPLIGCfunctions::coorconvert(GPLIGCfunctions::igc2dec($wplon),'lon','igch');
push(@TASK_info, "$formlat $formlon $wpname");
}
}
}
#if there is no task in the igc-file set some, to prevent errors
if ($TASKEXISTS eq "no" ) {
$MAXWP =1;
# canberra
$WPIGCLAT[1]="3515690S";
$WPIGCLON[1]="14908123E";
$WPNAME[1]="GPLIGC Headquarter";
$WPRADFAC[1]=1.0;
}
# convert all wp's to decimal format!
for (my $i=1; $i<=$#WPIGCLAT; $i++){
$WPLAT[$i]=GPLIGCfunctions::igc2dec($WPIGCLAT[$i]);
$WPLON[$i]=GPLIGCfunctions::igc2dec($WPIGCLON[$i]);
}
# set start and finish time (for task_speed) initially to takeoff and landing time
# also the unpowered flight window
#$task_start_time_index = GPLIGCfunctions::takeoff_detect(\@nonISPEED,'s');
$task_finish_time_index = GPLIGCfunctions::takeoff_detect(\@nonISPEED,'l');
$task_start_time_index = GPLIGCfunctions::releaseDetect(\@BARO,GPLIGCfunctions::takeoff_detect(\@nonISPEED,'s'));
###test triangle
#GPLIGCfunctions::bestriangle(\@DECLAT, \@DECLON, 1, $#DECLAT, 'x', 100000);
#print "hannes routine..... is working\n";
#GPLIGCfunctions::bestrecurse(\@DECLAT, \@DECLON);
#print "ready \n";
foreach (@HEADER) {
# i have to chop off trailing garbage first
$_ =~ s/\s+$// ;
if (/^FPLT[\w\d\s]+:(.+)$/) {$gpi{'pilot'} = $1}
if (/^FGTY[\w\d\s]+:(.+)$/) {$gpi{'glider'} = $1}
if (/^FGID[\w\d\s]+:(.+)$/) {$gpi{'callsign'} = $1}
if ($gpi{'year'} == 0 && $gpi{'month'} == 0 && $gpi{'day'} == 0) {
if (/^FDTE(\d{6})/) {$gpi{'day'} = substr($1,0,2); $gpi{'month'}=substr($1,2,2); $gpi{'year'}=substr($1,4,2);
if ($gpi{'year'} > 90) {$gpi{'year'} +=1900} else {$gpi{'year'} +=2000}
}
}
}
$stat_start =0;
$stat_end= $#BARO;
# check for gpi file and load if present!
# if not
my $gpifile = substr($file, 0, -3)."gpi";
if (-r $gpifile) {load_gpi();}
elsif ($config{'open_additional_info'} == 1) {
gpiinput();
}
if ($gpi{'altitude_calibration_type'} eq "baro") {elevationcalibration("baro",$gpi{'altitude_calibration_point_alt'},$gpi{'altitude_calibration_point'},1);}
if ($gpi{'altitude_calibration_type'} eq "constant") {elevationcalibration("constant",$gpi{'altitude_calibration_point_alt'},$gpi{'altitude_calibration_point'},1);}
if ($gpi{'altitude_calibration_type'} eq "refpress") {qnhcalibration($gpi{'qnh'},$gpi{'altitude_calibration_ref_press'},1);}
unzoomed();
if ($config{'photos'}) {
print "Starting to process Photo-stuff.... .... \n" if ($config{'DEBUG'});
checkPhotos();
processPhotos();
print "..... processing Photo-stuff finished. \n" if ($config{'DEBUG'});
}
my($ofilename, $odirectories, $osuffix) = File::Basename::fileparse($file);
$FlightView->configure(-title=>"$ofilename");#.$osuffix"); #<-- osuffix empty
$busy=$FlightView->Unbusy;
print "sub oeffnen fertig\n" if ($config{'DEBUG'});
}
# oeffnen
###############################################################################
# Give out plots via gnuplot
sub Ausgabe { ### Ausgabe der Plots mit Gnuplot
if ($filestat eq 'closed') {
$FlightView->bell;
return;
}
#check for gnuplot!
if ($^O ne "MSWin32") {
if (system("echo 'q' | gnuplot")) {
Errorbox("Can't execute gnuplot. Please check your gnuplot installation");
return;
}
}
my $mode = shift;
my $bereich='['.$xmin.':'.$xmax.']['.$ymin.':'.$ymax.']['.$zmin.':'.$zmax.']';
# Linux/Unix Gnupot 3.x
if ( $^O ne "MSWin32" && $config{'gnuplot_major_version'} != 4 ) {
open (BPIPE, "| gnuplot -persist"); ###oeffnen von GNUPLOT write-Pipe
print "using old gnuplot 3.x \n" if ($config{'DEBUG'});
} else {
unlink ("${pfadftmp}plot.gpl");
open (BPIPE, ">${pfadftmp}plot.gpl"); # command file for gnuplot
print "using new gnuplot 4.x \n" if ($config{'DEBUG'} && $config{'gnuplot_major_version'} == 4);
print "using windows gnuplot: $config{'gnuplot_win_exec'} \n" if ($config{'DEBUG'} && $^O eq "MSWin32") ;
}
my $w32_persist;
my $linuxquiet = '';
if ($^O ne "MSWin32") {$linuxquiet =' 2>/dev/null >&2';}
if ( ($config{'gnuplot_terminal'} ne 'x11') && ($config{'gnuplot_terminal'} ne 'qt')){
if ($savname eq 'no'){$savname=save();}
if ($savname eq 'no'){close BPIPE;return;}
if ($savname ne 'no'){print BPIPE "set term $config{'gnuplot_terminal'}\n";
print BPIPE "set output "."\'".$savname."\'"."\n";}
$w32_persist = "";
} else {
print BPIPE "set term $config{'gnuplot_terminal'}\n";
$w32_persist = "-";
}
$busy=$FlightView->Busy;
$file=~ /(.+)\/(.+?)$/; #Filename nach letztem "/" in $2
my $title=$2; ### titel fuer plot
if (defined $title) {} else {$title="No Title";}
print BPIPE "set title \"$title\"\n"; ### wird gesetzt
if ($mode eq '3d') {
print BPIPE "set view ".(90-$config{'gnuplot_3d_rotx'}).",".(360-$config{'gnuplot_3d_rotz'})."\n";
print BPIPE "set ticslevel 0\n";
}
if ($config{'gnuplot_grid_state'} eq 'set grid') {
print BPIPE "set grid\n";
} ### grid on
#experimental
#print BPIPE "set mouse\n";
print BPIPE "set title \"$file\"\n";
print BPIPE $com1." $bereich ".$com2."\n";
print $com1." $bereich ".$com2."\n" if ($config{'DEBUG'});
close (BPIPE) if ($^O ne "MSWin32" && $config{'gnuplot_major_version'} == 3);
if ($^O eq "MSWin32") {
close (BPIPE);
open (BATCH, ">${pfadftmp}plot.bat");
print BATCH "\@ECHO off\n";
print BATCH "$config{'gnuplot_win_exec'} ${pfadftmp}plot.gpl $w32_persist\n";
close (BATCH);
system("start $start_parameter ${pfadftmp}plot.bat"); # windows trick ;-)
} elsif ($config{'gnuplot_major_version'} == 4) {
# here new start of gnuplot for unices
# if gnuplot==4
#print BPIPE "bind x \"quit\"\n";
print BPIPE "pause -1 \n" if (!$config{'gnuplot_4_terminal'});
#print BPIPE "exit \n";
close (BPIPE);
my $pidf = fork();
if ($pidf == 0) {
print "starting gnuplot 4 forked!\n" if ($config{'DEBUG'});
system( "gnuplot ${pfadftmp}plot.gpl $w32_persist $linuxquiet") if (!$config{'gnuplot_4_terminal'});
system( "$config{'gnuplot_terminal_app'} \'gnuplot ${pfadftmp}plot.gpl $w32_persist\'") if ($config{'gnuplot_4_terminal'});
#use POSIX ":sys_wait_h";
#waitpid($pidgp,NULL);
#close(GP);
wait();
CORE::exit();
}
}
$savname='no'; ##nach ausgabe savname auf 'no' damit next time ein neuer name abgefragt wird
$bereich=''; ### bereich loeschen!
$busy=$FlightView->Unbusy;
}
# Ausgabe
###############################################################################
# give out an error message
sub Errorbox {
my $fm=$_[0];
my $Errorbox=$FlightView->messageBox(-message=>$fm, -type=>'OK', -icon=>'error');
return ;
}
# Errorbox
###############################################################################
sub Photodirselect {
if (!$config{'photos'}) {return;}
my $initdir = $config{'working_directory'};
if ($config{'photo_path'} ne "none") {
$initdir = $config{'photo_path'};
}
my $types = [
['JPEG photos', ['.jpg', '.JPG', '.JPEG', '.jpeg']],
['Audio', ['.amr', '.mp3', '.AMR', '.MP3','.ogg','.OGG']],
['Video', ['.3gp', '.3GP', '.avi', '.AVI']],
['All Files', '*' , ],
];
my $dir = $FlightView->getOpenFile(-initialdir=>$initdir,-title=>"Open photos",-filetypes=>$types);
if (defined $dir) {
$dir = GPLIGCfunctions::setpwd($dir);
if (-d $dir) {
$config{'photo_path'}= $dir;
checkPhotos(1); # 1 = flag, that we call from Photodirselect and photo_path should be used first!
processPhotos();
}
}
return;
}
# Fileselector for opening (called from main loop)
sub Fileselekt {
my $types = [
['IGC Files', ['.igc', '.IGC']],
['All Files', '*' ]
];
my $pwd_winsafe = $config{'working_directory'};
if ($^O eq "MSWin32") {
$pwd_winsafe =~ s#/#\\#g;
}
my $file = $FlightView->getOpenFile(-initialdir=>$pwd_winsafe,-title=>"Open IGC file",-filetypes=>$types);
if (defined $file) {
schliessen();
$config{'working_directory'}=GPLIGCfunctions::setpwd($file);
oeffnen($file);
updateFVW('i');
}
return;
}
# Fileselekt
###############################################################################
###Fileselector f.saving files
sub save {
my $vorschlag = shift;
if (!defined $vorschlag) {$vorschlag="";}
my $sfile=$FlightView->getSaveFile(-initialfile=>$vorschlag,-initialdir=>$config{'working_directory'}, -title=>"Save output as");
if (defined $sfile) {
$config{'working_directory'}=GPLIGCfunctions::setpwd($sfile);
# thats tested by getSaveFile already and asked for overwriting!
#if (open (TEST,"<$sfile")) {close (TEST); Errorbox("File exists"); return ('no');}
if (open (TEST,">$sfile")) {
close (TEST);
unlink($sfile);
} else {
close (TEST); Errorbox("Cannot write"); return('no');
}
} else {
$sfile='no';
}
return ($sfile);
}
sub directory {
my $sfile=$FlightView->chooseDirectory(-initialdir=>$config{'working_directory'}, -title=>"Choose Directory");
if (defined $sfile && $file ne "") {
$config{'working_directory'}=$sfile;
return ($sfile);
} else {
return ("no");
}
}
###############################################################################
my ($FF, $FI, $MF, $thermal_statistik, $glide_statistik);
###schliessen
# used if new file is opened
sub schliessen {
# clear temp files
foreach (@clearlist) {
unlink($pfadftmp.$_);
}
#$calcstat='no';
if ($filestat eq 'closed'){return;}
$filestat='closed';
$file='No file opened';
#close additional windows
if (Exists($FF)) {$FF->destroy;}
if (Exists($FI)) {$FI->destroy;}
if (Exists($MF)) {$MF->destroy;}
if (Exists($WPPlotWindow)) {$WPPlotWindow->destroy;}
if (Exists($thermal_statistik)) {$thermal_statistik->destroy;}
if (Exists($glide_statistik)) {$glide_statistik->destroy;}
#check for input-windows?!
# clear drawing
if (@trackplot) {$canvas -> delete (@trackplot); undef @trackplot;}
if (@mapplot) {$canvas -> delete (@mapplot); undef @mapplot;}
if (@wpcyl_lines) {$canvas -> delete (@wpcyl_lines); undef @wpcyl_lines;}
if (@acc_lines) {$canvas -> delete (@acc_lines); undef @acc_lines;}
if (@task_lines) {$canvas -> delete (@task_lines); undef @task_lines;}
if (@baroplot) {$barocanvas -> delete (@baroplot); undef @baroplot;}
if (@baroplot_task) {$barocanvas -> delete (@baroplot_task); undef @baroplot_task;}
if (@marks_lines) {$canvas -> delete (@marks_lines); undef @marks_lines;}
}
###############################################################################
### subroutine ende. alle erzeugten *.dat werden geloescht
sub gpligcexit {
# remove temporary files
foreach (@clearlist) {
unlink($pfadftmp.$_);
}
#system ("rm -r $pfadftmp");
rmdir $pfadftmp;
# remove the shared memory segment
# if ($^O ne "MSWin32") {
# if (defined $shm_id) {
# shmctl($shm_id, IPC_RMID, 0) || print "Error removing shared mem\n";
# }
# }
#print "ENDE!!!!!!!!!! GUT ALLES GUT! \n";
exit;
}
###############################################################################
sub FVWsetInfo {
@introtext=();
push(@introtext, $canvas->createText(5,5, -anchor=>"nw", -text=>$text, -fill=>"black"));
$canvas->update();
}
# Global stat, bleh.
my $infoFenster;
my $helpFenster;
### subroutine info
sub info {
# jpg if Tk::JPEG availabel, otherwise gif
my $pictype;
my $picname = "logos";
if ($have_jpeg) {
$pictype = "jpg";
print "Tk::JPEG available. Trying to use jpeg-logo!\n" if ($config{'DEBUG'});
} else {
$pictype = "gif";
print "Tk::JPEG not available. Trying to use gif-logo!\n" if ($config{'DEBUG'});
}
if (Exists($infoFenster)) {$infoFenster->destroy;}
$infoFenster=$FlightView->Toplevel();
$infoFenster->configure(-title=>"Information");
setexit($infoFenster);
my $pic=$infoFenster->Photo();
# Look in install-directory AND in ./ for appropriate files...
if(-f "$config{'datadir'}/$picname.$pictype"){
$pic->configure(-file=>"$config{'datadir'}/$picname.$pictype");
} elsif (-f "./$picname.$pictype"){
$pic->configure(-file=>"./$picname.$pictype");
} elsif(-f "${scriptpath}$picname.$pictype") {
$pic->configure(-file=>"${scriptpath}$picname.$pictype");
} else {
print "Could not find \'$picname.$pictype\' in $config{'datadir'}/ and ./ and $scriptpath Fix this, please. Exiting now...\n";
gpligcexit(1);
}
my $picbut=$infoFenster->Label(-image=>$pic);
$picbut->pack();
my $mess=$infoFenster->Message(-width=>"80c",-text=>$text);
$mess->pack();
my $exb=$infoFenster->Button(-text=>"Exit",-command=>sub{$infoFenster->destroy();});
$exb->pack();
}
sub help {
# jpg if Tk::JPEG availabel, otherwise gif
if (Exists($helpFenster)) {$helpFenster->destroy;}
$helpFenster=$FlightView->Toplevel();
$helpFenster->configure(-title=>"Help / Keys");
setexit($helpFenster);
my $labeltext= <<ENDE;
Move cursor:
<<(F1) <(F2) (F3)> (F4)>>
Measuring/select tool:
(F5)=Set first point, (F6)=Set second point, (F7)=Measure
(F11)=zoom to selection, (F12)=reset selection
Statistics:
(F8)=Thermal statistics, (F9)=Glide statistics
Set task markers:
(s)start, (f)inish
Tasks:
(t)=on/off, add (w)aypoint, insert waypoint (b)efore / (a)fter actual WP, re(p)lace WP
Waypoints:
(c)ylinder on/off, set (r)ange
Output:
(o)utput to postscript, (i)=baro, (F10)=save point to .lif file
Altitude:
(e)levation calibration, Q(n)H calibration
Drawing:
(g)rid on/off, (y) resize/redraw, (z)oom on/off,
(M)aps on/off, (#)=re-download maps, (+)/(-) change map zoom level
(F11)=zoom to selected
ENDE
if ($config{'photos'}) {
$labeltext .= "Photos / Multimedia:\n (v)iew next photo/mm, e(x)act photo/mm time calibration\n (h)ide photos/mm, (m)edia list, geotag pict(u)res\n\n";
}
$labeltext .= "(ESC) Exit";
my $mess=$helpFenster->Message(-text=>$labeltext); #-width=>"80c",-text=>$labeltext);
$mess->pack();
my $exb=$helpFenster->Button(-text=>"Exit",-command=>sub{$helpFenster->destroy();});
$exb->pack();
}
###############################################################################
my @PHOTO_FILES;
my @PHOTO_FILES_INDICES;
my @PHOTO_FILES_TIMES;
my $oGLePID;
sub OpenGLexplorer {
if ($filestat eq 'closed') {$FlightView->bell; return;}
# we may have more that one...
# if ($^O ne "MSWin32") {
# if (defined $oGLePID) {return}
# }
if (system("ogie --check")) {Errorbox("Can't execute \"ogie\". Check installation");
return;}
# We start the explorer with --parent-pid $$, it will send a SIGUSR1 on exit
# On receiving SIGUSR1 we will waitpid for it (we dont need a zombie...)
# but not on windows
my $DEBUGOGIE = "";
$DEBUGOGIE = "--debug" if ($config{'DEBUG'});
my $lifts="";
my $liftfile = substr($file, 0, -3)."lif";
if (-r $liftfile) {$lifts= "--lifts \"$liftfile\"";}
# so far lifts or photos
else {
if ($config{'photos'} && !$hide_mm && $#PHOTO_FILES > 0) {
my $pfile = substr($file, 0, -3)."photocoord";
open (PF, ">$pfile");
for (my $z=0; $z<=$#PHOTO_FILES;$z++) {
my ($picname, $p, $suf) = File::Basename::fileparse($PHOTO_FILES[$z]);
print PF "$DECLAT[$PHOTO_FILES_INDICES[$z]] $DECLON[$PHOTO_FILES_INDICES[$z]] $BARO[$PHOTO_FILES_INDICES[$z]] 0 0 0 0 $picname \n";
}
close PF;
# ausgabe pseudo-liftsfile
$lifts = "--lifts-info-mode 7 --lifts \"$pfile\" ";
}
}
if ($^O ne "MSWin32") {
# this produced the warning
$oGLePID = open (OGLEX, "| ogie $DEBUGOGIE -i \"$file\" --parent-pid $$ --marker-pos $nr --marker --offset $offset --quiet $lifts ");
# $oGLePID = open (OGLEX, "| ogie $DEBUGOGIE -i \"$file\" --marker-pos $nr --marker --offset $offset --quiet");
print "OGIE PID is : $oGLePID \n" if ($config{'DEBUG'});
#close (OGLEX);
# -> Don't forget to waitpid somewhere.... (what formerly was don on receiving SIGUSR1, see below)
### This was the old SysV IPC communication (shared memory)
### not available on many platforms (win32)
### SIGNAL handling "too" safe in perl for that reason
### no signal processing in MainLoop, when idle.
$SIG{'USR1'} = sub {waitpid $oGLePID,0; close OGLEX; undef $oGLePID;
# shmctl($shm_id, IPC_RMID, 0) || print "Error removing shared mem\n";
# undef $shm_id;
};
#
## what to do on receiving sigusr2, sigusr2 is send by openGLIGCexplorer, when marker is moved...
#$SIG{'USR2'} = sub {$sigusr2flag=1; print "got sigusr2.. (GPLIGC)\n"; FVWausg();$FlightView->update;};
#
## After we startet the explorer we can initialize the SysV IPC shared Memory.....
## 76 is a magic number
#$shm_key = ftok($file, 76);
#
##print "SHM_key vom GPLIGC = $shm_key \n";
#$shm_id = shmget($shm_key , 4, IPC_CREAT | S_IRWXU);
#
#if (!defined $shm_id) {
# print "Error initializing the SysV IPC Shared Memory.... No communication with openGLIGCexplorer :-(\n";
#}
} else { # starting openGLIGCexplorer for windows
system("start $start_parameter ogie $DEBUGOGIE -i \"$file\" --marker-pos $nr --marker --offset $offset --quiet $lifts ");
#print "start /B ogie -i $file --marker-pos $nr --marker --offset $offset --quiet";
}
###
# -> Here goes the new sockets-code
# start a listening tcp server (non-blocking mode)
# with fileevent-> callback for recieving and updating
# we need a flag to decide if explorer is running
# and we need to send the explorer positions also.
# ............
}
########################################
### FlightInfo
sub FlightInfo {
if (Exists($FI)) {$FI->destroy;}
if ($filestat eq 'closed') {$FlightView->bell; return;}
$FI=$FlightView->Toplevel();
$FI->configure(-title=>"Flight information");
setexit($FI);
$FDR = "unknown" if !defined $FDR;
my $finfotext="Flight data recorder:\n$FDR\nHeader:\n";
foreach (@HEADER) {
$_=~/(.*?)(\s*)$/;
$finfotext.=$1."\n";
}
foreach (@TASK_info) {
$finfotext.=$_."\n";
}
my $label=$FI->Message(-width=>"80c",-textvariable=>\$finfotext);
$label->pack(-fill=>"x");
my $exb=$FI->Button(-text=>"Exit",-command=>sub{$FI->destroy();});
$exb->pack();
}
###############################################################################
### Flight Statistics
my $fstattext;
sub FlightStatistics {
if (Exists($FF)) {$FF->destroy;}
if ($filestat eq 'closed') {$FlightView->bell; return;}
$FF=$FlightView->Toplevel();
$FF->configure(-title=>"Flight Statistics");
$fstattext='';
setexit($FF);
FSupdate();
my $label=$FF->Message(-width=>"80c",-textvariable=>\$fstattext);
$label->pack();
my $exb=$FF->Button(-text=>"Exit",-command=>sub{$FF->destroy();});
$exb->pack();
print "Flight statistics:\n".$fstattext if ($config{'DEBUG'});
}
################################################################################
sub FSupdate {
if (!Exists($FF)) {return;}
$fstattext='';
my $starttimeindex=GPLIGCfunctions::takeoff_detect(\@nonISPEED, 's');
my $landtimeindex=GPLIGCfunctions::takeoff_detect(\@nonISPEED, 'l');
my $stime=GPLIGCfunctions::time2human($TIME[$starttimeindex], 't');
my $ltime=GPLIGCfunctions::time2human($TIME[$landtimeindex], 't');
$fstattext.="Takeoff: $stime\nLanding: $ltime\n";
my $decflighttime=$DECTIME[$landtimeindex]-$DECTIME[$starttimeindex];
my $flighttime=GPLIGCfunctions::dec2time($decflighttime);
$fstattext.="Time of flight: $flighttime\n";
my ($maxalt,$maxpalt,$t100,$t125,$t125acc,$t140,$t180,$l100,$l125,$l125acc,$l140,$l180,$free) = GPLIGCfunctions::OxygenStatistics(\@BARO,\@DECTIME,$gpi{'qnh'});
$fstattext.="Maximum baro altitude: ".sprintf("%.0f",$maxalt*$config{'altitude_unit_factor'})." ".$config{'altitude_unit_name'}."\n";
$fstattext.="Maximum press altitude: ".sprintf("%.0f",$maxpalt*$config{'altitude_unit_factor'})." ".$config{'altitude_unit_name'}." (assuming QNH $gpi{'qnh'})\n";
$fstattext.="Maximum GPS altitude: ".sprintf("%.0f",$GPSALT_max*$config{'altitude_unit_factor'})." ".$config{'altitude_unit_name'}."\n-----\n";
$fstattext.="Oxygen debriefing, FAR 91.211 (constant open flow systems)\n";
$fstattext.="FL100 < alt < FL125: ".sprintf("%.0f",$t100*60)." min ".sprintf("%.1f",$l100)." l (".sprintf("%.1f",$l100/3)." l) \n";
$fstattext.="FL125 < alt < FL140: ".sprintf("%.0f",$t125*60)." min ".sprintf("%.1f",$l125)." l (".sprintf("%.1f",$l125/3)." l), FAA: ".sprintf("%.0f min %.1f l (%.1f l)\n",$t125acc*60, $l125acc,$l125acc/3);
$fstattext.="FL140 < alt < FL180: ".sprintf("%.0f",$t140*60)." min ".sprintf("%.1f",$l140)." l (".sprintf("%.1f",$l140/3)." l) \n";
$fstattext.="FL180 < alt < ORBIT: ".sprintf("%.0f",$t180*60)." min ".sprintf("%.1f",$l180)." l\n";
my $rec= $l100+$l125+$l140+$l180;
my $rec_oxy = $l100/3+$l125/3+$l140/3+$l180;
my $faa = $l125acc+$l140+$l180;
my $faa_oxy= $l125acc/3+$l140/3+$l180;
$fstattext .= sprintf("Oxygen totals:\nRecommended: %.1f l (%.1f l)\n",$rec,$rec_oxy);
$fstattext .= sprintf ("FAA: %.1f l (%.1f l)\n",$faa,$faa_oxy);
$fstattext.="-----\n"; #5
# sum all legs (plain task)
my $entf=0;
my @entf=();
$entf[0]=0;
for (my $zaehl=1 ; $zaehl<=$#WPLAT-1; $zaehl++) {
$entf[$zaehl]=GPLIGCfunctions::dist($WPLAT[$zaehl],$WPLON[$zaehl],$WPLAT[$zaehl+1],$WPLON[$zaehl+1]);
}
foreach (@entf) {
$entf+=$_;
}
#print "$task_start_time \n $task_finish_time \n";
my $taskstt=GPLIGCfunctions::time2human($TIME[$task_start_time_index],'t');
my $taskft=GPLIGCfunctions::time2human($TIME[$task_finish_time_index],'t');
my $task_speed;
$fstattext.="Begin of task/unpowered flight (s-marker): $taskstt \nEnd of task/unpowered flight (f-marker): $taskft\n";
my $task_time=GPLIGCfunctions::dec2time($DECTIME[$task_finish_time_index]-$DECTIME[$task_start_time_index]);
$fstattext.="Task time (unpowered flight time): $task_time\n";
my $dec_task_time=$DECTIME[$task_finish_time_index]-$DECTIME[$task_start_time_index];
if ($dec_task_time != 0) { $task_speed= $entf / $dec_task_time ;} else { $task_speed = "42";} #this is an egg :)
$fstattext.= "-----\n"; #5
# calculate partial distances
my @anteil=();
$anteil[0]=0;
my @anteil_ohne_null=();
#bestimmung der entfernungen und anteile zwischen allen wp
for (my $zaehl=1 ; $zaehl<=$#WPLAT-1; $zaehl++) {
$anteil[$zaehl] = ($entf[$zaehl]/$entf)*100 if $entf != 0;
if ($entf == 0) {$anteil[$zaehl] = 0;}
$anteil[$zaehl] = sprintf ("%5.2f",$anteil[$zaehl]);
my $p_entf=sprintf ("%6.2f",$entf[$zaehl]*$config{'distance_unit_factor'});
$fstattext.="$anteil[$zaehl] % $p_entf $config{'distance_unit_name'} $WPNAME[$zaehl] -> $WPNAME[$zaehl+1]\n";
}
my $print_entf=sprintf("%.4f", $entf*$config{'distance_unit_factor'});
$fstattext.="Taskdistance: $print_entf $config{'distance_unit_name'}\n";
my $task_speed_rounded = sprintf ("%.2f",$task_speed*$config{'speed_unit_factor'});
$fstattext.="Task speed: $task_speed_rounded $config{'speed_unit_name'}\n";
#BESTIMMUNG OB DREIECK UND FAI!!!
#How many legs has the task?
my $z = 0;
# z ist die anzahl der schenkel mit anteil > 0
foreach (@anteil) {
$z++ if $_ != 0;
}
# calculate task for triangular task
$entf = 0;
@entf=();
$entf[0]=0;
if ($#WPLAT >= 4 ) {
for (my $z=2; $z<4; $z++) {
$entf[$z-1]=GPLIGCfunctions::dist($WPLAT[$z],$WPLON[$z],$WPLAT[$z+1],$WPLON[$z+1]);
$entf+=$entf[$z-1];
}
$entf[3] = GPLIGCfunctions::dist($WPLAT[4],$WPLON[4],$WPLAT[2],$WPLON[2]);
$entf+=$entf[3];
# triangular task
if ( (($z == 4) && ($WPNAME[1] eq $WPNAME[5])) || (($z == 4) && (GPLIGCfunctions::dist($WPLAT[1],$WPLON[1],$WPLAT[5],$WPLON[5]) <= 0.2 * $entf) ) ) {
$fstattext.="\n-----\nTriangular task (start and finish on leg)\n";
my $print_close = (GPLIGCfunctions::dist($WPLAT[1],$WPLON[1],$WPLAT[5],$WPLON[5])/$entf)*100;
$print_close = sprintf("%.1f",$print_close);
my $print_close_dist = GPLIGCfunctions::dist($WPLAT[1],$WPLON[1],$WPLAT[5],$WPLON[5]) * $config{'distance_unit_factor'};
my $print_close_distr = sprintf("%.4f",$print_close_dist);
my $task_m_close = sprintf("%.4f", $entf - $print_close_dist);
$fstattext.="Closing distance (between start and finish): ".$print_close_distr." $config{'distance_unit_name'} ".$print_close."% of triangular task\n";
@anteil=();
$anteil[0]=0;
for (my $zaehl=2 ; $zaehl<4; $zaehl++) {
$anteil[$zaehl-1] = ($entf[$zaehl-1]/$entf)*100 if $entf != 0;
$anteil[$zaehl-1] = sprintf ("%5.2f",$anteil[$zaehl-1]);
my $p_entf =sprintf ("%6.2f",$entf[$zaehl-1]*$config{'distance_unit_factor'});
$fstattext.="$anteil[$zaehl-1] % $p_entf $config{'distance_unit_name'} $WPNAME[$zaehl] -> $WPNAME[$zaehl+1]\n";
}
$anteil[3] = ($entf[3]/$entf)*100 if $entf != 0;
$anteil[3] = sprintf ("%5.2f",$anteil[3]);
my $p_entf =sprintf ("%6.2f",$entf[3]*$config{'distance_unit_factor'});
$fstattext.="$anteil[3] % $p_entf $config{'distance_unit_name'} $WPNAME[4] -> $WPNAME[2]\n";
my $p2_entf=sprintf("%.4f", $entf * $config{'distance_unit_factor'});
$fstattext.="Triangular task distance: $p2_entf $config{'distance_unit_name'}\n";
if ($dec_task_time != 0) { $task_speed= $entf / $dec_task_time ;} else { $task_speed = "42";} #this is an egg :)
my $task_speed_rounded = sprintf ("%.2f",$task_speed * $config{'speed_unit_factor'});
$fstattext.="Triangular task speed: $task_speed_rounded $config{'speed_unit_name'}\n";
$fstattext.="Triangular task distance - closing: $task_m_close\n";
}
}
#check for FAI Task
#we need an array of the percentages, but without the ones which are zero
for (my $run=0; $run <=$#anteil; $run++) {
if ($anteil[$run] != 0) {push(@anteil_ohne_null,$anteil[$run]);}
}
#check if task is triangular...
my $TASKSHAPE = 'unknown';
# z==3: these can only be a predeclared task, (or defined by hand? :( )
if (($z == 3) && (($WPNAME[1] eq $WPNAME[4]) || (GPLIGCfunctions::dist($WPLAT[1],$WPLON[1],$WPLAT[4],$WPLON[4]) <= 1.0) ) ){$TASKSHAPE='triangular';}
# z==4 this should be an optimized task, we will assume the "softest" closing criteria (holc)
if (($z == 4) && (($WPNAME[1] eq $WPNAME[5]) || (GPLIGCfunctions::dist($WPLAT[1],$WPLON[1],$WPLAT[5],$WPLON[5]) <= 0.2 * $entf) ) ){$TASKSHAPE='triangular';}
if ($TASKSHAPE eq 'triangular') { #Task has 3 legs and closed FAI?
my ($max, $min) = GPLIGCfunctions::MaxKoor(\@anteil_ohne_null); # can be used to get maximum and minimum... :)
#print "$min $max\n";
$fstattext.="Triangular task ";
if ($entf < 500) { #kleiner 500
#print "kleiner 500\n";
if ($min >= 28) {$fstattext.= "with FAI record shape";}
}
if ($entf >= 500) {
#print "guter pilot, ueber 500! :) \n";
if ($min > 25 && $max <=45) {$fstattext.= "with FAI record shape";}
}
$fstattext.="\n";
}
$fstattext.="-----\nFlown task:\n";
my ($wpinxref, $wpnameref) = getWPreachedIndices();
for (my $idx=0; $idx < $#{$wpinxref}; $idx++) {
my $legdist = GPLIGCfunctions::dist($DECLAT[$wpinxref->[$idx]], $DECLON[$wpinxref->[$idx]],$DECLAT[$wpinxref->[$idx+1]], $DECLON[$wpinxref->[$idx+1]]);
my $dtime = $DECTIME[$wpinxref->[$idx+1]]-$DECTIME[$wpinxref->[$idx]];
my $legspeed;
if ($dtime !=0) { $legspeed=$legdist / $dtime;} else {$legspeed = 9999;}
my $legaltdiff = $BARO[$wpinxref->[$idx+1]]-$BARO[$wpinxref->[$idx]];
my $legtime = GPLIGCfunctions::time2human($TIME[$wpinxref->[$idx]],'t')."-".GPLIGCfunctions::time2human($TIME[$wpinxref->[$idx+1]],'t');
my $legglide;
if ($legaltdiff !=0 ){ $legglide = ($legdist * 1000) / -$legaltdiff;} else {$legglide= 9999;}
print "$legglide\n" if ($config{'DEBUG'});
$legdist *= $config{'distance_unit_factor'};
$legaltdiff *= $config{'altitude_unit_factor'};
$fstattext.= sprintf("%1.0f: %4.2f $config{'distance_unit_name'} %3.0f $config{'speed_unit_name'} $legaltdiff $config{'altitude_unit_name'} %.0f $legtime $wpnameref->[$idx] -> $wpnameref->[$idx+1]\n",$idx+1, $legdist,$legspeed, $legglide);
}
}
##############################################################################
sub zylinder {
use Math::Trig;
my ($lat, $lon, $r, $h) = @_; ###r=durchmesser
my $gpx;
Ausschnitt($lat, $lon);
#if ($r eq "point") {$gpx=0.0008993216;} ### 100m for point-like marks
#if ($r eq "200m") {$gpx=0.0017986432;} ### /0.3km on great-circle on FAI-Spheroid
#if ($r eq "300m") {$gpx=0.002697964;} ### /0.3km on great-circle on FAI-Spheroid
#if ($r eq "400m") {$gpx=0.0035972864;} ### /0.3km on great-circle on FAI-Spheroid
#if ($r eq "500m") {$gpx=0.004496608;} ### /0.5km on great-circle on FAI-Spheroid
#if ($r eq "1km") {$gpx=0.0089932161;}
$gpx=0.0089932161 * $r;
#if ($r eq "FAI") {$gpx=0.026979648;} ### 3 km for FAI sector
#if ($r eq "off") {$gpx=0;}
my @dlat=();
my @dlon=();
for (my $a=0;$a<=6.283185307;$a=$a+0.0314) {
push(@dlat, cos($a)*$gpx);
push(@dlon, sin($a)*$gpx*(1/cos(deg2rad($lat))));
}
open (ZYLOUT,">${pfadftmp}zyl.dat");
for (my $i=0; $i<=$#dlat; $i++) {
for (my $j=0; $j<=$h; $j=$j+100) { ###make it a zylinder!
print ZYLOUT $lon+$dlon[$i]," ",$lat+$dlat[$i]," $j \n";
}
}
close ZYLOUT;
}
# end zylinder
##############################################################################################################################################
##############################################################################################################################################
################################# FLIGHTVIEW #################################################################################################
my $lastphoto_idx;
my $mmlist;
my $savename;
my $trackheight;
my $fvwtext;
my $baroheight;
my $canvas_frame;
my @debugboxlist;
sub FlightView {
if ($config{'fvw_baro_fraction'} < 1.1 || $config{'fvw_baro_fraction'} > 10) {
print ("fvw_baro_fraction should be larger than 1.1 and smaller than 10\n");
gpligcexit();
}
$FlightView = MainWindow->new();
$FlightView->configure(-title=>"GPLIGC $version");
# this catches wm-exit-button, wm-exit...
$FlightView->protocol('WM_DELETE_WINDOW', =>\&gpligcexit);
$FlightView->wm("iconname", "GPLIGC");
#$Fenster->resizable(0, 0);
# CREATE AND pack menu bar
my $menuleiste=$FlightView->Frame(-relief=>'solid', -borderwidth=>1);
my $menu_file=$menuleiste->Menubutton(-text=>"File");#, -underline=>0);
$menu_file->command(-label=>"Open", -command=>sub{Fileselekt();});
$menu_file->command(-label=>"Reload", -command=>sub{
if ($filestat ne 'closed') { oeffnen($file);FVWausg();FSupdate();}
});
$menu_file->command(-label=>"Download track (gpsbabel)", -command=>sub{download_gpsbabel();});
if ($^O ne "MSWin32") {
$menu_file->command(-label=>"Download garmin (gpspoint)", -command=>sub{download_garmin();});
$menu_file->command(-label=>"Download media", -command=>sub{download_media();});
}
$menu_file->command(-label=>"Export kml", -command=>sub{kml_export();});
$menu_file->command(-label=>"Export gpx", -command=>sub{gpx_export();});
# this is not needed.
#$menu_file->command(-label=>"Close",-command=>sub{schliessen();});
# if ($config{'photos'}) {
$menu_file->command(-label=>"Open photo/multimedia directory", -command=>sub{
if ($filestat ne 'closed') {
Photodirselect();}
});
# }
$menu_file->separator();
$menu_file->command(-label=>"Exit",-command=>\&gpligcexit);
$menuleiste->pack(-side=>'top', -fill=>'x',-padx=>3);
$menu_file->pack(-side=>'left');
my $menu_about=$menuleiste->Menubutton(-text=>"About");
$menu_about->command(-label=>"Help",-command=>\&help);
$menu_about->command(-label=>"Info",-command=>\&info);
$menu_about->command(-label=>"GPLIGC home",-command=>sub{browseURL("http://gpligc.sf.net");});
$menu_about->command(-label=>"Subscribe mailinglist",-command=>sub{browseURL("https://lists.sourceforge.net/lists/listinfo/gpligc-announce");});
$menu_about->command(-label=>"Get support / report bugs",-command=>sub{browseURL("https://sourceforge.net/projects/gpligc/support");});
#$menu_about->command(-label=>"donate money",-command=>sub{browseURL("https://sourceforge.net/donate/index.php?group_id=101635");});
$menu_about->pack(-side=>"right");
my