예제 #1
0
 public AntennaWindow(IAntenna antenna)
     : base(Guid, "Antenna Configuration", new Rect(100, 100, 300, 500), WindowAlign.Floating)
 {
     mSavePosition = true;
     mSetAntenna = antenna;
     mTargetInfos = new TargetInfoWindow(this, WindowAlign.Floating);
 }
 private void OnUnregister(IAntenna antenna)
 {
     if (Unregistered != null)
     {
         Unregistered(antenna);
     }
 }
 private void OnRegister(IAntenna antenna)
 {
     if (Registered != null)
     {
         Registered(antenna);
     }
 }
예제 #4
0
        /// <summary>Finds the maximum range between an antenna and a specific target.</summary>
        /// <returns>The maximum distance at which the two spacecraft could communicate.</returns>
        /// <param name="antenna">The antenna attempting to target.</param>
        /// <param name="target">The satellite being targeted by <paramref name="antenna"/>.</param>
        /// <param name="antennaSat">The satellite on which <paramref name="antenna"/> is mounted.</param>
        /// <param name="rangeFunc">A function that computes the maximum range between two
        /// satellites, given their individual ranges.</param>
        public static double GetRangeInContext(IAntenna antenna, ISatellite target, ISatellite antennaSat,
                                               Func <double, double, double> rangeFunc)
        {
            // Which antennas on the other craft are capable of communication?
            IEnumerable <IAntenna> omnisB  = GetOmnis(target);
            IEnumerable <IAntenna> dishesB = GetDishesThatSee(target, antennaSat);

            // Pick the best range for each case
            double maxOmniB = omnisB.Any() ?  omnisB.Max(ant => ant.Omni) : 0.0;
            double maxDishB = dishesB.Any() ? dishesB.Max(ant => ant.Dish) : 0.0;
            double bonusB   = GetMultipleAntennaBonus(omnisB, maxOmniB);

            // Also need local antenna bonus, if antenna is an omni
            IEnumerable <IAntenna> omnisA = GetOmnis(antennaSat);
            double maxOmniA = omnisA.Any()  ? omnisA.Max(ant => ant.Omni) : 0.0;
            double bonusA   = GetMultipleAntennaBonus(omnisA, maxOmniA);

            // What is the range?
            // Note: IAntenna.Omni and IAntenna.Dish are zero for antennas of the other type
            double maxOmni = Math.Max(CheckRange(rangeFunc, antenna.Omni + bonusA, omniClamp, maxOmniB + bonusB, omniClamp),
                                      CheckRange(rangeFunc, antenna.Omni + bonusA, omniClamp, maxDishB, dishClamp));
            double maxDish = Math.Max(CheckRange(rangeFunc, antenna.Dish, dishClamp, maxOmniB + bonusB, omniClamp),
                                      CheckRange(rangeFunc, antenna.Dish, dishClamp, maxDishB, dishClamp));

            return(Math.Max(maxOmni, maxDish));
        }
예제 #5
0
 public AntennaWindow(IAntenna antenna)
     : base(Guid, "Antenna Configuration", new Rect(100, 100, 300, 500), WindowAlign.Floating)
 {
     mSavePosition = true;
     mSetAntenna   = antenna;
     mTargetInfos  = new TargetInfoWindow(this, WindowAlign.Floating);
 }
