Exemple #1
0
        /// <summary>
        /// Gestore interno del watch dog sulle FSUIPC. In caso di errore sorreva un ErrorOccurredEvent
        /// </summary>
        private void TickHandle(object sender, ElapsedEventArgs e)
        {
            try
            {
                PositioningEvent toBeRaised      = new PositioningEvent();
                AircraftPosition currentPosition = new AircraftPosition();

#if FEDE_DEBUG
                currentPosition.IndicatedAirspeedSpeed = (new Random()).NextDouble() * 100;
                currentPosition.Altitude         = 0;
                currentPosition.AutopilotHeading = 100;
                currentPosition.AvailableFuel    = 100;
                currentPosition.GroundSpeed      = currentPosition.IndicatedAirspeedSpeed;
                currentPosition.Heading          = 196;
                currentPosition.IsAirborne       = false;
                currentPosition.IsEngineStarted  = false;
                currentPosition.Latitude         = 44;
                currentPosition.Longitude        = 11;
                currentPosition.Nav1             = 112.2;
                currentPosition.Nav1DME          = 0.7;
                currentPosition.Nav1Glide        = 0;
                currentPosition.Nav1OBS          = 270;
                currentPosition.Nav1Radial       = 291;
                currentPosition.Nav1Localizer    = 50;
                currentPosition.QNH                = 1013;
                currentPosition.RadioAltitude      = 0;
                currentPosition.Timestamp          = DateTime.Now;
                currentPosition.TrueAirspeedSpeed  = currentPosition.IndicatedAirspeedSpeed;
                currentPosition.ThrottlePercentage = 75;

                toBeRaised.Position = currentPosition;
                FlightSimEvent(toBeRaised);
                return;
#endif

                FSUIPCConnection.Process();

                //issue 63
                #region gestione di ivap
                IvapStatus.Instance.IsRunning = ((byte)ivapDetected.Value == 1);
                if (IvapStatus.Instance.IsRunning)
                {
                    IvapStatus.Instance.IvapTrasponderIsInStandby = ((byte)ivapTrasponder.Value == 1);
                }
                else
                {
                    IvapStatus.Instance.IvapTrasponderIsInStandby = true;
                }
                #endregion

                //issue 11
                #region versione FS
                switch ((short)ivapTrasponder.Value)
                {
                case 7:
                    IvapStatus.Instance.FSVersion = FlightSimulatorVersion.FS2004;
                    break;

                case 9:
                    IvapStatus.Instance.FSVersion = FlightSimulatorVersion.FSX;
                    break;

                default:
                    IvapStatus.Instance.FSVersion = FlightSimulatorVersion.Altro;
                    break;
                }
                #endregion

                //ground speed
                currentPosition.GroundSpeed = ((double)groundspeed.Value / 65536d) * 1.943844492; //Knots
                //airspeed
                currentPosition.TrueAirspeedSpeed      = ((double)airspeed.Value / 128);          //issue 38
                currentPosition.IndicatedAirspeedSpeed = ((double)indicatedAirspeed.Value / 128);
                //latitude
                currentPosition.Latitude = (double)latitude.Value * 90d / (10001750d * 65536d * 65536d);
                //longitude
                currentPosition.Longitude = (double)longitude.Value * 360d / (65536d * 65536d * 65536d * 65536d);
                //altitude
                currentPosition.Altitude = (int)altitude.Value * 3.28d;
                //radio altitude
                currentPosition.RadioAltitude = (double)radioAlt.Value / 65536;
                //heading
                currentPosition.Heading = heading.Value * 360d / (65536d * 65536d);
                if (currentPosition.Heading < 0)
                {
                    currentPosition.Heading = 360 + currentPosition.Heading;
                }
                //QNH letto sull'altimetro
                currentPosition.QNH = (int)qnh.Value / 16;
                //NAV 1
                currentPosition.Nav1          = 100 + ReadBCD((short)nav1.Value);
                currentPosition.Nav1Localizer = (short)(byte)nav1_loc.Value;
                if (currentPosition.Nav1Localizer > 128)
                {
                    currentPosition.Nav1Localizer = (short)(-256 + currentPosition.Nav1Localizer);
                }
                currentPosition.Nav1Glide = (byte)nav1_glide.Value;
                currentPosition.Nav1OBS   = (short)nav1_obs.Value;
                if (currentPosition.Nav1OBS < 0)
                {
                    currentPosition.Nav1OBS = (180 - currentPosition.Nav1OBS);
                }
                currentPosition.Nav1Radial = ((short)nav1_radial.Value) * 360 / 65536;
                if (currentPosition.Nav1Radial < 0)
                {
                    currentPosition.Nav1Radial = (180 - currentPosition.Nav1Radial);
                }

                currentPosition.Nav1DME = ReadDME((byte[])nav1_dme.Value);

                //Throttle
                if ((short)throttle1.Value <= 0)
                {
                    currentPosition.ThrottlePercentage = 0;                             //inversori di spinta inseriti
                }
                else
                {
                    currentPosition.ThrottlePercentage = (int)((short)throttle1.Value / 16384d * 100);
                }



                //Autopilot
                currentPosition.AutopilotHeading = ((short)autopilot_hdg.Value) * 360 / 65536;
                if (currentPosition.AutopilotHeading < 0)
                {
                    currentPosition.AutopilotHeading = (180 - currentPosition.AutopilotHeading);
                }

                //fuel
                currentPosition.AvailableFuel  = 0;
                currentPosition.AvailableFuel += fuelCap1.Value * ((double)(fuelQty1.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap2.Value * ((double)(fuelQty2.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap3.Value * ((double)(fuelQty3.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap4.Value * ((double)(fuelQty4.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap5.Value * ((double)(fuelQty5.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap6.Value * ((double)(fuelQty6.Value) / (128 * 65536));
                currentPosition.AvailableFuel += fuelCap7.Value * ((double)(fuelQty7.Value) / (128 * 65536));

                toBeRaised.Position = currentPosition;
                //sollevo l'evento
                FlightSimEvent(toBeRaised);

                //gestione stato airborne
                currentPosition.IsAirborne = (airborne.Value == 0) || /*issue 36*/ (currentPosition.RadioAltitude > 10);
                if (!LastPosition.IsAirborne && currentPosition.IsAirborne)
                {
                    //decollato
                    FSEvent to = new TakeOffEvent();
                    FlightSimEvent(to);
                }
                else if (LastPosition.IsAirborne && !currentPosition.IsAirborne)
                {
                    //atterrato
                    FSEvent ldg = new LandingEvent();
                    FlightSimEvent(ldg);
                }

                //gestione dello stato del motore (ed invio eventi associati) issue 29
                currentPosition.IsEngineStarted = currentPosition.AvailableFuel < LastPosition.AvailableFuel;

                if (!LastPosition.IsEngineStarted && currentPosition.IsEngineStarted)
                {
                    //il motore si è acceso
                    FSEvent evt = new EngineStartUpEvent();
                    FlightSimEvent(evt);
                }
                else if (LastPosition.IsEngineStarted && !currentPosition.IsEngineStarted)
                {
                    if (isFirsPosWithNoFuelFlow)
                    {
                        //visto che è la prima volta che questo accade, lascio una tolleranza di un giro
                        //issue 44
                        isFirsPosWithNoFuelFlow         = false;
                        currentPosition.IsEngineStarted = true;
                    }
                    else
                    {
                        //il motore si è spento davvero
                        FSEvent evt = new EngineShutDownEvent();
                        FlightSimEvent(evt);
                        isFirsPosWithNoFuelFlow = true;
                    }
                }

                //gestione del movimento (ed invio eventi associati) issue 29
                //l'1 invece dello 0 è dovuto a potenziali errori di arrotondamento nel calcolo della velocità
                if (LastPosition.GroundSpeed <= 1 && currentPosition.GroundSpeed > 1)
                {
                    //inizia a muoversi
                    FSEvent evt = new StartMovingEvent();
                    FlightSimEvent(evt);
                }
                else if (LastPosition.GroundSpeed >= 1 && currentPosition.GroundSpeed < 1)
                {
                    //si ferma
                    FSEvent evt = new EndMovingEvent();
                    FlightSimEvent(evt);
                }

                LastPosition = currentPosition;
            }
            catch (Exception ex)
            {
                ErrorOccurred(ex);
            }
        }
        /// <summary>
        /// Metodo fondamentale: è il listener che viene notificato ogni volta che si ricevono dati "freschi"
        /// da FS, quindi è qui che si decide cosa fa l'applazione in risposta a ciascuna situazione
        /// </summary>
        /// <param name="e">L'evento di FS da gestire. Consultare la tassonomia con capostipite FSEvent
        /// per sapere quali sono gli eventi gestibili</param>
        private void HandleEvent(FSEvent e)
        {
            lock (this)
            {
                if (e is PositioningEvent)
                {
                    PositioningEvent pe = (PositioningEvent)e;
                    status.CurrentPosition = pe.Position;
                    if (PositionUpdated != null)
                    {
                        PositionUpdated(pe.Position);
                    }
                }
                else if (e is TakeOffEvent)
                {
                    //se sono già airborne o atterrato vuol dire che è un touch 'n' go o un goaround, quindi non faccio nulla
                    if (status.CurrentStatus <= FlightStates.TakeOffTaxi)//il <= inserito per issue 51
                    {
                        status.DepartureTime = e.Timestamp;
                    }
                    status.CurrentStatus = FlightStates.Airborne;
                    //isssue 63
                    if (IPSConfiguration.AUTO_TRASPONDER)
                    {
                        if (IvapStatus.Instance.IsRunning && IvapStatus.Instance.IvapTrasponderIsInStandby)
                        {
                            //ivap è presente ma il trasponder è in Sierra, quindi lo metto in charlie
                            flightSim.SetTrasponderMode(true);
                        }
                    }
                }
                else if (e is LandingEvent)
                {
                    if (status.CurrentStatus == FlightStates.Airborne)
                    {
                        status.CurrentStatus = FlightStates.Landed;
                        status.ArrivalTime   = e.Timestamp;
                        //in questo modo l'ultimo atterraggio è sempre quello che fa fede per l'ora di arrivo
                        //isssue 63:
                        if (IPSConfiguration.AUTO_TRASPONDER)
                        {
                            if (IvapStatus.Instance.IsRunning && !IvapStatus.Instance.IvapTrasponderIsInStandby)
                            {
                                //ivap è presente ma il trasponder è in Sierra, quindi lo metto in charlie
                                flightSim.SetTrasponderMode(false);
                            }
                        }
                    }
                }
                else if (e is EngineStartUpEvent)
                {
                    //se è la prima accensione la considero come quella "buona"
                    if (status.CurrentStatus == FlightStates.Before_Departed)
                    {
                        status.CurrentStatus = FlightStates.Engine_Started;
                        status.DepartureFuel = status.CurrentFuel;
                    }
                }
                else if (e is EngineShutDownEvent)
                {
                    //seconda condizione del primo if è aggiunta per issue 49
                    //se c'è vento l'indicata non scende sotto 1 e quindi non si passa mai nello stato "ai blocchi"
                    if (status.CurrentStatus == FlightStates.OnBlocks || status.CurrentStatus == FlightStates.Landed)
                    {
                        status.CurrentStatus = FlightStates.EngineOff;
                        status.ArrivalFuel   = status.CurrentFuel;
                    }
                    else if (status.CurrentStatus == FlightStates.Engine_Started || status.CurrentStatus == FlightStates.TakeOffTaxi)
                    {
                        status.CurrentStatus = FlightStates.Before_Departed;
                    }
                }
                else if (e is StartMovingEvent)
                {
                    if (status.CurrentStatus <= FlightStates.Engine_Started)
                    {
                        status.CurrentStatus = FlightStates.TakeOffTaxi;
                        //issue 54
                        if (status.DepartureFuel == 0)
                        {
                            status.DepartureFuel = status.CurrentFuel;
                        }
                    }
                    else if (status.CurrentStatus == FlightStates.OnBlocks)
                    {
                        //vuol dire che non ero realmente ai blocchi, ma che mi ero solo arrestato durante il taxi dopo l'atterraggio
                        status.CurrentStatus = FlightStates.Landed;
                    }
                    //negli altri casi è un normale stop durante il rullaggio di partenza o di arrivo
                }
                else if (e is EndMovingEvent)
                {
                    if (status.CurrentStatus == FlightStates.Landed || status.CurrentStatus == FlightStates.OnBlocks)
                    {
                        //la seconda condizione è per evitare di avere problemi se mi fermo durante il taxi dopo l'atterraggio
                        status.CurrentStatus = FlightStates.OnBlocks;
                        //l'ultimo tra on-bock e shutdown motori determina l'ultimo calcolo di fuel
                        status.ArrivalFuel = status.CurrentFuel;
                    }
                }
                else
                {
                    throw new InvalidOperationException("non implementato");
                }

                if (!(e is PositioningEvent))
                {
                    Log(e.GetType().FullName.Substring(e.GetType().FullName.LastIndexOf('.')));
                }
            }

            //rinfresco la view
            viewMainForm.mainPanel.DrawStatus(status);
            utilBar.UpdateView(status);
        }