public ConstellationPlanEntry DeepCopy() { ConstellationPlanEntry copy = new ConstellationPlanEntry(Position, Fields.Values.ToList().ConvertAll(x => x.DeepCopy()), compareFunction); copy.NodeID = NodeID; return(copy); }
// Start is called before the first frame update void Start() { _satellitePrefab = SatellitePrefab; Constants.EarthRadius = (GetComponent <SphereCollider>().radius *transform.localScale.x); float constellationAltitude = Constants.EarthRadius + Constants.ScaleToSize(SatelliteAltitude); float constellationRadius = constellationAltitude / 2; List <ConstellationPlanEntry> entries = new List <ConstellationPlanEntry>(); List <INode> nodes = new List <INode>(); for (int i = 0; i < PlaneNum; i++) { float yAngle = Mathf.PI / PlaneNum * i; for (uint?j = 0; j < SatellitesPerPlane; j++) { float angle = (int)j * Mathf.PI * 2f / SatellitesPerPlane; Vector3 instantiationPos = new Vector3( Mathf.Cos(angle) * constellationRadius, Mathf.Sin(yAngle / SatellitesPerPlane * (int)j) * constellationRadius, Mathf.Sin(angle) * constellationRadius); //Create a vector from earth center to the desired position Vector3 instantiationVector = (instantiationPos - transform.position).normalized * constellationAltitude; GameObject satellite = Instantiate(SatellitePrefab, transform.position + instantiationVector, Quaternion.identity); CommsSim sim = satellite.AddComponent <CommsSim>(); INode node = new Node(j, BackendHelpers.NumericsVectorFromUnity(satellite.transform.position)); node.TargetPosition = node.Position; node.CommsModule = sim; node.PlaneNormalDir = BackendHelpers.NumericsVectorFromUnity(Vector3.up); satellite.name = "P(" + i + "), S(" + j + ")"; satellite.GetComponent <SatelliteComms>().Node = node; satellite.GetComponent <SatelliteComms>().Node.AutoChecksAllowed = CanvasHandler.AutoChecksAllowed; List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry entry = new ConstellationPlanEntry(node.Position, fields, (x, y) => 1); entry.NodeID = node.Id; entries.Add(entry); nodes.Add(node); SatManager._instance.SatIndex++; } } ConstellationPlan plan = new ConstellationPlan(entries); nodes.ForEach(node => { node.ActivePlan = plan; node.GenerateRouter(); }); }
public static ConstellationPlan CreatePlan(List <Vector3> targetPositions) { List <ConstellationPlanEntry> entries = new List <ConstellationPlanEntry>(); foreach (Vector3 targetPosition in targetPositions) { List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry entry = new ConstellationPlanEntry(targetPosition, fields, (x, y) => 1); entries.Add(entry); } ConstellationPlan plan = new ConstellationPlan(entries); return(plan); }
private static void UpdateConstellationPlan(INode myNode) { List <ConstellationPlanEntry> newPlanEntries = new List <ConstellationPlanEntry>(); //update my constellationplan based on the new knowledge foreach (NetworkMapEntry entry in myNode.Router.NetworkMap.Entries) { Vector3 position = entry.Position; List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry planEntry = new ConstellationPlanEntry(position, fields, (x, y) => 1); planEntry.NodeID = entry.ID; newPlanEntries.Add(planEntry); } myNode.ActivePlan = new ConstellationPlan(newPlanEntries); }
public static ConstellationPlan GenerateTargetConstellation(int satCount, float constellationAltitude) { Random rng = new Random(); List <Vector3> TargetPositions = new List <Vector3>(); //Generate the target positions for (int i = 0; i < satCount; i++) { //Create random angle for position of Targetposition float angle = (360 / satCount) * i; angle = (float)(Math.PI / 180) * angle; Vector3 instantiationPos = Vector3.Transform(new Vector3(0, 0, 1), Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), angle)); //Set it relative to the earth Vector3 instantiationVector = Vector3.Normalize(instantiationPos) * constellationAltitude * rng.Next(1, 1); //Store for propagation TargetPositions.Add(instantiationVector); } List <ConstellationPlanEntry> entries = new List <ConstellationPlanEntry>(); //Create a plan containing the taraget positions foreach (Vector3 pos in TargetPositions) { Vector3 position = new Vector3(pos.X, pos.Y, pos.Z); List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry entry = new ConstellationPlanEntry(position, fields, (x, y) => 1); entries.Add(entry); } ConstellationPlan plan = new ConstellationPlan(entries); //Send the targetconstellation to random sat return(plan); }
/// <summary> /// Returns whether or not swapping the two nodes yields a more cost-efficient constellation. /// </summary> /// <returns></returns> public bool TrySwapNodes(uint?nodeID1, Vector3 nodePosition1, uint?nodeID2, Vector3 nodePosition2, out ConstellationPlan newPlan) { ConstellationPlan planCopy = DeepCopy(); // Make a copy of the plan to avoid the method having side effects. ConstellationPlanEntry entry1 = planCopy.Entries.Find(x => x.NodeID == nodeID1); ConstellationPlanEntry entry2 = planCopy.Entries.Find(x => x.NodeID == nodeID2); entry1.NodeID = nodeID2; entry1.Fields["DeltaV"].Value = Vector3.Distance(nodePosition2, entry1.Position); entry2.NodeID = nodeID1; entry2.Fields["DeltaV"].Value = Vector3.Distance(nodePosition1, entry2.Position); float currentSum = Entries.Select(x => x.Fields["DeltaV"].Value).Sum(); float newSum = planCopy.Entries.Select(x => x.Fields["DeltaV"].Value).Sum(); if (newSum < currentSum) { newPlan = planCopy; return(true); } else { newPlan = null; return(false); } }
private static ConstellationPlan ProcessPlan(List <NodeLocationMatch> matches, PlanRequest request, INode myNode) { //Find entries not taken by other nodes List <ConstellationPlanEntry> FreeEntries = request.Plan.Entries .Where(entry => entry.NodeID == null && matches.Select(match => match.Position) //Select positions from matches .Contains(entry.Position) == false).ToList(); //Order by distance to my node FreeEntries.OrderBy(entry => Vector3.Distance(myNode.Position, entry.Position)); //Lowest distance is my best entry. ConstellationPlanEntry bestEntry = FreeEntries.First(); bestEntry = request.Plan.Entries.Find(entry => entry.Position == bestEntry.Position); //Take the location in the plan bestEntry.NodeID = myNode.Id; bestEntry.Fields["DeltaV"].Value = Vector3.Distance(bestEntry.Position, myNode.Position); myNode.GeneratingPlan = request.Plan; //Return the plan return(request.Plan); }
public void GenerateTargetConstellation(INode RequesterNode) { System.Random r = new System.Random(RandomSeed); TargetPositions.Clear(); //If the constellation altitude input from textfield isn't numbers, return if (float.TryParse(ConstellationAltitudeInput, out float constellationAltitude) == false) { return; } //Set the constellation altitude based on the input textfield constellationAltitude = Constants.EarthRadius + Constants.ScaleToSize(constellationAltitude); //Get reference to satellites Sats = GameObject.FindGameObjectsWithTag("Satellite").ToList(); List <uint?> reachableNodes = RequesterNode.Router.ReachableSats(RequesterNode).ToList(); Sats.RemoveAll(sat => reachableNodes.Contains(sat.GetComponent <SatelliteComms>().Node.Id) == false); //Remove old location Placeholders GameObject.FindGameObjectsWithTag("LocationPlaceholder")?.ToList().ForEach(Destroy); for (int i = 0; i < Sats.Count; i++) { //Create random angle for position of Targetposition float angle = (360 / Sats.Count) * i; Vector3 instantiationPos = Quaternion.Euler(0, angle, 0) * Vector3.forward; //Set it relative to the earth Vector3 instantiationVector = (instantiationPos - Vector3.zero).normalized * constellationAltitude; //Store for propagation TargetPositions.Add(instantiationVector); Instantiate(SatLocationPlaceholderPrefab, instantiationVector, Quaternion.identity); } List <ConstellationPlanEntry> entries = new List <ConstellationPlanEntry>(); foreach (Vector3 pos in TargetPositions) { Vector3 position = new Vector3(pos.x, pos.y, pos.z); List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry entry = new ConstellationPlanEntry(BackendHelpers.NumericsVectorFromUnity(position), fields, (x, y) => 1); entries.Add(entry); } plan = new ConstellationPlan(entries); //Send the targetconstellation to random sat INode targetSat = RequesterNode; PlanRequest request = new PlanRequest { Command = Request.Commands.GENERATE, SourceID = targetSat.Id, DestinationID = targetSat.Id, SenderID = 42, Dir = Router.CommDir.CW, AckExpected = true, MessageIdentifer = "42", Plan = plan }; PlanGenerator.GeneratePlan(targetSat, request); }
private void Update() { if (SatManager._instance.satellites.TrueForAll(sat => sat.Node.State != Node.NodeState.PLANNING)) { GameObject.FindGameObjectsWithTag("LocationPlaceholder")?.ToList().ForEach(Destroy); } if (GameObject.FindGameObjectsWithTag("LocationPlaceholder").Length == 0 && SatManager._instance.satellites.Any(sat => sat.Node.State == Node.NodeState.PLANNING)) { SatelliteComms planningNode = SatManager._instance.satellites.Find(sat => sat.Node.State == Node.NodeState.PLANNING); planningNode.Node.GeneratingPlan.Entries.ForEach(entry => Instantiate(SatLocationPlaceholderPrefab, BackendHelpers.UnityVectorFromNumerics(entry.Position), Quaternion.identity)); } if (nodes.Count == 0) { Sats.ForEach(sat => nodes.Add(sat.GetComponent <SatelliteComms>().Node)); } if (plan == null) { return; } if (Input.GetMouseButtonDown(0) && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, float.MaxValue, ManualDesignMask) && plan.Entries.TrueForAll(entry => nodes.Any(node => System.Numerics.Vector3.Distance(node.Position, entry.Position) < 0.1f))) { if (EnableManualDesign == false) { Clear(); } if (GameObject.FindGameObjectsWithTag("LocationPlaceholder")?.ToList().Count < nodes.Count) { Instantiate(SatLocationPlaceholderPrefab, hit.point, Quaternion.identity); EnableAutotest = false; EnableManualDesign = true; } else if (EnableManualDesign) { List <ConstellationPlanEntry> entries = new List <ConstellationPlanEntry>(); foreach (Vector3 pos in GameObject.FindGameObjectsWithTag("LocationPlaceholder")?.ToList().Select(loc => loc.transform.position)) { System.Numerics.Vector3 position = new System.Numerics.Vector3(pos.x, pos.y, pos.z); List <ConstellationPlanField> fields = new List <ConstellationPlanField> { new ConstellationPlanField("DeltaV", 0, (x, y) => x.CompareTo(y)) }; ConstellationPlanEntry entry = new ConstellationPlanEntry(position, fields, (x, y) => 1); entries.Add(entry); } plan = new ConstellationPlan(entries); //Send the targetconstellation to random sat INode targetSat = Sats[UnityEngine.Random.Range(0, Sats.Count - 1)].GetComponent <SatelliteComms>().Node; PlanRequest request = new PlanRequest(); request.Command = Request.Commands.GENERATE; request.DestinationID = targetSat.Id; request.Plan = plan; request.MessageIdentifer = "42"; targetSat.Communicate(request); EnableManualDesign = false; } } }