Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
727 rain-er 1
#!/usr/bin/perl
2
#!/usr/bin/perl -d:ptkdb
3
 
4
###############################################################################
5
#
6
# logging.pl -  CSV, KLM, GPS Logging
7
#
8
# Copyright (C) 2009  Rainer Walther  (rainerwalther-mail@web.de)
9
#
10
# Creative Commons Lizenz mit den Zusaetzen (by, nc, sa)
11
#
12
# Es ist Ihnen gestattet: 
13
#     * das Werk vervielfältigen, verbreiten und öffentlich zugänglich machen
14
#     * Abwandlungen bzw. Bearbeitungen des Inhaltes anfertigen
15
# 
16
# Zu den folgenden Bedingungen:
17
#     * Namensnennung.
18
#       Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
19
#     * Keine kommerzielle Nutzung.
20
#       Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden.
21
#     * Weitergabe unter gleichen Bedingungen.
22
#       Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten,
23
#       verändern oder als Grundlage für einen anderen Inhalt verwenden,
24
#       dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen
25
#       weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.
26
# 
27
# Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen, unter welche dieses
28
# Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden.
29
# 
30
# Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie die Einwilligung
31
# des Rechteinhabers dazu erhalten.
32
# 
33
# Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.
34
# 
35
# Weitere Details zur Lizenzbestimmung gibt es hier:
36
#   Kurzform: http://creativecommons.org/licenses/by-nc-sa/3.0/de/
37
#   Komplett: http://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode
38
#
39
###############################################################################
40
#
41
# 2009-02-23 0.0.1 rw created
42
# 2009-04-01 0.1.0 rw RC1
43
# 2009-05-01 0.1.1 rw configurable logging interval
44
# 2009-05-17 0.1.7 rw _Timestamp timeout von 2s auf 10s erhoeht
45
# 2009-09-30 0.1.8 rw SignalHandler removed
46
# 2010-01-23 0.1.9 rw kosmetics
47
#                     no logging, if simulator is active
48
#
49
###############################################################################
50
 
51
$Version{'logging.pl'} = "0.1.9 - 2010-01-23";
52
 
53
#
54
# Parameter
55
#
56
 
57
my $LoopTime = $Cfg->{'logging'}->{'Intervall'} || 1;  # in s
58
$LoopTime *= 1000000;      # in us
59
 
60
# Packages
61
use threads;                 # http://search.cpan.org/~jdhedden/threads-1.72/threads.pm
62
                             # http://perldoc.perl.org/threads.html
63
use threads::shared;         # http://search.cpan.org/~jdhedden/threads-shared-1.28/shared.pm
64
use Thread::Queue;           # http://search.cpan.org/dist/Thread-Queue-2.11/lib/Thread/Queue.pm
65
use Time::HiRes qw(usleep);
66
 
67
require "mkcomm.pl";     # MK communication
68
require "geserver.pl";   # Google Earth Server
69
require "translate.pl";  # Übersetzungstable
70
 
71
# Queue for receiving commands
72
$LogQueue = Thread::Queue->new();
73
 
74
my $LogState = "LOG";        # LOG, OFF
75
my $LogCsvIsOpen = 0;
76
my $LogKmlIsOpen = 0;
77
my $LogGpxIsOpen = 0;
78
my $GeServerIsRunning = 0;
79
 
80
#
81
# CSV
82
#
83
 
84
# Open CSV logfile
85
sub LogCsvOpen()
86
    {
87
    if ( ! $LogCsvIsOpen )
88
        {      
89
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
90
        my $Filename = sprintf ("mk-%04d%02d%02d-%02d%02d%02d.csv", $year+1900, $mon+1, $mday, $hour, $min, $sec);
91
        open LOGCSV, ">$Cfg->{'logging'}->{'CsvLogDir'}/$Filename";
92
 
93
        $LogCsvIsOpen = 1;
94
 
95
        # print labes at first line
96
 
97
        # NC OSD
98
        my $Sep = "";
99
        foreach $Label (sort keys %MkOsd)
100
            {
101
            if ( $Translate{$Label} ne "" )
102
                {
103
                $Label = $Translate{$Label};
104
                }
105
            print LOGCSV "$Sep" . "$Label";
106
            $Sep = ",";
107
            }
108
 
109
        # NC Debug
110
        foreach $Label (sort keys %MkNcDebug)
111
            {
112
            if ( $Translate{$Label} ne "" )
113
                {
114
                $Label = $Translate{$Label};
115
                }
116
            print LOGCSV "$Sep" . "$Label";
117
            }
118
        print LOGCSV "\n";
119
        }
120
 
121
    return 0;
122
    }
123
 
124
 
