Blame |
Last modification |
View Log
| RSS feed
#!/usr/bin/perl
#!/usr/bin/perl -d:ptkdb
###############################################################################
#
# libmap.pl - Conversion GPS and Map-X/Y Coordinates
#
# Copyright (C) 2009 Rainer Walther (rainerwalther-mail@web.de)
#
# Creative Commons Lizenz mit den Zusaetzen (by, nc, sa)
#
# Es ist Ihnen gestattet:
# * das Werk vervielfältigen, verbreiten und öffentlich zugänglich machen
# * Abwandlungen bzw. Bearbeitungen des Inhaltes anfertigen
#
# Zu den folgenden Bedingungen:
# * Namensnennung.
# Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
# * Keine kommerzielle Nutzung.
# Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden.
# * Weitergabe unter gleichen Bedingungen.
# Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten,
# verändern oder als Grundlage für einen anderen Inhalt verwenden,
# dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen
# weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.
#
# Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen, unter welche dieses
# Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden.
#
# Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie die Einwilligung
# des Rechteinhabers dazu erhalten.
#
# Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.
#
# Weitere Details zur Lizenzbestimmung gibt es hier:
# Kurzform: http://creativecommons.org/licenses/by-nc-sa/3.0/de/
# Komplett: http://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode
#
###############################################################################
#
# 2009-10-10 0.0.1 rw created
# 2009-12-05 0.0.2 rw check, if no WP is defined
# 2010-01-27 0.0.3 rw UsedCapacity, Current
# switch of logging while sim is active
#
###############################################################################
$Version{'libmksim.pl'} = "0.0.3 - 2010-01-27";
my $Simulator = "OFF";
sub MkSim
()
{
# switch off logging
$LogQueue->enqueue( "OFF" );
my $popup = $main->Toplevel();
$popup->title("MikroKopter Simulator");
# Catch delete window event and exit sim
$popup->protocol( 'WM_DELETE_WINDOW' => sub
{
&CbSimStop();
$popup->destroy();
});
my $menu_bar = $popup->Menu;
$popup->optionAdd("*tearOff", "false");
$popup->configure ('-menu' => $menu_bar);
my $menu_action = $menu_bar->cascade('-label' => "Action");
$menu_action->command('-label' => "3D Fix",
'-command' => [\&CbSim3DFix ],
);
$menu_action->command('-label' => "Make MK Fly",
'-command' => [\&CbSimMkFly ],
);
$menu_action->separator;
$menu_action->command('-label' => "Start Simulator",
'-command' => [\&CbSimStart ],
);
$menu_action->command('-label' => "Stop Simulator",
'-command' => [\&CbSimStop ],
);
my $frame = $popup->Frame() -> pack('-side' => 'top',
'-expand' => 'y',
'-anchor' => 's',
'-padx' => 5,
'-pady' => 5,
);
my $button = $popup->Frame() -> pack('-side' => 'bottom',
'-expand' => 'y',
'-anchor' => 's',
'-padx' => 5,
'-pady' => 5,
);
# Exit Button
$button->Button('-text' => 'Exit',
'-width' => 10,
'-command' => sub
{
&CbSimStop();
$popup->destroy();
}) -> pack( '-anchor' => 's',
'-padx' => 5,
'-pady' => 5,
);
# Tabs erstellen
my $book = $frame->NoteBook()->pack( -fill
=>'both', -expand
=>1 );
#
# Tab: GPS
#
my $GpsTab = $book->add( "GPS", -label
=>"GPS" );
# canvas grid position
my $GpsRow = 0;
my $GpsCol = 0;
my $GpsRowMap = $GpsRow + 1;
my $GpsColMap = $GpsCol;
my $GpsRowAlt = $GpsRow + 2;
my $GpsColAlt = $GpsCol;
my $GpsRowStat = $GpsRow + 4;
my $GpsColStat = $GpsCol;
my $GpsRowSats = $GpsRow + 5;
my $GpsColSats = $GpsCol;
# Create and scale Photo
my $ImgWidth = "$Cfg->{'map'}->{'SimImageSize'}" || 300;
my $Factor = $MapSizeX / $ImgWidth;
my $Img1 = $popup->Photo( 'SimFoto',
'-file' => "$Cfg->{'map'}->{'MapDir'}/$Map{'File'}",
);
my $Img2 = $popup->Photo ('SimFoto-Resized');
$Img2->copy ( $Img1,
'-shrink',
'-subsample' => $Factor, $Factor,
);
my $ImgWidth = $Img2->width;
my $ImgHeight = $Img2->height;
my $ImgScaleX = $MapSizeX / $ImgWidth;
my $ImgScaleY = $MapSizeY / $ImgHeight;
# display scaled Photo on canvas
my $canvas = $GpsTab->Canvas( '-width' => $ImgWidth,
'-height' => $ImgHeight,
) -> grid (-row
=> $GpsRowMap,
-column
=> $GpsColMap,
-columnspan
=> 4,
);
$canvas->createImage( 0, 0,
'-tags' => 'SimMap',
'-anchor' => 'nw',
'-image' => $Img2,
);
# Circle-Icon for MK, Target, Home
my $Dia = 14;
my $ImgSplit = $ImgWidth / 4;
my $MkX = $ImgSplit - $Dia/2;
my $MkY = $ImgHeight / 2 + $Dia/2;
my $TargetX = $ImgSplit * 2 - $Dia/2;
my $TargetY = $ImgHeight / 2 + $Dia/2;
my $HomeX = $ImgSplit * 3 - $Dia/2;
my $HomeY = $ImgHeight / 2 + $Dia/2;
($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'}) = &MapXY2Gps ($MkX * $ImgScaleX, $MkY * $ImgScaleY);
($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapXY2Gps ($TargetX * $ImgScaleX, $TargetY * $ImgScaleY);
($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'}) = &MapXY2Gps ($HomeX * $ImgScaleX, $HomeY * $ImgScaleY);
$canvas->createOval ( $HomeX, $HomeY, $HomeX + $Dia, $HomeY + $Dia,
'-tags' => "SimHome",
'-fill' => $Cfg->{'mkcockpit'}->{'ColorHomeLine'},
'-outline' => "white",
);
$canvas->createOval ( $TargetX, $TargetY, $TargetX + $Dia, $TargetY + $Dia,
'-tags' => "SimTarget",
'-fill' => $Cfg->{'mkcockpit'}->{'ColorTargetLine'},
'-outline' => "white",
);
$canvas->createOval ( $MkX, $MkY, $MkX + $Dia, $MkY + $Dia,
'-tags' => "SimMk",
'-fill' => $Cfg->{'mkcockpit'}->{'ColorMkSatGood'},
'-outline' => "white",
);
# GPS Alt MK
$GpsTab->Label(-text
=> , $Translate{'CurPos_Alt'},
)->grid ('-row' => $GpsRowAlt,
'-column' => $GpsColAlt,
'-sticky' => 'w',
);
$MkOsd{'CurPos_Alt'} = 0;
$scCurPos_Alt = $GpsTab->Scale(
'-orient' => 'vertical',
'-from' => 400,
'-to' => 0,
'-tickinterval' => 50,
'-resolution' => 1,
'-label' => "",
'-font' => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
'-length' => 150,
'-width' => 15,
'-variable' => \$MkOsd{'CurPos_Alt'},
)->grid ('-row' => $GpsRowAlt+1,
'-column' => $GpsColAlt,
);
$MkOsd{'CurPos_Stat'} = 0;
$cbCurPos_Stat = $GpsTab->Checkbutton(
-text
=> $Translate{'CurPos_Stat'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$MkOsd{'CurPos_Stat'},
)->grid (-row
=> $GpsRowStat,
-column
=> $GpsColStat,
-columnspan
=> 2,
-sticky
=> 'w',
);
# Altimeter
$GpsTab->Label(-text
=> , $Translate{'Altimeter'},
)->grid ('-row' => $GpsRowAlt,
'-column' => $GpsColAlt +1,
);
$MkOsd{'Altimeter'} = 0;
$scAltimeter = $GpsTab->Scale(
-orient
=> 'vertical',
-from
=> 8000,
-to
=> 0,
-tickinterval
=> 2000,
-resolution
=> 1,
-label
=> "",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 150,
-width
=> 15,
-variable
=> \$MkOsd{'Altimeter'},
)->grid (-row
=> $GpsRowAlt +1,
-column
=> $GpsColAlt +1,
);
# GPS Alt Target
$GpsTab->Label(-text
=> , $Translate{'TargetPos_Alt'},
)->grid ('-row' => $GpsRowAlt,
'-column' => $GpsColAlt +2,
);
$MkOsd{'TargetPos_Alt'} = 0;
$scTargetPos_Alt = $GpsTab->Scale(
'-orient' => 'vertical',
'-from' => 400,
'-to' => 0,
'-tickinterval' => 50,
'-resolution' => 1,
'-label' => "",
'-font' => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
'-length' => 150,
'-width' => 15,
'-variable' => \$MkOsd{'TargetPos_Alt'},
)->grid ('-row' => $GpsRowAlt +1,
'-column' => $GpsColAlt +2,
);
$MkOsd{'TargetPos_Stat'} = 0;
$cbTargetPos_Stat = $GpsTab->Checkbutton(-text
=> $Translate{'TargetPos_Stat'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$MkOsd{'TargetPos_Stat'},
)->grid (-row
=> $GpsRowStat,
-column
=> $GpsColStat +2,
);
# GPS Alt Home
$GpsTab->Label(-text
=> , $Translate{'HomePos_Alt'},
)->grid ('-row' => $GpsRowAlt,
'-column' => $GpsColAlt +3,
);
$MkOsd{'HomePos_Alt'} = 0;
$scHomePos_Alt = $GpsTab->Scale(
'-orient' => 'vertical',
'-from' => 400,
'-to' => 0,
'-tickinterval' => 50,
'-resolution' => 1,
'-label' => "",
'-font' => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
'-length' => 150,
'-width' => 15,
'-variable' => \$MkOsd{'HomePos_Alt'},
)->grid ('-row' => $GpsRowAlt +1,
'-column' => $GpsColAlt +3,
);
$MkOsd{'HomePos_Stat'} = 0;
$cbHomePos_Stat = $GpsTab->Checkbutton(
-text
=> "Home Status", # $Translate{'HomePos_Stat'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$MkOsd{'HomePos_Stat'},
)->grid (-row
=> $GpsRowStat,
-column
=> $GpsColStat +3,
);
# Sats in Use
$MkOsd{'SatsInUse'} = 0;
$scSatsInUse = $GpsTab->Scale(
'-orient' => 'horizontal',
'-from' => 0,
'-to' => 12,
'-resolution' => 1,
'-tickinterval' => 1,
'-label' => $Translate{'SatsInUse'},
'-font' => '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
'-length' => 300,
'-width' => 15,
'-variable' => \$MkOsd{'SatsInUse'},
)->grid (-row
=> $GpsRowSats,
-column
=> $GpsColSats,
-columnspan
=> 4,
);
# Balloon
my $simballoon = $popup->Balloon();
$simballoon->attach($canvas,
'-balloonposition' => 'mouse',
'-state' => 'balloon',
'-msg' => { 'SimMk' => 'MikroKopter',
'SimTarget' => 'Target',
'SimHome' => 'Home',
},
);
# Mouse button 1 for MK
my $MkOldx = 0;
my $MkOldy = 0;
# Pick MK
$canvas->bind('SimMk' => '<Button-1>' => sub
{
# prepare to move
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
$MkOldx = $x;
$MkOldy = $y;
});
# Move Mk
$canvas->bind('SimMk' => '<Button1-Motion>' => sub
{
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
my $id = $canvas->find('withtag', 'current');
my $Dia2 = $Dia/2;
if ( $x < $Dia2 ) { $x = $Dia2 };
if ( $y < $Dia2 ) { $y = $Dia2 };
if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
$canvas->move($id => $x - $MkOldx, $y - $MkOldy);
$MkOldx = $x;
$MkOldy = $y;
($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
});
# Mouse button 1 for Target
my $TargetOldx = 0;
my $TargetOldy = 0;
# Pick Target
$canvas->bind('SimTarget' => '<Button-1>' => sub
{
# prepare to move
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
$TargetOldx = $x;
$TargetOldy = $y;
});
# Move Target
$canvas->bind('SimTarget' => '<Button1-Motion>' => sub
{
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
my $id = $canvas->find('withtag', 'current');
my $Dia2 = $Dia/2;
if ( $x < $Dia2 ) { $x = $Dia2 };
if ( $y < $Dia2 ) { $y = $Dia2 };
if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
$canvas->move($id => $x - $TargetOldx, $y - $TargetOldy);
$TargetOldx = $x;
$TargetOldy = $y;
($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
});
# Mouse button 1 for Home
my $HomeOldx = 0;
my $HomeOldy = 0;
# Pick Home
$canvas->bind('SimHome' => '<Button-1>' => sub
{
# prepare to move
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
$HomeOldx = $x;
$HomeOldy = $y;
});
# Move Home
$canvas->bind('SimHome' => '<Button1-Motion>' => sub
{
my ($x, $y) = ($Tk::event->x, $Tk::event->y);
my $id = $canvas->find('withtag', 'current');
my $Dia2 = $Dia/2;
if ( $x < $Dia2 ) { $x = $Dia2 };
if ( $y < $Dia2 ) { $y = $Dia2 };
if ( $x > $ImgWidth - $Dia2 ) { $x = $ImgWidth - $Dia2 };
if ( $y > $ImgHeight - $Dia2) { $y = $ImgHeight - $Dia2 };
$canvas->move($id => $x - $HomeOldx, $y - $HomeOldy);
$HomeOldx = $x;
$HomeOldy = $y;
($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'}) = &MapXY2Gps ($x * $ImgScaleX, $y * $ImgScaleY);
});
#
# Tab: Navigation
#
my $NavTab = $book->add( "Navigation", -label
=>"Navigation", );
my $Row = 0;
my $Col = 0;
# Waypoint Index
$MkOsd{'WaypointIndex'} = 0;
$scWaypointIndex = $NavTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 20,
-tickinterval
=> 5,
-resolution
=> 1,
-label
=> $Translate{'WaypointIndex'},
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'WaypointIndex'},
)->grid (-row
=> $Row + 1,
-column
=> $Col,
);
# Waypoint Number
$MkOsd{'WaypointNumber'} = 0;
$scWaypointNumber = $NavTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 20,
-tickinterval
=> 5,
-resolution
=> 1,
-label
=> $Translate{'WaypointNumber'},
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'WaypointNumber'},
)->grid (-row
=> $Row + 2,
-column
=> $Col,
);
# Operating Radius
$MkOsd{'OperatingRadius'} = 250;
$scOperatingRadius = $NavTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 250,
-tickinterval
=> 50,
-resolution
=> 1,
-label
=> "$Translate{'OperatingRadius'} (m)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'OperatingRadius'},
)->grid (-row
=> $Row + 3,
-column
=> $Col,
);
# TargetPosDev_Dist
$MkOsd{'TargetPosDev_Dist'} = 250;
$scTargetPosDev_Dist = $NavTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 500,
-tickinterval
=> 100,
-resolution
=> 1,
-label
=> "$Translate{'TargetPosDev_Dist'} (dm)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'TargetPosDev_Dist'},
)->grid (-row
=> $Row + 4,
-column
=> $Col,
);
#
# Tab: MK
#
my $MkTab = $book->add( "MikroKopter1", -label
=>"MikroKopter 1", );
my $Row = 0;
my $Col = 0;
# Battery
$MkOsd{'UBat'} = 12.6;
$scUBat = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 6.0,
-to
=> 18.0,
-tickinterval
=> 2,
-resolution
=> 0.1,
-label
=> "$Translate{'UBat'} (V)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkOsd{'UBat'},
)->grid (-row
=> $Row,
-column
=> $Col,
);
# RC Quality
$MkOsd{'RC_Quality'} = 190;
$scRC_Quality = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 200,
-tickinterval
=> 50,
-resolution
=> 1,
-label
=> $Translate{'RC_Quality'},
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkOsd{'RC_Quality'},
)->grid (-row
=> $Row +1,
-column
=> $Col,
);
# CompassHeading
$MkOsd{'CompassHeading'} = 0;
$scCompassHeading = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 360,
-tickinterval
=> 45,
-resolution
=> 1,
-label
=> $Translate{'CompassHeading'},
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkOsd{'CompassHeading'},
)->grid (-row
=> $Row +2,
-rowspan
=> 4,
-column
=> $Col,
);
# GPS Groundspeed
$MkOsd{'GroundSpeed'} = 0;
$scGroundSpeed = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 1000,
-tickinterval
=> 200,
-resolution
=> 1,
-label
=> "$Translate{'GroundSpeed'} (dm/s)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkOsd{'GroundSpeed'},
)->grid (-row
=> $Row + 6,
-rowspan
=> 4,
-column
=> $Col,
);
# GPS Speed North
$MkNcDebug{'Analog_21'} = 0;
$scAnalog_21 = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> -1000,
-to
=> 1000,
-tickinterval
=> 400,
-resolution
=> 1,
-label
=> "$Translate{'Analog_21'} (dm/s)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkNcDebug{'Analog_21'},
)->grid (-row
=> $Row + 10,
-rowspan
=> 4,
-column
=> $Col,
);
# GPS Speed East
$MkNcDebug{'Analog_22'} = 0;
$scAnalog_22 = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> -1000,
-to
=> 1000,
-tickinterval
=> 400,
-resolution
=> 1,
-label
=> "$Translate{'Analog_22'} (dm/s)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 200,
-width
=> 15,
-variable
=> \$MkNcDebug{'Analog_22'},
)->grid (-row
=> $Row + 14,
-rowspan
=> 4,
-column
=> $Col,
);
# Variometer
$MkOsd{'Variometer'} = 0;
$scVariometer = $MkTab->Scale(
-orient
=> 'vertical',
-from
=> 30,
-to
=> -30,
-tickinterval
=> 10,
-resolution
=> 1,
-label
=> $Translate{'Variometer'},
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 100,
-width
=> 15,
-variable
=> \$MkOsd{'Variometer'},
)->grid (-row
=> $Row,
-rowspan
=> 2,
-column
=> $Col + 1,
);
my $DataLink = 1;
$cbDataLink = $MkTab->Checkbutton(
-text
=> $Translate{'DataLink'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$DataLink,
)->grid (-row
=> $Row + 2,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
$MkTab->Label(-text
=> "", # space
)->grid (-row
=> $Row +3,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
$MkTab->Label(-text
=> "$Translate{'MKFlags'}: --------",
)->grid (-row
=> $Row +4,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $MkMotorRun = 0;
$cbMkMotorRun = $MkTab->Checkbutton(
-text
=> $Translate{'MkMotorRun'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$MkMotorRun,
)->grid (-row
=> $Row + 5,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $MkFly = 0;
$cbMkFly = $MkTab->Checkbutton(
-text
=> $Translate{'MkFly'},
-variable
=> \$MkFly,
-offvalue
=> 0x00
,
-onvalue
=> 0x02
,
)->grid (-row
=> $Row + 6,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $MkCalibrate = 0;
$cbMkCalibrate = $MkTab->Checkbutton(
-text
=> $Translate{'MkCalibrate'},
-variable
=> \$MkCalibrate,
-offvalue
=> 0x00
,
-onvalue
=> 0x04
,
)->grid (-row
=> $Row + 7,
-column
=> $Col +1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $MkStart = 0;
$cbMkStart = $MkTab->Checkbutton(
-text
=> $Translate{'MkStart'},
-variable
=> \$MkStart,
-offvalue
=> 0x00
,
-onvalue
=> 0x08
,
)->grid (-row
=> $Row + 8,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $MkEmergency = 0;
$cbMkEmergency = $MkTab->Checkbutton(
-text
=> $Translate{'MkEmergency'},
-variable
=> \$MkEmergency,
-offvalue
=> 0x00
,
-onvalue
=> 0x10
,
)->grid (-row
=> $Row + 9,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
$MkTab->Label(-text
=> "$Translate{'NCFlags'}: --------",
)->grid (-row
=> $Row + 10,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagFree = 0;
$cbNcFlagFree = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagFree'},
-offvalue
=> 0x00
,
-onvalue
=> 0x01
,
-variable
=> \$NcFlagFree,
)->grid (-row
=> $Row + 11,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagPH = 0;
$cbNcFlagPH = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagPH'},
-offvalue
=> 0x00
,
-onvalue
=> 0x02
,
-variable
=> \$NcFlagPH,
)->grid (-row
=> $Row + 12,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagCH = 0;
$cbNcFlagCH = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagCH'},
-offvalue
=> 0x00
,
-onvalue
=> 0x04
,
-variable
=> \$NcFlagCH,
)->grid (-row
=> $Row + 13,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagRangeLimit = 0;
$cbNcFlagRangeLimit = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagRangeLimit'},
-offvalue
=> 0x00
,
-onvalue
=> 0x08
,
-variable
=> \$NcFlagRangeLimit,
)->grid (-row
=> $Row + 14,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagNoSerialLink = 0;
$cbNcFlagNoSerialLink = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagNoSerialLink'},
-offvalue
=> 0x00
,
-onvalue
=> 0x10
,
-variable
=> \$NcFlagNoSerialLink,
)->grid (-row
=> $Row + 15,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagTargetReached = 0;
$cbNcFlagTargetReached = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagTargetReached'},
-offvalue
=> 0x00
,
-onvalue
=> 0x20
,
-variable
=> \$NcFlagTargetReached,
)->grid (-row
=> $Row + 16,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
my $NcFlagManualControl = 0;
$cbNcFlagManualControl = $MkTab->Checkbutton(
-text
=> $Translate{'NcFlagManualControl'},
-offvalue
=> 0x00
,
-onvalue
=> 0x40
,
-variable
=> \$NcFlagManualControl
)->grid (-row
=> $Row + 17,
-column
=> $Col + 1,
-sticky
=>'w',
-ipadx
=> 10,
);
#
# Tab: MK 2
#
my $Mk2Tab = $book->add( "MikroKopter2", -label
=>"MikroKopter 2", );
my $Row = 0;
my $Col = 0;
# Current
$MkOsd{'Current'} = 0;
$scCurrent = $Mk2Tab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 50,
-tickinterval
=> 10,
-resolution
=> 1,
-label
=> "$Translate{'Current'} (A)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'Current'},
)->grid (-row
=> $Row,
-column
=> $Col,
);
# Used Capacity
$MkOsd{'UsedCapacity'} = 0;
$scUsedCapacity = $Mk2Tab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 5000,
-tickinterval
=> 1000,
-resolution
=> 50,
-label
=> "$Translate{'UsedCapacity'} (mAh)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$MkOsd{'UsedCapacity'},
)->grid (-row
=> $Row + 1,
-column
=> $Col,
);
#
# Tab: Simulator
#
my $MkTab = $book->add( "Simulator", -label
=>"Simulator", );
my $Row = 0;
my $Col = 0;
# Speed
my $SimSpeed = 20; # km/h
$scSimSpeed = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 50,
-tickinterval
=> 5,
-resolution
=> 1,
-label
=> "Speed (km/h)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$SimSpeed,
)->grid (-row
=> $Row,
-column
=> $Col,
);
# Acceleration
my $SimAcc = 10; # m/s**2
$scSimAcc = $MkTab->Scale(
-orient
=> 'horizontal',
-from
=> 0,
-to
=> 30,
-tickinterval
=> 5,
-resolution
=> 0.5,
-label
=> "Acceleration (m/s**2)",
-font
=> '-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1',
-length => 300,
-width
=> 15,
-variable
=> \$SimAcc,
)->grid (-row
=> $Row +1,
-column
=> $Col,
);
my $Speed = 0; # Current Mk Speed
my $SpeedN = 0; # Speed North
my $SpeedE = 0; # Speed East
#
# Timer
#
my $SimTimebase = 100; # Simulator Timebase in ms
$popup->repeat ($SimTimebase, sub
{
lock
(%MkOsd); # until end of block
$MkOsd{'MKFlags'} = $MkMotorRun | $MkFly | $MkCalibrate | $MkStart | $MkEmergency;
$MkOsd{'NCFlags'} = $NcFlagFree | $NcFlagPH | $NcFlagCH | $NcFlagRangeLimit |
$NcFlagNoSerialLink | $NcFlagTargetReached | $NcFlagManualControl;
# Calibration sequence
if ( $CalibCount > 0 )
{
$CalibCount ++;
}
if ( $CalibCount > 2 * 1000 / $SimTimebase ) # 2s
{
$cbMkCalibrate-> deselect();
$cbMkStart->deselect();
$cbMkMotorRun->select();
$cbMkFly->select();
$CalibCount = 0;
}
#
# Simulator
#
if ( $Simulator =~ /ON/i and
$MkSim{'Target_Lat'} ne "" and $MkSim{'Target_Lon'} ne "" )
{
# Set Target-Pos
$MkOsd{'TargetPos_Lat'} = $MkSim{'Target_Lat'};
$MkOsd{'TargetPos_Lon'} = $MkSim{'Target_Lon'};
$MkOsd{'TargetPos_Alt'} = $MkSim{'Target_Alt'};
$MkOsd{'TargetPos_Stat'} = 1;
my ($HomeDist, $HomeBearing) = &MapGpsTo($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'},
$MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'} );
if ( $HomeDist > $MkOsd{'OperatingRadius'} )
{
# Target entsprechend Operation Radius neu berechnen
$HomeDist = $MkOsd{'OperatingRadius'};
($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'}) = &MapGpsAt($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'},
$HomeDist, $HomeBearing);
$cbNcFlagRangeLimit->select;
}
else
{
$cbNcFlagRangeLimit->deselect;
}
#
# Mk physics
# Move MK to Target with constant acceleration
#
my ($Dist, $Bearing) = &MapGpsTo($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'},
$MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'} );
$MkOsd{'TargetPosDev_Dist'} = $Dist * 10; # in dm
$MkOsd{'TargetPosDev_Bearing'} = $Bearing;
my $AccN = $SimAcc * cos (deg2rad
$Bearing); # Acceleration North
my $AccE = $SimAcc * sin (deg2rad
$Bearing); # Acceleration East
my $t = $SimTimebase / 1000;
$SpeedN = $SpeedN + $AccN * $t; # Speed North
$SpeedE = $SpeedE + $AccE * $t; # Speed East
$Speed = sqrt ($SpeedN * $SpeedN + $SpeedE * $SpeedE);
if ( $Speed >= $SimSpeed/3.6 )
{
# Limit maximum Speed
my $SpeedBearing = rad2deg
atan2 ($SpeedE, $SpeedN);
$SpeedN = $SimSpeed/3.6 * cos (deg2rad
$SpeedBearing);
$SpeedE = $SimSpeed/3.6 * sin (deg2rad
$SpeedBearing);
$Speed = $SimSpeed/3.6;
}
my $BreakDist = 5;
if ( $Dist <= $BreakDist )
{
$Speed = $SimSpeed/3.6 - $SimSpeed/3.6 * (1 - $Dist/$BreakDist);
my $SpeedBearing = rad2deg
atan2 ($SpeedE, $SpeedN);
$SpeedN = $Speed * cos (deg2rad
$SpeedBearing);
$SpeedE = $Speed * sin (deg2rad
$SpeedBearing);
$AccN = 0;
$AccE = 0;
}
# Distance to go in this loop
my $GoDistN = $SpeedN * $t + 0.5 * $AccN * $t * $t;
my $GoDistE = $SpeedE * $t + 0.5 * $AccE * $t * $t;
my $GoDist = sqrt ( $GoDistN * $GoDistN + $GoDistE * $GoDistE);
my $GoBearing = rad2deg
atan2 ($GoDistE, $GoDistN);
if ($GoDist > 0 )
{
($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'}) = &MapGpsAt($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'},
$GoDist, $GoBearing);
}
if ( $Dist < $MkSim{'Target_ToleranceRadius'} )
{
$cbNcFlagTargetReached -> select();
}
else
{
$cbNcFlagTargetReached -> deselect();
}
# GPS Groundspeed, North, East
$MkOsd{'GroundSpeed'} = $Speed * 100; # dm/s
$MkNcDebug{'Analog_21'} = $SpeedN * 100;
$MkNcDebug{'Analog_22'} = $SpeedE * 100;
# Heading
if ( $MkSim{'Target_Heading'} != 0 )
{
$scCompassHeading -> set($MkSim{'Target_Heading'});
}
}
# update display
$scAnalog_21 -> set($MkNcDebug{'Analog_21'});
$scAnalog_22 -> set($MkNcDebug{'Analog_22'});
$scTargetPos_Alt -> set($MkOsd{'TargetPos_Alt'});
$scTargetPosDev_Dist -> set ($MkOsd{'TargetPosDev_Dist'});
$scGroundSpeed -> set($MkOsd{'GroundSpeed'});
$scWaypointNumber -> set ($MkOsd{'WaypointNumber'});
$scWaypointIndex -> set ($MkOsd{'WaypointIndex'});
# move MK symbol on canvas
my ($x, $y) = &MapGps2XY ($MkOsd{'CurPos_Lat'}, $MkOsd{'CurPos_Lon'});
$x = $x / $ImgScaleX;
$y = $y / $ImgScaleY;
$canvas->coords ('SimMk', $x, $y, $x + $Dia, $y + $Dia);
# move Home symbol on canvas
my ($x, $y) = &MapGps2XY ($MkOsd{'HomePos_Lat'}, $MkOsd{'HomePos_Lon'});
$x = $x / $ImgScaleX;
$y = $y / $ImgScaleY;
$canvas->coords ('SimHome', $x, $y, $x + $Dia, $y + $Dia);
# move Target symbol on canvas
my ($x, $y) = &MapGps2XY ($MkOsd{'TargetPos_Lat'}, $MkOsd{'TargetPos_Lon'});
$x = $x / $ImgScaleX;
$y = $y / $ImgScaleY;
$canvas->coords ('SimTarget', $x, $y, $x + $Dia, $y + $Dia);
if ( $DataLink)
{
# Timestamp, wann der Datensatz geschrieben wurde
$MkOsd{'_Timestamp'} = time;
}
});
}
# Make MK Fly
sub CbSimMkFly
{
$scWaypointIndex->set(5);
$scWaypointNumber->set(10);
$cbNcFlagCH->select();
# start calibration sequence
$cbMkCalibrate-> select();
$cbMkStart->select();
$CalibCount = 1;
}
# 3D Fix
sub CbSim3DFix
{
my $Alt = 50;
$scCurPos_Alt->set($Alt);
$scAltimeter->set($Alt * $Cfg->{'mkcockpit'}->{'AltFactor'});
$scSatsInUse->set(10);
$cbCurPos_Stat->select();
$cbTargetPos_Stat->select();
$cbHomePos_Stat->select();
# Set Home-Pos to Cur-Pos
$MkOsd{'HomePos_Lat'} = $MkOsd{'CurPos_Lat'};
$MkOsd{'HomePos_Lon'} = $MkOsd{'CurPos_Lon'};
$scGroundSpeed->set(400);
$scAnalog_21->set(10);
$scAnalog_22->set(10);
}
# Switch Simulator ON
sub CbSimStart
{
$Simulator = "ON";
# Only one Target from Player
$MkOsd{'WaypointNumber'} = 1;
$MkOsd{'WaypointIndex'} = 0;
}
# Switch Simulator OFF
sub CbSimStop
{
$Simulator = "OFF";
# switch on logging
$MkOsd{'_Timestamp'} = 0;
$LogQueue->enqueue( "LOG" );
}
1;
__END__