示例#1
0
        private void updateLandingRoll(APIAircraftState state)
        {
            if (_pLastState == null)
            {
                _pLastState = state;
            }
            else if (!state.IsOnGround)
            {
                _pLastState                    = state;
                _pLastLandingRoll              = 0.0;
                _pLandingLocation              = null;
                _txtLandingRoll.IsVisible      = false;
                _txtLandingRollLabel.IsVisible = false;
                //btnViewLandingStats.Visibility = Visibility.Hidden;
            }
            else if (!_pLastState.IsLanded && state.IsLanded
                     ) //Just transitioned to "landed" state, so start the roll accumulation
            {
                _pLandingLocation          = state.Location;
                _pStateJustBeforeTouchdown = _pLastState;
                _pStateJustAfterTouchdown  = state;
                _pLastState = state;
            }
            else if (state.IsLanded && _pLandingLocation != null) //We are in landed state. Calc the roll length.
            {
                var currentPosition = state.Location;
                var R    = 3959; // Radius of the earth in miles
                var dLat = (currentPosition.Latitude - _pLandingLocation.Latitude) * (Math.PI / 180);
                var dLon = (currentPosition.Longitude - _pLandingLocation.Longitude) * (Math.PI / 180);
                var a    =
                    Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
                    Math.Cos(currentPosition.Latitude * (Math.PI / 180)) *
                    Math.Cos(_pLandingLocation.Latitude * (Math.PI / 180)) *
                    Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
                ;
                var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
                var d = R * c; // Distance in miles
                d *= 5280;     //Distance in ft
                _txtLandingRoll.Text           = string.Format("{0:0.00}", d) + " ft";
                _txtLandingRoll.IsVisible      = true;
                _txtLandingRollLabel.IsVisible = true;
                _pLastState = state;
                _landingDetails.updateLandingStats(_pLandingLocation, _pAircraftState.Location,
                                                   _pStateJustBeforeTouchdown, _pStateJustAfterTouchdown, "");
            }

            if (_pLandingLocation != null && state.IsLanded && state.IsOnGround && state.GroundSpeedKts < 10)
            {
                _pLandingStatDlg = new LandingStats();
                _pLandingStatDlg.updateLandingStats(_pLandingLocation, _pAircraftState.Location,
                                                    _pStateJustBeforeTouchdown, _pStateJustAfterTouchdown, "");
                _landingDetails.updateLandingStats(_pLandingLocation, _pAircraftState.Location,
                                                   _pStateJustBeforeTouchdown, _pStateJustAfterTouchdown, "");
                //btnViewLandingStats.Visibility = Visibility.Visible;
            }
        }
示例#2
0
        public void updateLandingStats(Coordinate touchdownPosition, Coordinate positionAtEndOfRoll,
                                       APIAircraftState stateJustBeforeTouchdown, APIAircraftState stateJustAfterTouchdown, string aircraftType)
        {
            pTouchdownInfo = new touchdownInfo();
            pTouchdownInfo.touchdownGroundSpeed = stateJustBeforeTouchdown.GroundSpeedKts;
            pTouchdownInfo.touchdownIAS         = stateJustBeforeTouchdown.IndicatedAirspeedKts;
            pTouchdownInfo.touchdownPitch       = stateJustBeforeTouchdown.Pitch;
            pTouchdownInfo.touchdownGforce      = stateJustBeforeTouchdown.GForce > stateJustAfterTouchdown.GForce
                ? stateJustBeforeTouchdown.GForce
                : stateJustAfterTouchdown.GForce;
            pTouchdownInfo.touchdownVS  = stateJustBeforeTouchdown.VerticalSpeed;
            pTouchdownInfo.wasStalling  = stateJustBeforeTouchdown.Stalling;
            pTouchdownInfo.wasNearStall = stateJustBeforeTouchdown.StallWarning;
            pTouchdownInfo.wasOverMLW   = stateJustBeforeTouchdown.IsOverLandingWeight;

            pTouchdownInfo.rollDistance = calcRollDistance(touchdownPosition, positionAtEndOfRoll);

            _gridLandingStats.DataContext = pTouchdownInfo;
        }
