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); } }
/// <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)); }
/// <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); }
public void Refresh(IAntenna sat) { if (sat == Antenna) { Antenna = null; } }
/// <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(); } }
/// <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); }
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(); }
private void OnAntenna(IAntenna antenna) { if (antenna == mFocus) { mForceClose.Invoke(); } }
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); }
/// <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; } }
public void OpenAntennaConfig(IAntenna a, Vessel v) { ISatellite s = RTCore.Instance.Satellites[v]; if (s != null) { (new AntennaWindow(a, s)).Show(); } }
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()); } }
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(); }
public AntennaConfigFragment(IAntenna antenna, OnClick forceClose, OnAntenna onUpdate) { mFocus = antenna; mForceClose = forceClose; mOnUpdate = onUpdate; RTCore.Instance.Antennas.Unregistered += OnAntenna; RebuildTargetList(); }
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(); } }
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(); } }
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(); }
/// <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); }
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; }
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); }
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); }
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);// }
/// <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); }
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); } }
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(); }
/// <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; }
public void OpenAntennaConfig(IAntenna a, ISatellite s) { (new AntennaWindow(a, s)).Show(); }
/// <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); }
/// <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); }
public void Refresh(IAntenna sat) { if (sat == Antenna) { Antenna = null; mOnQuit.Invoke(); } }
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); } }
/// <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; }
/// <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); }
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(); } }
/// <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); }
public int CompareTo(IAntenna antenna) { return(Consumption.CompareTo(antenna.Consumption)); }
public AntennaWindow(IAntenna antenna) : base(Guid, "Antenna Configuration", new Rect(100, 100, 300, 500), WindowAlign.Floating) { mSetAntenna = antenna; }
/// <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); }
/// <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}; }
/// <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); }