Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various changes made to support Σκοπός over the past few years #1

Merged
merged 13 commits into from
Jun 1, 2024
4 changes: 2 additions & 2 deletions src/RealAntennasProject/MapUI/GroundStationSiteNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace RealAntennas.MapUI
{
class GroundStationSiteNode : ISiteNode
public class GroundStationSiteNode : ISiteNode
{
RACommNode node;
public readonly RACommNode node;

public GroundStationSiteNode(RACommNode node)
{
Expand Down
24 changes: 24 additions & 0 deletions src/RealAntennasProject/MapUI/RACommNetUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class RACommNetUI : CommNet.CommNetUI
public Color color3dB = XKCDColors.BarbiePink;
public Color color10dB = XKCDColors.Lavender;

public readonly List<SiteNode> groundStationSiteNodes = new List<SiteNode>();

private readonly List<Vector3d> targetPoints = new List<Vector3d>();
private readonly List<Vector3> targetPoints_out = new List<Vector3>();
private readonly List<Vector3d> cone3Points = new List<Vector3d>();
Expand Down Expand Up @@ -51,11 +53,21 @@ protected override void Start()
Texture2D stationTexture = (GameDatabase.Instance.GetTexture(home.icon, false) is Texture2D tex) ? tex : defaultTex;
siteNode.wayPoint.node.SetIcon(Sprite.Create(stationTexture, new Rect(0, 0, stationTexture.width, stationTexture.height), new Vector2(0.5f, 0.5f), 100f));
siteNode.wayPoint.node.OnUpdateVisible += home.OnUpdateVisible;
groundStationSiteNodes.Add(siteNode);
}
}
RATelemetryUpdate.Install();
}

// If either one of these lists is nonempty, the links that are shown
// are exactly those in OverrideShownLinks, and the beamwidth cones are
// exactly those of the nodes in OverrideShownCones, regardless of the
// UI mode.
// The list is used and cleared by this class at the BetterLateThanNever
// timing of LateUpdate.
public List<CommLink> OverrideShownLinks { get; private set; } = new List<CommLink>();
public List<RACommNode> OverrideShownCones { get; private set; } = new List<RACommNode>();

private void GatherLinkLines(List<CommLink> linkList)
{
var settings = RACommNetScenario.MapUISettings;
Expand Down Expand Up @@ -255,6 +267,7 @@ public void Init(Vector3d vertex, Vector3d axis, Vector3d normal, double angle)
public Vector3d Midpoint => (end1 + end2) / 2;
}

