Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 654 → Rev 655

/MissionCockpit/tags/V0.2.7/libmksim.pl
0,0 → 1,1067
#!/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
#
###############################################################################
 
$Version{'libmksim.pl'} = "0.0.1 - 2009-10-10";
 
my $Simulator = "OFF";
 
sub MkSim()
{
my $popup = $main->Toplevel();
$popup->title("MikroKopter Simulator");
 
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
{
$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->{'mksim'}->{'ImageSize'}";
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( "MikroKopter", -label=>"MikroKopter", );
 
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: 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 )
{
# Set Target-Pos
$MkOsd{'TargetPos_Lat'} = $MkSim{'Target_Lat'};
$MkOsd{'TargetPos_Lon'} = $MkSim{'Target_Lon'};
$MkOsd{'TargetPos_Alt'} = $MkSim{'Target_Alt'};
$MkOsd{'TargetPos_Status'} = 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";
}
 
1;
 
__END__