示例#3
0
        public void performHold(APIAircraftState acState)
        {
            pAircraftState = acState;
            Double degChg = 0;

            switch (holdLeg)
            {
            case 0:
                //Get initial fix and heading
                if (initialHoldStart == null)
                {
                    initialHoldStart = pAircraftState.Location;
                }
                if (initialHdg == -1)
                {
                    initialHdg = pAircraftState.HeadingMagnetic;
                }

                //turn to back-bearing
                backBearing = initialHdg < 180 ? initialHdg + 180 : initialHdg - 180;
                if (lblHoldInfo.Content.ToString() != ("Holding: Turn " + Math.Floor(backBearing).ToString()))
                {
                    lblHoldInfo.Content = ("Holding: Turn " + Math.Floor(backBearing).ToString());
                }

                if (!hdgSetComplete)
                {
                    hdgSet = initialHdg;
                }
                degChg = 0;
                while (Math.Abs(hdgSet - Math.Floor(backBearing)) > 5)
                {
                    if (leftTurns)
                    {
                        hdgSet -= 45;
                    }
                    else
                    {
                        hdgSet += 45;
                    }
                    hdgSet %= 360;
                    setAutoPilotParams(-1, Math.Floor(hdgSet), 999999, -1);
                    degChg = 0;
                    // while degChg < requiredchange then wait
                    System.Threading.Thread.Sleep(15000);
                }
                setAutoPilotParams(-1, backBearing, 999999, -1);
                hdgSetComplete = true;
                if (Math.Abs(Math.Floor(pAircraftState.HeadingMagnetic) - Math.Floor(backBearing)) < 2)
                {       //hit backbearing
                    setAutoPilotParams(-1, backBearing, 999999, -1);
                    leg2start = pAircraftState.Location;
                    holdLeg   = 1;
                }
                break;

            case 1:
                //maintain back-bearing for legLength
                if (lblHoldInfo.Content.ToString() != ("Holding: Leg 1"))
                {
                    lblHoldInfo.Content = "Holding: Leg 1";
                }
                double err = acState.CourseTrue - acState.HeadingTrue;
                setAutoPilotParams(-1, backBearing - err, 999999, -1);
                hdgSetComplete = false;
                if (getDistBtwnPoints(leg2start, pAircraftState.Location) > legLength)
                {
                    holdLeg = 2;
                }
                break;

            case 2:
                //turn back to initial heading
                if (lblHoldInfo.Content.ToString() != ("Holding: Turn " + Math.Floor(initialHdg).ToString()))
                {
                    lblHoldInfo.Content = ("Holding: Turn " + Math.Floor(initialHdg).ToString());
                }
                degChg = 0;
                while (Math.Abs(hdgSet - Math.Floor(initialHdg)) > 1)
                {
                    if (leftTurns)
                    {
                        hdgSet -= 90;
                    }
                    else
                    {
                        hdgSet += 90;
                    }
                    hdgSet %= 360;

                    setAutoPilotParams(-1, hdgSet, 999999, -1); degChg = 0;
                    System.Threading.Thread.Sleep(2000);
                }
                setAutoPilotParams(-1, initialHdg, 999999, -1);
                hdgSetComplete = true;
                if (Math.Abs(Math.Floor(pAircraftState.HeadingMagnetic) - Math.Floor(initialHdg)) < 2)
                {
                    //hit initial hdg
                    setAutoPilotParams(-1, initialHdg, 999999, -1);
                    //initialHoldStart = pAircraftState.Location;
                    holdLeg = 3;
                }
                break;

            case 3:
                //Maintain initial heading for legLength back to the hold fix
                if (lblHoldInfo.Content.ToString() != "Holding: To Fix")
                {
                    lblHoldInfo.Content = "Holding: To Fix";
                }
                hdgSetComplete = false;

                //if (getDistBtwnPoints(initialHoldStart, pAircraftState.Location) > legLength) { holdLeg = 1; }
                //Fly to initial Fix
                double declination = acState.HeadingTrue - acState.HeadingMagnetic;
                double hdg         = getHeadingToPoint(pAircraftState.Location, initialHoldStart) - declination;
                err = acState.CourseTrue - acState.HeadingTrue;
                setAutoPilotParams(-1, hdg - err, 999999, -1);
                if (getDistBtwnPoints(initialHoldStart, pAircraftState.Location) < 0.25)
                {
                    holdLeg = 0;
                }
                break;

            default:
                break;
            }

            return;
        }