예제 #6
0
파일: API.cs 프로젝트: jvdnbus/SSAT2
        /// <summary>
        /// Change the Omni range of a ground station.
        /// Note that this change is temporary. For example it is overridden to the value written in the settings file if the tracking station is upgraded.
        /// </summary>
        /// <param name="stationId">The station ID for which to change the antenna range.</param>
        /// <param name="newRange">The new range in meters.</param>
        /// <returns>true if the ground station antenna range was changed, false otherwise.</returns>
        public static bool ChangeGroundStationRange(Guid stationId, float newRange)
        {
            RTLog.Notify("Trying to change ground station {0} Omni range to {1}", RTLogLevel.API, stationId.ToString(), newRange);

            if (RTSettings.Instance == null)
            {
                return(false);
            }

            if (RTSettings.Instance.GroundStations.Count > 0)
            {
                MissionControlSatellite groundStation = RTSettings.Instance.GroundStations.First(gs => gs.mGuid == stationId);
                if (groundStation == null)
                {
                    return(false);
                }

                IEnumerable <IAntenna> antennas = groundStation.MissionControlAntennas.ToArray();
                if (antennas.Count() > 0)
                {
                    // first antenna
                    IAntenna antenna = antennas.ToArray()[0];
                    if (antenna is MissionControlAntenna)
                    {
                        ((MissionControlAntenna)antenna).SetOmniAntennaRange(newRange);
                        RTLog.Notify("Ground station Omni range successfully changed.", RTLogLevel.API);
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #7
0
 public void Refresh(IAntenna sat)
 {
     if (sat == Antenna)
     {
         Antenna = null;
     }
 }
예제 #8
0
        /// <summary>Counts the number of ISatellites that are in the antenna cone and in range.</summary>
        /// <returns>The number of reachable satellites.</returns>
        /// <remarks>If antenna does not have a cone, returns 0.</remarks>
        /// <param name="antenna">The antenna whose cone must be tested.</param>
        /// <param name="target">The object the cone is pointed at.</param>
        public static int countInCone(IAntenna antenna, Guid target)
        {
            if (antenna.Dish <= 0.0 || antenna.CosAngle >= 1.0)
            {
                return(0);
            }

            try {
                Vector3d      myPos     = RTCore.Instance.Network[antenna.Guid].Position;
                Vector3d      targetDir = (targetPosition(target) - myPos).normalized;
                CelestialBody myBody    = targetBody(target);

                int count = 0;
                foreach (ISatellite sat in RTCore.Instance.Satellites)
                {
                    Vector3d satDir = (sat.Position - myPos).normalized;
                    if (Vector3d.Distance(myPos, sat.Position) <= antenna.Dish && // in range
                        Vector3d.Dot(targetDir, satDir) >= antenna.CosAngle &&  // in cone
                        sat.Body == myBody)                                     // in target SoI... remove later

                    {
                        count++;
                    }
                }

                return(count);
            } catch (ArgumentException) {
                return(0);
            } catch (NullReferenceException) {
                return(0);
            }
        }
 private void OnAntenna(IAntenna antenna)
 {
     if (mFocusAntennas.Contains(antenna))
     {
         RebuildAntennaList();
     }
 }
예제 #10
0
        /// <summary>Finds the maximum range between an antenna and a specific target.</summary>
        /// <returns>The maximum distance at which the two spacecraft could communicate.</returns>
        /// <param name="antenna">The antenna attempting to target.</param>
        /// <param name="target">The satellite being targeted by <paramref name="antenna"/>.</param>
        /// <param name="antennaSat">The satellite on which <paramref name="antenna"/> is mounted.</param>
        /// <param name="rangeFunc">A function that computes the maximum range between two 
        /// satellites, given their individual ranges.</param>
        public static double GetRangeInContext(IAntenna antenna, ISatellite target, ISatellite antennaSat,
            Func<double, double, double> rangeFunc) {
            // Which antennas on the other craft are capable of communication?
            IEnumerable<IAntenna>  omnisB = GetOmnis(target);
            IEnumerable<IAntenna> dishesB = GetDishesThatSee(target, antennaSat);

            // Pick the best range for each case
            double maxOmniB =  omnisB.Any() ?  omnisB.Max(ant => ant.Omni) : 0.0;
            double maxDishB = dishesB.Any() ? dishesB.Max(ant => ant.Dish) : 0.0;
            double   bonusB = GetMultipleAntennaBonus(omnisB, maxOmniB);

            // Also need local antenna bonus, if antenna is an omni
            IEnumerable<IAntenna> omnisA  = GetOmnis(antennaSat);
            double maxOmniA = omnisA.Any()  ? omnisA.Max( ant => ant.Omni) : 0.0;
            double   bonusA = GetMultipleAntennaBonus(omnisA, maxOmniA);

            // What is the range?
            // Note: IAntenna.Omni and IAntenna.Dish are zero for antennas of the other type
            double maxOmni = Math.Max(CheckRange(rangeFunc, antenna.Omni + bonusA, omniClamp, maxOmniB + bonusB, omniClamp),
                                      CheckRange(rangeFunc, antenna.Omni + bonusA, omniClamp, maxDishB         , dishClamp));
            double maxDish = Math.Max(CheckRange(rangeFunc, antenna.Dish         , dishClamp, maxOmniB + bonusB, omniClamp), 
                                      CheckRange(rangeFunc, antenna.Dish         , dishClamp, maxDishB         , dishClamp));

            return Math.Max(maxOmni, maxDish);
        }
예제 #11
0
        public void Draw()
        {
            if (Satellite == null) return;

            GUILayout.BeginHorizontal();
            {
                GUILayout.TextField(Satellite.Name.Truncate(25), GUILayout.ExpandWidth(true));
                RTUtil.Button("Name", () =>
                {
                    var vessel = FlightGlobals.Vessels.First(v => v.id == Satellite.Guid);
                    if (vessel) vessel.RenameVessel();
                }, GUILayout.ExpandWidth(false), GUILayout.Height(24));
            }
            GUILayout.EndHorizontal();

            mScrollPosition = GUILayout.BeginScrollView(mScrollPosition, GUILayout.ExpandHeight(true));
            {
                Color pushColor = GUI.contentColor;
                TextAnchor pushAlign = GUI.skin.button.alignment;
                GUI.skin.button.alignment = TextAnchor.MiddleLeft;
                foreach (var a in Satellite.Antennas.Where(a => a.CanTarget))
                {
                    GUI.contentColor = (a.Powered) ? XKCDColors.ElectricLime : XKCDColors.Scarlet;
                    String text = a.Name.Truncate(25) + Environment.NewLine + "Target: " + RTUtil.TargetName(a.Target).Truncate(18);
                    RTUtil.StateButton(text, Antenna, a, s =>
                    {
                        Antenna = (s > 0) ? a : null;
                    });
                }
                GUI.skin.button.alignment = pushAlign;
                GUI.contentColor = pushColor;
            }
            GUILayout.EndScrollView();
        }
예제 #12
0
 private void OnAntenna(IAntenna antenna)
 {
     if (antenna == mFocus)
     {
         mForceClose.Invoke();
     }
 }
예제 #13
0
        public override void Correct(EpochSatellite epochSatellite)
        {
            Time gpsTime = epochSatellite.RecevingTime;

            IEphemeris      sat = epochSatellite.Ephemeris;
            SatelliteNumber prn = epochSatellite.Prn;

            //计算太阳位置方法
            //XYZ sunPosition = epochSatellite.EpochInfo.DataSouceProvider.UniverseObjectProvider.GetSunPosition(gpsTime);

            //新的计算太阳位置方法
            Time tutc = gpsTime.GpstToUtc();

            //查找地球自转信息
            Gnsser.Data.ErpItem erpv = null;
            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            XYZ sunPosition = new XYZ();

            DataSouceProvider.UniverseObjectProvider.GetSunPosition(gpsTime, erpv, ref sunPosition);

            //use L1 value
            IAntenna antenna = DataSouceProvider.AntennaDataSource.Get(prn.ToString(), gpsTime);

            if (antenna == null)
            {
                return;
            }

            string AntennaType = antenna.AntennaType;

            XYZ svPos = sat.XYZ;

            XYZ receiverPosition = epochSatellite.SiteInfo.EstimatedXyz;

            if (receiverPosition.Equals(XYZ.Zero))
            {
                return;
            }

            bool cycleSlip = epochSatellite.IsUnstable;

            if (cycleSlip || !PhaseManager.Contains(prn)) //a cycle slip happend
            {
                PhaseManager[prn] = new SatVectorPhase();
            }

            double windUpCorrection = GetSatPhaseWindUpCorectValue(prn, gpsTime, svPos, receiverPosition, sunPosition, AntennaType);

            //double windUpCorrection2 = GetSatPhaseWindUpCorectValue(satelliteType, gpsTime, svPos, receiverPosition, epochSatellite, sunPosition);

            this.Correction = (windUpCorrection);
        }
예제 #14
0
        /// <summary>Counts the number of ISatellites that are in the antenna cone and in range.</summary>
        /// <returns>The number of reachable satellites.</returns>
        /// <remarks>If antenna does not have a cone, returns 0.</remarks>
        /// <param name="antenna">The antenna whose cone must be tested.</param>
        /// <param name="target">The object the cone is pointed at.</param>
        public static int countInCone(IAntenna antenna, Guid target) {
            if (antenna.Dish <= 0.0 || antenna.CosAngle >= 1.0) {
                return 0;
            }

            try {
                Vector3d myPos = RTCore.Instance.Network[antenna.Guid].Position;
                Vector3d targetDir = (targetPosition(target) - myPos).normalized;
                CelestialBody myBody = targetBody(target);

                int count = 0;
                foreach (ISatellite sat in RTCore.Instance.Satellites) {
                    Vector3d satDir = (sat.Position - myPos).normalized;
                    if (Vector3d.Distance(myPos, sat.Position) <= antenna.Dish  // in range
                        && Vector3d.Dot(targetDir, satDir) >= antenna.CosAngle  // in cone
                        && sat.Body == myBody)                                  // in target SoI... remove later

                        count++;
                }

                return count;
            } catch (ArgumentException) {
                return 0;
            } catch (NullReferenceException) {
                return 0;
            }
        }
예제 #15
0
 public void OpenAntennaConfig(IAntenna a, Vessel v)
 {
     ISatellite s = RTCore.Instance.Satellites[v];
     if (s != null) {
         (new AntennaWindow(a, s)).Show();
     }
 }
예제 #16
0
 public AntennaFragment(IAntenna antenna)
 {
     Antenna = antenna;
     RTCore.Instance.Satellites.OnRegister += Refresh;
     RTCore.Instance.Satellites.OnUnregister += Refresh;
     RTCore.Instance.Antennas.OnUnregister += Refresh;
     Refresh();
 }
예제 #17
0
 public AntennaFragment(IAntenna antenna)
 {
     Antenna = antenna;
     RTCore.Instance.Satellites.OnRegister   += Refresh;
     RTCore.Instance.Satellites.OnUnregister += Refresh;
     RTCore.Instance.Antennas.OnUnregister   += Refresh;
     Refresh();
 }
 private void OnAntennaClick(IAntenna antenna)
 {
     OnAntennaFragmentClose();
     if (antenna != null) {
         mAntennaFragment = new AntennaConfigFragment(antenna, OnAntennaFragmentClose,
             x => mSatelliteFragment.RebuildAntennaList());
     }
 }
예제 #19
0
 public AntennaFragment(IAntenna antenna, Action quit)
 {
     Antenna = antenna;
     mOnQuit = quit;
     RTCore.Instance.Satellites.OnRegister += Refresh;
     RTCore.Instance.Satellites.OnUnregister += Refresh;
     RTCore.Instance.Antennas.OnUnregister += Refresh;
     Refresh();
 }
예제 #20
0
 private void OnAntennaClick(IAntenna antenna)
 {
     OnAntennaFragmentClose();
     if (antenna != null)
     {
         mAntennaFragment = new AntennaConfigFragment(antenna, OnAntennaFragmentClose,
                                                      x => mSatelliteFragment.RebuildAntennaList());
     }
 }
예제 #21
0
        public void OpenAntennaConfig(IAntenna a, Vessel v)
        {
            ISatellite s = RTCore.Instance.Satellites[v];

            if (s != null)
            {
                (new AntennaWindow(a, s)).Show();
            }
        }
        public AntennaConfigFragment(IAntenna antenna, OnClick forceClose, OnAntenna onUpdate)
        {
            mFocus = antenna;
            mForceClose = forceClose;
            mOnUpdate = onUpdate;

            RTCore.Instance.Antennas.Unregistered += OnAntenna;

            RebuildTargetList();
        }
예제 #23
0
        public AntennaConfigFragment(IAntenna antenna, OnClick forceClose, OnAntenna onUpdate)
        {
            mFocus      = antenna;
            mForceClose = forceClose;
            mOnUpdate   = onUpdate;

            RTCore.Instance.Antennas.Unregistered += OnAntenna;

            RebuildTargetList();
        }
예제 #24
0
        private void UpdateMesh(CelestialBody cb, IAntenna a)
        {
            var camera = MapView.MapCamera.camera;

            var antenna_pos = ScaledSpace.LocalToScaledSpace(RTCore.Instance.Network[a.Guid].Position);
            var planet_pos = ScaledSpace.LocalToScaledSpace(cb.position);

            var up = cb.transform.up;
            var space = Vector3.Cross(planet_pos - antenna_pos, up).normalized * Vector3.Distance(antenna_pos, planet_pos) * (float)Math.Tan(Math.Acos(a.Radians));
            var end1 = antenna_pos + (planet_pos + space - antenna_pos).normalized * Math.Min(a.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antenna_pos, planet_pos));
            var end2 = antenna_pos + (planet_pos - space - antenna_pos).normalized * Math.Min(a.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antenna_pos, planet_pos));


            var line_start = camera.WorldToScreenPoint(antenna_pos);
            var line_end1 = camera.WorldToScreenPoint(end1);
            var line_end2 = camera.WorldToScreenPoint(end2);
            var segment1 = new Vector3(line_end1.y - line_start.y, line_start.x - line_end1.x, 0).normalized * (LineWidth / 2);
            var segment2 = new Vector3(line_end2.y - line_start.y, line_start.x - line_end2.x, 0).normalized * (LineWidth / 2);

            if (!MapView.Draw3DLines)
            {
                var dist = Screen.height / 2;
                line_start.z = line_start.z > 0 ? dist : -dist;
                line_end1.z = line_end1.z > 0 ? dist : -dist;
                line_end2.z = line_end2.z > 0 ? dist : -dist;
            }

            mPoints2D[0] = (line_start - segment1);
            mPoints2D[1] = (line_start + segment1);
            mPoints2D[2] = (line_end1 - segment1);
            mPoints2D[3] = (line_end1 + segment1);
            mPoints2D[4] = (line_start - segment2);
            mPoints2D[5] = (line_start + segment2);
            mPoints2D[6] = (line_end2 - segment2);
            mPoints2D[7] = (line_end2 + segment2);

            for (int i = 0; i < 8; i++)
            {
                mPoints3D[i] = camera.ScreenToWorldPoint(mPoints2D[i]);
            }

            mMeshFilter.mesh.vertices = MapView.Draw3DLines ? mPoints3D : mPoints2D;

            if (!MapView.Draw3DLines)
            {
                var bounds = new Bounds();
                bounds.center = new Vector3(Screen.width / 2, Screen.height / 2, Screen.height / 2);
                bounds.extents = new Vector3(Screen.width * 100, Screen.height * 100, 0.1f);
                mMeshFilter.mesh.bounds = bounds;
            }
            else
            {
                mMeshFilter.mesh.RecalculateBounds();
            }
        }
예제 #25
0
        private void UpdateMesh(CelestialBody cb, IAntenna a)
        {
            var camera = MapView.MapCamera.camera;

            var antenna_pos = ScaledSpace.LocalToScaledSpace(RTCore.Instance.Network[a.Guid].Position);
            var planet_pos  = ScaledSpace.LocalToScaledSpace(cb.position);

            var up    = cb.transform.up;
            var space = Vector3.Cross(planet_pos - antenna_pos, up).normalized *Vector3.Distance(antenna_pos, planet_pos) * (float)Math.Tan(Math.Acos(a.Radians));
            var end1  = antenna_pos + (planet_pos + space - antenna_pos).normalized * Math.Min(a.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antenna_pos, planet_pos));
            var end2  = antenna_pos + (planet_pos - space - antenna_pos).normalized * Math.Min(a.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antenna_pos, planet_pos));


            var line_start = camera.WorldToScreenPoint(antenna_pos);
            var line_end1  = camera.WorldToScreenPoint(end1);
            var line_end2  = camera.WorldToScreenPoint(end2);
            var segment1   = new Vector3(line_end1.y - line_start.y, line_start.x - line_end1.x, 0).normalized *(LineWidth / 2);
            var segment2   = new Vector3(line_end2.y - line_start.y, line_start.x - line_end2.x, 0).normalized *(LineWidth / 2);

            if (!MapView.Draw3DLines)
            {
                var dist = Screen.height / 2;
                line_start.z = line_start.z > 0 ? dist : -dist;
                line_end1.z  = line_end1.z > 0 ? dist : -dist;
                line_end2.z  = line_end2.z > 0 ? dist : -dist;
            }

            mPoints2D[0] = (line_start - segment1);
            mPoints2D[1] = (line_start + segment1);
            mPoints2D[2] = (line_end1 - segment1);
            mPoints2D[3] = (line_end1 + segment1);
            mPoints2D[4] = (line_start - segment2);
            mPoints2D[5] = (line_start + segment2);
            mPoints2D[6] = (line_end2 - segment2);
            mPoints2D[7] = (line_end2 + segment2);

            for (int i = 0; i < 8; i++)
            {
                mPoints3D[i] = camera.ScreenToWorldPoint(mPoints2D[i]);
            }

            mMeshFilter.mesh.vertices = MapView.Draw3DLines ? mPoints3D : mPoints2D;

            if (!MapView.Draw3DLines)
            {
                var bounds = new Bounds();
                bounds.center           = new Vector3(Screen.width / 2, Screen.height / 2, Screen.height / 2);
                bounds.extents          = new Vector3(Screen.width * 100, Screen.height * 100, 0.1f);
                mMeshFilter.mesh.bounds = bounds;
            }
            else
            {
                mMeshFilter.mesh.RecalculateBounds();
            }
        }
