Blame |
Last modification |
View Log
| RSS feed
#!/usr/bin/perl
#!/usr/bin/perl -d:ptkdb
###############################################################################
#
# logging.pl - CSV, KLM, GPS Logging
#
# Copyright (C) 2009 Rainer Walther (rainerwalther-mail@web.de)
#
# Creative Commons Lizenz mit den Zusaetzen (by, nc, sa)
#
# Es ist Ihnen gestattet:
# * das Werk vervielfältigen, verbreiten und öffentlich zugänglich machen
# * Abwandlungen bzw. Bearbeitungen des Inhaltes anfertigen
#
# Zu den folgenden Bedingungen:
# * Namensnennung.
# Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
# * Keine kommerzielle Nutzung.
# Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden.
# * Weitergabe unter gleichen Bedingungen.
# Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten,
# verändern oder als Grundlage für einen anderen Inhalt verwenden,
# dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen
# weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.
#
# Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen, unter welche dieses
# Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden.
#
# Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie die Einwilligung
# des Rechteinhabers dazu erhalten.
#
# Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.
#
# Weitere Details zur Lizenzbestimmung gibt es hier:
# Kurzform: http://creativecommons.org/licenses/by-nc-sa/3.0/de/
# Komplett: http://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode
#
###############################################################################
#
# 2009-02-23 0.0.1 rw created
# 2009-04-01 0.1.0 rw RC1
# 2009-05-01 0.1.1 rw configurable logging intervav
#
###############################################################################
$Version{'logging.pl'} = "0.1.0 - 2009-04-01";
#
# Parameter
#
my $LoopTime = $Cfg->{'logging'}->{'Intervall'} || 1; # in s
$LoopTime *= 1000000; # in us
# Packages
use threads
;
use threads
::shared;
use Time
::HiRes qw(usleep
);
require "mkcomm.pl"; # MK communication
require "geserver.pl"; # Google Earth Server
require "translate.pl"; # Übersetzungstable
#
# Signal handler
#
$SIG{'INT'} = 'LogSigHandler';
$SIG{'KILL'} = 'LogSigHandler';
sub SigHandler
()
{
if ( defined threads
->self() )
{
threads
->exit();
}
exit;
}
my $LogCsvIsOpen = 0;
my $LogKmlIsOpen = 0;
my $LogGpxIsOpen = 0;
my $GeServerIsRunning = 0;
#
# CSV
#
# Open CSV logfile
sub LogCsvOpen
()
{
if ( ! $LogCsvIsOpen )
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $Filename = sprintf ("mk-%04d%02d%02d-%02d%02d%02d.csv", $year+1900, $mon+1, $mday, $hour, $min, $sec);
open LOGCSV
, ">$Cfg->{'logging'}->{'CsvLogDir'}/$Filename";
$LogCsvIsOpen = 1;
# print labes at first line
# NC OSD
my $Sep = "";
foreach $Label (sort keys %MkOsd)
{
if ( $Translate{$Label} ne "" )
{
$Label = $Translate{$Label};
}
print LOGCSV
"$Sep" . "$Label";
$Sep = ",";
}
# NC Debug
foreach $Label (sort keys %MkNcDebug)
{
if ( $Translate{$Label} ne "" )
{
$Label = $Translate{$Label};
}
print LOGCSV
"$Sep" . "$Label";
}
print LOGCSV
"\n";
}
return 0;
}
# Close CSV
sub LogCsvClose
()
{
if ( $LogCsvIsOpen )
{
close LOGCSV
;
$LogCsvIsOpen = 0;
}
return 0;
}
# Log CSV
sub LogCsv
()
{
lock
%MkOsd; # until end of Block
lock
%MkNcDebug; # until end of Block
if ( $MkOsd{'_Timestamp'} >= time
-2 )
{
# active connection to MK
&LogCsvOpen();
# NC OSD
my $Sep = "";
foreach $Label (sort keys %MkOsd)
{
print LOGCSV
"$Sep" . "$MkOsd{$Label}";
$Sep = ",";
}
# NC Debug
foreach $Label (sort keys %MkNcDebug)
{
print LOGCSV
"$Sep" . "$MkNcDebug{$Label}";
}
print LOGCSV
"\n";
}
else
{
# connection to MK lost, close Logfile
&LogCsvClose();
}
return 0;
}
#
# GPX
# http://www.topografix.com/gpx_manual.asp
#
# Open GPX logfile
sub LogGpxOpen
()
{
if ( ! $LogGpxIsOpen )
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
my $Filename = "mk-" . $TimeStamp . ".gpx";
open LOGGPX
, ">$Cfg->{'logging'}->{'GpxLogDir'}/$Filename";
$LogGpxIsOpen = 1;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
# print GPX-Header
print LOGGPX
<<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
creator="MK Mission Cockpit"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>${UtcTimeStamp}</time>
<trk>
<name>Mikrokopter GPS logging</name>
<desc>Flight ${TimeStamp}</desc>
<trkseg>
EOF
}
return 0;
}
# Close GPX
sub LogGpxClose
()
{
if ( $LogGpxIsOpen )
{
# print GPX-Trailer
print LOGGPX
<<EOF;
</trkseg>
</trk>
</gpx>
EOF
close LOGGPX
;
$LogGpxIsOpen = 0;
}
return 0;
}
# Log GPX
sub LogGpx
()
{
lock
%MkOsd; # until end of Block
if ( $MkOsd{'_Timestamp'} >= time
-2 and
$MkOsd{'MKFlags'} & 0x02
and $MkOsd{'CurPos_Stat'} == 1 )
{
# active connection to MK, MK is flying, valid GPS
&LogGpxOpen();
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
my $Speed = $MkOsd{'GroundSpeed'} / 100; # m/s
printf LOGGPX
<<EOF;
<trkpt lat="$MkOsd{'CurPos_Lat'}" lon="$MkOsd{'CurPos_Lon'}">
<ele>$MkOsd{'CurPos_Alt'}</ele>
<time>${UtcTimeStamp}</time>
<sat>$MkOsd{'SatsInUse'}</sat>
<course>$MkOsd{'CompassHeading'}</course>
<speed>$Speed</speed>
<extensions>
<Target-Lat>$MkOsd{'TargetPos_Lat'}</Target-Lat>
<Target-Lon>$MkOsd{'TargetPos_Lon'}</Target-Lon>
<Target-Alt>$MkOsd{'TargetPos_Alt'}</Target-Alt>
<Target-Bearing>$MkOsd{'TargetPosDev_Bearing'}</Target-Bearing>
<Target-Dist>$MkOsd{'TargetPosDev_Dist'}</Target-Dist>
<Waypoint>$MkOsd{'WaypointIndex'} / $MkOsd{'WaypointNumber'}</Waypoint>
<Altimeter>$MkOsd{'Altimeter'}</Altimeter>
<Variometer>$MkOsd{'Variometer'}</Variometer>
<UBat>$MkOsd{'UBat'}</UBat>
<AngleNick>$MkOsd{'AngleNick'}</AngleNick>
<AngleRoll>$MkOsd{'AngleRoll'}</AngleRoll>
<MKFlags>$MkOsd{'MKFlags'}</MKFlags>
<NCFlags>$MkOsd{'NCFlags'}</NCFlags>
</extensions>
</trkpt>
EOF
}
else
{
&LogGpxClose();
}
}
#
# KML
# http://code.google.com/intl/de-DE/apis/kml/documentation/kml_tut.html
#
# Open KML logfile
sub LogKmlOpen
()
{
if ( ! $LogKmlIsOpen )
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
my $Filename = "mk-" . $TimeStamp . ".kml";
open LOGKML
, ">$Cfg->{'logging'}->{'KmlLogDir'}/$Filename";
$LogKmlIsOpen = 1;
# print KML-Header
print LOGKML
<<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<name>Mikrokopter GPS logging</name>
<Style id="MK_gps-style">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
</Style>
<Placemark>
<name>Flight ${TimeStamp}</name>
<styleUrl>MK_gps-style</styleUrl>
<LineString>
<tessellate>1</tessellate>
<altitudeMode>relativeToGround</altitudeMode>
<coordinates>
EOF
}
return 0;
}
# Close KML
sub LogKmlClose
()
{
if ( $LogKmlIsOpen )
{
# print KML-Trailer
print LOGKML
<<EOF;
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>
EOF
close LOGKML
;
$LogKmlIsOpen = 0;
}
return 0;
}
# Log KML
sub LogKml
()
{
lock
%MkOsd; # until end of Block
if ( $MkOsd{'_Timestamp'} >= time
-2 and
$MkOsd{'MKFlags'} & 0x02
and $MkOsd{'CurPos_Stat'} == 1 )
{
# active connection to MK, MK is flying, valid GPS
&LogKmlOpen();
my $AltRel = $MkOsd{'CurPos_Alt'} - $MkOsd{'HomePos_Alt'};
if ( $AltRel < 0 ) { $AltRel = 0; }
printf LOGKML
" %f, %f, %f\n", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $AltRel;
}
else
{
&LogKmlClose();
}
}
# Send Coords to GoogleEarth server
sub Send2GeServer
()
{
lock
%MkOsd; # until end of Block
if ( $MkOsd{'_Timestamp'} >= time
-2 and
$MkOsd{'MKFlags'} & 0x02
and $MkOsd{'CurPos_Stat'} == 1 )
{
# active connection to MK, MK is flying, valid GPS
my $AltRel = $MkOsd{'CurPos_Alt'} - $MkOsd{'HomePos_Alt'};
if ( $AltRel < 0 ) { $AltRel = 0; }
push @GeCoords, sprintf "%f, %f, %f", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $AltRel;
}
}
sub MkLogLoop
()
{
while (1)
{
&LogCsv();
&LogKml();
&LogGpx();
&Send2GeServer(); # Google Earth
# kurz schlafen legen
usleep
$LoopTime;
}
}
#
# Hauptprgramm
#
if ( $0 =~ /logging.pl$/i )
{
# Program wurde direkt aufgerufen
# Kommunikation zum MK herstellen
$mk_thr = threads
->create (\&MkCommLoop) -> detach();
&MkLogLoop();
# should never exit
}
1;
__END__