示例#4
0
        public void handleAtcMessage(APIATCMessage AtcMsg, APIAircraftState acState)
        {
            logMessage(AtcMsg.Message);
            //Only act on messages received by us that are directed at us.
            if (AtcControlledAutopilotEnabled == true && AtcMsg.Received && AtcMsg.Message.Contains(Callsign))
            {
                string msg = AtcMsg.Message.ToLower(); //Just to make things easier

                //Heading
                if (msg.Contains("heading"))
                {
                    Match mtch = Regex.Match(msg, "heading\\W+(?<hdg>\\d+)");
                    if (mtch.Success)
                    {
                        string sHdg = mtch.Groups["hdg"].Value;
                        double hdg  = Convert.ToDouble(sHdg);
                        setHeading(hdg);
                    }
                }

                //Altitude
                if (msg.Contains("descend") || msg.Contains("climb"))
                {
                    Match mtch = Regex.Match(msg, "maintain\\W+(?<fl>FL)*(?<alt>\\d+,*\\d+)(ft)*");
                    if (mtch.Success)
                    {
                        double alt = 1000.0;
                        if (mtch.Groups["fl"].Success) //Convert flight level
                        {
                            alt = Convert.ToDouble(mtch.Groups["alt"].Value) * 100;
                        }
                        else //Else it is just in ft, but remove comma
                        {
                            alt = Convert.ToDouble(mtch.Groups["alt"].Value.Replace(",", ""));
                        }
                        if (msg.Contains("descend"))
                        {
                            setAltitude(alt, -1800);
                        }
                        else
                        {
                            setAltitude(alt, 1800);
                        }
                    }
                }

                //Speed
                if (msg.Contains("kts"))
                {
                    Match mtch = Regex.Match(msg, "\\W+(?<speed>\\d+)kts");
                    if (mtch.Success)
                    {
                        double speed = Convert.ToDouble(mtch.Groups["speed"].Value);
                        if (msg.Contains("do not exceed"))
                        {
                            speed -= 5;
                        }
                        setSpeed(speed);
                        if (acState.IndicatedAirspeedKts > (speed + 30))
                        {
                            client.ExecuteCommand("Commands.Spoilers");
                        }
                    }
                }

                //Acknowledge ATC
                client.ExecuteCommand("Commands.ATCEntry2");
                if (msg.Contains("contact") && !msg.Contains("exit runway"))
                {
                    //contact next freq if handed off (but not if exiting runway to contact gnd)
                    client.ExecuteCommand("Commands.ATCEntry2"); //send & switch on second menu
                }
            }
        }