예제 #26
0
        public static bool IsTargetingActiveVessel(this IAntenna a, ISatellite sat_b)
        {
            var active_vessel = FlightGlobals.ActiveVessel;

            if (active_vessel == null && HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                active_vessel = MapView.MapCamera.target.vessel;
            }

            return(a.Target == NetworkManager.ActiveVesselGuid && active_vessel != null && sat_b.Guid == active_vessel.id);
        }
        public AntennaWindowStandalone(IAntenna antenna)
            : base(Guid, "Antenna Configuration", new Rect(startX, startY, winWidth, winHeight), WindowAlign.Floating)
        {
            mSavePosition = true;
            mAntenna      = antenna;

            AddDefaultTargets();
            AddCelestialBodies();
            AddMissionControls();
            ComputeEntryDepths();
        }
예제 #28
0
        /// <summary>Constructs a link between two satellites, if one is possible.</summary>
        /// <returns>The new link, or null if the two satellites cannot connect.</returns>
        /// <param name="rangeFunc">A function that computes the maximum range between two
        /// satellites, given their individual ranges.</param>
        public static NetworkLink <ISatellite> GetLink(ISatellite satA, ISatellite satB,
                                                       Func <double, double, double> rangeFunc)
        {
            // Which antennas on either craft are capable of communication?
            IEnumerable <IAntenna> omnisA  = GetOmnis(satA);
            IEnumerable <IAntenna> omnisB  = GetOmnis(satB);
            IEnumerable <IAntenna> dishesA = GetDishesThatSee(satA, satB);
            IEnumerable <IAntenna> dishesB = GetDishesThatSee(satB, satA);

            // Pick the best range for each case
            double maxOmniA = omnisA.Any() ?  omnisA.Max(ant => ant.Omni) : 0.0;
            double maxOmniB = omnisB.Any() ?  omnisB.Max(ant => ant.Omni) : 0.0;
            double maxDishA = dishesA.Any() ? dishesA.Max(ant => ant.Dish) : 0.0;
            double maxDishB = dishesB.Any() ? dishesB.Max(ant => ant.Dish) : 0.0;

            double bonusA = GetMultipleAntennaBonus(omnisA, maxOmniA);
            double bonusB = GetMultipleAntennaBonus(omnisB, maxOmniB);

            double distance = satA.DistanceTo(satB);

            // Which antennas have the range to reach at least one antenna on the other satellite??
            omnisA = omnisA.Where(ant =>
                                  CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxOmniB + bonusB, omniClamp) >= distance ||
                                  CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxDishB, dishClamp) >= distance);
            dishesA = dishesA.Where(ant =>
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxOmniB + bonusB, omniClamp) >= distance ||
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxDishB, dishClamp) >= distance);
            omnisB = omnisB.Where(ant =>
                                  CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxOmniA + bonusA, omniClamp) >= distance ||
                                  CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxDishA, dishClamp) >= distance);
            dishesB = dishesB.Where(ant =>
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxOmniA + bonusA, omniClamp) >= distance ||
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxDishA, dishClamp) >= distance);

            // Just because an antenna is in `omnisA.Concat(dishesA)` doesn't mean it can connect to *any*
            //  antenna in `omnisB.Concat(dishesB)`, and vice versa. Pick the max to be safe.
            IAntenna selectedAntennaA = omnisA.Concat(dishesA)
                                        .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();
            IAntenna selectedAntennaB = omnisB.Concat(dishesB)
                                        .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();

            if (selectedAntennaA != null && selectedAntennaB != null)
            {
                List <IAntenna> interfaces = omnisA.Concat(dishesA).ToList();

                LinkType type = (dishesA.Contains(selectedAntennaA) || dishesB.Contains(selectedAntennaB)
                    ? LinkType.Dish : LinkType.Omni);

                return(new NetworkLink <ISatellite>(satB, interfaces, type));
            }

            return(null);
        }
