Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
827 - 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
# 2010-06-24 0.5.0 rw GPX logging match MK format
49
#
50
###############################################################################
51
 
52
$Version{'logging.pl'} = "0.5.0 - 2010-06-24";
53
 
54
#
55
# Parameter
56
#
57
 
58
my $LoopTime = $Cfg->{'logging'}->{'Intervall'} || 1;  # in s
59
$LoopTime *= 1000000;      # in us
60
 
61
# Packages
62
use threads;                 # http://search.cpan.org/~jdhedden/threads-1.72/threads.pm
63
                             # http://perldoc.perl.org/threads.html
64
use threads::shared;         # http://search.cpan.org/~jdhedden/threads-shared-1.28/shared.pm
65
use Thread::Queue;           # http://search.cpan.org/dist/Thread-Queue-2.11/lib/Thread/Queue.pm
66
use Time::HiRes qw(usleep);
67
 
68
require "mkcomm.pl";     # MK communication
69
require "geserver.pl";   # Google Earth Server
70
require "translate.pl";  # Übersetzungstable
71
 
72
# Queue for receiving commands
73
$LogQueue = Thread::Queue->new();
74
 
75
my $LogState = "LOG";        # LOG, OFF
76
my $LogCsvIsOpen = 0;
77
my $LogKmlIsOpen = 0;
78
my $LogGpxIsOpen = 0;
79
my $GeServerIsRunning = 0;
80
 
81
#
82
# CSV
83
#
84
 
85
# Open CSV logfile
86
sub LogCsvOpen()
87
    {
88
    if ( ! $LogCsvIsOpen )
89
        {      
90
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
91
        my $Filename = sprintf ("mk-%04d%02d%02d-%02d%02d%02d.csv", $year+1900, $mon+1, $mday, $hour, $min, $sec);
92
        open LOGCSV, ">$Cfg->{'logging'}->{'CsvLogDir'}/$Filename";
93
 
94
        # print labes at first line
95
 
96
        # wait for hash labels
97
        while ( $MkOsd{'_Timestamp'} eq ""  or  $MkNcDebug{'_Timestamp'} eq "" )
98
            {
99
            sleep 1;
100
            }
101
 
102
        # NC OSD
103
        my $Sep = "";
104
        foreach $Label (sort keys %MkOsd)
105
            {
106
            if ( $Translate{$Label} ne "" )
107
                {
108
                $Label = $Translate{$Label};
109
                }
110
            print LOGCSV "$Sep" . "$Label";
111
            $Sep = ",";
112
            }
113
 
114
        # NC Debug
115
        foreach $Label (sort keys %MkNcDebug)
116
            {
117
            if ( $Translate{$Label} ne "" )
118
                {
119
                $Label = $Translate{$Label};
120
                }
121
            print LOGCSV "$Sep" . "$Label";
122
            }
123
        print LOGCSV "\n";
124
 
125
        $LogCsvIsOpen = 1;
126
        }
127
 
128
    return 0;
129
    }
130
 
131
 
132
# Close CSV
133
sub LogCsvClose()
134
    {
135
    if ( $LogCsvIsOpen )
136
        {
137
        close LOGCSV;
138
        $LogCsvIsOpen = 0;
139
        }
140
 
141
    return 0;
142
    }  
143
 
144
# Log CSV
145
sub LogCsv()
146
    {
147
    lock %MkOsd;      # until end of Block
148
    lock %MkNcDebug;  # until end of Block
149
 
150
    if ( $MkOsd{'_Timestamp'} >= time-10 )
151
        {
152
        # active connection to MK
153
        &LogCsvOpen();
154
 
155
        # NC OSD
156
        my $Sep = "";
157
        foreach $Label (sort keys %MkOsd)
158
            {
159
            print LOGCSV "$Sep" . "$MkOsd{$Label}";
160
            $Sep = ",";
161
            }
162
 
163
        # NC Debug
164
        foreach $Label (sort keys %MkNcDebug)
165
            {
166
            print LOGCSV "$Sep" . "$MkNcDebug{$Label}";
167
            }
168
        print LOGCSV "\n";
169
        }
170
    else
171
        {
172
        # connection to MK lost, close Logfile
173
        &LogCsvClose();
174
        }
175
 
176
    return 0;
177
    }
178
 
179
 
180
#
181
# GPX
182
# http://www.topografix.com/gpx_manual.asp
183
#
184
 
