Example #1
0
        /// <summary>
        /// Create a random IFR flight
        /// </summary>
        /// <param name="awyTableRef">The airway table to chose from</param>
        /// <param name="acftNo">The aircraft regNo</param>
        /// <param name="acftType">The aircraft type</param>
        /// <param name="airline">The airline operator ICAO code</param>
        /// <returns></returns>
        public static CmdList GetRandomFlight(awyTable awyTableRef, int acftNo, string acftType, string airline)
        {
            var route   = new CmdList( );
            var visited = new List <string>( ); // visited Navs and Fixes, we don't want to run circles

            var awy = GetRandomAwy(awyTableRef);

            if (awy == null)
            {
                return(route);         // no airways available ??
            }
            // add Aircraft Descriptor first
            route.Enqueue(new CmdA(acftType, CmdA.FlightT.Airway, airline));
            // some random altitude and complete start of the route
            var altMsl = m_random.Next(MinLevel(awy.baseFt), MaxLevel(awy.topFt));

            altMsl = (int)Math.Round(altMsl / 100.0) * 100;                            // get 100 ft increments
            route.Descriptor.InitFromAirway(acftNo, awy, altMsl, GetSpeed(awy.layer)); // set start conditions (assumes MslBase=0)
            // add segment length command
            route.Enqueue(new CmdD(awy.Distance_nm));
            visited.Add(awy.startID); // we add all startIDs

            // do we have an airway to go from here?
            var newleg = awyTableRef.GetNextSegment(awy);

            while (newleg != null)
            {
                if (visited.Contains(newleg.startID))
                {
                    break; // this would create a circle (endless loop)
                }

                awy = newleg;
                // random speed change
                if (m_random.Next(10) == 0) // one out of 10
                // add S command
                {
                    route.Enqueue(new CmdS(GetSpeed(awy.layer)));
                }
                // random alt change
                if (m_random.Next(20) == 0) // one out of 20
                // add V command
                {
                    altMsl = GetNewAlt(altMsl, awy.baseFt, awy.topFt);
                    route.Enqueue(new CmdV(1200, altMsl));
                }
                // add Goto command
                route.Enqueue(new CmdG(awy.end_latlon));
                visited.Add(awy.startID); // we add all startIDs to avoid loops above

                // try next one
                newleg = awyTableRef.GetNextSegment(awy);
            }
            route.Descriptor.FinishFromAirway(awy); // set end location ID from last segment
            // add mandatory end segment
            route.Enqueue(new CmdE( ));

            return(route);
        }
Example #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);
        }