125
# Close CSV
126
sub LogCsvClose()
127
    {
128
    if ( $LogCsvIsOpen )
129
        {
130
        close LOGCSV;
131
        $LogCsvIsOpen = 0;
132
        }
133
 
134
    return 0;
135
    }  
136
 
137
# Log CSV
138
sub LogCsv()
139
    {
140
    lock %MkOsd;      # until end of Block
141
    lock %MkNcDebug;  # until end of Block
142
 
143
    if ( $MkOsd{'_Timestamp'} >= time-10 )
144
        {
145
        # active connection to MK
146
        &LogCsvOpen();
147
 
148
        # NC OSD
149
        my $Sep = "";
150
        foreach $Label (sort keys %MkOsd)
151
            {
152
            print LOGCSV "$Sep" . "$MkOsd{$Label}";
153
            $Sep = ",";
154
            }
155
 
156
        # NC Debug
157
        foreach $Label (sort keys %MkNcDebug)
158
            {
159
            print LOGCSV "$Sep" . "$MkNcDebug{$Label}";
160
            }
161
        print LOGCSV "\n";
162
        }
163
    else
164
        {
165
        # connection to MK lost, close Logfile
166
        &LogCsvClose();
167
        }
168
 
169
    return 0;
170
    }
171
 
172
 
173
#
174
# GPX
175
# http://www.topografix.com/gpx_manual.asp
176
#
177
 
178
# Open GPX logfile
179
sub LogGpxOpen()
180
    {
181
    if ( ! $LogGpxIsOpen )
182
        {
183
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
184
        my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
185
        my $Filename = "mk-" . $TimeStamp . ".gpx";
186
        open LOGGPX, ">$Cfg->{'logging'}->{'GpxLogDir'}/$Filename";
187
        $LogGpxIsOpen = 1;
188
 
189
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
190
        my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
191
 
192
        # print GPX-Header
193
        print LOGGPX <<EOF;
194
<?xml version="1.0" encoding="UTF-8"?>
195
<gpx
196
  version="1.0"
197
  creator="MK Mission Cockpit"
198
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
199
  xmlns="http://www.topografix.com/GPX/1/0"
200
  xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
201
  <time>${UtcTimeStamp}</time>
202
  <trk>
203
    <name>Mission Cockpit GPS logging</name>
204
        <desc>Flight ${TimeStamp}</desc>
205
    <trkseg>
206
EOF
207
        }
208
 
209
    return 0;
210
    }  
211
 
212
 
213
# Close GPX
214
sub LogGpxClose()
215
    {
216
    if ( $LogGpxIsOpen )
217
        {
218
        # print GPX-Trailer
219
        print LOGGPX <<EOF;
220
    </trkseg>
221
  </trk>
222
</gpx>
223
EOF
224
        close LOGGPX;
225
        $LogGpxIsOpen = 0;
226
        }
227
 
228
    return 0;
229
    }  
230
 
231
 