// Runs in LateUpdate at BetterLateThanNever (Timing5, 8008).
protected override void UpdateDisplay()
{
//base.UpdateDisplay();
Expand All @@ -274,6 +287,17 @@ protected override void UpdateDisplay()

if (RACommNetScenario.RACN is RACommNetwork commNet)
{
if (OverrideShownLinks.Count > 0 || OverrideShownCones.Count > 0)
{
GatherLinkLines(OverrideShownLinks);
foreach (RACommNode node in OverrideShownCones)
{
GatherAntennaCones(node);
}
OverrideShownLinks.Clear();
OverrideShownCones.Clear();
return;
}
if (CommNetUI.Mode == CommNetUI.DisplayMode.Network)
{
foreach (RACommNode node in commNet.Nodes)
Expand Down
2 changes: 1 addition & 1 deletion src/RealAntennasProject/Network/RACommLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace RealAntennas
{
class RACommLink : CommNet.CommLink
public class RACommLink : CommNet.CommLink
{
private const double CostScalar = 1e5;
public double FwdDataRate { get; set; }
Expand Down
24 changes: 20 additions & 4 deletions src/RealAntennasProject/Network/RACommNetHome.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public class RACommNetHome : CommNetHome
{
protected static readonly string ModTag = "[RealAntennasCommNetHome] ";
protected ConfigNode config = null;
protected bool isHome = true;
protected bool isControlSource = true;
protected bool isControlSourceMultiHop = true;
private readonly double DriftTolerance = 10000.0;
public string icon = "radio-antenna";
public RACommNode Comm => comm as RACommNode;
Expand All @@ -31,6 +34,19 @@ public void Configure(ConfigNode node, CelestialBody body)
lat = double.Parse(node.GetValue("lat"));
lon = double.Parse(node.GetValue("lon"));
alt = double.Parse(node.GetValue("alt"));
string value = null;
if (node.TryGetValue("isHome", ref value))
{
isHome = bool.Parse(value);
}
if (node.TryGetValue("isControlSource", ref value))
{
isControlSource = bool.Parse(value);
}
if (node.TryGetValue("isControlSourceMultiHop", ref value))
{
isControlSourceMultiHop = bool.Parse(value);
}
node.TryGetValue("icon", ref icon);
SetTransformFromLatLonAlt(lat, lon, alt, body);
}
Expand All @@ -41,9 +57,9 @@ protected override void CreateNode()
comm = new RACommNode(nodeTransform)
{
OnNetworkPreUpdate = new Action(OnNetworkPreUpdate),
isHome = true,
isControlSource = true,
isControlSourceMultiHop = true
isHome = isHome,
isControlSource = isControlSource,
isControlSourceMultiHop = isControlSourceMultiHop
};
}
comm.name = nodeName;
Expand Down Expand Up @@ -72,7 +88,7 @@ protected override void CreateNode()
}
}

internal void OnUpdateVisible(KSP.UI.Screens.Mapview.MapNode mapNode, KSP.UI.Screens.Mapview.MapNode.IconData iconData)
public void OnUpdateVisible(KSP.UI.Screens.Mapview.MapNode mapNode, KSP.UI.Screens.Mapview.MapNode.IconData iconData)
{
Vector3d worldPos = ScaledSpace.LocalToScaledSpace(Comm.precisePosition);
iconData.visible &= MapView.MapCamera.transform.InverseTransformPoint(worldPos).z >= 0 && !IsOccludedToCamera(Comm.precisePosition, body);
Expand Down
2 changes: 1 addition & 1 deletion src/RealAntennasProject/Physics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static float PointingLoss(double angle, double beamwidth)
else return math.lerp(9, 10, (norm - 0.86f) / 1);
}
public static float PointingLoss(RealAntenna ant, Vector3 origin)
=> (ant.CanTarget && ant.ToTarget != Vector3.zero) ? PointingLoss(Vector3.Angle(origin - ant.Position, ant.ToTarget), ant.Beamwidth) : 0;
=> (ant.CanTarget && !ant.IsTracking) ? PointingLoss(Vector3.Angle(origin - ant.Position, ant.ToTarget), ant.Beamwidth) : 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just be careful here, as the pointingloss for a poorly defined angle (ie direction to target is somehow near 0,0,0) will produce bad results. Unsure how much this particular library code is exercised now, especially with the conversion to jobs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this won’t affect cases where ToTarget is near zero, only those where it is zero.
It seems unlikely that it would be zero in cases where it should be, since it is computed as difference in double precision where one of the terms is Position, which is PrecisePosition, which is a position in double precision (the other term of the difference, Target.transform.position, is regrettably in single precision, but the result, while perhaps garbage, shouldn’t come out to 0).

(The difference is then converted to single precision but this matters not. All that switching between precisions is neither a recipe for performance nor correctness, but let’s not get distracted.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be irrelevant if calculating garbage data anyway [what is ToTarget with a somehow broken/invalid target?]. Other source of potentially bad result is maybe no longer possible for reason you described [PrecisePosition is double]. Main indicator might be vessels & targets that are extremely far away from current origin [ie, focus on a vessel past Pluto, what are the calculations for vessels/targets in similar orbit near Earth?]


public static float GainAtAngle(float gain, float angle) => gain - PointingLoss(math.abs(angle), Beamwidth(gain));
// Beamwidth is the 3dB full beamwidth contour, ~= the offset angle to the 10dB contour.
Expand Down
10 changes: 6 additions & 4 deletions src/RealAntennasProject/Precompute/Jobs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public struct ExtractDataJob : IJobParallelForDefer
[WriteOnly] public NativeArray<float> rxGain;
[WriteOnly] public NativeArray<float> rxBeamwidth;
[WriteOnly] public NativeArray<bool> rxHome;
[WriteOnly] public NativeArray<bool> rxTracking;
[WriteOnly] public NativeArray<double3> rxPos;
[WriteOnly] public NativeArray<float3> rxDir;
[WriteOnly] public NativeArray<float> rxAMW;
Expand All @@ -47,14 +48,15 @@ public void Execute(int index)
txBeamwidth[index] = tx.beamwidth;
txHome[index] = tx.isHome;
txPos[index] = tx.position;
txDir[index] = tx.isHome ? (float3) (rx.position - tx.position) : tx.dir;
txDir[index] = tx.isTracking ? (float3) (rx.position - tx.position) : tx.dir;

rxFreq[index] = rx.freq;
rxGain[index] = rx.gain;
rxBeamwidth[index] = rx.beamwidth;
rxHome[index] = rx.isHome;
rxTracking[index] = rx.isTracking;
rxPos[index] = rx.position;
rxDir[index] = rx.isHome ? (float3) (tx.position - rx.position) : rx.dir;
rxDir[index] = rx.isTracking ? (float3) (tx.position - rx.position) : rx.dir;
rxAMW[index] = rx.AMW;
}
}
Expand All @@ -79,7 +81,7 @@ public struct CalcAntennaBodyNoise : IJobParallelForDefer
{
[ReadOnly] public NativeArray<OccluderInfo> occluders;
[ReadOnly] public NativeArray<float> rxPrecalcNoise;
[ReadOnly] public NativeArray<bool> rxHome;
[ReadOnly] public NativeArray<bool> rxTracking;
[ReadOnly] public NativeArray<double3> rxPos;
[ReadOnly] public NativeArray<float> rxGain;
[ReadOnly] public NativeArray<float> rxBeamwidth;
Expand All @@ -88,7 +90,7 @@ public struct CalcAntennaBodyNoise : IJobParallelForDefer
[WriteOnly] public NativeArray<float> bodyNoise;
public void Execute(int index)
{
bodyNoise[index] = rxHome[index] ? Precompute.NoiseFromOccluders(rxPos[index], rxGain[index], rxDir[index], rxFreq[index], rxBeamwidth[index], occluders) : rxPrecalcNoise[index];
bodyNoise[index] = rxTracking[index] ? Precompute.NoiseFromOccluders(rxPos[index], rxGain[index], rxDir[index], rxFreq[index], rxBeamwidth[index], occluders) : rxPrecalcNoise[index];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder about this particular change. The purpose of this job was to defer the noise calculation for antennas whose pointing was not determined earlier, specifically: the ground station antennas that are allowed to "simultaneously" point at any possible peer (as a gameplay simplification).

But isTracking is also changing, from:

        public virtual bool CanTarget => Shape != AntennaShape.Omni && (ParentNode == null || !ParentNode.isHome);

to:

        public bool IsTracking => Shape != AntennaShape.Omni && Target == null;

I don't know if those are the same, ie do only ground stations have Target == null?
But this is the only purpose of isTracking -- to indicate this non-physical idea of how a given antenna is pointing.

Copy link
Collaborator Author

@eggrobin eggrobin Jun 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To your question

I don't know if those are the same, ie do only ground stations have Target == null?

I think the answer is yes, because this is how Target is initialized, where we see some of the logic that was in CanTarget:

            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);

The only intended change in behaviour in the changes surrounding the introduction of IsTracking is that you can explicitly configure an antenna to have this kind of track-everything-at-once behaviour using TARGET {}; Σκοπός uses that for its ground stations.

Those ground stations are not home, so that you cannot downlink your science to a random Орбита station (or maybe even someone’s TVRO dish!) using the entire C band.

}

Expand Down
8 changes: 7 additions & 1 deletion src/RealAntennasProject/Precompute/Precompute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public struct AntennaData
internal float gain;
internal float beamwidth;
internal bool isHome;
internal bool isTracking;
internal double3 position;
internal float3 dir;
internal float AMW;
Expand Down Expand Up @@ -83,6 +84,7 @@ internal class Precompute
private NativeArray<float> rxGain;
private NativeArray<float> rxBeamwidth;
private NativeArray<bool> rxHome;
private NativeArray<bool> rxTracking;
private NativeArray<double3> rxPos;
private NativeArray<float3> rxDir;
private NativeArray<float> rxAMW;
Expand Down Expand Up @@ -229,6 +231,7 @@ public void DoThings(List<CelestialBody> bodies = null, List<CommNet.CommNode> n
rxGain = new NativeArray<float>(allAntennaPairs.Length, Allocator.TempJob);
rxBeamwidth = new NativeArray<float>(allAntennaPairs.Length, Allocator.TempJob);
rxHome = new NativeArray<bool>(allAntennaPairs.Length, Allocator.TempJob);
rxTracking = new NativeArray<bool>(allAntennaPairs.Length, Allocator.TempJob);
rxPos = new NativeArray<double3>(allAntennaPairs.Length, Allocator.TempJob);
rxDir = new NativeArray<float3>(allAntennaPairs.Length, Allocator.TempJob);
rxAMW = new NativeArray<float>(allAntennaPairs.Length, Allocator.TempJob);
Expand All @@ -251,6 +254,7 @@ public void DoThings(List<CelestialBody> bodies = null, List<CommNet.CommNode> n
rxBeamwidth = rxBeamwidth,
txHome = txHome,
rxHome = rxHome,
rxTracking = rxTracking,
txFreq = txFreq,
rxFreq = rxFreq,
txPower = txPower,
Expand Down Expand Up @@ -324,7 +328,7 @@ public void DoThings(List<CelestialBody> bodies = null, List<CommNet.CommNode> n
{
occluders = occluders,
rxPrecalcNoise = rxPrecalcNoise,
rxHome = rxHome,
rxTracking = rxTracking,
rxPos = rxPos,
rxGain = rxGain,
rxBeamwidth = rxBeamwidth,
Expand Down Expand Up @@ -619,6 +623,7 @@ private void DisposeJobData()
rxGain.Dispose();
rxBeamwidth.Dispose();
rxHome.Dispose();
rxTracking.Dispose();
rxPos.Dispose();
rxDir.Dispose();
rxAMW.Dispose();
Expand Down Expand Up @@ -728,6 +733,7 @@ private NativeArray<AntennaData> GatherAllAntennas(Dictionary<RealAntenna, int>
gain = ra.Gain,
beamwidth = ra.Beamwidth,
isHome = node.isHome,
isTracking = ra.IsTracking,
AMW = Physics.AntennaMicrowaveTemp(ra),
encoder = new Encoder(ra.Encoder),
maxSymbolRate = Convert.ToSingle(ra.SymbolRate),
Expand Down
5 changes: 3 additions & 2 deletions src/RealAntennasProject/RealAntenna.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public class RealAntenna
public Vector3d PrecisePosition => ParentNode.precisePosition;
public Vector3d TransformPosition => ParentNode.position;
public virtual AntennaShape Shape => Gain <= Physics.MaxOmniGain ? AntennaShape.Omni : AntennaShape.Dish;
public virtual bool CanTarget => Shape != AntennaShape.Omni && (ParentNode == null || !ParentNode.isHome);
public bool IsTracking => Shape != AntennaShape.Omni && Target == null;
public virtual bool CanTarget => Shape != AntennaShape.Omni && !IsTracking;
public Vector3 ToTarget => (CanTarget && Target != null) ? (Vector3) (Target.transform.position - Position) : Vector3.zero;

private Targeting.AntennaTarget _target;
Expand Down Expand Up @@ -114,7 +115,7 @@ 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);
if (CanTarget && !(Target?.Validate() == true) && HighLogic.LoadedSceneHasPlanetarium)
else if (Shape != AntennaShape.Omni && (ParentNode == null || !ParentNode.isHome) && !(Target?.Validate() == true) && HighLogic.LoadedSceneHasPlanetarium)
Target = Targeting.AntennaTarget.LoadFromConfig(SetDefaultTarget(), this);
}

Expand Down
4 changes: 2 additions & 2 deletions src/RealAntennasProject/TechLevelInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class TechLevelInfo

public static bool initialized = false;

private static readonly Dictionary<int, TechLevelInfo> All = new Dictionary<int, TechLevelInfo>();
public static int MaxTL { get; private set; } = -1;
public static readonly Dictionary<int, TechLevelInfo> All = new Dictionary<int, TechLevelInfo>();
public static int MaxTL { get; set; } = -1;
protected static readonly string ModTag = "[RealAntennas.TechLevelInfo] ";

public TechLevelInfo() { }
Expand Down