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; } }
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; } }
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; } }
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)); } }
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; } }
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; } } } }
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(); }