コード例 #1
0
        internal void OnAltidudeDataSampled(int id)
        {
            if (_mcp.AltitudeHold)
            {
                var altitudeDelta = _mcp.ALT - Timeline.AltitudeAvg;
                var mult          = 10;
                if (SystemManager.Instance.Nav.IsOnGlidePath)
                {
                    mult = 6;
                }
                _mcp.VS = Math2.Clamp(altitudeDelta / mult, -15, 20);

                Timeline.Data[id].Altitude.SetpointValue = _mcp.ALT;
            }
        }
コード例 #2
0
        internal void OnRollDataSampled(int id)
        {
            if (double.IsNaN(Timeline.Heading))
            {
                return;
            }

            if (_mcp.BankHold | _mcp.HeadingHold | _mcp.LNAV)
            {
                if (!double.IsNaN(Timeline.Data[id].Roll.Value))
                {
                    if (_mcp.HeadingHold | _mcp.LNAV)
                    {
                        var rollDelta = Math2.DiffAngles(Timeline.Heading, _mcp.HDG) * 0.7;

                        var rollMax = 25;
                        if (Math.Abs(rollDelta) > 5)
                        {
                            // if (SystemManager.Instance.Nav.IsOnGlidePath90) rollMax = 0;

                            var newRoll = Math2.Clamp(-1 * rollDelta, -1 * rollMax, rollMax);
                            _mcp.Bank += (_mcp.Bank > newRoll) ? -.15 : .15;

                            if (Timeline.Altitude < 800)
                            {
                                _mcp.Bank = 0;
                            }
                        }
                        else
                        {
                            _mcp.Bank = 0;
                        }
                    }

                    var rollValue = Timeline.LatestAvg(3, f => f.Roll.Value, id);
                    var output    = _rollPid.Compute(
                        rollValue,
                        _mcp.Bank,
                        GetTimeBetweenThisFrameAndLastGoodFrame(id, (f) => f.Roll.Value));

                    _control.Set(XINPUT_GAMEPAD_AXIS.LEFT_THUMB_X, (int)RemoveDeadZone(output, 8500, 9500));

                    Timeline.Data[id].Roll.OutputValue = output;
                }
                Timeline.Data[id].Roll.SetpointValue = _mcp.Bank;
            }
        }
コード例 #3
0
        public static void Load(string filePath)
        {
            var lines = System.IO.File.ReadAllLines(filePath);

            for (var i = 0; i < lines.Length; i++)
            {
                var d = Data[i] = new TimelineFrame {
                    Id = i
                };

                var parts = lines[i].Split(',');
                d.Seconds        = double.Parse(parts[0]);
                d.Roll.Value     = double.Parse(parts[1]);
                d.Pitch.Value    = double.Parse(parts[2]);
                d.Speed.Value    = double.Parse(parts[3]);
                d.Altitude.Value = double.Parse(parts[4]);
                d.Heading.Value  = Math2.SafeAddAngle(double.Parse(parts[5]), 0);
                CompleteFrame(i);
                LatestFrameId = i;
            }
        }
コード例 #4
0
        private void AddPosition(Point pt, bool save = true)
        {
            double heading = double.NaN;

            if (lastPoint != default(Point))
            {
                var l = new Line
                {
                    X1 = pt.X,
                    Y1 = pt.Y,
                    X2 = lastPoint.X,
                    Y2 = lastPoint.Y
                };
                l.Stroke          = Brushes.Blue;
                l.StrokeThickness = 1;
                canvas.Children.Insert(canvas.Children.Count - 1, l);

                heading = Math2.GetPolarHeadingFromLine(pt.ToPointF(), lastPoint.ToPointF());
            }

            Ellipse dot = new Ellipse();

            dot.Fill   = Brushes.Red;
            dot.Height = dot.Width = 2;
            Canvas.SetTop(dot, pt.Y - dot.Height / 2);
            Canvas.SetLeft(dot, pt.X - dot.Width / 2);
            canvas.Children.Add(dot);
            lastPoint = pt;

            if (save)
            {
                Positions.Add(new Position {
                    pt = pt
                });
                Points.Add(new System.Drawing.PointF((float)pt.X * Metrics.SCALE_Map4_20_TO_100, (float)pt.Y * Metrics.SCALE_Map4_20_TO_100));
            }
        }