예제 #29
0
 public Guid Register(Guid key, IAntenna antenna)
 {
     RTUtil.Log("AntennaManager: Register: " + key + ", " + antenna.Name);
     if (!mLoadedAntennaCache.ContainsKey(key)) {
         mLoadedAntennaCache[key] = new List<IAntenna>();
     }
     IAntenna instance = mLoadedAntennaCache[key].Find(x => x == antenna);
     if (instance == null) {
         mLoadedAntennaCache[key].Add(antenna);
         OnRegister(antenna);
     }
     return key;
 }
예제 #30
0
        public Guid Register(Guid key, IAntenna antenna)
        {
            RTUtil.Log("AntennaManager: Register: " + key + ", " + antenna.Name);
            if (!mLoadedAntennaCache.ContainsKey(key))
            {
                mLoadedAntennaCache[key] = new List <IAntenna>();
            }
            IAntenna instance = mLoadedAntennaCache[key].Find(x => x == antenna);

            if (instance == null)
            {
                mLoadedAntennaCache[key].Add(antenna);
                OnRegister(antenna);
            }
            return(key);
        }
예제 #31
0
        public static bool IsTargetingPlanet(this IAntenna a, ISatellite sat_b, ISatellite sat_a)
        {
            var planets = RTCore.Instance.Network.Planets;

            if (!planets.ContainsKey(a.Target) || sat_b.Body != planets[a.Target])
            {
                return(false);
            }
            var dir_cb = (planets[a.Target].position - sat_a.Position);
            var dir_b  = (sat_b.Position - sat_a.Position);

            if (Vector3d.Dot(dir_cb.normalized, dir_b.normalized) >= a.Radians)
            {
                return(true);
            }
            return(false);
        }