185
# Open GPX logfile
186
sub LogGpxOpen()
187
    {
188
    if ( ! $LogGpxIsOpen )
189
        {
190
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
191
        my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
192
        my $Filename = "mk-" . $TimeStamp . ".gpx";
193
        open LOGGPX, ">$Cfg->{'logging'}->{'GpxLogDir'}/$Filename";
194
        $LogGpxIsOpen = 1;
195
 
196
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
197
        my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
198
 
199
        # print GPX-Header
200
        print LOGGPX <<EOF;
201
<?xml version="1.0" encoding="UTF-8"?>
202
<gpx
203
  version="1.0"
204
  creator="MK Mission Cockpit"
205
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
206
  xmlns="http://www.topografix.com/GPX/1/0"
207
  xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
208
  <time>${UtcTimeStamp}</time>
209
  <trk>
210
    <name>Mission Cockpit GPS logging</name>
211
        <desc>Flight ${TimeStamp}</desc>
212
    <trkseg>
213
EOF
214
        }
215
 
216
    return 0;
217
    }  
218
 
219
 
220
# Close GPX
221
sub LogGpxClose()
222
    {
223
    if ( $LogGpxIsOpen )
224
        {
225
        # print GPX-Trailer
226
        print LOGGPX <<EOF;
227
    </trkseg>
228
  </trk>
229
</gpx>
230
EOF
231
        close LOGGPX;
232
        $LogGpxIsOpen = 0;
233
        }
234
 
235
    return 0;
236
    }  
237
 
238
 