232
# Log GPX
233
sub LogGpx()
234
    {
235
    lock %MkOsd;   # until end of Block
236
 
237
    if ( $MkOsd{'_Timestamp'} >= time-10  and
238
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
239
        {
240
        # active connection to MK, MK is flying, valid GPS
241
        &LogGpxOpen();
242
 
243
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
244
        my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
245
 
246
        my $Speed = $MkOsd{'GroundSpeed'} / 100;  # m/s
247
        my $Elevation = &Altitude();
248
 
249
        printf LOGGPX <<EOF;
250
      <trkpt lat="$MkOsd{'CurPos_Lat'}" lon="$MkOsd{'CurPos_Lon'}">
251
        <ele>$Elevation</ele>
252
        <time>${UtcTimeStamp}</time>
253
        <sat>$MkOsd{'SatsInUse'}</sat>
254
        <course>$MkOsd{'CompassHeading'}</course>
255
        <speed>$Speed</speed>
256
        <extensions>
257
          <Target-Lat>$MkOsd{'TargetPos_Lat'}</Target-Lat>
258
          <Target-Lon>$MkOsd{'TargetPos_Lon'}</Target-Lon>
259
          <Target-Alt>$MkOsd{'TargetPos_Alt'}</Target-Alt>
260
          <Target-Bearing>$MkOsd{'TargetPosDev_Bearing'}</Target-Bearing>
261
          <Target-Dist>$MkOsd{'TargetPosDev_Dist'}</Target-Dist>
262
          <Waypoint>$MkOsd{'WaypointIndex'} / $MkOsd{'WaypointNumber'}</Waypoint>
263
          <Altimeter>$MkOsd{'Altimeter'}</Altimeter>
264
          <Variometer>$MkOsd{'Variometer'}</Variometer>
265
          <UBat>$MkOsd{'UBat'}</UBat>
266
          <AngleNick>$MkOsd{'AngleNick'}</AngleNick>
267
          <AngleRoll>$MkOsd{'AngleRoll'}</AngleRoll>
268
          <MKFlags>$MkOsd{'MKFlags'}</MKFlags>
269
          <NCFlags>$MkOsd{'NCFlags'}</NCFlags>
270
        </extensions>
271
      </trkpt>         
272
EOF
273
        }
274
    else
275
        {
276
        &LogGpxClose();
277
        }
278
    }
279
 
280
#
281
# KML
282
# http://code.google.com/intl/de-DE/apis/kml/documentation/kml_tut.html
283
#
284
 
285
# Open KML logfile
286
sub LogKmlOpen()
287
    {
288
    if ( ! $LogKmlIsOpen )
289
        {      
290
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
291
        my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
292
        my $Filename = "mk-" . $TimeStamp . ".kml";
293
        open LOGKML, ">$Cfg->{'logging'}->{'KmlLogDir'}/$Filename";
294
        $LogKmlIsOpen = 1;
295
 
296
        # print KML-Header
297
        print LOGKML <<EOF;
298
<?xml version="1.0" encoding="UTF-8"?>
299
<kml xmlns="http://earth.google.com/kml/2.2">
300
  <Document>
301
    <name>Mission Cockpit GPS logging</name>
302
    <Style id="MK_gps-style">
303
      <LineStyle>
304
        <color>ff0000ff</color>
305
        <width>2</width>
306
      </LineStyle>
307
    </Style>
308
    <Placemark>
309
      <name>Flight ${TimeStamp}</name>
310
      <styleUrl>MK_gps-style</styleUrl>
311
      <LineString>
312
        <tessellate>1</tessellate>
313
        <altitudeMode>relativeToGround</altitudeMode>
314
        <coordinates>
315
EOF
316
        }
317
 
318
    return 0;
319
    }  
320
 
321
 
322
# Close KML
323
sub LogKmlClose()
324
    {
325
    if ( $LogKmlIsOpen )
326
        {
327
        # print KML-Trailer
328
        print LOGKML <<EOF;
329
        </coordinates>
330
      </LineString>
331
    </Placemark>
332
  </Document>
333
</kml>
334
EOF
335
        close LOGKML;
336
        $LogKmlIsOpen = 0;
337
        }
338
 
339
    return 0;
340
    }  
341
 
342
 
343
# Log KML
344
sub LogKml()
345
    {
346
    lock %MkOsd;   # until end of Block
347
 
348
    if ( $MkOsd{'_Timestamp'} >= time-10  and
349
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
350
        {
351
        # active connection to MK, MK is flying, valid GPS
352
        &LogKmlOpen();
353
 
354
        my $Alt = &Altitude();
355
        if ( $Alt < 0 ) { $Alt = 0; }
356
        printf LOGKML "          %f, %f, %f\n", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $Alt;
357
        }
358
    else
359
        {
360
        &LogKmlClose();
361
        }
362
    }
363
 
364
 
365
# Send Coords to GoogleEarth server
366
sub Send2GeServer()
367
    {
368
    lock %MkOsd;   # until end of Block
369
 
370
    if ( $MkOsd{'_Timestamp'} >= time-10  and
371
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
372
        {
373
        # active connection to MK, MK is flying, valid GPS
374
 
375
        my $AltRel = $MkOsd{'CurPos_Alt'} - $MkOsd{'HomePos_Alt'};
376
        if ( $AltRel < 0 ) { $AltRel = 0; }
377
 
378
        push @GeCoords, sprintf "%f, %f, %f", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $AltRel;
379
        }
380
    }
381
 
382
 
383
sub MkLogLoop()
384
    {
385
    while (1)
386
        {
387
 
388
        # check commnd queue
389
        if ( $LogQueue->pending() > 0 )
390
            {
391
            $LogState = $LogQueue->dequeue(1);
392
            }
393
 
394
        if ( $LogState eq "LOG" )
395
            {
396
            &LogCsv();
397
            &LogKml();
398
            &LogGpx();
399
            }
400
 
401
        &Send2GeServer();  # Google Earth
402
 
403
        # kurz schlafen legen
404
        usleep $LoopTime;
405
        }
406
    }
407
 
408
#
409
# Hauptprgramm
410
#       
411
 
412
if ( $0 =~ /logging.pl$/i )
413
    {
414
    # Program wurde direkt aufgerufen
415
 
416
    # Kommunikation zum MK herstellen
417
    $mk_thr = threads->create (\&MkCommLoop) -> detach();
418
 
419
    &MkLogLoop();
420
 
421
    # should never exit
422
    }
423
 
424
1;
425
 
426
__END__