예제 #32
0
        public override void Correct(EpochSatellite epochSatellite)
        {
            if (AntennaDataSource == null || SatInfoService == null)
            {
                return;
            }

            Time gpsTime = epochSatellite.RecevingTime;


            //  XYZ sunPosition = epochSatellite.EpochInfo.DataSouceProvider.UniverseObjectProvider.GetSunPosition(gpsTime);// 这个可以每个历元算一次,有待优化。???czs 2014.10.05
            //下面是新的计算太阳位置
            Time tutc = gpsTime.GpstToUtc();

            //查找地球自转信息
            Gnsser.Data.ErpItem erpv = null;
            if (ErpDataService != null)
            {
                erpv = ErpDataService.Get(tutc);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }

            XYZ sunPosition = new XYZ();

            UniverseObjectProvider.GetSunPosition(gpsTime, erpv, ref sunPosition);


            IEphemeris sat = epochSatellite.Ephemeris;

            XYZ svPos = sat.XYZ;

            XYZ receiverPosition = epochSatellite.SiteInfo.EstimatedXyz;

            SatelliteNumber prn = epochSatellite.Prn;

            SatInfoFile periodSatInfoCollection = SatInfoService.SatInfoFile;
            IAntenna    antenna = AntennaDataSource.Get(prn.ToString(), gpsTime);

            double correction = GetSatPhaseCenterCorectValue(prn, gpsTime, svPos, receiverPosition, sunPosition, periodSatInfoCollection, antenna);

            this.Correction = (correction);//
        }
예제 #33
0
        /// <summary>Determines if an antenna can connect to a target indirectly, using a cone.</summary>
        /// <returns><c>true</c> if <paramref name="target"/> lies within the cone of <paramref name="dish"/>;
        /// otherwise, <c>false</c>.</returns>
        /// <param name="dish">The antenna being queried.</param>
        /// <param name="target">The satellite being tested for being the antenna target.</param>
        /// <param name="antennaSat">The satellite containing <paramref name="dish"/>.</param>
        ///
        /// <exceptsafe>The program state is unchanged in the event of an exception.</exceptsafe>
        public static bool IsInFieldOfView(this IAntenna dish, ISatellite target, ISatellite antennaSat)
        {
            if (dish.Target == Guid.Empty)
            {
                return(false);
            }

            Vector3d?coneCenter = RTCore.Instance.Network.GetPositionFromGuid(dish.Target);

            if (coneCenter.HasValue)
            {
                Vector3d dirToConeCenter = (coneCenter.Value - antennaSat.Position);
                Vector3d dirToTarget     = (target.Position - antennaSat.Position);

                return(Vector3d.Dot(dirToConeCenter.normalized, dirToTarget.normalized) >= dish.CosAngle);
            }

            return(false);
        }
예제 #34
0
        public void Unregister(Guid key, IAntenna antenna)
        {
            RTUtil.Log("AntennaManager: Unregister: " + key + ", " + antenna.Name);
            if (!mLoadedAntennaCache.ContainsKey(key))
            {
                return;
            }

            int instance_id = mLoadedAntennaCache[key].FindIndex(x => x == antenna);

            if (instance_id != -1)
            {
                mLoadedAntennaCache[key].RemoveAt(instance_id);
                if (mLoadedAntennaCache[key].Count == 0)
                {
                    mLoadedAntennaCache.Remove(key);
                }
                OnUnregister(antenna);
            }
        }
예제 #35
0
        public void Draw()
        {
            if (Satellite == null)
            {
                return;
            }

            GUILayout.BeginHorizontal();
            {
                GUILayout.TextField(Satellite.Name.Truncate(25), GUILayout.ExpandWidth(true));
                RTUtil.Button("Name", () =>
                {
                    var vessel = FlightGlobals.Vessels.First(v => v.id == Satellite.Guid);
                    if (vessel)
                    {
                        vessel.RenameVessel();
                    }
                }, GUILayout.ExpandWidth(false), GUILayout.Height(24));
            }
            GUILayout.EndHorizontal();

            mScrollPosition = GUILayout.BeginScrollView(mScrollPosition, GUILayout.ExpandHeight(true));
            {
                Color      pushColor = GUI.contentColor;
                TextAnchor pushAlign = GUI.skin.button.alignment;
                GUI.skin.button.alignment = TextAnchor.MiddleLeft;
                foreach (var a in Satellite.Antennas.Where(a => a.CanTarget))
                {
                    GUI.contentColor = (a.Powered) ? XKCDColors.ElectricLime : XKCDColors.Scarlet;
                    String text = a.Name.Truncate(25) + Environment.NewLine + "Target: " + RTUtil.TargetName(a.Target).Truncate(18);
                    RTUtil.StateButton(text, Antenna, a, s =>
                    {
                        Antenna = (s > 0) ? a : null;
                    });
                }
                GUI.skin.button.alignment = pushAlign;
                GUI.contentColor          = pushColor;
            }
            GUILayout.EndScrollView();
        }
