Example #1
0
    /// <summary>Performs work in order to find optimum location in new constellation for given node
    /// <para>Recieves planrequest, finds best free location, or trades locations with other node in order to optimize net cost</para>
    /// </summary>
    public static void GeneratePlan(INode myNode, PlanRequest request)
    {
        // Remove failure detection requests in queue as we are planning to make changes to network structure anyway, which might solve the failure
        myNode.CommsModule.RequestList.RemoveAll(x => x.Command == Request.Commands.DETECTFAILURE);

        if (request.DestinationID != myNode.Id)
        {
            return;
        }
        else
        {
            myNode.ExecutingPlan  = false;
            myNode.State          = Node.NodeState.PLANNING;
            myNode.GeneratingPlan = request.Plan;

            PlanRequest newRequest = request.DeepCopy();
            newRequest.AckExpected = true;


            if (newRequest.Plan.Entries.Any(entry => entry.NodeID == myNode.Id == false))
            {
                List <NodeLocationMatch> matches = CalculatePositions(myNode, newRequest);
                ConstellationPlan        newPlan = ProcessPlan(matches, newRequest, myNode);
                newRequest.Plan = newPlan;
            }


            Transmit(newRequest, myNode);
        }
    }
Example #2
0
    public static void ExcludeNode(INode myNode, DetectFailureRequest request)
    {
        ConstellationPlan RecoveryPlan = GenerateConstellation.GenerateTargetConstellation(myNode.Router.ReachableSats(myNode).Count, 7.152f);

        PlanRequest recoveryRequest = new PlanRequest {
            SourceID      = myNode.Id,
            DestinationID = myNode.Id,
            Command       = Request.Commands.GENERATE,
            Plan          = RecoveryPlan,
            Dir           = Router.CommDir.CW
        };

        NetworkUpdateRequest updateRequest = new NetworkUpdateRequest(new List <uint?>()
        {
            request.NodeToCheck
        });

        recoveryRequest.DependencyRequests.Add(updateRequest);

        if (myNode.Router.NextSequential(myNode, Router.CommDir.CW) == null)
        {
            recoveryRequest.Dir = Router.CommDir.CCW;
        }

        PlanGenerator.GeneratePlan(myNode, recoveryRequest);
    }
Example #3
0
    public ConstellationPlan DeepCopy()
    {
        ConstellationPlan copy = new ConstellationPlan(Entries.ConvertAll(x => x.DeepCopy()));

        copy.LastEditedBy = LastEditedBy;
        return(copy);
    }
Example #4
0
    // 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(); });
    }
Example #5
0
    public static ConstellationPlan GenerateRecoveryConstellation(Vector3 midpoint, int nodeCount)
    {
        // Calculate positions evenly spread starting from midpoint
        List <Vector3> targetPositions = CalculatePositions(midpoint, nodeCount);

        // Create constellation plan based on target positions
        ConstellationPlan plan = CreatePlan(targetPositions);

        return(plan);
    }
Example #6
0
    public static void Recovery(INode myNode, uint?secondFailedNode)
    {
        //Remove edge from router, ensuring it won't try to route through the failed node
        myNode.Router.DeleteEdge(myNode.Id, secondFailedNode);

        // Find positions of nodes this node can reach
        List <Vector3> positions = new List <Vector3> {
            myNode.Position
        };
        List <uint?> nodesToVisit = new List <uint?> {
            myNode.Id
        };

        while (nodesToVisit.Count > 0)
        {
            uint?nodeToVisit = nodesToVisit[0];
            nodesToVisit.RemoveAt(0);
            List <NetworkMapEntry> neighbourEntries = myNode.Router.NetworkMap.GetEntryByID(nodeToVisit).Neighbours.Select(x => myNode.Router.NetworkMap.GetEntryByID(x)).ToList();
            nodesToVisit.AddRange(neighbourEntries.Where(x => positions.Contains(x.Position) == false).Select(x => x.ID));
            positions.AddRange(neighbourEntries.Where(x => positions.Contains(x.Position) == false).Select(x => x.Position));
        }

        // Calculate midpoint
        Vector3 midpoint = positions.Aggregate(Vector3.Zero, (x, y) => x + y);
        Vector3 midpointOnRightAltitude = Vector3.Normalize(midpoint) * Vector3.Distance(Vector3.Zero, myNode.Position);

        // Generate recovery plan and start planning
        ConstellationPlan recoveryPlan = GenerateConstellation.GenerateRecoveryConstellation(midpointOnRightAltitude, positions.Count);

        PlanRequest recoveryRequest = new PlanRequest {
            SourceID      = myNode.Id,
            DestinationID = myNode.Id,
            Command       = Request.Commands.GENERATE,
            Plan          = recoveryPlan,
        };

        NetworkUpdateRequest updateRequest =
            new NetworkUpdateRequest(new NetworkUpdateRequest(new List <uint?>()
        {
            secondFailedNode
        }));

        recoveryRequest.DependencyRequests.Add(updateRequest);

        myNode.Router.NetworkMap.Entries.RemoveAll(entry => entry.ID == secondFailedNode);

        myNode.CommsModule.Send(myNode.Id, recoveryRequest);
    }
Example #7
0
    public Router(INode _node, ConstellationPlan _plan)
    {
        node       = _node;
        NetworkMap = new NetworkMap();

        if (_plan != null && _plan.Entries.TrueForAll(entry => entry.NodeID != null))
        {
            foreach (ConstellationPlanEntry entry in _plan.Entries)
            {
                NetworkMap.Entries.Add(new NetworkMapEntry(entry.NodeID, entry.Position));
                NodeToNodeIDMapping.Add(entry.NodeID, 0);
            }
        }

        UpdateNetworkMap(_plan);
        AddNodeToGraph(node.Id);
    }
