Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 826 → Rev 827

/MissionCockpit/tags/V0.5.4/logging.pl
0,0 → 1,445
#!/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 interval
# 2009-05-17 0.1.7 rw _Timestamp timeout von 2s auf 10s erhoeht
# 2009-09-30 0.1.8 rw SignalHandler removed
# 2010-01-23 0.1.9 rw kosmetics
# no logging, if simulator is active
# 2010-06-24 0.5.0 rw GPX logging match MK format
#
###############################################################################
 
$Version{'logging.pl'} = "0.5.0 - 2010-06-24";
 
#
# Parameter
#
 
my $LoopTime = $Cfg->{'logging'}->{'Intervall'} || 1; # in s
$LoopTime *= 1000000; # in us
 
# Packages
use threads; # http://search.cpan.org/~jdhedden/threads-1.72/threads.pm
# http://perldoc.perl.org/threads.html
use threads::shared; # http://search.cpan.org/~jdhedden/threads-shared-1.28/shared.pm
use Thread::Queue; # http://search.cpan.org/dist/Thread-Queue-2.11/lib/Thread/Queue.pm
use Time::HiRes qw(usleep);
 
require "mkcomm.pl"; # MK communication
require "geserver.pl"; # Google Earth Server
require "translate.pl"; # Übersetzungstable
 
# Queue for receiving commands
$LogQueue = Thread::Queue->new();
 
my $LogState = "LOG"; # LOG, OFF
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";
 
# print labes at first line
 
# wait for hash labels
while ( $MkOsd{'_Timestamp'} eq "" or $MkNcDebug{'_Timestamp'} eq "" )
{
sleep 1;
}
# 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";
 
$LogCsvIsOpen = 1;
}
 
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-10 )
{
# 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>Mission Cockpit 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-10 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
my $Elevation = &Altitude();
 
printf LOGGPX <<EOF;
<trkpt lat="$MkOsd{'CurPos_Lat'}" lon="$MkOsd{'CurPos_Lon'}">
<ele>$Elevation</ele>
<time>${UtcTimeStamp}</time>
<sat>$MkOsd{'SatsInUse'}</sat>
<course>$MkOsd{'CompassHeading'}</course>
<speed>$Speed</speed>
<extensions>
<Altimeter>$MkOsd{'Altimeter'}</Altimeter>
<Variometer>$MkOsd{'Variometer'}</Variometer>
<Course>$MkOsd{'Heading'}</Course>
<GroundSpeed>$MkOsd{'GroundSpeed'}</GroundSpeed>
<VerticalSpeed>$MkOsd{'TopSpeed'}</VerticalSpeed>
<FlightTime>$MkOsd{'FlyingTime'}</FlightTime>
<Voltage>$MkOsd{'UBat'}</Voltage>
<Current>$MkOsd{'Current'}</Current>
<Capacity>$MkOsd{'UsedCapacity'}</Capacity>
<RCQuality>$MkOsd{'RC_Quality'}</RCQuality>
<RCRSSI>$MkOsd{'RC_RSSI'}</RCRSSI>
<Compass>$MkOsd{'CompassHeading'}</Compass>
<NickAngle>$MkOsd{'AngleNick'}</NickAngle>
<RollAngle>$MkOsd{'AngleRoll'}</RollAngle>
<NCFlag>$MkOsd{'NCFlags'}</NCFlag>
<MKFlag>$MkOsd{'MKFlags'}</MKFlag>
<ErrorCode>$MkOsd{'ErrorCode'}</ErrorCode>
<TargetLat>$MkOsd{'TargetPos_Lat'}</TargetLat>
<TargetLon>$MkOsd{'TargetPos_Lon'}</TargetLon>
<TargetAlt>$MkOsd{'TargetPos_Alt'}</TargetAlt>
<TargetBearing>$MkOsd{'TargetPosDev_Bearing'}</TargetBearing>
<TargetDistance>$MkOsd{'TargetPosDev_Dist'}</TargetDistance>
<Waypoint>$MkOsd{'WaypointIndex'} / $MkOsd{'WaypointNumber'}</Waypoint>
<RCSticks>0, 0, 0</RCSticks>
<GPSSticks>0, 0, 0</GPSSticks>
</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>Mission Cockpit 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-10 and
$MkOsd{'MKFlags'} & 0x02 and $MkOsd{'CurPos_Stat'} == 1 )
{
# active connection to MK, MK is flying, valid GPS
&LogKmlOpen();
my $Alt = &Altitude();
if ( $Alt < 0 ) { $Alt = 0; }
printf LOGKML " %f, %f, %f\n", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $Alt;
}
else
{
&LogKmlClose();
}
}
 
 
# Send Coords to GoogleEarth server
sub Send2GeServer()
{
lock %MkOsd; # until end of Block
 
if ( $MkOsd{'_Timestamp'} >= time-10 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)
{
 
# check commnd queue
if ( $LogQueue->pending() > 0 )
{
$LogState = $LogQueue->dequeue(1);
}
 
if ( $LogState eq "LOG" )
{
&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__