예제 #36
0
        /// <summary>
        /// 计算改正数
        /// </summary>
        /// <param name="input"></param>
        public override void Correct(EpochInformation input)
        {
            if (input.EnabledSatCount == 0)
            {
                return;
            }
            var correction = new Dictionary <RinexSatFrequency, NEU>();

            IAntenna antenna = input.SiteInfo.Antenna;

            if (antenna == null)
            {
                if (!WarnedSites.Contains(input.SiteInfo.SiteName))
                {
                    WarnedSites.Add(input.SiteInfo.SiteName);
                    log.Warn(input.Name + "接收机天线为: " + input.SiteInfo.AntennaType + ", " + input.SiteInfo.AntennaNumber + " 没有在天线文件夹中找到该类型的天线,无法进行 PCV 改正,精度影响可达10厘米(特别是高程)!请到 https://www.ngs.noaa.gov/ANTCAL/ 下载对应天线改正信息,并追加到.atx文件中");
                }
                this.Correction = correction;
                return;
            }

            foreach (var item in antenna.Data)
            {
                var satFreq = item.Key;
                var pco     = antenna.GetPcoValue(satFreq); //这个值不变,实际上一次赋值就可以了!!//2018.08.02, czs,in hmx
                correction.Add(satFreq, pco);
            }
            //多频的权宜之计
            if (input.SatelliteTypes.Count > 0)
            {
                correction[RinexSatFrequency.BdsA]     = correction[RinexSatFrequency.GpsA];
                correction[RinexSatFrequency.BdsB]     = correction[RinexSatFrequency.GpsB];
                correction[RinexSatFrequency.GalileoA] = correction[RinexSatFrequency.GpsA];
                correction[RinexSatFrequency.GalileoB] = correction[RinexSatFrequency.GpsB];
            }

            this.Correction = correction;
        }
예제 #37
0
 public void OpenAntennaConfig(IAntenna a, ISatellite s)
 {
     (new AntennaWindow(a, s)).Show();
 }
 private void OnAntenna(IAntenna antenna)
 {
     if (antenna == mFocus) {
         mForceClose.Invoke();
     }
 }
 public void Refresh(IAntenna sat)
 {
     if (sat == Antenna) { Antenna = null; }
 }
 private void OnAntenna(IAntenna antenna)
 {
     if (mFocusAntennas.Contains(antenna)) {
         RebuildAntennaList();
     }
 }
예제 #41
0
 /// <summary>Determines if an antenna has a specific satellite as its target.</summary>
 /// <returns><c>true</c> if a's target is set to <paramref name="target"/>; false otherwise.</returns>
 /// <param name="dish">The antenna being queried.</param>
 /// <param name="target">The satellite being tested for being the antenna target.</param>
 public static bool IsTargetingDirectly(this IAntenna dish, ISatellite target)
 {
     return(dish.Target == target.Guid);
 }
예제 #42
0
 /// <summary>
 /// Set a new target for this targetwindow
 /// </summary>
 /// <param name="target">Target from the antenna fragment</param>
 /// <param name="antenna">current antenna</param>
 public void SetTarget(AntennaFragment.Entry target,IAntenna antenna)
 {
     tif.SetTarget(target, antenna);
 }
예제 #43
0
 public void Refresh(IAntenna sat)
 {
     if (sat == Antenna) { Antenna = null; mOnQuit.Invoke(); }
 }
예제 #44
0
        public void Unregister(Guid key, IAntenna antenna)
        {
            RTUtil.Log("AntennaManager: Unregister: " + key + ", " + antenna.Name);
            if (!mLoadedAntennaCache.ContainsKey(key)) return;

            int instance_id = mLoadedAntennaCache[key].FindIndex(x => x == antenna);

            if (instance_id != -1) {
                mLoadedAntennaCache[key].RemoveAt(instance_id);
                if (mLoadedAntennaCache[key].Count == 0) {
                    mLoadedAntennaCache.Remove(key);
                }
                OnUnregister(antenna);
            }
        }
예제 #45
0
        /// <summary>Tests whether an antenna can connect to a target</summary>
        /// <returns>The range to the target, or a diagnostic error message. Returns the
        /// empty string if target is invalid.</returns>
        /// <param name="antenna">The antenna attempting to make a connection.</param>
        /// <param name="target">The Guid to which it is trying to connect.</param>
        public static KeyValuePair <string, UnityEngine.Color> tryConnection(IAntenna antenna, Guid target)
        {
            String status = "ok";

            // What kind of target?
            if (RTCore.Instance != null && RTCore.Instance.Network != null &&
                target != Guid.Empty && target != NetworkManager.ActiveVesselGuid)
            {
                bool warning = false, error = false;

                ISatellite mySat = RTCore.Instance.Network[antenna.Guid];
                if (mySat == null)
                {
                    return(new KeyValuePair <string, UnityEngine.Color>("", UnityEngine.Color.white));
                }

                List <string> conditions = new List <string>();

                // Most probably a satellite
                ISatellite targetSat = RTCore.Instance.Network[target];
                if (targetSat != null)
                {
                    if (!RangeModelExtensions.HasLineOfSightWith(mySat, targetSat))
                    {
                        status = "No line of sight";
                        error  = true;
                    }

                    double dist = RangeModelExtensions.DistanceTo(mySat, targetSat);
                    // Only standard model supported for now, RangeModel isn't designed for this problem
                    double maxDist = Math.Max(antenna.Omni, antenna.Dish);
                    conditions.Add("Current distance:" + RTUtil.FormatSI(dist, "m"));
                    conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));
                    if (dist > maxDist)
                    {
                        status = "Target not in range";
                        error  = true;
                    }
                }

                try {
                    CelestialBody targetPlanet = RTCore.Instance.Network.Planets[target];
                    double        dist         = Vector3d.Distance(mySat.Position, targetPlanet.position);
                    double        maxDist      = Math.Max(antenna.Omni, antenna.Dish);
                    double        spread       = 2.0 * dist * Math.Sqrt(1 - antenna.CosAngle * antenna.CosAngle);
                    int           numTargets   = countInCone(antenna, target);

                    if (spread < 2.0 * targetPlanet.Radius)
                    {
                        // WHAT does this info?
                        // conditions.Add("Small Cone");
                        warning = true;
                    }

                    conditions.Add("Current distance:" + RTUtil.FormatSI(dist, "m"));
                    conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));

                    if (dist <= maxDist)
                    {
                        conditions.Add(String.Format("Info:{0} beam covers {1} targets)",
                                                     RTUtil.FormatSI(spread, "m"),
                                                     numTargets
                                                     ));
                    }
                    else
                    {
                        status = "Target not in range";
                        error  = true;
                    }
                    if (numTargets <= 0)
                    {
                        warning = true;
                    }
                } catch (KeyNotFoundException) {}

                conditions.Add("Status:" + status);

                return(new KeyValuePair <string, UnityEngine.Color>(
                           String.Join("; ", conditions.ToArray()),
                           error ? UnityEngine.Color.red : (warning ? UnityEngine.Color.yellow : UnityEngine.Color.white)
                           ));
            }

            // Default behavior
            return(new KeyValuePair <string, UnityEngine.Color>("", UnityEngine.Color.white));
        }
 public AntennaWindow(IAntenna antenna, ISatellite sat)
     : base("Antenna Configuration", new Rect(100, 100, 0, 0), WindowAlign.Floating)
 {
     mAntenna = antenna;
     mSatellite = sat;
 }
