Ejemplo n.º 1
0
        // Asynch processing from receiving actual user position (Triggered by TCPclient)
        private void LTLink_LTEvent(object sender, LTEventArgs e)
        {
            long secSinceLastPing = (long)(DateTime.Now - m_lastUpdate).TotalSeconds;

            OnTraffic(secSinceLastPing);

            if (!Valid)
            {
                return;     // catch out of bounds messages
            }
            m_userAcft.NewPos(e.LatLon);
            if (POOL == null)
            {
                // create the first subset with our AcftPos
                POOL = new VAcftPool(m_radius_nm, m_stepLen_sec)
                {
                    NumAcft     = m_numAcft,
                    NumVFRcraft = m_numVFR
                };
                POOL.CreateAwySelection(AWYDB.GetTable( ), RWYDB.GetTable( ), m_userAcft.LatLon);
                POOL.UpdateVFRscripts(CMDS);
                Logger.Instance.Log($"TrafficHandler: Create POOL with {m_numAcft} aircrafts where {m_numVFR} are VFR, one sim step is >= {m_stepLen_sec} seconds");
            }
            // push an update only after 'StepLen_sec' secs
            if (secSinceLastPing >= POOL.StepLen_sec)
            {
                m_lastUpdate = DateTime.Now;                      // reset timer

                LT_Weather.SendMsg(RealTraffic.WeatherString( )); // send a 'generic' weather string
                // do POOL maintenance
                POOL.ReGenerate( );
                POOL.Update( );
                // send updates to LiveTraffic - TODO need to pace it ??
                foreach (var vac in POOL.AircraftPoolRef)
                {
                    string msg = RealTraffic.AITrafficString(vac);
                    LT_Traffic.SendMsg(msg);
                }
                // recreates the airway selection if needed
                POOL.UpdateAwySelection(AWYDB.GetTable( ), RWYDB.GetTable( ), m_userAcft.LatLon);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Converts from a list of AITraffic messages to a route
        /// returns null if something was wrong
        /// </summary>
        /// <param name="aitStream">A list of AITraffic messages as strings</param>
        /// <returns>A created route or null</returns>
        private CmdList RouteFromAIT(List <string> aitStream, bool absoluteTrack, bool ignoreAirborne)
        {
            if (aitStream.Count < 2)
            {
                Error = "# messages 2"; return(null);
            }
            ;                                                              // we don't handle below 3 reports

            var vac = RealTraffic.FromAITrafficString(aitStream[0]);

            if (vac == null)
            {
                Error = "AIT message conversion error"; return(null);
            }
            ;                           // converter error
            long   cTs    = vac.TStamp; // start time,
            var    cPos   = new LatLon(vac.LatLon);
            double cAlt   = vac.Alt_ft;
            double cGs    = vac.GS;
            double cVsi   = vac.VSI;
            double cTrack = vac.TRK;

            if (cGs == 0)
            {
                //Initial Speed is Zero - we may not have GS at all so try to calculate some..
                // try to calculate a GS
                var vac1 = RealTraffic.FromAITrafficString(aitStream[1]);
                if (vac1 == null)
                {
                    return(null);                                                                                   // ERROR Exit, this one is not usable at all
                }
                cGs = cPos.DistanceTo(vac1.LatLon, ConvConsts.EarthRadiusNm) * 3600.0 / (vac1.TStamp - vac.TStamp); // let's try the calculated one..
            }
            ;
            if (cGs == 0)
            {
                //Still Speed is Zero - we may not have GS at all so try to calculate some..
                Error = "Speed is not available, cannot continue";
                return(null);
            }

            double maxGS = cGs; // track Max Speed to adjust for the AcftType later

            var  route = new CmdList( );
            CmdA a     = null;

            if (absoluteTrack)
            {
                a = new CmdA(vac.AcftType, CmdA.FlightT.MsgAbsolute);
                a.CreateForMsgAbsolute(cPos, cTrack, cAlt, cGs);
            }
            else
            {
                a = new CmdA(vac.AcftType, CmdA.FlightT.MsgRelative);
                a.CreateForMsgRelative(cAlt, cGs);
            }

            route.Enqueue(a);
            // walk through route
            for (int i = 1; i < aitStream.Count; i++)
            {
                if (string.IsNullOrEmpty(aitStream[i]))
                {
                    continue;                                 // empty CRLFs ??
                }
                vac = RealTraffic.FromAITrafficString(aitStream[i]);
                if (vac == null)
                {
                    Error = "AIT message conversion error"; return(null);
                }
                ; // converter error
                if ((!ignoreAirborne) && (!vac.Airborne))
                {
                    continue;                                     // catch some incomplete ones
                }
                // see what delta we have
                long dT = vac.TStamp - cTs;
                cTs = vac.TStamp; // update time

                if (vac.GS == 0)
                {
                    // try to calculate a GS ( but this does not account for turns - so it is likely too low
                    vac.GS = cPos.DistanceTo(vac.LatLon, ConvConsts.EarthRadiusNm) * 3600.0 / dT; // let's try the calculated one..
                }
                if (vac.GS < 5)
                {
                    continue;       // plane is not moving
                }
                double dAlt = vac.Alt_ft - cAlt;
                double dGs  = vac.GS - cGs;
                double dTrk = vac.TRK - cTrack;
                double dVsi = vac.VSI - cVsi;
                maxGS = (vac.GS > cGs) ? vac.GS : cGs;

                // change speed if delta is large enough
                // don't collect speeds under 5 else the model does not move anymore..
                if ((vac.GS >= 5) && Math.Abs(dGs) > 4)
                {
                    route.Enqueue(new CmdS(vac.GS));
                    cGs = vac.GS; // update if used
                }
                // change Alt if delta is large enough
                if (Math.Abs(dAlt) > 25)
                {
                    if (dAlt > 0 && cVsi < 0)
                    {
                        cVsi = 1200;               // wrong sign, just apply a VSI
                    }
                    if (dAlt < 0 && cVsi > 0)
                    {
                        cVsi = 1200;                           // wrong sign, just apply a VSI
                    }
                    route.Enqueue(new CmdV(cVsi, vac.Alt_ft)); // we change at old VSI as this was the start to get to the new alt
                    cAlt = vac.Alt_ft;                         // update if used
                    cVsi = vac.VSI;                            // update if used
                }
                // Goto Pos
                if (absoluteTrack)
                {
                    //just goto absolute location (let the model do the flying..)
                    route.Enqueue(new CmdG(vac.LatLon));
                }
                else
                {
                    // OR calc Direction and Distance for relative flying..
                    route.Enqueue(new CmdH(cPos.BearingTo(vac.LatLon)));
                    route.Enqueue(new CmdD(cPos.DistanceTo(vac.LatLon, ConvConsts.EarthRadiusNm)));
                }
                cPos   = new LatLon(vac.LatLon); // move position
                cTrack = vac.TRK;                // update track
            }
            route.Enqueue(new CmdE( ));          // mandatory end command

            // we don't know the real acft type (no lookup in the converter)
            // so take a jet for above 180 and a GA one below
            if (maxGS > 180)
            {
                route.Descriptor.UpdateAcftType(Aircrafts.AircraftSelection.GetRandomAcftTypeOp( ).AcftType);
            }
            else
            {
                route.Descriptor.UpdateAcftType(Aircrafts.AircraftSelection.GetRandomGAAcftTypeOp( ).AcftType);
            }
            return(route);
        }