239
# Log GPX
240
sub LogGpx()
241
    {
242
    lock %MkOsd;   # until end of Block
243
 
244
    if ( $MkOsd{'_Timestamp'} >= time-10  and
245
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
246
        {
247
        # active connection to MK, MK is flying, valid GPS
248
        &LogGpxOpen();
249
 
250
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
251
        my $UtcTimeStamp = sprintf ("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $mday, $hour, $min, $sec);
252
 
253
        my $Speed = $MkOsd{'GroundSpeed'} / 100;  # m/s
254
        my $Elevation = &Altitude();
255
 
256
        printf LOGGPX <<EOF;
257
      <trkpt lat="$MkOsd{'CurPos_Lat'}" lon="$MkOsd{'CurPos_Lon'}">
258
        <ele>$Elevation</ele>
259
        <time>${UtcTimeStamp}</time>
260
        <sat>$MkOsd{'SatsInUse'}</sat>
261
        <course>$MkOsd{'CompassHeading'}</course>
262
        <speed>$Speed</speed>
263
        <extensions>
264
          <Altimeter>$MkOsd{'Altimeter'}</Altimeter>
265
          <Variometer>$MkOsd{'Variometer'}</Variometer>
266
          <Course>$MkOsd{'Heading'}</Course>
267
          <GroundSpeed>$MkOsd{'GroundSpeed'}</GroundSpeed>
268
          <VerticalSpeed>$MkOsd{'TopSpeed'}</VerticalSpeed>
269
          <FlightTime>$MkOsd{'FlyingTime'}</FlightTime>
270
          <Voltage>$MkOsd{'UBat'}</Voltage>
271
          <Current>$MkOsd{'Current'}</Current>
272
          <Capacity>$MkOsd{'UsedCapacity'}</Capacity>
273
          <RCQuality>$MkOsd{'RC_Quality'}</RCQuality>
274
          <RCRSSI>$MkOsd{'RC_RSSI'}</RCRSSI>
275
          <Compass>$MkOsd{'CompassHeading'}</Compass>
276
          <NickAngle>$MkOsd{'AngleNick'}</NickAngle>
277
          <RollAngle>$MkOsd{'AngleRoll'}</RollAngle>
278
          <NCFlag>$MkOsd{'NCFlags'}</NCFlag>
279
          <MKFlag>$MkOsd{'MKFlags'}</MKFlag>
280
          <ErrorCode>$MkOsd{'ErrorCode'}</ErrorCode>
281
          <TargetLat>$MkOsd{'TargetPos_Lat'}</TargetLat>
282
          <TargetLon>$MkOsd{'TargetPos_Lon'}</TargetLon>
283
          <TargetAlt>$MkOsd{'TargetPos_Alt'}</TargetAlt>
284
          <TargetBearing>$MkOsd{'TargetPosDev_Bearing'}</TargetBearing>
285
          <TargetDistance>$MkOsd{'TargetPosDev_Dist'}</TargetDistance>
286
          <Waypoint>$MkOsd{'WaypointIndex'} / $MkOsd{'WaypointNumber'}</Waypoint>
287
          <RCSticks>0, 0, 0</RCSticks>
288
          <GPSSticks>0, 0, 0</GPSSticks>
289
        </extensions>
290
      </trkpt>         
291
EOF
292
        }
293
    else
294
        {
295
        &LogGpxClose();
296
        }
297
    }
298
 
299
#
300
# KML
301
# http://code.google.com/intl/de-DE/apis/kml/documentation/kml_tut.html
302
#
303
 
304
# Open KML logfile
305
sub LogKmlOpen()
306
    {
307
    if ( ! $LogKmlIsOpen )
308
        {      
309
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
310
        my $TimeStamp = sprintf ("%04d%02d%02d-%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
311
        my $Filename = "mk-" . $TimeStamp . ".kml";
312
        open LOGKML, ">$Cfg->{'logging'}->{'KmlLogDir'}/$Filename";
313
        $LogKmlIsOpen = 1;
314
 
315
        # print KML-Header
316
        print LOGKML <<EOF;
317
<?xml version="1.0" encoding="UTF-8"?>
318
<kml xmlns="http://earth.google.com/kml/2.2">
319
  <Document>
320
    <name>Mission Cockpit GPS logging</name>
321
    <Style id="MK_gps-style">
322
      <LineStyle>
323
        <color>ff0000ff</color>
324
        <width>2</width>
325
      </LineStyle>
326
    </Style>
327
    <Placemark>
328
      <name>Flight ${TimeStamp}</name>
329
      <styleUrl>MK_gps-style</styleUrl>
330
      <LineString>
331
        <tessellate>1</tessellate>
332
        <altitudeMode>relativeToGround</altitudeMode>
333
        <coordinates>
334
EOF
335
        }
336
 
337
    return 0;
338
    }  
339
 
340
 
341
# Close KML
342
sub LogKmlClose()
343
    {
344
    if ( $LogKmlIsOpen )
345
        {
346
        # print KML-Trailer
347
        print LOGKML <<EOF;
348
        </coordinates>
349
      </LineString>
350
    </Placemark>
351
  </Document>
352
</kml>
353
EOF
354
        close LOGKML;
355
        $LogKmlIsOpen = 0;
356
        }
357
 
358
    return 0;
359
    }  
360
 
361
 
362
# Log KML
363
sub LogKml()
364
    {
365
    lock %MkOsd;   # until end of Block
366
 
367
    if ( $MkOsd{'_Timestamp'} >= time-10  and
368
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
369
        {
370
        # active connection to MK, MK is flying, valid GPS
371
        &LogKmlOpen();
372
 
373
        my $Alt = &Altitude();
374
        if ( $Alt < 0 ) { $Alt = 0; }
375
        printf LOGKML "          %f, %f, %f\n", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $Alt;
376
        }
377
    else
378
        {
379
        &LogKmlClose();
380
        }
381
    }
382
 
383
 
384
# Send Coords to GoogleEarth server
385
sub Send2GeServer()
386
    {
387
    lock %MkOsd;   # until end of Block
388
 
389
    if ( $MkOsd{'_Timestamp'} >= time-10  and
390
         $MkOsd{'MKFlags'} & 0x02  and  $MkOsd{'CurPos_Stat'} == 1 )
391
        {
392
        # active connection to MK, MK is flying, valid GPS
393
 
394
        my $AltRel = $MkOsd{'CurPos_Alt'} - $MkOsd{'HomePos_Alt'};
395
        if ( $AltRel < 0 ) { $AltRel = 0; }
396
 
397
        push @GeCoords, sprintf "%f, %f, %f", $MkOsd{'CurPos_Lon'}, $MkOsd{'CurPos_Lat'}, $AltRel;
398
        }
399
    }
400
 
401
 
402
sub MkLogLoop()
403
    {
404
    while (1)
405
        {
406
 
407
        # check commnd queue
408
        if ( $LogQueue->pending() > 0 )
409
            {
410
            $LogState = $LogQueue->dequeue(1);
411
            }
412
 
413
        if ( $LogState eq "LOG" )
414
            {
415
            &LogCsv();
416
            &LogKml();
417
            &LogGpx();
418
            }
419
 
420
        &Send2GeServer();  # Google Earth
421
 
422
        # kurz schlafen legen
423
        usleep $LoopTime;
424
        }
425
    }
426
 
427
#
428
# Hauptprgramm
429
#       
430
 
431
if ( $0 =~ /logging.pl$/i )
432
    {
433
    # Program wurde direkt aufgerufen
434
 
435
    # Kommunikation zum MK herstellen
436
    $mk_thr = threads->create (\&MkCommLoop) -> detach();
437
 
438
    &MkLogLoop();
439
 
440
    # should never exit
441
    }
442
 
443
1;
444
 
445
__END__