private void Update() { movement.TargetPosition = BackendHelpers.UnityVectorFromNumerics(Node.TargetPosition); Node.Position = BackendHelpers.NumericsVectorFromUnity(transform.position); text.text = Node.Id.ToString() + "\n" + Node.State.ToString(); }
// 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(); }); }
private void Update() { sleepCount = comms.Node.SleepCount; comms.Node.Position = BackendHelpers.NumericsVectorFromUnity(transform.position); ReachableNodes = comms.Node.Router.ReachableSats(comms.Node).Select(node => (uint)node).ToList(); if (Constants.EnableDebug) { logs.ForEach(Debug.LogWarning); logs.Clear(); } }
public static void InstantiateSatellite(Vector3 instantiationPoisition) { GameObject satellite = Instantiate(_satellitePrefab, instantiationPoisition, Quaternion.identity); CommsSim sim = satellite.AddComponent <CommsSim>(); int satIndex = SatManager._instance.SatIndex; INode node = new Node((uint?)satIndex, BackendHelpers.NumericsVectorFromUnity(satellite.transform.position)); node.TargetPosition = node.Position; node.CommsModule = sim; node.PlaneNormalDir = BackendHelpers.NumericsVectorFromUnity(Vector3.up); satellite.name = "P(" + 0 + "), S(" + (satIndex) + ")"; satellite.GetComponent <SatelliteComms>().Node = node; SatManager._instance.SatIndex++; node.AutoChecksAllowed = CanvasHandler.AutoChecksAllowed; node.GenerateRouter(); }
// Returns next sequential neighbour node based on current plan. // Always sends clockwise or counterclockwise (cant remember which one). public uint?NextSequential(INode source, CommDir dir) { Vector3 EarthPosition = Vector3.Zero; // Assumption: Always 2 neighbours, if not the case it is handled by fault mechanisms. //List<ConstellationPlanEntry> neighbourEntries = plan.Entries.Where(x => NetworkMap[source].Contains(x.NodeID)).ToList(); List <NetworkMapEntry> neighbourEntries = source.Router.NetworkMap.Entries.Where(entry => source.Router.NetworkMap.GetEntryByID(source.Id).Neighbours.Contains(entry.ID)).ToList(); // //The "up" vector for the constellation plan is calculated. //(B - A) cross (C - B) List <uint?> NeighbourIDs = NetworkMap.GetEntryByID(source.Id).Neighbours; Vector3 SatClockwiseVector = Vector3.Cross(EarthPosition - source.Position, source.PlaneNormalDir); // Assumption: Always 2 neighbours, if not the case it is handled by fault mechanisms. Vector3 normalVector = source.PlaneNormalDir; List <double> angles = neighbourEntries.Select(x => BackendHelpers.NumericsVectorSignedAngle(source.Position, x.Position, normalVector)).ToList(); if (angles.Any(angle => dir == CommDir.CW ? (angle > 0) : (angle < 0))) { if (dir == CommDir.CW) { return(neighbourEntries[angles.IndexOf(angles.Where(angle => angle > 0).Min())].ID); } else if (dir == CommDir.CCW) { return(neighbourEntries[angles.IndexOf(angles.Where(angle => angle < 0).Max())].ID); } } return(null); }
public void Send(uint?nextHop, Response response) { if (Constants.EnableDebug) { Debug.Log(comms.Node.Id + " -> " + nextHop + "\t : " + response.GetType() + ": " + response.ResponseCode + "." + "\t dst: " + response.DestinationID); } SatelliteComms hop = SatManager._instance.satellites.Find(sat => sat.Node.Id == nextHop); SatManager.MessageProps message = new SatManager.MessageProps(BackendHelpers.UnityVectorFromNumerics(comms.Node.Position), BackendHelpers.UnityVectorFromNumerics(hop.Node.Position), Color.cyan, Constants.SEND_DURATION_TIME / Constants.TimeScale); satMan.SentMessages.Add(message); if (System.Numerics.Vector3.Distance(comms.Node.Position, hop.Node.Position) < Constants.ScaleToSize(comms.CommRadius)) { hop.Node.CommsModule.Receive(response); ActiveCommSat = hop; ActiveCommSat = null; } }
// Update is called once per frame void Update() { state = comms.Node.State; SatManager.MessageProps[] messageSnapshot = SatManager._instance.SentMessages.ToArray(); if (messageSnapshot.Length > 0) { foreach (SatManager.MessageProps props in messageSnapshot) { StartCoroutine(DisplayMessageSent(props.StartVect + Vector3.up, props.EndVect + Vector3.up, props.Duration, 0f, props.Color)); } } SatManager._instance.SentMessages.Clear(); reachableSats.Clear(); KnownNeighbours = comms.Node.Router.NetworkMap.GetEntryByID(comms.Node.Id)?.Neighbours; reachableSats.Clear(); foreach (SatelliteComms node in reachableSats.Where(sat => KnownNeighbours.Contains(sat.Node.Id) == false)) { reachableSats.Remove(node); } uint?toRemove = null; foreach (uint?node in KnownNeighbours) { if (reachableSats.Select(sat => sat.Node.Id).Contains(node) == false) { if (SatManager._instance.satellites.Any(sat => sat.Node.Id == node) == false) { toRemove = node; } else { Transform nodeTransform = SatManager._instance.satellites.Find(sat => sat.Node.Id == node).transform; reachableSats.Add(nodeTransform.GetComponent <SatelliteComms>()); } } } if (toRemove != null) { KnownNeighbours.Remove(toRemove); } List <uint?> reachableSatsID = new List <uint?>(); for (int i = 0; i < reachableSats?.Count; i++) { uint?id = reachableSats[i].Node.Id; reachableSatsID.Add(id); if (commLineRenderes.ContainsKey(id) == false) { GameObject commlineGO = new GameObject(); commlineGO.transform.parent = this.transform; LineRenderer lineRenderer = commlineGO.AddComponent <LineRenderer>(); lineRenderer.material = CommLineMat; lineRenderer.material.SetColor("_BaseColor", CommsMat); lineRenderer.startWidth = 0.025f; lineRenderer.endWidth = 0.025f; lineRenderer.positionCount = 2; lineRenderer.SetPosition(0, this.transform.position); lineRenderer.SetPosition(1, reachableSats[i].transform.position); commLineRenderes.Add(id, lineRenderer); } else { Transform _transform = reachableSats[i].transform; Vector3 commLineDir = new Vector3 { x = _transform.position.x - comms.Node.Position.X, y = _transform.position.y - comms.Node.Position.Y, z = _transform.position.z - comms.Node.Position.Z, }; LineRenderer lineRenderer = commLineRenderes[id]; lineRenderer.SetPosition(1, _transform.position); lineRenderer.startWidth = 0.025f; lineRenderer.endWidth = 0.025f; } } for (int i = commLineRenderes.Count - 1; i >= 0; i--) { if (comms.Node.Active == false) { Destroy(commLineRenderes.ElementAt(i).Value); commLineRenderes.Remove(commLineRenderes.ElementAt(i).Key); continue; } uint?key = commLineRenderes.ElementAt(i).Key; if (reachableSatsID.Contains(key) == false) { Destroy(commLineRenderes[key]); commLineRenderes.Remove(key); } else { commLineRenderes[key].SetPosition(0, this.transform.position); } } uint?nextSeq = comms.Node.Router.NextSequential(comms.Node, Router.CommDir.CW); if (nextSeq != null && commLineRenderes.ContainsKey(nextSeq)) { LineRenderer nextSeqCommLine = commLineRenderes[nextSeq]; nextSeqCommLine.startWidth = 0.1f; nextSeqCommLine.endWidth = 0.1f; } switch (comms.Node.State) { case Node.NodeState.PASSIVE: meshRenderer.material.SetColor("_BaseColor", PassiveMat); //targetPositionLineRenderer.material.SetColor("_BaseColor", PassiveMat); break; case Node.NodeState.PLANNING: //meshRenderer.material.SetColor("_BaseColor", LeaderMat); //targetPositionLineRenderer.material.SetColor("_BaseColor", LeaderMat); break; case Node.NodeState.EXECUTING: meshRenderer.material.SetColor("_BaseColor", ExecuteMat); //targetPositionLineRenderer.material.SetColor("_BaseColor", ExecuteMat); break; case Node.NodeState.OVERRIDE: meshRenderer.material.SetColor("_BaseColor", OverrideMat); //targetPositionLineRenderer.material.SetColor("_BaseColor", OverrideMat); break; case Node.NodeState.DEAD: meshRenderer.material.SetColor("_BaseColor", DeadMat); break; case Node.NodeState.HEARTBEAT: meshRenderer.material.SetColor("_BaseColor", HeartbeatMat); break; } lastState = comms.Node.State; // Turn active communication link on and off if (commsSim.ActiveCommSat != null && commLineRenderes.ContainsKey(commsSim.ActiveCommSat.Node.Id)) { uint?id = commsSim.ActiveCommSat.Node.Id; commLineRenderes[id].material.SetColor("_BaseColor", CommsActiveMat); lastActiveComm = id; } else if (lastActiveComm != null && commLineRenderes.ContainsKey(lastActiveComm)) { commLineRenderes[lastActiveComm].material.SetColor("_BaseColor", CommsMat); } // Remove all non-reachable links, then update position if (comms.Node.GeneratingPlan != null) { Vector3 plannedposition = transform.position; foreach (ConstellationPlanEntry e in comms.Node.GeneratingPlan.Entries) { if (e.NodeID != null && e.NodeID == comms.Node.Id) { plannedposition = BackendHelpers.UnityVectorFromNumerics(e.Position); } } targetPositionLineRenderer.positionCount = 2; targetPositionLineRenderer.SetPositions(new Vector3[] { transform.position, plannedposition }); } }
public void Send(uint?nextHop, Request request) { request.SenderID = comms.Node.Id; SatelliteComms hop = SatManager._instance.satellites.Find(sat => sat.Node.Id == nextHop); SatManager.MessageProps message = new SatManager.MessageProps( BackendHelpers.UnityVectorFromNumerics(comms.Node.Position), BackendHelpers.UnityVectorFromNumerics(hop.Node.Position), Color.yellow, Constants.SEND_DURATION_TIME / Constants.TimeScale); switch (request.Command) { case Request.Commands.DETECTFAILURE: message.Color = Color.red; break; case Request.Commands.HEARTBEAT: message.Color = Color.red; break; case Request.Commands.PING: message.Color = Color.red; break; case Request.Commands.DISCOVER: message.Color = Color.green; break; case Request.Commands.POSITION: message.Color = Color.green; break; case Request.Commands.ADDITION: message.Color = Color.green; break; case Request.Commands.GENERATE: message.Color = Color.yellow; break; case Request.Commands.EXECUTE: message.Color = Color.yellow; break; } satMan.SentMessages.Add(message); if (System.Numerics.Vector3.Distance(comms.Node.Position, hop.Node.Position) < Constants.ScaleToSize(comms.CommRadius)) { ActiveCommSat = hop; if (request.MessageIdentifer == null) { request.MessageIdentifer = DateTime.Now.ToString() + " milli " + DateTime.Now.Millisecond; } if (Constants.EnableDebug) { Debug.Log(request.Dir + ": " + comms.Node.Id + " -> " + nextHop + "\t : " + request.Command.ToString() + "\t dst: " + request.DestinationID + "\t msgID: " + request.MessageIdentifer); } hop.Node.CommsModule.Receive(request); ActiveCommSat = null; } else { if (Constants.EnableDebug) { Debug.Log(request.Dir + ": " + comms.Node.Id + " -> " + nextHop + "\t : " + request.Command.ToString() + "\t dst: " + request.DestinationID + "\t msgID: " + request.MessageIdentifer); } } }
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; } } }