コード例 #5
0
        private void Update()
        {
            var didAdvanceWaypoint = _plan.UpdateLocation();

            if (didAdvanceWaypoint && _plan.CurrentIndex == 3)
            {
                Trace.WriteLine("Gear up");
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.LEFT_THUMB, 10);
            }

            // One waypoint before top of G/P
            if (didAdvanceWaypoint && _plan.CurrentIndex == _plan.Points.Count - 3)
            {
                _mcp.ALT        = 800;
                _mcp.IAS        = 80;
                glidePathTopAlt = _mcp.ALT;
            }

            if (didAdvanceWaypoint && IsOnGlideToThreshold)
            {
                isAt75PercentGlide = false;
                isAt4PercentGlide  = false;
                isAt3PercentGlide  = false;
                isFlare            = false;
                Timeline.UpdateLocationFromMenu();
            }

            if (IsOnGlideToThreshold)
            {
                var percent_done = OnGlidePathPercent();

                if (percent_done < .7 && !isAt75PercentGlide)
                {
                    isAt75PercentGlide = true;

                    Timeline.UpdateLocationFromMenu();
                }

                if (percent_done < .5 && !isAt3PercentGlide)
                {
                    isAt3PercentGlide = true;
                    Trace.WriteLine("Gear down");
                    SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.LEFT_THUMB, 10);
                }

                if (percent_done < .3 && !isAt4PercentGlide)
                {
                    isAt4PercentGlide = true;

                    Timeline.UpdateLocationFromMenu();
                }


                _mcp.ALT = Math.Round(Math2.MapValue(0, 1, _plan.Destination.Elevation, glidePathTopAlt, percent_done));
            }

            // Flare
            if (_plan.CurrentIndex == _plan.Points.Count - 1)
            {
                _mcp.ALT = _plan.Destination.Elevation;


                if (!isFlare && Timeline.AltitudeAvg < _plan.Destination.Elevation + 25)
                {
                    Trace.WriteLine("Flare");
                    isFlare     = true;
                    _mcp.IAS    = 0;
                    _mcp.VSHold = true;
                    _mcp.VS     = 10;
                }
            }

            // Disconnect
            if (_mcp.IASHold && _plan.CurrentIndex == _plan.Points.Count - 1 &&
                Timeline.Speed < 20)
            {
                if (_mcp.LNAV)
                {
                    Timeline.ResetGameFromSavePointByMenu();
                }

                _mcp.IASHold = false;
                _mcp.VSHold  = false;
                _mcp.LNAV    = false;
            }

            if (_mcp.LNAV)
            {
                var targetHdg = _plan.TargetHeading;

                if (_plan.CurrentIndex > 0)
                {
                    var tightHoldLine = (Timeline.Altitude < 800) ||
                                        (_plan.CurrentIndex >= _plan.Points.Count - 2);
                    var heading_cap = 8;

                    var mult = (tightHoldLine ? 1.5 : 0.5);
                    if (Timeline.Altitude < 150)
                    {
                        mult = 2;
                    }

                    var distanceFromTargetLine = mult * DistanceFromTargetLine;
                    distanceFromTargetLine = Math.Max(Math.Min(heading_cap, distanceFromTargetLine), -1 * heading_cap);

                    targetHdg -= distanceFromTargetLine;
                }
                _mcp.HDG = targetHdg;
            }
        }
コード例 #6
0
        public void Tick()
        {
            if (Indicator != null)
            {
                double current_x = Width - 1;
                double x_size    = 250f / NUM_FRAMES;

                zeroLine.X1 = 0;
                zeroLine.X2 = Width;
                zeroLine.Y1 = Height / 2;
                zeroLine.Y2 = Height / 2;

                topLine.X1 = 0;
                topLine.X2 = Width;
                topLine.Y1 = 0;
                topLine.Y2 = 0;

                bottomLine.X1 = 0;
                bottomLine.X2 = Width;
                bottomLine.Y1 = Height;
                bottomLine.Y2 = Height;

                bottomText.Text = "" + GetRangeForIndicator()[0];
                topText.Text    = "" + GetRangeForIndicator()[1];

                Canvas.SetTop(topText, 4);
                Canvas.SetLeft(topText, 4);

                Canvas.SetTop(bottomText, Height - 20);
                Canvas.SetLeft(bottomText, 4);

                int           childIndex = SKIP_LINES + NUM_FRAMES;
                TimelineFrame last       = null;
                for (var i = Timeline.LatestFrameId; i >= 0 && i > Timeline.LatestFrameId - NUM_FRAMES; i--)
                {
                    var current = Timeline.Data[i];
                    if (last == null || current == null)
                    {
                        last = current;
                    }
                    else
                    {
                        var l = (Line)Children[childIndex];
                        var s = (Line)Children[childIndex - NUM_FRAMES];

                        if (!double.IsNaN(GetValueForIndicator(current)) && !double.IsNaN(GetValueForIndicator(last)))
                        {
                            l.Stroke = Brushes.Blue;

                            if (Type == IndicatorChartType.Delay)
                            {
                                if (GetValueForIndicator(current) > 0.2)
                                {
                                    l.Stroke = Brushes.Red;
                                }
                                else
                                {
                                    l.Stroke = Brushes.Green;
                                }
                            }


                            l.X1 = current_x;
                            l.X2 = current_x - x_size;
                            l.Y2 = Math2.MapValue(GetRangeForIndicator()[0], GetRangeForIndicator()[1], Height, 0, GetValueForIndicator(current));
                            l.Y1 = Math2.MapValue(GetRangeForIndicator()[0], GetRangeForIndicator()[1], Height, 0, GetValueForIndicator(last));
                        }
                        else
                        {
                            if (Type == IndicatorChartType.Value)
                            {
                                s.X1 = s.X2 = s.Y1 = s.Y2 = 0;
                            }

                            if (Type != IndicatorChartType.InputOutput)
                            {
                                l.Stroke = Brushes.Gray;
                                l.X1     = current_x;
                                l.X2     = current_x;
                                l.Y1     = 0;
                                l.Y2     = Height;
                            }
                            else
                            {
                                l.X1 = l.X2 = l.Y1 = l.Y2 = 0;
                            }
                        }

                        if (Type == IndicatorChartType.Value || Type == IndicatorChartType.InputOutput)
                        {
                            s.X1 = current_x;
                            s.X2 = current_x - x_size;

                            if (!double.IsNaN(GetSetPointForIndicator(current)) && !double.IsNaN(GetSetPointForIndicator(last)))
                            {
                                s.Y1 = Math2.MapValue(GetRangeForIndicator()[0], GetRangeForIndicator()[1], Height, 0, GetSetPointForIndicator(current));
                                s.Y2 = Math2.MapValue(GetRangeForIndicator()[0], GetRangeForIndicator()[1], Height, 0, GetSetPointForIndicator(last));
                            }
                            else
                            {
                                s.X1 = s.X2 = s.Y1 = s.Y2 = 0;
                            }
                        }

                        current_x = current_x - x_size;
                        childIndex++;
                        last = current;
                    }
                }
            }
        }
