Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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