예제 #47
0
 /// <summary>Finds the maximum range between an antenna and a potential target.</summary>
 /// <returns>The maximum distance at which the two spacecraft could communicate.</returns>
 /// <param name="antenna">The antenna attempting to target.</param>
 /// <param name="target">The satellite being targeted by <paramref name="antenna"/>.</param>
 /// <param name="antennaSat">The satellite on which <paramref name="antenna"/> is mounted.</param>
 public static double GetRangeInContext(IAntenna antenna, ISatellite target, ISatellite antennaSat) {
     return AbstractRangeModel.GetRangeInContext(antenna, target, antennaSat, MaxDistance);
 }
예제 #48
0
 private void OnRegister(IAntenna antenna)
 {
     if (Registered != null) {
         Registered(antenna);
     }
 }
        private void UpdateMesh(Vector3d center, IAntenna dish)
        {
            var camera = PlanetariumCamera.Camera;

            Vector3d antennaPos = ScaledSpace.LocalToScaledSpace(RTCore.Instance.Network[dish.Guid].Position);
            Vector3d planetPos = ScaledSpace.LocalToScaledSpace(center);

            CelestialBody refFrame = (MapView.MapCamera.target.vessel != null
                ? MapView.MapCamera.target.vessel.mainBody
                : MapView.MapCamera.target.celestialBody);
            Vector3 up = (refFrame != null ? refFrame.transform.up : Vector3.up);

            Vector3 space = Vector3.Cross(planetPos - antennaPos, up).normalized
                * Vector3.Distance(antennaPos, planetPos)
                * (float)Math.Tan(Math.Acos(dish.CosAngle));
            Vector3d end1 = antennaPos + (planetPos + space - antennaPos).normalized
                * Math.Min(dish.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antennaPos, planetPos));
            Vector3d end2 = antennaPos + (planetPos - space - antennaPos).normalized
                * Math.Min(dish.Dish / ScaledSpace.ScaleFactor, Vector3.Distance(antennaPos, planetPos));

            Vector3 lineStart = camera.WorldToScreenPoint(antennaPos);
            Vector3 lineEnd1 = camera.WorldToScreenPoint(end1);
            Vector3 lineEnd2 = camera.WorldToScreenPoint(end2);
            var segment1 = new Vector3(lineEnd1.y - lineStart.y, lineStart.x - lineEnd1.x, 0).normalized * (LineWidth / 2);
            var segment2 = new Vector3(lineEnd2.y - lineStart.y, lineStart.x - lineEnd2.x, 0).normalized * (LineWidth / 2);

            if (!MapView.Draw3DLines)
            {
                int dist = Screen.height / 2;
                lineStart.z = lineStart.z > 0 ? dist : -dist;
                lineEnd1.z = lineEnd1.z > 0 ? dist : -dist;
                lineEnd2.z = lineEnd2.z > 0 ? dist : -dist;
            }

            mPoints2D[0] = (lineStart - segment1);
            mPoints2D[1] = (lineStart + segment1);
            mPoints2D[2] = (lineEnd1 - segment1);
            mPoints2D[3] = (lineEnd1 + segment1);
            mPoints2D[4] = (lineStart - segment2);
            mPoints2D[5] = (lineStart + segment2);
            mPoints2D[6] = (lineEnd2 - segment2);
            mPoints2D[7] = (lineEnd2 + segment2);

            for (int i = 0; i < 8; i++)
            {
                mPoints3D[i] = camera.ScreenToWorldPoint(mPoints2D[i]);
            }

            mMeshFilter.mesh.vertices = MapView.Draw3DLines ? mPoints3D : mPoints2D;

            if (!MapView.Draw3DLines)
            {
                var bounds = new Bounds();
                bounds.center = new Vector3(Screen.width / 2, Screen.height / 2, Screen.height / 2);
                bounds.extents = new Vector3(Screen.width * 100, Screen.height * 100, 0.1f);
                mMeshFilter.mesh.bounds = bounds;
            }
            else
            {
                mMeshFilter.mesh.RecalculateBounds();
            }
        }
예제 #50
0
        /// <summary>
        /// 根据太阳计算卫星偏差
        /// </summary>
        /// <param name="prn"></param>
        /// <param name="eph"></param>
        /// <param name="emissionTime"></param>
        /// <returns></returns>
        private XYZ GetSatAntOff(SatelliteNumber prn, IEphemeris eph, Time emissionTime)
        {
            ErpItem erpv = null;

            if (DataSouceProvider.ErpDataService != null)
            {
                erpv = DataSouceProvider.ErpDataService.Get(emissionTime);
            }
            if (erpv == null)
            {
                erpv = ErpItem.Zero;
            }
            XYZ rsun = new XYZ();

            //sun position in ecef
            //  rsun = EpochSat.EpochInfo.DataSouceProvider.UniverseObjectProvider.GetSunPosition(emissionTime);
            this.DataSouceProvider.UniverseObjectProvider.GetSunPosition(emissionTime, erpv, ref rsun);


            //unit vetcors of satellite fixed coordinates

            XYZ ez = -1 * eph.XYZ.UnitVector();

            XYZ es = (rsun - eph.XYZ).UnitVector();
            //outer product of 3D vectors
            XYZ r = new XYZ();

            r.X = ez.Y * es.Z - ez.Z * es.Y;
            r.Y = ez.Z * es.X - ez.X * es.Z;
            r.Z = ez.X * es.Y - ez.Y * es.X;



            XYZ r0 = new XYZ();

            r0.X = r.Y * ez.Z - r.Z * ez.Y;
            r0.Y = r.Z * ez.X - r.X * ez.Z;
            r0.Z = r.X * ez.Y - r.Y * ez.X;

            XYZ ex = r0.UnitVector();


            XYZ ey = r.UnitVector();


            //XYZ ex = new XYZ();

            //ex.X = ey.Y * ez.Z - ey.Z * ez.Y;
            //ex.Y = ey.Z * ez.X - ey.X * ez.Z;
            //ex.Z = ey.X * ez.Y - ey.Y * ez.X;


            //use L1 value
            if (DataSouceProvider.AntennaDataSource == null)
            {
                return(new XYZ());
            }

            IAntenna antenna = DataSouceProvider.AntennaDataSource.Get(prn.ToString(), emissionTime);

            //如果为空,则返回 0 坐标
            if (antenna == null)
            {
                return(new XYZ());
            }

            // Get antenna eccentricity for frequency "G01" (L1), in
            // satellite reference system.
            // NOTE: It is NOT in ECEF, it is in UEN!!!
            RinexSatFrequency freq = new RinexSatFrequency(prn, 1);
            // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01);
            NEU satAnt = antenna.GetPcoValue(freq);

            XYZ dant = new XYZ();

            dant.X = satAnt.E * ex.X + satAnt.N * ey.X + satAnt.U * ez.X;
            dant.Y = satAnt.E * ex.Y + satAnt.N * ey.Y + satAnt.U * ez.Y;
            dant.Z = satAnt.E * ex.Z + satAnt.N * ey.Z + satAnt.U * ez.Z;


            // Unitary vector from satellite to Earth mass center (ECEF)
            XYZ satToEarthUnit = (-1.0) * eph.XYZ.UnitVector();

            // Unitary vector from Earth mass center to Sun (ECEF)
            XYZ earthToSunUnit = rsun.UnitVector();
            // rj = rk x ri: Rotation axis of solar panels (ECEF)
            XYZ rj = satToEarthUnit.Cross(earthToSunUnit);

            // Redefine ri: ri = rj x rk (ECEF)
            earthToSunUnit = rj.Cross(satToEarthUnit);
            // Let's funcKeyToDouble ri to an unitary vector. (ECEF)
            earthToSunUnit = earthToSunUnit.UnitVector();

            XYZ dant1 = new XYZ();

            dant1.X = satAnt.E * rj.X + satAnt.N * earthToSunUnit.X + satAnt.U * satToEarthUnit.X;
            dant1.Y = satAnt.E * rj.Y + satAnt.N * earthToSunUnit.Y + satAnt.U * satToEarthUnit.Y;
            dant1.Z = satAnt.E * rj.Z + satAnt.N * earthToSunUnit.Z + satAnt.U * satToEarthUnit.Z;

            return(dant1);
        }