コード例 #7
0
        public static void ResetGameFromSavePointByMenu()
        {
            IsInGame = false;

            new Thread(() =>
            {
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.START, 10);
                SystemManager.Instance.App.Controller.Flush();
                while (!SystemManager.Instance.IndicatorHost.Menu.IsInMenu)
                {
                    Thread.Sleep(100);
                }


                Thread.Sleep(800);
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();
                Thread.Sleep(1200);

                var location = SystemManager.Instance.IndicatorHost.Menu.Location;
                while (location == default(PointF))
                {
                    //      Trace.WriteLine("wait for location");
                    Thread.Sleep(400);
                    location = SystemManager.Instance.IndicatorHost.Menu.Location;
                }

                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.B, 10);
                SystemManager.Instance.App.Controller.Flush();
                Thread.Sleep(900);

                var line = new LineSegment2DF(Timeline.CurrentLocation, location);
                Trace.WriteLine($"MOVE: {Math.Round(line.Length)} {Math.Round(Math2.GetPolarHeadingFromLine(line))}");
                Trace.WriteLine($"Location: {location}");



                //   Trace.WriteLine("now in menu!");

                while (!SystemManager.Instance.IndicatorHost.Menu.SelectedMenuItem.Contains("GAME"))
                {
                    //   Trace.WriteLine("SELECTED: " + SystemManager.Instance.IndicatorHost.Menu.SelectedMenuItem);
                    SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.DPAD_LEFT, 10);
                    SystemManager.Instance.App.Controller.Flush();
                    Thread.Sleep(500);
                }

                //   Trace.WriteLine("now in game!");
                Thread.Sleep(200);
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();

                //  Trace.WriteLine("now game menu list");


                while (SystemManager.Instance.IndicatorHost.Menu.SelectedGameMenuItem != "LOADGAME")
                {
                    //        Trace.WriteLine("SELECTED: " + SystemManager.Instance.IndicatorHost.Menu.SelectedGameMenuItem);
                    SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.DPAD_DOWN, 10);
                    SystemManager.Instance.App.Controller.Flush();

                    Thread.Sleep(500);
                }

                //  Trace.WriteLine("now save list");

                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();
                Thread.Sleep(800);
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();
                Thread.Sleep(800);
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();
                Thread.Sleep(800);
                SystemManager.Instance.App.Controller.Press(Interop.XINPUT_GAMEPAD_BUTTONS.A, 10);
                SystemManager.Instance.App.Controller.Flush();

                //   Trace.WriteLine("now game should be loading");

                while (!SystemManager.Instance.IndicatorHost.Loading.IsLoading)
                {
                    //     Trace.WriteLine("wait for loading " + SystemManager.Instance.IndicatorHost.Loading.LoadingTextRead);

                    Thread.Sleep(1000);
                }

                //   Trace.WriteLine("confirm loading!");

                while (SystemManager.Instance.IndicatorHost.Loading.IsLoading)
                {
                    //      Trace.WriteLine("wait for no loading " + SystemManager.Instance.IndicatorHost.Loading.LoadingTextRead);

                    Thread.Sleep(1000);
                }

                SystemManager.Instance.FlightPlan.CurrentIndex = 0;
                Reset();

                Trace.WriteLine("GAME READY!");
                Timeline.Begin();

                Thread.Sleep(2000);

                SystemManager.Instance.MCP.IAS          = 120;
                SystemManager.Instance.MCP.ALT          = 1200;
                SystemManager.Instance.MCP.AltitudeHold = true;
                SystemManager.Instance.MCP.LNAV         = true;
                SystemManager.Instance.MCP.IASHold      = true;
            }).Start();
        }