diff --git a/src/RealAntennasProject/Physics.cs b/src/RealAntennasProject/Physics.cs index 87c049f..29a281e 100644 --- a/src/RealAntennasProject/Physics.cs +++ b/src/RealAntennasProject/Physics.cs @@ -227,8 +227,8 @@ public static float NoiseTemperature(RealAntenna rx, Vector3d origin) float amt = AntennaMicrowaveTemp(rx); float atmos = AtmosphericTemp(rx, origin); float cosmic = CosmicBackgroundTemp(rx, origin); - // Home Stations are directional, but treated as always pointing towards the peer. - float allbody = rx.ParentNode.isHome ? AllBodyTemps(rx, origin - rx.Position) : AllBodyTemps(rx, rx.ToTarget); + // Tracking antennas always point towards the peer. + float allbody = (rx.IsTracking) ? AllBodyTemps(rx, origin - rx.Position) : AllBodyTemps(rx, rx.ToTarget); float total = amt + atmos + cosmic + allbody; // Debug.LogFormat("NoiseTemp: Antenna {0:F2} Atmos: {1:F2} Cosmic: {2:F2} Bodies: {3:F2} Total: {4:F2}", amt, atmos, cosmic, allbody, total); return total; @@ -260,11 +260,11 @@ public static float NoiseTemperature(RealAntenna rx, Vector3d origin) // P(dBW) = 10*log10(Kb*T*bandwidth) = -228.59917 + 10*log10(T*BW) } public static float AntennaMicrowaveTemp(RealAntenna rx) => - ((rx.ParentNode as RACommNode)?.ParentBody is CelestialBody) ? rx.AMWTemp : rx.TechLevelInfo.ReceiverNoiseTemperature; + (rx.ParentNode is RACommNode raNode && raNode.isGroundStation) ? rx.AMWTemp : rx.TechLevelInfo.ReceiverNoiseTemperature; public static float AtmosphericTemp(RealAntenna rx, Vector3d origin) { - if (rx.ParentNode is RACommNode rxNode && rxNode.ParentBody != null) + if (rx.ParentNode is RACommNode rxNode && rxNode.isGroundStation) { Vector3d normal = rxNode.GetSurfaceNormalVector(); return AtmosphericTemp(new double3(rx.Position.x, rx.Position.y, rx.Position.z), @@ -299,12 +299,12 @@ private static float CosmicBackgroundTemp(RealAntenna rx, Vector3d origin) float temp = 3; if (rx.ParentNode is RACommNode rxNode) { - Vector3d normal = (rxNode.ParentBody is CelestialBody) ? rxNode.GetSurfaceNormalVector() : Vector3d.zero; + Vector3d normal = rxNode.isGroundStation ? rxNode.GetSurfaceNormalVector() : Vector3d.zero; Vector3d to_origin = origin - rx.Position; temp = CosmicBackgroundTemp(new double3(normal.x, normal.y, normal.z), new double3(to_origin.x, to_origin.y, to_origin.z), rx.Frequency, - rxNode.isHome); + rxNode.isGroundStation); } return temp; @@ -320,7 +320,7 @@ public static float AllBodyTemps(RealAntenna rx, Vector3d rxPointing) // Note there are ~33 bodies in RSS. foreach (CelestialBody body in FlightGlobals.Bodies) { - if (!node.isHome || !node.ParentBody.Equals(body)) + if (!node.isGroundStation || !node.ParentBody.Equals(body)) { temp += BodyNoiseTemp(rx, body, rxPointing); } diff --git a/src/RealAntennasProject/PlannerGUI.cs b/src/RealAntennasProject/PlannerGUI.cs index 4b6175e..623dca5 100644 --- a/src/RealAntennasProject/PlannerGUI.cs +++ b/src/RealAntennasProject/PlannerGUI.cs @@ -349,18 +349,23 @@ private void FireOnce() var defaultPos = home.GetWorldSurfacePosition(0, 0, 100); var defaultOffset = home.GetWorldSurfacePosition(0, 0, 1e6); var defaultDir = (defaultOffset - defaultPos).normalized; - var offset = fixedNode.isHome ? 1e8 : 0; + fixedNode.isHome = fixedAntenna.ParentNode?.isHome ?? false; + primaryNearNode.isHome = primaryFarNode.isHome = primaryAntenna.ParentNode?.isHome ?? false; + primaryNearNode.ParentBody = (primaryAntenna.ParentNode as RACommNode)?.ParentBody; + primaryFarNode.ParentBody = (primaryAntenna.ParentNode as RACommNode)?.ParentBody; + fixedNode.ParentBody = (fixedAntenna.ParentNode as RACommNode)?.ParentBody; + primaryNearNode.ParentVessel = (primaryAntenna.ParentNode as RACommNode)?.ParentVessel; // Copy this info over as well in case anything needs it. + primaryFarNode.ParentVessel = (primaryAntenna.ParentNode as RACommNode)?.ParentVessel; + fixedNode.ParentVessel = (fixedAntenna.ParentNode as RACommNode)?.ParentVessel; + + var offset = fixedNode.isGroundStation ? 1e8 : 0; fixedNode.transform.SetPositionAndRotation(defaultPos + offset * defaultDir, Quaternion.identity); primaryNearNode.transform.SetPositionAndRotation(defaultPos + (offset + distanceMin) * defaultDir, Quaternion.identity); primaryFarNode.transform.SetPositionAndRotation(defaultPos + (offset + distanceMax) * defaultDir, Quaternion.identity); + fixedNode.precisePosition = fixedNode.position; primaryNearNode.precisePosition = primaryNearNode.position; primaryFarNode.precisePosition = primaryFarNode.position; - fixedNode.isHome = fixedAntenna.ParentNode?.isHome ?? false; - primaryNearNode.isHome = primaryFarNode.isHome = primaryAntenna.ParentNode?.isHome ?? false; - primaryNearNode.ParentBody = (primaryAntenna.ParentNode as RACommNode)?.ParentBody; - primaryFarNode.ParentBody = (primaryAntenna.ParentNode as RACommNode)?.ParentBody; - fixedNode.ParentBody = (fixedAntenna.ParentNode as RACommNode)?.ParentBody; var nodes = new List { fixedNode, primaryNearNode }; var bodies = new List { Planetarium.fetch.Home }; diff --git a/src/RealAntennasProject/Precompute/FilteringJobs.cs b/src/RealAntennasProject/Precompute/FilteringJobs.cs index a85d9c4..260e135 100644 --- a/src/RealAntennasProject/Precompute/FilteringJobs.cs +++ b/src/RealAntennasProject/Precompute/FilteringJobs.cs @@ -18,7 +18,7 @@ public void Execute(int index) int y = pairs[index].y; CNInfo a = nodes[x]; CNInfo b = nodes[y]; - valid[index] = x != y && !(a.isHome && b.isHome) && a.canComm && b.canComm; + valid[index] = x != y && !(a.isGroundStation && b.isGroundStation) && a.canComm && b.canComm; } } diff --git a/src/RealAntennasProject/Precompute/Precompute.cs b/src/RealAntennasProject/Precompute/Precompute.cs index 199ff00..2b9a57f 100644 --- a/src/RealAntennasProject/Precompute/Precompute.cs +++ b/src/RealAntennasProject/Precompute/Precompute.cs @@ -28,7 +28,7 @@ public struct CNInfo { internal double3 position; internal double3 surfaceNormal; - internal bool isHome; + internal bool isGroundStation; internal bool canComm; } @@ -682,7 +682,7 @@ private void SetupCommNodes(out NativeList infos, List infos.Add(new CNInfo() { position = new double3(node.precisePosition.x, node.precisePosition.y, node.precisePosition.z), - isHome = node.isHome, + isGroundStation = node.isGroundStation, canComm = forceValid || node.CanComm(), surfaceNormal = new double3(surfN.x, surfN.y, surfN.z), //name = $"{node}", @@ -736,7 +736,7 @@ private NativeArray GatherAllAntennas(Dictionary // ParentVessel deep enough in the atmosphere. // It might make sense to take the altitude into // account eventually. - inAtmosphere = node.ParentBody != null, + inAtmosphere = node.isGroundStation, isTracking = ra.IsTracking, AMW = Physics.AntennaMicrowaveTemp(ra), encoder = new Encoder(ra.Encoder), diff --git a/src/RealAntennasProject/RACommNetVessel.cs b/src/RealAntennasProject/RACommNetVessel.cs index 1a2b0e2..599b2a6 100644 --- a/src/RealAntennasProject/RACommNetVessel.cs +++ b/src/RealAntennasProject/RACommNetVessel.cs @@ -256,8 +256,8 @@ public List DiscoverAntennas() } private void ValidateAntennaTarget(RealAntenna ra) { - if (ra.CanTarget && !(ra.Target?.Validate() == true)) - ra.Target = Targeting.AntennaTarget.LoadFromConfig(ra.SetDefaultTarget(), ra); + if (ra.CanTarget && ra.Target?.Validate() != true) + ra.SetDefaultTarget(); } public static bool DeployedUnloaded(ProtoPartSnapshot part) { diff --git a/src/RealAntennasProject/RACommNetwork.cs b/src/RealAntennasProject/RACommNetwork.cs index 866f941..742c44d 100644 --- a/src/RealAntennasProject/RACommNetwork.cs +++ b/src/RealAntennasProject/RACommNetwork.cs @@ -22,6 +22,8 @@ public class RACommNetwork : CommNetwork public List Nodes { get => nodes; } public RealAntenna DebugAntenna => connectionDebugger?.antenna; public Network.ConnectionDebugger connectionDebugger = null; + public readonly EventVoid NetworkUpdateComplete = new EventVoid("Network Rebuild Complete"); + public double LastUpdateUT { get; private set; } = 0; public override CommNode Add(CommNode conn) { @@ -164,6 +166,8 @@ public virtual void CompleteRebuild() PostUpdateNodes(); if (OnNetworkPostUpdate is Action) OnNetworkPostUpdate(); + LastUpdateUT = Planetarium.GetUniversalTime(); + NetworkUpdateComplete.Fire(); tempWatch.Stop(); Profiler.EndSample(); (RACommNetScenario.Instance as RACommNetScenario).metrics.AddMeasurement("Precompute LateRebuild", PrecomputeLateWatch.Elapsed.TotalMilliseconds); diff --git a/src/RealAntennasProject/RACommNode.cs b/src/RealAntennasProject/RACommNode.cs index e8ddbdb..1c967d9 100644 --- a/src/RealAntennasProject/RACommNode.cs +++ b/src/RealAntennasProject/RACommNode.cs @@ -10,6 +10,8 @@ public class RACommNode : CommNet.CommNode public List RAAntennaList { get; set; } public CelestialBody ParentBody { get; set; } public Vessel ParentVessel { get; set; } + public bool isGroundStation => ParentBody != null; + // Skopos stations have isHome set to false, hence the need for this check. public RACommNode() : base() { } public RACommNode(Transform t) : base(t) @@ -31,7 +33,7 @@ public Vector3d GetSurfaceNormalVector() public bool CanComm() { - if (ParentBody != null) return true; + if (isGroundStation) return true; return (ParentVessel?.Connection is RACommNetVessel raCNV) && raCNV.powered && raCNV.CanComm; } diff --git a/src/RealAntennasProject/RealAntenna.cs b/src/RealAntennasProject/RealAntenna.cs index bac4083..23ea17d 100644 --- a/src/RealAntennasProject/RealAntenna.cs +++ b/src/RealAntennasProject/RealAntenna.cs @@ -45,6 +45,8 @@ public class RealAntenna public virtual bool CanTarget => Shape != AntennaShape.Omni && !IsTracking; public Vector3 ToTarget => (CanTarget && Target != null) ? (Vector3) (Target.transform.position - Position) : Vector3.zero; + // In the absence of a TARGET config node, antennas will target the centre of the home body. + // However, if the antenna belongs to a node with a ParentBody, Target will be set to null. private Targeting.AntennaTarget _target; public Targeting.AntennaTarget Target { @@ -119,8 +121,9 @@ public virtual void LoadFromConfigNode(ConfigNode config) AMWTemp = (config.HasValue("AMWTemp")) ? float.Parse(config.GetValue("AMWTemp")) : 290f; if (config.HasNode("TARGET")) Target = Targeting.AntennaTarget.LoadFromConfig(config.GetNode("TARGET"), this); - else if (Shape != AntennaShape.Omni && (ParentNode == null || !ParentNode.isHome) && !(Target?.Validate() == true) && HighLogic.LoadedSceneHasPlanetarium) - Target = Targeting.AntennaTarget.LoadFromConfig(SetDefaultTarget(), this); + else if (Shape != AntennaShape.Omni && Target?.Validate() != true && HighLogic.LoadedSceneHasPlanetarium) + SetDefaultTarget(); + EncoderOverride = (config.HasValue("EncoderOverride")) ? config.GetValue("EncoderOverride") : null; } @@ -152,14 +155,24 @@ public virtual void UpgradeFromConfigNode(ConfigNode config) if (config.TryGetValue("RFBand", ref s)) RFBand = Antenna.BandInfo.All[s]; if (config.TryGetValue("EncoderOverride", ref s)) EncoderOverride = s; } - - public virtual ConfigNode SetDefaultTarget() + + public virtual void SetDefaultTarget() { - var x = new ConfigNode(Targeting.AntennaTarget.nodeName); - x.AddValue("name", $"{Targeting.AntennaTarget.TargetMode.BodyLatLonAlt}"); - x.AddValue("bodyName", Planetarium.fetch.Home.name); - x.AddValue("latLonAlt", new Vector3(0, 0, (float)-Planetarium.fetch.Home.Radius)); - return x; + if (!(ParentNode is RACommNode raNode)) + { + Debug.Log($"{ModTag} {ParentNode?.displayName} is not an RA comm node but has a RealAntenna! Defaulting target for {Name} to null"); + Target = null; + } + else if (raNode.isGroundStation) + Target = null; + else + { + var x = new ConfigNode(Targeting.AntennaTarget.nodeName); + x.AddValue("name", $"{Targeting.AntennaTarget.TargetMode.BodyLatLonAlt}"); + x.AddValue("bodyName", Planetarium.fetch.Home.name); + x.AddValue("latLonAlt", new Vector3(0, 0, (float)-Planetarium.fetch.Home.Radius)); + Target = Targeting.AntennaTarget.LoadFromConfig(x, this); + } } } -} \ No newline at end of file +} diff --git a/src/RealAntennasProject/RealAntennasUI.cs b/src/RealAntennasProject/RealAntennasUI.cs index 74177a2..46c8818 100644 --- a/src/RealAntennasProject/RealAntennasUI.cs +++ b/src/RealAntennasProject/RealAntennasUI.cs @@ -128,7 +128,7 @@ private void VesselCounts(out int vessels, out int groundStations, out int anten net = $"{racn}"; foreach (RACommNode node in racn.Nodes) { - if (node.isHome) + if (node.isGroundStation) { groundStations++; } diff --git a/src/RealAntennasProject/Tools.cs b/src/RealAntennasProject/Tools.cs index 60c22d4..4e2c3e0 100644 --- a/src/RealAntennasProject/Tools.cs +++ b/src/RealAntennasProject/Tools.cs @@ -51,7 +51,7 @@ public static RealAntenna HighestGainCompatibleDSNAntenna(List nodes, { RealAntenna result = null; double highestGain = 0; - foreach (RACommNode node in nodes.Where(obj => obj.isHome)) + foreach (RACommNode node in nodes.Where(obj => obj is RACommNode raNode && raNode.isGroundStation)) { foreach (RealAntenna ra in node.RAAntennaList) {