0,0 → 1,421 |
#!/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__ |