Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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