Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
779 - 1
#!/usr/bin/perl
2
#!/usr/bin/perl -d:ptkdb
3
 
4
###############################################################################
5
#
6
# libmap.pl -  Conversion GPS and Map-X/Y Coordinates
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-10-10 0.0.1 rw created
42
# 2009-12-05 0.0.2 rw check, if no WP is defined
43
# 2010-01-27 0.0.3 rw UsedCapacity, Current
44
#                     switch of logging while sim is active
45
#
46
###############################################################################
47
 
48
$Version{'libmksim.pl'} = "0.0.3 - 2010-01-27";
49
 
50
my $Simulator = "OFF";
51
 
52
sub MkSim()
53
    {
54
    # switch off logging
55
    $LogQueue->enqueue( "OFF" );
56
 
57
    my $popup = $main->Toplevel();
58
    $popup->title("MikroKopter Simulator");
59
 
60
    # Catch delete window event and exit sim
61
    $popup->protocol( 'WM_DELETE_WINDOW' => sub
62
        {
63
        &CbSimStop();
64
        $popup->destroy();
65
        });
66
 
67
 
68
    my $menu_bar = $popup->Menu;
69
    $popup->optionAdd("*tearOff", "false");
70
    $popup->configure ('-menu' => $menu_bar);
71
 
72
    my $menu_action = $menu_bar->cascade('-label' => "Action");
73
    $menu_action->command('-label' => "3D Fix",
74
                          '-command' => [\&CbSim3DFix ],
75
                        );
76
    $menu_action->command('-label' => "Make MK Fly",
77
                          '-command' => [\&CbSimMkFly ],
78
                        );
79
    $menu_action->separator;                                   
80
    $menu_action->command('-label' => "Start Simulator",
81
                          '-command' => [\&CbSimStart ],
82
                         );
83
    $menu_action->command('-label' => "Stop Simulator",
84
                          '-command' => [\&CbSimStop ],
85
                        );
86
 
87
    my $frame = $popup->Frame() -> pack('-side' => 'top',
88
                                        '-expand' => 'y',
89
                                        '-anchor' => 's',
90
                                        '-padx' => 5,
91
                                        '-pady' => 5,
92
                                        );
93
 
94
    my $button = $popup->Frame() -> pack('-side' => 'bottom',
95
                                          '-expand' => 'y',
96
                                          '-anchor' => 's',
97
                                          '-padx' => 5,
98
                                          '-pady' => 5,
99
                                          );
100
 
101
     # Exit Button
102
     $button->Button('-text'    => 'Exit',
103
                     '-width' => 10,
104
                     '-command' => sub
105
                {
106
                &CbSimStop();
107
                $popup->destroy();
108
                }) -> pack( '-anchor' => 's',
109
                            '-padx' => 5,
110
                            '-pady' => 5,
111
                          );
112
 
113
 
114
    # Tabs erstellen
115
    my $book = $frame->NoteBook()->pack( -fill=>'both', -expand=>1 );
116
 
117
    #
118
    # Tab: GPS
119
    #
120
    my $GpsTab = $book->add( "GPS", -label=>"GPS" );
121
 
122
    # canvas grid position
123
    my $GpsRow = 0;
124
    my $GpsCol = 0;
125
    my $GpsRowMap = $GpsRow + 1;
126
    my $GpsColMap = $GpsCol;
127
    my $GpsRowAlt = $GpsRow + 2;
128
    my $GpsColAlt = $GpsCol;
129
    my $GpsRowStat = $GpsRow + 4;
130
    my $GpsColStat = $GpsCol;
131
    my $GpsRowSats = $GpsRow + 5;
132
    my $GpsColSats = $GpsCol;
133
 
134
    # Create and scale Photo
135
    my $ImgWidth = "$Cfg->{'map'}->{'SimImageSize'}" || 300;
136
    my $Factor = $MapSizeX / $ImgWidth;
137
 
138
    my $Img1 = $popup->Photo( 'SimFoto',
139
                              '-file' => "$Cfg->{'map'}->{'MapDir'}/$Map{'File'}",
140
                            );
141
    my $Img2 = $popup->Photo ('SimFoto-Resized');
142
    $Img2->copy ( $Img1,
143
                  '-shrink',
144
                  '-subsample' => $Factor, $Factor,
145
                 );
146
 
147
    my $ImgWidth  = $Img2->width;
148
    my $ImgHeight = $Img2->height;
149
    my $ImgScaleX = $MapSizeX / $ImgWidth;
150
    my $ImgScaleY = $MapSizeY / $ImgHeight;
151
 
152
    # display scaled Photo on canvas
153
    my $canvas = $GpsTab->Canvas( '-width'  => $ImgWidth,
154
                                  '-height' => $ImgHeight,
155
                                ) -> grid (-row    => $GpsRowMap,
156
                                           -column => $GpsColMap,
157
                                           -columnspan => 4,
158
                                          );
159
    $canvas->createImage( 0, 0,
160
                          '-tags'   => 'SimMap',
161
                          '-anchor' => 'nw',
162
                          '-image'  => $Img2,
163
                         );
164
 
165
    # Circle-Icon for MK, Target, Home
166
    my $Dia = 14;
167
    my $ImgSplit = $ImgWidth / 4;
168
    my $MkX     = $ImgSplit - $Dia/2;
169
    my $MkY     = $ImgHeight / 2 + $Dia/2;
170
    my $TargetX = $ImgSplit * 2  - $Dia/2;
171
    my $TargetY = $ImgHeight / 2 + $Dia/2;
172
    my $HomeX   = $ImgSplit * 3  - $Dia/2;
173
    my $HomeY   = $ImgHeight / 2 + $Dia/2;
174
 
175
 
176
    ($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'})       = &MapXY2Gps ($MkX * $ImgScaleX, $MkY * $ImgScaleY);
177
    ($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapXY2Gps ($TargetX * $ImgScaleX, $TargetY * $ImgScaleY);
178
    ($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'})     = &MapXY2Gps ($HomeX * $ImgScaleX, $HomeY * $ImgScaleY);
179
 
180
    $canvas->createOval ( $HomeX, $HomeY, $HomeX + $Dia, $HomeY + $Dia,
181
                         '-tags'    => "SimHome",
182
                         '-fill'    => $Cfg->{'mkcockpit'}->{'ColorHomeLine'},
183
                         '-outline' => "white",
184
                       );
185
    $canvas->createOval ( $TargetX, $TargetY, $TargetX + $Dia, $TargetY + $Dia,
186
                         '-tags'    => "SimTarget",
187
                         '-fill'    => $Cfg->{'mkcockpit'}->{'ColorTargetLine'},
188
                         '-outline' => "white",
189
                       );
190
    $canvas->createOval ( $MkX, $MkY, $MkX + $Dia, $MkY + $Dia,
191
                         '-tags'    => "SimMk",
192
                         '-fill'    => $Cfg->{'mkcockpit'}->{'ColorMkSatGood'},
193
                         '-outline' => "white",
194
                       );
195
 
196
    # GPS Alt MK
197
    $GpsTab->Label(-text => , $Translate{'CurPos_Alt'},
198
                  )->grid ('-row'    => $GpsRowAlt,
199
                           '-column' => $GpsColAlt,
200
                           '-sticky' => 'w',
201
                         );
202
 
203
    $MkOsd{'CurPos_Alt'} = 0;
204
    $scCurPos_Alt = $GpsTab->Scale(
205
                    '-orient'       => 'vertical',
206
                    '-from'         => 400,
207
                    '-to'           => 0,
208
                    '-tickinterval' => 50,
209
                    '-resolution'   => 1,
210
                    '-label'        => "",
211
                    '-font'         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
212
                    '-length'       => 150,
213
                    '-width'        => 15,
214
                    '-variable'     => \$MkOsd{'CurPos_Alt'},
215
                   )->grid ('-row'    => $GpsRowAlt+1,
216
                            '-column' => $GpsColAlt,
217
                           );
218
 
219
    $MkOsd{'CurPos_Stat'} = 0;
220
    $cbCurPos_Stat = $GpsTab->Checkbutton(
221
                      -text => $Translate{'CurPos_Stat'},
222
                      -offvalue  => 0x00,
223
                      -onvalue   => 0x01,
224
                      -variable  => \$MkOsd{'CurPos_Stat'},
225
                     )->grid (-row    => $GpsRowStat,
226
                              -column => $GpsColStat,
227
                              -columnspan => 2,
228
                              -sticky => 'w',
229
                             );
230
 
231
    # Altimeter
232
    $GpsTab->Label(-text => , $Translate{'Altimeter'},
233
                  )->grid ('-row'    => $GpsRowAlt,
234
                           '-column' => $GpsColAlt +1,
235
                         );
236
 
237
    $MkOsd{'Altimeter'} = 0;
238
    $scAltimeter = $GpsTab->Scale(
239
                  -orient       => 'vertical',
240
                  -from         => 8000,
241
                  -to           => 0,
242
                  -tickinterval => 2000,
243
                  -resolution   => 1,
244
                  -label        => "",
245
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
246
                  -length       => 150,
247
                  -width        => 15,
248
                  -variable     => \$MkOsd{'Altimeter'},
249
                  )->grid (-row    => $GpsRowAlt +1,
250
                           -column => $GpsColAlt +1,
251
                          );
252
 
253
    # GPS Alt Target
254
    $GpsTab->Label(-text => , $Translate{'TargetPos_Alt'},
255
                  )->grid ('-row'    => $GpsRowAlt,
256
                           '-column' => $GpsColAlt +2,
257
                         );
258
 
259
    $MkOsd{'TargetPos_Alt'} = 0;
260
    $scTargetPos_Alt = $GpsTab->Scale(
261
                    '-orient'       => 'vertical',
262
                    '-from'         => 400,
263
                    '-to'           => 0,
264
                    '-tickinterval' => 50,
265
                    '-resolution'   => 1,
266
                    '-label'        => "",
267
                    '-font'         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
268
                    '-length'       => 150,
269
                    '-width'        => 15,
270
                    '-variable'     => \$MkOsd{'TargetPos_Alt'},
271
                   )->grid ('-row'    => $GpsRowAlt +1,
272
                            '-column' => $GpsColAlt +2,
273
                           );
274
 
275
    $MkOsd{'TargetPos_Stat'} = 0;
276
    $cbTargetPos_Stat = $GpsTab->Checkbutton(-text => $Translate{'TargetPos_Stat'},
277
                      -offvalue  => 0x00,
278
                      -onvalue   => 0x01,
279
                      -variable  => \$MkOsd{'TargetPos_Stat'},
280
                     )->grid (-row    => $GpsRowStat,
281
                              -column => $GpsColStat +2,
282
                             );
283
 
284
    # GPS Alt Home
285
    $GpsTab->Label(-text => , $Translate{'HomePos_Alt'},
286
                  )->grid ('-row'    => $GpsRowAlt,
287
                           '-column' => $GpsColAlt +3,
288
                         );
289
 
290
    $MkOsd{'HomePos_Alt'} = 0;
291
    $scHomePos_Alt = $GpsTab->Scale(
292
                    '-orient'       => 'vertical',
293
                    '-from'         => 400,
294
                    '-to'           => 0,
295
                    '-tickinterval' => 50,
296
                    '-resolution'   => 1,
297
                    '-label'        => "",
298
                    '-font'         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
299
                    '-length'       => 150,
300
                    '-width'        => 15,
301
                    '-variable'     => \$MkOsd{'HomePos_Alt'},
302
                   )->grid ('-row'    => $GpsRowAlt +1,
303
                            '-column' => $GpsColAlt +3,
304
                           );
305
 
306
    $MkOsd{'HomePos_Stat'} = 0;
307
    $cbHomePos_Stat = $GpsTab->Checkbutton(
308
                      -text => "Home Status",   # $Translate{'HomePos_Stat'},
309
                      -offvalue  => 0x00,
310
                      -onvalue   => 0x01,
311
                      -variable  => \$MkOsd{'HomePos_Stat'},
312
                     )->grid (-row    => $GpsRowStat,
313
                              -column => $GpsColStat +3,
314
                             );
315
 
316
    # Sats in Use
317
    $MkOsd{'SatsInUse'} = 0;
318
    $scSatsInUse = $GpsTab->Scale(
319
                   '-orient'       => 'horizontal',
320
                   '-from'         => 0,
321
                   '-to'           => 12,
322
                   '-resolution'   => 1,
323
                   '-tickinterval' => 1,
324
                   '-label'        => $Translate{'SatsInUse'},
325
                   '-font'         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
326
                   '-length'       => 300,
327
                   '-width'        => 15,
328
                   '-variable'     => \$MkOsd{'SatsInUse'},
329
                   )->grid (-row    => $GpsRowSats,
330
                            -column => $GpsColSats,
331
                            -columnspan => 4,
332
                           );
333
 
334
     # Balloon
335
     my $simballoon = $popup->Balloon();
336
     $simballoon->attach($canvas,
337
                         '-balloonposition' => 'mouse',
338
                         '-state' => 'balloon',
339
                         '-msg' => { 'SimMk'     => 'MikroKopter',
340
                                     'SimTarget' => 'Target',
341
                                     'SimHome'   => 'Home',
342
                                   },
343
                        );
344
 
345
    # Mouse button 1 for MK
346
    my $MkOldx = 0;
347
    my $MkOldy = 0;
348
 
349
    # Pick MK
350
    $canvas->bind('SimMk' => '<Button-1>' => sub
351
        {
352
        # prepare to move
353
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
354
        $MkOldx = $x;
355
        $MkOldy = $y;
356
        });
357
 
358
    # Move Mk
359
    $canvas->bind('SimMk' => '<Button1-Motion>' => sub
360
        {
361
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
362
        my $id      = $canvas->find('withtag', 'current');
363
 
364
        my $Dia2 = $Dia/2;
365
        if ( $x < $Dia2 ) { $x = $Dia2 };
366
        if ( $y < $Dia2 ) { $y = $Dia2 };
367
        if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
368
        if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
369
 
370
        $canvas->move($id => $x - $MkOldx, $y - $MkOldy);
371
        $MkOldx = $x;
372
        $MkOldy = $y;
373
 
374
        ($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
375
        });
376
 
377
    # Mouse button 1 for Target
378
    my $TargetOldx = 0;
379
    my $TargetOldy = 0;
380
 
381
    # Pick Target
382
    $canvas->bind('SimTarget' => '<Button-1>' => sub
383
        {
384
        # prepare to move
385
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
386
        $TargetOldx = $x;
387
        $TargetOldy = $y;
388
        });
389
 
390
    # Move Target
391
    $canvas->bind('SimTarget' => '<Button1-Motion>' => sub
392
        {
393
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
394
        my $id      = $canvas->find('withtag', 'current');
395
 
396
        my $Dia2 = $Dia/2;
397
        if ( $x < $Dia2 ) { $x = $Dia2 };
398
        if ( $y < $Dia2 ) { $y = $Dia2 };
399
        if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
400
        if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
401
 
402
        $canvas->move($id => $x - $TargetOldx, $y - $TargetOldy);
403
        $TargetOldx = $x;
404
        $TargetOldy = $y;
405
 
406
        ($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
407
        });
408
 
409
    # Mouse button 1 for Home
410
    my $HomeOldx = 0;
411
    my $HomeOldy = 0;
412
 
413
    # Pick Home
414
    $canvas->bind('SimHome' => '<Button-1>' => sub
415
        {
416
        # prepare to move
417
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
418
        $HomeOldx = $x;
419
        $HomeOldy = $y;
420
        });
421
 
422
    # Move Home
423
    $canvas->bind('SimHome' => '<Button1-Motion>' => sub
424
        {
425
        my ($x, $y) = ($Tk::event->x, $Tk::event->y);
426
        my $id      = $canvas->find('withtag', 'current');
427
 
428
        my $Dia2 = $Dia/2;
429
        if ( $x < $Dia2 ) { $x = $Dia2 };
430
        if ( $y < $Dia2 ) { $y = $Dia2 };
431
        if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
432
        if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
433
 
434
        $canvas->move($id => $x - $HomeOldx, $y - $HomeOldy);
435
        $HomeOldx = $x;
436
        $HomeOldy = $y;
437
 
438
        ($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
439
        });
440
 
441
 
442
    #
443
    # Tab: Navigation
444
    #
445
    my $NavTab = $book->add( "Navigation", -label=>"Navigation", );
446
 
447
    my $Row = 0;
448
    my $Col = 0;
449
 
450
    # Waypoint Index
451
    $MkOsd{'WaypointIndex'} = 0;
452
    $scWaypointIndex = $NavTab->Scale(
453
                   -orient       => 'horizontal',
454
                   -from         => 0,
455
                   -to           => 20,
456
                   -tickinterval => 5,
457
                   -resolution   => 1,
458
                   -label        => $Translate{'WaypointIndex'},
459
                   -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
460
                   -length       => 300,
461
                   -width        => 15,
462
                   -variable     => \$MkOsd{'WaypointIndex'},
463
                   )->grid (-row    => $Row + 1,
464
                            -column => $Col,
465
                           );
466
 
467
    # Waypoint Number
468
    $MkOsd{'WaypointNumber'} = 0;
469
    $scWaypointNumber = $NavTab->Scale(
470
                   -orient       => 'horizontal',
471
                   -from         => 0,
472
                   -to           => 20,
473
                   -tickinterval => 5,
474
                   -resolution   => 1,
475
                   -label        => $Translate{'WaypointNumber'},
476
                   -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
477
                   -length       => 300,
478
                   -width        => 15,
479
                   -variable     => \$MkOsd{'WaypointNumber'},
480
                   )->grid (-row    => $Row + 2,
481
                            -column => $Col,
482
                           );
483
 
484
    # Operating Radius
485
    $MkOsd{'OperatingRadius'} = 250;
486
    $scOperatingRadius = $NavTab->Scale(
487
                   -orient       => 'horizontal',
488
                   -from         => 0,
489
                   -to           => 250,
490
                   -tickinterval => 50,
491
                   -resolution   => 1,
492
                   -label        => "$Translate{'OperatingRadius'} (m)",
493
                   -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
494
                   -length       => 300,
495
                   -width        => 15,
496
                   -variable     => \$MkOsd{'OperatingRadius'},
497
                   )->grid (-row    => $Row + 3,
498
                            -column => $Col,
499
                           );
500
 
501
    # TargetPosDev_Dist
502
    $MkOsd{'TargetPosDev_Dist'} = 250;
503
    $scTargetPosDev_Dist = $NavTab->Scale(
504
                   -orient       => 'horizontal',
505
                   -from         => 0,
506
                   -to           => 500,
507
                   -tickinterval => 100,
508
                   -resolution   => 1,
509
                   -label        => "$Translate{'TargetPosDev_Dist'} (dm)",
510
                   -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
511
                   -length       => 300,
512
                   -width        => 15,
513
                   -variable     => \$MkOsd{'TargetPosDev_Dist'},
514
                   )->grid (-row    => $Row + 4,
515
                            -column => $Col,
516
                           );
517
 
518
 
519
    #
520
    # Tab: MK
521
    #
522
    my $MkTab = $book->add( "MikroKopter1", -label=>"MikroKopter 1", );
523
 
524
    my $Row = 0;
525
    my $Col = 0;
526
 
527
    # Battery
528
    $MkOsd{'UBat'} = 12.6;
529
    $scUBat = $MkTab->Scale(
530
                   -orient       => 'horizontal',
531
                   -from         => 6.0,
532
                   -to           => 18.0,
533
                   -tickinterval => 2,
534
                   -resolution   => 0.1,
535
                   -label        => "$Translate{'UBat'} (V)",
536
                   -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
537
                   -length       => 200,
538
                   -width        => 15,
539
                   -variable     => \$MkOsd{'UBat'},
540
                   )->grid (-row    => $Row,
541
                            -column => $Col,
542
                           );
543
 
544
    # RC Quality
545
    $MkOsd{'RC_Quality'} = 190;
546
    $scRC_Quality = $MkTab->Scale(
547
                  -orient       => 'horizontal',
548
                  -from         => 0,
549
                  -to           => 200,
550
                  -tickinterval => 50,
551
                  -resolution   => 1,
552
                  -label        => $Translate{'RC_Quality'},
553
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
554
                  -length       => 200,
555
                  -width        => 15,
556
                  -variable     => \$MkOsd{'RC_Quality'},
557
                  )->grid (-row    => $Row +1,
558
                           -column => $Col,
559
                          );
560
    # CompassHeading
561
    $MkOsd{'CompassHeading'} = 0;
562
    $scCompassHeading = $MkTab->Scale(
563
                  -orient       => 'horizontal',
564
                  -from         => 0,
565
                  -to           => 360,
566
                  -tickinterval => 45,
567
                  -resolution   => 1,
568
                  -label        => $Translate{'CompassHeading'},
569
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
570
                  -length       => 200,
571
                  -width        => 15,
572
                  -variable     => \$MkOsd{'CompassHeading'},
573
                  )->grid (-row    => $Row +2,
574
                           -rowspan => 4,
575
                           -column => $Col,
576
                          );
577
 
578
    # GPS Groundspeed
579
    $MkOsd{'GroundSpeed'} = 0;
580
    $scGroundSpeed = $MkTab->Scale(
581
                  -orient       => 'horizontal',
582
                  -from         => 0,
583
                  -to           => 1000,
584
                  -tickinterval => 200,
585
                  -resolution   => 1,
586
                  -label        => "$Translate{'GroundSpeed'} (dm/s)",
587
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
588
                  -length       => 200,
589
                  -width        => 15,
590
                  -variable     => \$MkOsd{'GroundSpeed'},
591
                  )->grid (-row    => $Row + 6,
592
                           -rowspan => 4,
593
                           -column => $Col,
594
                          );
595
 
596
    # GPS Speed North
597
    $MkNcDebug{'Analog_21'} = 0;
598
    $scAnalog_21 = $MkTab->Scale(
599
                  -orient       => 'horizontal',
600
                  -from         => -1000,
601
                  -to           => 1000,
602
                  -tickinterval => 400,
603
                  -resolution   => 1,
604
                  -label        => "$Translate{'Analog_21'} (dm/s)",
605
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
606
                  -length       => 200,
607
                  -width        => 15,
608
                  -variable     => \$MkNcDebug{'Analog_21'},
609
                  )->grid (-row    => $Row + 10,
610
                           -rowspan => 4,
611
                           -column => $Col,
612
                          );
613
 
614
    # GPS Speed East
615
    $MkNcDebug{'Analog_22'} = 0;
616
    $scAnalog_22 = $MkTab->Scale(
617
                  -orient       => 'horizontal',
618
                  -from         => -1000,
619
                  -to           => 1000,
620
                  -tickinterval => 400,
621
                  -resolution   => 1,
622
                  -label        => "$Translate{'Analog_22'} (dm/s)",
623
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
624
                  -length       => 200,
625
                  -width        => 15,
626
                  -variable     => \$MkNcDebug{'Analog_22'},
627
                  )->grid (-row    => $Row + 14,
628
                           -rowspan => 4,
629
                           -column => $Col,
630
                          );
631
 
632
    # Variometer
633
    $MkOsd{'Variometer'} = 0;
634
    $scVariometer = $MkTab->Scale(
635
                  -orient       => 'vertical',
636
                  -from         => 30,
637
                  -to           => -30,
638
                  -tickinterval => 10,
639
                  -resolution   => 1,
640
                  -label        => $Translate{'Variometer'},
641
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
642
                  -length       => 100,
643
                  -width        => 15,
644
                  -variable     => \$MkOsd{'Variometer'},
645
                  )->grid (-row    => $Row,
646
                           -rowspan => 2,
647
                           -column => $Col + 1,
648
                          );
649
 
650
    my $DataLink = 1;
651
    $cbDataLink = $MkTab->Checkbutton(
652
                        -text => $Translate{'DataLink'},
653
                        -offvalue => 0x00,
654
                        -onvalue  => 0x01,
655
                        -variable  => \$DataLink,
656
                       )->grid (-row    => $Row + 2,
657
                                -column => $Col +1,
658
                                -sticky=>'w',
659
                                -ipadx => 10,
660
                               );
661
 
662
    $MkTab->Label(-text => "",                    # space
663
                 )->grid (-row    => $Row +3,
664
                          -column => $Col +1,
665
                          -sticky=>'w',
666
                          -ipadx => 10,
667
                         );
668
 
669
    $MkTab->Label(-text => "$Translate{'MKFlags'}: --------",
670
                 )->grid (-row    => $Row +4,
671
                          -column => $Col +1,
672
                          -sticky=>'w',
673
                          -ipadx => 10,
674
                         );
675
    my $MkMotorRun = 0;
676
    $cbMkMotorRun = $MkTab->Checkbutton(
677
                        -text => $Translate{'MkMotorRun'},
678
                        -offvalue => 0x00,
679
                        -onvalue  => 0x01,
680
                        -variable  => \$MkMotorRun,
681
                       )->grid (-row    => $Row + 5,
682
                                -column => $Col +1,
683
                                -sticky=>'w',
684
                                -ipadx => 10,
685
                               );
686
    my $MkFly = 0;
687
    $cbMkFly = $MkTab->Checkbutton(
688
                      -text => $Translate{'MkFly'},
689
                      -variable  => \$MkFly,
690
                      -offvalue => 0x00,
691
                      -onvalue  => 0x02,
692
                     )->grid (-row    => $Row + 6,
693
                              -column => $Col +1,
694
                                -sticky=>'w',
695
                                -ipadx => 10,
696
                             );
697
    my $MkCalibrate = 0;
698
    $cbMkCalibrate = $MkTab->Checkbutton(
699
                      -text => $Translate{'MkCalibrate'},
700
                      -variable  => \$MkCalibrate,
701
                      -offvalue => 0x00,
702
                      -onvalue  => 0x04,
703
                     )->grid (-row    => $Row + 7,
704
                              -column => $Col +1,
705
                               -sticky=>'w',
706
                               -ipadx => 10,
707
                             );
708
    my $MkStart = 0;
709
    $cbMkStart = $MkTab->Checkbutton(
710
                      -text => $Translate{'MkStart'},
711
                      -variable  => \$MkStart,
712
                      -offvalue => 0x00,
713
                      -onvalue  => 0x08,
714
                     )->grid (-row    => $Row + 8,
715
                              -column => $Col + 1,
716
                              -sticky=>'w',
717
                              -ipadx => 10,
718
                             );
719
    my $MkEmergency = 0;
720
    $cbMkEmergency = $MkTab->Checkbutton(
721
                      -text => $Translate{'MkEmergency'},
722
                      -variable  => \$MkEmergency,
723
                      -offvalue => 0x00,
724
                      -onvalue  => 0x10,
725
                     )->grid (-row    => $Row + 9,
726
                              -column => $Col + 1,
727
                              -sticky=>'w',
728
                              -ipadx => 10,
729
                             );
730
 
731
    $MkTab->Label(-text => "$Translate{'NCFlags'}: --------",
732
                 )->grid (-row    => $Row + 10,
733
                          -column => $Col + 1,
734
                           -sticky=>'w',
735
                           -ipadx => 10,
736
                         );
737
    my $NcFlagFree = 0;
738
    $cbNcFlagFree = $MkTab->Checkbutton(
739
                      -text => $Translate{'NcFlagFree'},
740
                      -offvalue => 0x00,
741
                      -onvalue  => 0x01,
742
                      -variable  => \$NcFlagFree,
743
                     )->grid (-row    => $Row + 11,
744
                              -column => $Col + 1,
745
                              -sticky=>'w',
746
                              -ipadx => 10,
747
                             );
748
    my $NcFlagPH = 0;
749
    $cbNcFlagPH = $MkTab->Checkbutton(
750
                      -text => $Translate{'NcFlagPH'},
751
                      -offvalue => 0x00,
752
                      -onvalue  => 0x02,
753
                      -variable  => \$NcFlagPH,
754
                     )->grid (-row    => $Row + 12,
755
                              -column => $Col + 1,
756
                              -sticky=>'w',
757
                              -ipadx => 10,
758
                             );
759
    my $NcFlagCH = 0;
760
    $cbNcFlagCH = $MkTab->Checkbutton(
761
                      -text => $Translate{'NcFlagCH'},
762
                      -offvalue => 0x00,
763
                      -onvalue  => 0x04,
764
                      -variable  => \$NcFlagCH,
765
                     )->grid (-row    => $Row + 13,
766
                              -column => $Col + 1,
767
                              -sticky=>'w',
768
                              -ipadx => 10,
769
                             );
770
    my $NcFlagRangeLimit = 0;
771
    $cbNcFlagRangeLimit = $MkTab->Checkbutton(
772
                      -text => $Translate{'NcFlagRangeLimit'},
773
                      -offvalue => 0x00,
774
                      -onvalue  => 0x08,
775
                      -variable  => \$NcFlagRangeLimit,
776
                     )->grid (-row    => $Row + 14,
777
                              -column => $Col + 1,
778
                              -sticky=>'w',
779
                              -ipadx => 10,
780
                             );
781
    my $NcFlagNoSerialLink = 0;
782
    $cbNcFlagNoSerialLink = $MkTab->Checkbutton(
783
                      -text => $Translate{'NcFlagNoSerialLink'},
784
                      -offvalue => 0x00,
785
                      -onvalue  => 0x10,
786
                      -variable  => \$NcFlagNoSerialLink,
787
                     )->grid (-row    => $Row + 15,
788
                              -column => $Col + 1,
789
                              -sticky=>'w',
790
                              -ipadx => 10,
791
                             );
792
    my $NcFlagTargetReached = 0;
793
    $cbNcFlagTargetReached = $MkTab->Checkbutton(
794
                      -text => $Translate{'NcFlagTargetReached'},
795
                      -offvalue => 0x00,
796
                      -onvalue  => 0x20,
797
                      -variable  => \$NcFlagTargetReached,
798
                     )->grid (-row    => $Row + 16,
799
                              -column => $Col + 1,
800
                              -sticky=>'w',
801
                              -ipadx => 10,
802
                             );
803
 
804
    my $NcFlagManualControl = 0;
805
    $cbNcFlagManualControl = $MkTab->Checkbutton(
806
                      -text => $Translate{'NcFlagManualControl'},
807
                      -offvalue => 0x00,
808
                      -onvalue  => 0x40,
809
                      -variable  => \$NcFlagManualControl
810
                     )->grid (-row    => $Row + 17,
811
                              -column => $Col + 1,
812
                              -sticky=>'w',
813
                              -ipadx => 10,
814
                             );
815
 
816
    #
817
    # Tab: MK 2
818
    #
819
    my $Mk2Tab = $book->add( "MikroKopter2", -label=>"MikroKopter 2", );
820
 
821
    my $Row = 0;
822
    my $Col = 0;
823
 
824
    # Current
825
    $MkOsd{'Current'} = 0;
826
    $scCurrent = $Mk2Tab->Scale(
827
                  -orient       => 'horizontal',
828
                  -from         => 0,
829
                  -to           => 50,
830
                  -tickinterval => 10,
831
                  -resolution   => 1,
832
                  -label        => "$Translate{'Current'} (A)",
833
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
834
                  -length       => 300,
835
                  -width        => 15,
836
                  -variable     => \$MkOsd{'Current'},
837
                  )->grid (-row    => $Row,
838
                           -column => $Col,
839
                          );
840
 
841
    # Used Capacity
842
    $MkOsd{'UsedCapacity'} = 0;
843
    $scUsedCapacity = $Mk2Tab->Scale(
844
                  -orient       => 'horizontal',
845
                  -from         => 0,
846
                  -to           => 5000,
847
                  -tickinterval => 1000,
848
                  -resolution   => 50,
849
                  -label        => "$Translate{'UsedCapacity'} (mAh)",
850
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
851
                  -length       => 300,
852
                  -width        => 15,
853
                  -variable     => \$MkOsd{'UsedCapacity'},
854
                  )->grid (-row    => $Row + 1,
855
                           -column => $Col,
856
                          );
857
 
858
    #
859
    # Tab: Simulator
860
    #
861
    my $MkTab = $book->add( "Simulator", -label=>"Simulator", );
862
 
863
    my $Row = 0;
864
    my $Col = 0;
865
 
866
    # Speed
867
    my $SimSpeed = 20;  # km/h
868
    $scSimSpeed = $MkTab->Scale(
869
                  -orient       => 'horizontal',
870
                  -from         => 0,
871
                  -to           => 50,
872
                  -tickinterval => 5,
873
                  -resolution   => 1,
874
                  -label        => "Speed (km/h)",
875
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
876
                  -length       => 300,
877
                  -width        => 15,
878
                  -variable     => \$SimSpeed,
879
                  )->grid (-row    => $Row,
880
                           -column => $Col,
881
                          );
882
 
883
    # Acceleration
884
    my $SimAcc = 10;  # m/s**2
885
    $scSimAcc = $MkTab->Scale(
886
                  -orient       => 'horizontal',
887
                  -from         => 0,
888
                  -to           => 30,
889
                  -tickinterval => 5,
890
                  -resolution   => 0.5,
891
                  -label        => "Acceleration (m/s**2)",
892
                  -font         => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
893
                  -length       => 300,
894
                  -width        => 15,
895
                  -variable     => \$SimAcc,
896
                  )->grid (-row    => $Row +1,
897
                           -column => $Col,
898
                          );
899
 
900
 
901
    my $Speed  = 0;  # Current Mk Speed
902
    my $SpeedN = 0;  # Speed North
903
    my $SpeedE = 0;  # Speed East
904
 
905
 
906
    #
907
    # Timer
908
    #
909
    my $SimTimebase = 100;    # Simulator Timebase in ms
910
    $popup->repeat ($SimTimebase, sub
911
        {
912
        lock (%MkOsd);              # until end of block
913
 
914
        $MkOsd{'MKFlags'} = $MkMotorRun | $MkFly | $MkCalibrate | $MkStart | $MkEmergency;
915
        $MkOsd{'NCFlags'} = $NcFlagFree | $NcFlagPH | $NcFlagCH | $NcFlagRangeLimit |
916
                            $NcFlagNoSerialLink | $NcFlagTargetReached | $NcFlagManualControl;
917
 
918
        # Calibration sequence
919
        if ( $CalibCount > 0 )
920
            {
921
            $CalibCount ++;
922
            }
923
        if ( $CalibCount > 2 * 1000 / $SimTimebase )  # 2s
924
            {
925
            $cbMkCalibrate-> deselect();
926
            $cbMkStart->deselect();
927
 
928
            $cbMkMotorRun->select();
929
            $cbMkFly->select();
930
 
931
            $CalibCount = 0;
932
            }
933
 
934
        #
935
        # Simulator
936
        #
937
        if ( $Simulator =~ /ON/i and
938
             $MkSim{'Target_Lat'} ne ""  and $MkSim{'Target_Lon'} ne "" )
939
            {
940
            # Set Target-Pos
941
            $MkOsd{'TargetPos_Lat'} = $MkSim{'Target_Lat'};
942
            $MkOsd{'TargetPos_Lon'} = $MkSim{'Target_Lon'};
943
            $MkOsd{'TargetPos_Alt'} = $MkSim{'Target_Alt'};
944
            $MkOsd{'TargetPos_Stat'} = 1;
945
 
946
            my ($HomeDist, $HomeBearing) = &MapGpsTo($MkOsd{'HomePos_Lat'},   $MkOsd{'HomePos_Lon'},
947
                                                     $MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'} );
948
            if ( $HomeDist > $MkOsd{'OperatingRadius'} )
949
                {
950
                # Target entsprechend Operation Radius neu berechnen
951
                $HomeDist = $MkOsd{'OperatingRadius'};
952
                ($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapGpsAt($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'},
953
                                                                               $HomeDist, $HomeBearing);
954
                $cbNcFlagRangeLimit->select;
955
                }
956
            else
957
                {
958
                $cbNcFlagRangeLimit->deselect;
959
                }
960
 
961
            #
962
            # Mk physics
963
            # Move MK to Target with constant acceleration
964
            #
965
            my ($Dist, $Bearing) = &MapGpsTo($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'},
966
                                             $MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'} );
967
 
968
            $MkOsd{'TargetPosDev_Dist'} = $Dist * 10;  # in dm
969
            $MkOsd{'TargetPosDev_Bearing'} = $Bearing;
970
 
971
            my $AccN = $SimAcc * cos (deg2rad $Bearing);     # Acceleration North
972
            my $AccE = $SimAcc * sin (deg2rad $Bearing);     # Acceleration East
973
            my $t = $SimTimebase / 1000;
974
 
975
            $SpeedN = $SpeedN + $AccN * $t;  # Speed North
976
            $SpeedE = $SpeedE + $AccE * $t;  # Speed East
977
            $Speed  = sqrt ($SpeedN * $SpeedN + $SpeedE * $SpeedE);
978
 
979
            if ( $Speed >= $SimSpeed/3.6 )
980
                {
981
                # Limit maximum Speed
982
                my $SpeedBearing = rad2deg (atan2 ($SpeedE, $SpeedN));
983
 
984
                $SpeedN = $SimSpeed/3.6 * cos (deg2rad $SpeedBearing);
985
                $SpeedE = $SimSpeed/3.6 * sin (deg2rad $SpeedBearing);
986
                $Speed = $SimSpeed/3.6;
987
                }
988
 
989
            my $BreakDist = 5;
990
            if ( $Dist <= $BreakDist )
991
                {
992
                $Speed = $SimSpeed/3.6 - $SimSpeed/3.6 * (1 - $Dist/$BreakDist);
993
                my $SpeedBearing = rad2deg (atan2 ($SpeedE, $SpeedN));
994
                $SpeedN = $Speed * cos (deg2rad $SpeedBearing);
995
                $SpeedE = $Speed * sin (deg2rad $SpeedBearing);
996
                $AccN = 0;
997
                $AccE = 0;
998
                }
999
 
1000
            # Distance to go in this loop
1001
            my $GoDistN = $SpeedN * $t + 0.5 * $AccN * $t * $t;
1002
            my $GoDistE = $SpeedE * $t + 0.5 * $AccE * $t * $t;
1003
            my $GoDist = sqrt ( $GoDistN * $GoDistN + $GoDistE * $GoDistE);
1004
            my $GoBearing = rad2deg (atan2 ($GoDistE, $GoDistN));
1005
 
1006
            if ($GoDist > 0 )
1007
                {
1008
                ($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'}) = &MapGpsAt($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'},
1009
                                                                         $GoDist, $GoBearing);            
1010
                }
1011
 
1012
            if ( $Dist < $MkSim{'Target_ToleranceRadius'} )
1013
                {
1014
                $cbNcFlagTargetReached -> select();
1015
                }
1016
            else
1017
                {
1018
                $cbNcFlagTargetReached -> deselect();
1019
                }
1020
 
1021
            # GPS Groundspeed, North, East
1022
            $MkOsd{'GroundSpeed'}  = $Speed * 100;  # dm/s
1023
            $MkNcDebug{'Analog_21'} = $SpeedN * 100;
1024
            $MkNcDebug{'Analog_22'} = $SpeedE * 100;
1025
 
1026
            # Heading
1027
            if ( $MkSim{'Target_Heading'} != 0 )
1028
                {
1029
                $scCompassHeading -> set($MkSim{'Target_Heading'});
1030
                }
1031
 
1032
            }
1033
 
1034
        # update display
1035
        $scAnalog_21 -> set($MkNcDebug{'Analog_21'});
1036
        $scAnalog_22 -> set($MkNcDebug{'Analog_22'});
1037
        $scTargetPos_Alt -> set($MkOsd{'TargetPos_Alt'});
1038
        $scTargetPosDev_Dist -> set ($MkOsd{'TargetPosDev_Dist'});
1039
        $scGroundSpeed -> set($MkOsd{'GroundSpeed'});
1040
        $scWaypointNumber -> set ($MkOsd{'WaypointNumber'});
1041
        $scWaypointIndex -> set ($MkOsd{'WaypointIndex'});
1042
 
1043
        # move MK symbol on canvas
1044
        my ($x, $y) = &MapGps2XY ($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'});
1045
        $x = $x / $ImgScaleX;
1046
        $y = $y / $ImgScaleY;
1047
        $canvas->coords ('SimMk', $x, $y, $x + $Dia, $y + $Dia);
1048
 
1049
        # move Home symbol on canvas
1050
        my ($x, $y) = &MapGps2XY ($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'});
1051
        $x = $x / $ImgScaleX;
1052
        $y = $y / $ImgScaleY;
1053
        $canvas->coords ('SimHome', $x, $y, $x + $Dia, $y + $Dia);
1054
 
1055
        # move Target symbol on canvas
1056
        my ($x, $y) = &MapGps2XY ($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'});
1057
        $x = $x / $ImgScaleX;
1058
        $y = $y / $ImgScaleY;
1059
        $canvas->coords ('SimTarget', $x, $y, $x + $Dia, $y + $Dia);
1060
 
1061
        if ( $DataLink)
1062
            {
1063
            # Timestamp, wann der Datensatz geschrieben wurde
1064
            $MkOsd{'_Timestamp'} = time;
1065
            }
1066
 
1067
        });
1068
    }
1069
 
1070
# Make MK Fly
1071
sub CbSimMkFly
1072
    {
1073
    $scWaypointIndex->set(5);
1074
    $scWaypointNumber->set(10);
1075
    $cbNcFlagCH->select();
1076
 
1077
    # start calibration sequence
1078
    $cbMkCalibrate-> select();
1079
    $cbMkStart->select();
1080
    $CalibCount = 1;
1081
    }
1082
 
1083
 
1084
# 3D Fix
1085
sub CbSim3DFix
1086
    {
1087
    my $Alt = 50;
1088
    $scCurPos_Alt->set($Alt);
1089
    $scAltimeter->set($Alt * $Cfg->{'map'}->{'AltFactor'});
1090
 
1091
    $scSatsInUse->set(10);
1092
    $cbCurPos_Stat->select();
1093
    $cbTargetPos_Stat->select();
1094
    $cbHomePos_Stat->select();
1095
 
1096
    # Set Home-Pos to Cur-Pos
1097
    $MkOsd{'HomePos_Lat'} = $MkOsd{'CurPos_Lat'};
1098
    $MkOsd{'HomePos_Lon'} = $MkOsd{'CurPos_Lon'};
1099
 
1100
    $scGroundSpeed->set(400);
1101
    $scAnalog_21->set(10);
1102
    $scAnalog_22->set(10);
1103
    }
1104
 
1105
# Switch Simulator ON
1106
sub CbSimStart
1107
    {
1108
    $Simulator = "ON";
1109
 
1110
    # Only one Target from Player
1111
    $MkOsd{'WaypointNumber'} = 1;
1112
    $MkOsd{'WaypointIndex'} = 0;
1113
    }
1114
 
1115
 
1116
# Switch Simulator OFF
1117
sub CbSimStop
1118
    {
1119
    $Simulator = "OFF";
1120
 
1121
    # switch on logging
1122
    $MkOsd{'_Timestamp'} = 0;
1123
    $LogQueue->enqueue( "LOG" );
1124
    }
1125
 
1126
 
1127
1;
1128
 
1129
__END__