示例#5
0
        public void updateAutoNav(APIAircraftState acState)
        {
            if (pFplState == null)
            {
                client.ExecuteCommand("FlightPlan.GetFlightPlan");
            }

            //Set initial next waypoint as first waypoint
            if (pFplState.nextWpt == null)
            {
                pFplState.legIndex     = 0;
                pFplState.nextWpt      = pFplState.fpl.Waypoints[1];
                pFplState.dest         = pFplState.fpl.Waypoints.Last();
                pFplState.nextAltitude = pFplState.fplDetails.waypoints[pFplState.legIndex + 1].Altitude;
                pFplState.thisSpeed    = pFplState.fplDetails.waypoints[pFplState.legIndex].Airspeed;
                pFplState.nextSpeed    = pFplState.fplDetails.waypoints[pFplState.legIndex + 1].Airspeed;
            }

            //Get dist to next wpt
            pFplState.distToNextWpt = getDistToWaypoint(acState.Location, pFplState.nextWpt);

            //If dist<2nm, go to next wpt
            if (pFplState.distToNextWpt < 2)
            {
                pFplState.legIndex++;                  //next leg
                pFplState.prevWpt = pFplState.nextWpt; //current wpt is not prev wpt
                if (pFplState.legIndex >= pFplState.fpl.Waypoints.Count())
                {
                    //We hit the destination!
                    lblNextWpt.Content   = "Destination Reached!";
                    lblDist2Next.Content = "";
                    lblHdg2Next.Content  = "";
                    autoFplDirectActive  = false;
                    return;
                }
                pFplState.nextWpt      = pFplState.fpl.Waypoints[pFplState.legIndex]; //target next wpt
                pFplState.nextAltitude = pFplState.fplDetails.waypoints[pFplState.legIndex].Altitude;
                pFplState.thisSpeed    = pFplState.fplDetails.waypoints[pFplState.legIndex - 1].Airspeed;
                pFplState.nextSpeed    = pFplState.fplDetails.waypoints[pFplState.legIndex].Airspeed;
                //Get dist to new next wpt
                pFplState.distToNextWpt = getDistToWaypoint(acState.Location, pFplState.nextWpt);
            }

            lblNextWpt.Content     = pFplState.nextWpt.Name;
            lblDist2Next.Content   = String.Format("{0:0.000}", pFplState.distToNextWpt);
            lblAirspeedSet.Content = String.Format("{0:0.000}", pFplState.thisSpeed);
            lblAltitudeSet.Content = pFplState.nextAltitude.ToString();

            //Adjust heading for magnetic declination
            double declination = acState.HeadingTrue - acState.HeadingMagnetic;

            //Get heading to next
            pFplState.hdgToNextWpt = getHeadingToWaypoint(acState.Location, pFplState.nextWpt) - declination;
            lblHdg2Next.Content    = String.Format("{0:0.000}", pFplState.hdgToNextWpt);

            //Calculate VS to hit target altitude
            if (pFplState.nextAltitude > 0)
            {
                //double vs = calcVs(acState.AltitudeMSL, pFplState.nextAltitude, acState.GroundSpeedKts, pFplState.distToNextWpt);
                double vs       = 0;
                var    airspeed = pFplState.thisSpeed;
                if (airspeed > 0 && airspeed <= 60)
                {
                    vs = 700;
                }
                else if (airspeed > 60 && airspeed <= 160)
                {
                    vs = 1100;
                }
                else if (airspeed > 160 && airspeed <= 225)
                {
                    vs = 1500;
                }
                else if (airspeed > 225 && airspeed <= 285)
                {
                    vs = 1900;
                }
                else if (airspeed > 285 && airspeed <= 320)
                {
                    vs = 2200;
                }
                else
                {
                    vs = 2300;
                }

                lblVsSet.Content = string.Format("{0:0.000}", vs);
                //Adjust AutoPilot
                setAutoPilotParams(pFplState.nextAltitude, pFplState.hdgToNextWpt, vs, pFplState.nextSpeed);
            }
            else
            {
                //Adjust AutoPilot
                setAutoPilotParams(pFplState.nextAltitude, pFplState.hdgToNextWpt, 999999, pFplState.nextSpeed);
            }

            ////Dont think we need this
            //APIWaypoint closestWpt = pFplState.fpl.Waypoints.First();
            //foreach (APIWaypoint  wpt in pFplState.fpl.Waypoints)
            //{
            //   double distToClosest = getDistToWaypoint(acState.Location, closestWpt);
            //   if (getDistToWaypoint(acState.Location,wpt) < distToClosest)
            //    {
            //        closestWpt = wpt;
            //    }
            //}
        }
        void client_CommandReceived(object sender, CommandReceivedEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)(() =>
            {
                try {
                    var type = typeof(IFAPIStatus).Assembly.GetType(e.Response.Type);

                    if (type == typeof(APIAircraftState))
                    {
                        var state = Serializer.DeserializeJson <APIAircraftState>(e.CommandString);

                        Console.WriteLine(state.VerticalSpeed);

                        // convert to fpm
                        state.VerticalSpeed = float.Parse(Convert.ToString(state.VerticalSpeed * 200, CultureInfo.InvariantCulture.NumberFormat), CultureInfo.InvariantCulture.NumberFormat); // multiply by 200, this somehow gets it accurate..

                        airplaneStateGrid.DataContext = null;
                        airplaneStateGrid.DataContext = state;
                        pAircraftState = state;
                        if (FMSControl.autoFplDirectActive)
                        {
                            FMSControl.updateAutoNav(state);
                        }
                        AircraftStateControl.AircraftState = state;
                        AttitudeIndicator.updateAttitude(state.Pitch, state.Bank);
                        updateLandingRoll(state);
                    }
                    else if (type == typeof(GetValueResponse))
                    {
                        var state = Serializer.DeserializeJson <GetValueResponse>(e.CommandString);

                        Console.WriteLine("{0} -> {1}", state.Parameters[0].Name, state.Parameters[0].Value);
                    }
                    else if (type == typeof(LiveAirplaneList))
                    {
                        LiveAirplaneList airplaneList = Serializer.DeserializeJson <LiveAirplaneList>(e.CommandString);
                        //airplaneDataGrid.ItemsSource = airplaneList.Airplanes;
                    }
                    else if (type == typeof(FacilityList))
                    {
                        var facilityList = Serializer.DeserializeJson <FacilityList>(e.CommandString);

                        //facilitiesDataGrid.ItemsSource = facilityList.Facilities;
                    }
                    else if (type == typeof(IFAPIStatus))
                    {
                        var status = Serializer.DeserializeJson <IFAPIStatus>(e.CommandString);
                    }
                    else if (type == typeof(APIATCMessage))
                    {
                        var msg = Serializer.DeserializeJson <APIATCMessage>(e.CommandString);
                        // TODO client.ExecuteCommand("Live.GetCurrentCOMFrequencies");
                    }
                    else if (type == typeof(APIFrequencyInfoList))
                    {
                        var msg = Serializer.DeserializeJson <APIFrequencyInfoList>(e.CommandString);
                    }
                    else if (type == typeof(ATCMessageList))
                    {
                        var msg = Serializer.DeserializeJson <ATCMessageList>(e.CommandString);
                        atcMessagesDataGrid.ItemsSource = msg.ATCMessages;
                    }
                    else if (type == typeof(APIFlightPlan))
                    {
                        var msg = Serializer.DeserializeJson <APIFlightPlan>(e.CommandString);
                        Console.WriteLine("Flight Plan: {0} items", msg.Waypoints.Length);
                        FMSControl.fplReceived(msg); //Update FMS with FPL from IF.
                        foreach (var item in msg.Waypoints)
                        {
                            Console.WriteLine(" -> {0} {1} - {2}, {3}", item.Name, item.Code, item.Latitude, item.Longitude);
                        }
                    }
                } catch (System.NullReferenceException) {
                    Console.WriteLine("Disconnected from server!");
                    //Let the client handle the lost connection.
                    //connectionStatus = false;
                }
            }));
        }
        void client_CommandReceived(object sender, CommandReceivedEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)(() =>
            {
                var type = typeof(IFAPIStatus).Assembly.GetType(e.Response.Type);

                //System.IO.File.AppendAllText("C:\\IfApi\\IfApiCommandResp.txt", e.Response.Type + ": " + e.CommandString + "\n");
                //if (pCustomCmdSent)
                //{
                //    txtResp.AppendText(e.Response.Type + " " + e.CommandString + "\n\n");
                //    txtResp.ScrollToEnd();
                //    pCustomCmdSent = false;
                //}

                if (type == typeof(APIAircraftState))
                {
                    var state = Serializer.DeserializeJson <APIAircraftState>(e.CommandString);
                    //Console.WriteLine(e.CommandString);
                    //airplaneStateGrid.DataContext = null;
                    //airplaneStateGrid.DataContext = state;
                    pAircraftState = state;
                    if (FMSControl.autoFplDirectActive)
                    {
                        FMSControl.updateAutoNav(state);
                    }
                    AircraftStateControl.AircraftState = state;
                    AttitudeIndicator.updateAttitude(pAircraftState.Pitch, pAircraftState.Bank);
                }
                else if (type == typeof(GetValueResponse))
                {
                    var state = Serializer.DeserializeJson <GetValueResponse>(e.CommandString);

                    Console.WriteLine("{0} -> {1}", state.Parameters[0].Name, state.Parameters[0].Value);
                }
                else if (type == typeof(LiveAirplaneList))
                {
                    var airplaneList = Serializer.DeserializeJson <LiveAirplaneList>(e.CommandString);

                    //airplaneDataGrid.ItemsSource = airplaneList.Airplanes;
                }
                else if (type == typeof(FacilityList))
                {
                    var facilityList = Serializer.DeserializeJson <FacilityList>(e.CommandString);

                    //facilitiesDataGrid.ItemsSource = facilityList.Facilities;
                }
                else if (type == typeof(IFAPIStatus))
                {
                    var status = Serializer.DeserializeJson <IFAPIStatus>(e.CommandString);
                    updateConnectionStatus(status);
                    //versionTextBlock.Text = status.AppVersion;
                    //userNameTextBlock.Text = status.LoggedInUser;
                    //deviceNameTextBlock.Text = status.DeviceName;
                    //displayResolutionTextBlock.Text = string.Format("{0}x{1}", status.DisplayWidth, status.DisplayHeight);
                }
                else if (type == typeof(APIATCMessage))
                {
                    var msg = Serializer.DeserializeJson <APIATCMessage>(e.CommandString);

                    //atcMessagesListBox.Items.Add(msg.Message);

                    client.ExecuteCommand("Live.GetCurrentCOMFrequencies");
                }
                else if (type == typeof(APIFrequencyInfoList))
                {
                    var msg = Serializer.DeserializeJson <APIFrequencyInfoList>(e.CommandString);
                    //frequenciesDataGrid.ItemsSource = msg.Frequencies;
                }
                else if (type == typeof(ATCMessageList))
                {
                    var msg = Serializer.DeserializeJson <ATCMessageList>(e.CommandString);
                    //atcMessagesDataGrid.ItemsSource = msg.ATCMessages;
                }
                else if (type == typeof(APIFlightPlan))
                {
                    var msg = Serializer.DeserializeJson <APIFlightPlan>(e.CommandString);
                    Console.WriteLine("Flight Plan: {0} items", msg.Waypoints.Length);
                    FMSControl.fplReceived(msg);
                    foreach (var item in msg.Waypoints)
                    {
                        Console.WriteLine(" -> {0} {1} - {2}, {3}", item.Name, item.Code, item.Latitude, item.Longitude);
                    }
                }
            }));
        }