예제 #51
0
 public int CompareTo(IAntenna antenna)
 {
     return(Consumption.CompareTo(antenna.Consumption));
 }
 public AntennaWindow(IAntenna antenna, ISatellite sat)
     : base("Antenna Configuration", new Rect(100, 100, 0, 0), WindowAlign.Floating)
 {
     mAntenna   = antenna;
     mSatellite = sat;
 }
예제 #53
0
 public AntennaWindow(IAntenna antenna)
     : base(Guid, "Antenna Configuration", new Rect(100, 100, 300, 500), WindowAlign.Floating)
 {
     mSetAntenna = antenna;
 }
예제 #54
0
 /// <summary>
 /// Initialize the targetinfoFragment with a targetEntry and an antenna
 /// </summary>
 /// <param name="targetEntry">Target from the antenna fragment</param>
 /// <param name="antenna">current antenna</param>
 public TargetInfoFragment(AntennaFragment.Entry targetEntry, IAntenna antenna)
     : this()
 {
     SetTarget(targetEntry, antenna);
 }
 public int CompareTo(IAntenna antenna)
 {
     return Consumption.CompareTo(antenna.Consumption);
 }
예제 #56
0
 /// <summary>
 /// Set a new target to the targetfragment with a targetEntry and an antenna
 /// </summary>
 /// <param name="targetEntry">Target from the antenna fragment</param>
 /// <param name="antenna">current antenna</param>
 public void SetTarget(AntennaFragment.Entry targetEntry, IAntenna antenna)
 {
     target = new Target {TargetEntry = targetEntry, Antenna = antenna};
 }
예제 #57
0
        /// <summary>Tests whether an antenna can connect to a target</summary>
        /// <returns>The range to the target, or a diagnostic error message. Returns the 
        /// empty string if target is invalid.</returns>
        /// <param name="antenna">The antenna attempting to make a connection.</param>
        /// <param name="target">The Guid to which it is trying to connect.</param>
        public static KeyValuePair<string, UnityEngine.Color> tryConnection(IAntenna antenna, Guid target) {
            String status = "ok";
            // What kind of target?
            if (RTCore.Instance != null && RTCore.Instance.Network != null &&
                    target != Guid.Empty && target != NetworkManager.ActiveVesselGuid) {
                bool warning = false, error = false;

                ISatellite mySat = RTCore.Instance.Network[antenna.Guid];
                if (mySat == null)
                    return new KeyValuePair<string, UnityEngine.Color>("", UnityEngine.Color.white);

                List<string> conditions = new List<string>();

                // Most probably a satellite
                ISatellite targetSat = RTCore.Instance.Network[target];
                if (targetSat != null) {
                    if (!RangeModelExtensions.HasLineOfSightWith(mySat, targetSat)) {
                        status = "No line of sight";
                        error = true;
                    }

                    double dist    = RangeModelExtensions.DistanceTo(mySat, targetSat);
                    // Only standard model supported for now, RangeModel isn't designed for this problem
                    double maxDist = Math.Max(antenna.Omni, antenna.Dish);
                    conditions.Add("Current distance:" + RTUtil.FormatSI(dist, "m"));
                    conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));
                    if (dist > maxDist) {
                        status = "Target not in range";
                        error = true;
                    }
                }

                try {
                    CelestialBody targetPlanet = RTCore.Instance.Network.Planets[target];
                    double dist = Vector3d.Distance(mySat.Position, targetPlanet.position);
                    double maxDist = Math.Max(antenna.Omni, antenna.Dish);
                    double spread = 2.0 * dist * Math.Sqrt(1-antenna.CosAngle*antenna.CosAngle);
                    int numTargets = countInCone(antenna, target);
                    
                    if (spread < 2.0 * targetPlanet.Radius) {
                        // WHAT does this info?
                        // conditions.Add("Small Cone");
                        warning = true;
                    }

                    conditions.Add("Current distance:"+RTUtil.FormatSI(dist, "m"));
                    conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));

                    if (dist <= maxDist) {
                        conditions.Add(String.Format("Info:{0} beam covers {1} targets)",
                            RTUtil.FormatSI(spread, "m"),
                            numTargets
                        ));
                    } else {
                        status = "Target not in range";
                        error = true;
                    }
                    if (numTargets <= 0) {
                        warning = true;
                    }

                } catch (KeyNotFoundException) {}

                conditions.Add("Status:" + status);

                return new KeyValuePair<string, UnityEngine.Color>(
                    String.Join("; ", conditions.ToArray()), 
                    error ? UnityEngine.Color.red : (warning ? UnityEngine.Color.yellow : UnityEngine.Color.white)
                );
            }

            // Default behavior
            return new KeyValuePair<string, UnityEngine.Color>("", UnityEngine.Color.white);
        }
예제 #58
0
 private void OnUnregister(IAntenna antenna)
 {
     if (Unregistered != null) {
         Unregistered(antenna);
     }
 }