Example #8
0
    public override void UpdateNetworkMap(ConstellationPlan plan)
    {
        if (plan == null)
        {
            return;
        }

        NetworkMap newMap = new NetworkMap();

        foreach (ConstellationPlanEntry entry in plan.Entries)
        {
            List <Tuple <uint?, float> > neighbors = new List <Tuple <uint?, float> >();

            foreach (ConstellationPlanEntry innerEntry in plan.Entries.Where((x) => x != entry))
            {
                float dist = Vector3.Distance(entry.Position, innerEntry.Position);
                if (dist < satRange)
                {
                    if (innerEntry.NodeID != null)
                    {
                        neighbors.Add(new Tuple <uint?, float>(innerEntry.NodeID, dist));
                    }
                }
            }

            //Order sats by distance to myself
            neighbors = neighbors.OrderBy(sat => sat.Item2).ToList();//Only distinct please


            if (entry.NodeID != null)
            {
                if (newMap.GetEntryByID(entry.NodeID) == null)
                {
                    newMap.Entries.Add(new NetworkMapEntry(entry.NodeID, neighbors.Select(sat => sat.Item1).ToList(), entry.Position));
                }
                else
                {
                    newMap.GetEntryByID(entry.NodeID).Neighbours = neighbors.Select(sat => sat.Item1).ToList();
                    newMap.GetEntryByID(entry.NodeID).Position   = entry.Position;
                }
            }
        }
        NetworkMap = newMap;
        NodeToNodeIDMapping.Clear();
        UpdateGraph();
    }
Example #9
0
    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);
    }
Example #10
0
    private static void Recover(INode myNode)
    {
        ConstellationPlan recoveryPlan = GenerateConstellation.GenerateTargetConstellation(myNode.Router.ReachableSats(myNode).Count, 7.152f);


        PlanRequest recoveryRequest = new PlanRequest
        {
            SourceID      = myNode.Id,
            DestinationID = myNode.Id,
            Command       = Request.Commands.GENERATE,
            Plan          = recoveryPlan
        };

        if (myNode.Router.NextSequential(myNode, Router.CommDir.CW) == null)
        {
            recoveryRequest.Dir = Router.CommDir.CCW;
        }

        myNode.CommsModule.Send(myNode.Id, recoveryRequest);
    }
Example #11
0
    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);
    }
Example #12
0
    /// <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);
        }
    }
Example #13
0
 public AdditionRequest(AdditionRequest other) : base(other)
 {
     plan = other.plan;
 }
Example #14
0
 public PlanRequest(PlanRequest other) : base(other)
 {
     Plan = other.Plan.DeepCopy();
 }
    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;
            }
        }
    }
Example #16
0
 public abstract void UpdateNetworkMap(ConstellationPlan 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);
    }
Example #18
0
    public async static void FailureDetected(INode myNode, uint?failedNode)
    {
        //Remove edge from router, ensuring it won't try to route through the failed node
        myNode.Router.DeleteEdge(myNode.Id, failedNode);

        List <uint?> failedNeighbours = new List <uint?>()
        {
            myNode.Id
        };
        List <uint?> neighboursToCheck = myNode.Router.NetworkMap.GetEntryByID(failedNode).Neighbours.Except(failedNeighbours).ToList();

        // Start recovery plan gen without failedNode in case myNode is the only neighbour
        if (neighboursToCheck.Count == 0)
        {
            ConstellationPlan RecoveryPlan = GenerateConstellation.GenerateTargetConstellation(myNode.Router.ReachableSats(myNode).Count, 7.152f);

            PlanRequest recoveryRequest = new PlanRequest {
                SourceID      = myNode.Id,
                DestinationID = myNode.Id,
                Command       = Request.Commands.GENERATE,
                Plan          = RecoveryPlan,
                Dir           = Router.CommDir.CW
            };

            NetworkUpdateRequest updateRequest = new NetworkUpdateRequest(new NetworkUpdateRequest(new List <uint?>()
            {
                failedNode
            }));

            recoveryRequest.DependencyRequests.Add(updateRequest);


            if (myNode.Router.NextSequential(myNode, Router.CommDir.CW) == null)
            {
                recoveryRequest.Dir = Router.CommDir.CCW;
            }

            PlanGenerator.GeneratePlan(myNode, recoveryRequest);
        }
        else     // Otherwise ask another neighbour to try to contact failedNode
        {
            uint?neighbourID = neighboursToCheck[0];
            uint?nextHop     = myNode.Router.NextHop(myNode.Id, neighbourID);

            DetectFailureRequest request = new DetectFailureRequest {
                DestinationID    = neighbourID,
                SourceID         = myNode.Id,
                Command          = Request.Commands.DETECTFAILURE,
                ResponseExpected = false,
                AckExpected      = true,
                NodeToCheck      = failedNode,
                DeadEdges        = new List <Tuple <uint?, uint?> > {
                    new Tuple <uint?, uint?>(myNode.Id, failedNode)
                },
                FailedNeighbours = failedNeighbours
            };

            myNode.Router.NetworkMap.Entries.RemoveAll(entry => entry.ID == failedNode);

            await myNode.CommsModule.SendAsync(nextHop, request, Constants.COMMS_TIMEOUT, Constants.COMMS_ATTEMPTS);
        }
    }