示例#8
0
        private void client_CommandReceived(object sender, IFConnect.CommandReceivedEventArgs e)
        {
            Dispatcher.UIThread.InvokeAsync(() =>
            {
                try
                {
                    // System.Diagnostics.Debug.WriteLine(e.CommandString);
                    var type = typeof(IFAPIStatus).Assembly.GetType(e.Response.Type);

                    if (type == typeof(APIAircraftState))
                    {
                        var state = JsonSerializer.Deserialize <APIAircraftState>(e.CommandString);

                        // convert to fpm
                        state.VerticalSpeed =
                            float.Parse(
                                Convert.ToString(state.VerticalSpeed * 200, CultureInfo.InvariantCulture.NumberFormat),
                                CultureInfo.InvariantCulture
                                .NumberFormat);     // multiply by 200, this somehow gets it accurate..

                        _airplaneStateGrid.DataContext = null;
                        _airplaneStateGrid.DataContext = state;
                        _pAircraftState = state;
                        if (_FMSControl.autoFplDirectActive)
                        {
                            _FMSControl.updateAutoNav(state);
                        }
                        if (_FMSControl.HoldingActive)
                        {
                            _FMSControl.performHold(state);
                        }
                        _AircraftStateControl.AircraftState = state;
                        _AttitudeIndicator.updateAttitude(state.Pitch, state.Bank);
                        updateLandingRoll(state);
                    }
                    else if (type == typeof(GetValueResponse))
                    {
                        var state = JsonSerializer.Deserialize <GetValueResponse>(e.CommandString);

                        Console.WriteLine("{0} -> {1}", state.Parameters[0].Name, state.Parameters[0].Value);
                    }
                    else if (type == typeof(APIATCMessage))
                    {
                        var msg = JsonSerializer.Deserialize <APIATCMessage>(e.CommandString);

                        //Handle the ATC message to control the autopilot if enabled by checkbox
                        _FMSControl.handleAtcMessage(msg, _pAircraftState);

                        // TODO client.ExecuteCommand("Live.GetCurrentCOMFrequencies");
                    }
                    else if (type == typeof(ATCMessageList))
                    {
                        var msg = JsonSerializer.Deserialize <ATCMessageList>(e.CommandString);
                        _atcMessagesDataGrid.Items = msg.ATCMessages;
                    }
                    else if (type == typeof(APIFlightPlan))
                    {
                        var msg = JsonSerializer.Deserialize <APIFlightPlan>(e.CommandString);
                        Console.WriteLine("Flight Plan: {0} items", msg.Waypoints.Length);
                        _FMSControl.FplReceived(msg); //Update FMS with FPL from IF.
                        foreach (var item in msg.Waypoints)
                        {
                            Console.WriteLine(" -> {0} {1} - {2}, {3}", item.Name, item.Code, item.Latitude,
                                              item.Longitude);
                        }
                    }
                    else if (type == typeof(APIAutopilotState))
                    {
                        _FMSControl.APState = Serializer.DeserializeJson <APIAutopilotState>(e.CommandString);
                    }
                }
                catch (NullReferenceException)
                {
                    Console.WriteLine("Disconnected from server!");
                    //Let the client handle the lost connection.
                    //connectionStatus = false;
                }
            });
        }