/// <summary>Notification that the list of sensors has changed</summary>
 internal static void OnSensorsChanged(Guid sensorId, SensorAvailabilityChange change)
 {
     if (SensorsChanged != null)
     {
         SensorsChanged.Invoke(new SensorsChangedEventArgs(sensorId, change));
     }
 }
예제 #2
0
    void IMessageReceiver.ReceiveMessage(IPeerManager sender, DistributedMessage distributedMessage)
    {
        if (sensorsInstances.Any() || Loader.Instance.Network.IsMaster)
        {
            return;
        }
        var allSensorsString     = distributedMessage.Content.PopString();
        var allSensors           = JsonConvert.DeserializeObject <SensorData[]>(allSensorsString);
        var enabledSensorsString = distributedMessage.Content.PopString();
        var enabledSensors       = JsonConvert.DeserializeObject <List <string> >(enabledSensorsString);

        InstantiateSensors(allSensors);
        foreach (var instance in sensorsInstances)
        {
            if (enabledSensors.Contains(instance.Key))
            {
                instance.Value.Enable();
            }
            else
            {
                instance.Value.Disable();
            }
        }
        SensorsChanged?.Invoke();
    }
예제 #3
0
    private void DistributeSensors()
    {
        var network = SimulatorManager.Instance.Network;

        if (!network.IsMaster || network.Master.Clients.Count <= 0)
        {
            return;
        }

        var sensorsToDistribute = new List <SensorInstanceController>();

        foreach (var sensorData in sensorsInstances)
        {
            if (sensorData.Value.Instance.CanBeDelegatedToClient)
            {
                sensorsToDistribute.Add(sensorData.Value);
            }
        }

        var peerSensors = new JSONArray();

        //Distribute sensors between clients and master simulation
        var sensorsPerPeer = sensorsToDistribute.Count / network.Master.Clients.Count;
        var currentSensorI = 0;

        //Clients
        for (var i = 0; i < network.Master.Clients.Count; i++)
        {
            var client = network.Master.Clients[i];
            peerSensors = new JSONArray();
            for (; currentSensorI < sensorsPerPeer * (i + 1); currentSensorI++)
            {
                peerSensors.Add(sensorsToDistribute[currentSensorI].Configuration);
                sensorsToDistribute[currentSensorI].Disable();
            }

            var content = new BytesStack();
            content.PushString(peerSensors.ToString());
            var message = new Message(Key, content, MessageType.ReliableUnordered);
            UnicastMessage(client.Peer.PeerEndPoint, message);
        }
        SensorsChanged?.Invoke();
    }
예제 #4
0
    private void DistributeSensors()
    {
        var network = Loader.Instance.Network;
        var master  = network.Master;
        var clients = master.Clients;

        if (!network.IsMaster || clients.Count <= 0)
        {
            return;
        }

        var clientsCount   = clients.Count;
        var clientsSensors = new Dictionary <IPeerManager, List <string> >();

        for (var i = 0; i < clientsCount; i++)
        {
            clientsSensors.Add(clients[i].Peer, new List <string>());
        }

        //Order sensors by distribution type, so ultra high loads will be handled first
        var sensorsByDistributionType =
            sensorsInstances.Values.Where(controller =>
                                          controller.Instance.DistributionType != SensorBase.SensorDistributionType.MainOnly)
            .OrderByDescending(controller => controller.Instance.DistributionType);

        var loadBalancer = master.LoadBalancer;

        foreach (var sensorData in sensorsByDistributionType)
        {
            IPeerManager sensorPeer;
            switch (sensorData.Instance.DistributionType)
            {
            case SensorBase.SensorDistributionType.MainOnly:
                loadBalancer.AppendMasterLoad(sensorData.Instance.PerformanceLoad);
                break;

            case SensorBase.SensorDistributionType.MainOrClient:
                sensorPeer = loadBalancer.AppendLoad(sensorData.Instance.PerformanceLoad, true);
                if (sensorPeer != null)
                {
                    //Sensor will be distributed to lowest load client
                    clientsSensors[sensorPeer].Add(sensorData.Configuration.Name);
                    sensorData.Disable();
                    SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, sensorPeer.PeerEndPoint);
                }
                break;

            case SensorBase.SensorDistributionType.ClientOnly:
                sensorPeer = loadBalancer.AppendLoad(sensorData.Instance.PerformanceLoad, false);
                //Sensor will be distributed to lowest load client
                clientsSensors[sensorPeer].Add(sensorData.Configuration.Name);
                SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, sensorPeer.PeerEndPoint);
                sensorData.Disable();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }

        var sensorsData   = sensorsInstances.Select(s => s.Value.Configuration);
        var allSensors    = JsonConvert.SerializeObject(sensorsData, JsonSettings.camelCase);
        var sensorsLength = BytesStack.GetMaxByteCount(allSensors);

        //Send sensors data to clients
        for (var i = 0; i < clientsCount; i++)
        {
            var client         = network.Master.Clients[i];
            var enabledSensors = JsonConvert.SerializeObject(clientsSensors[client.Peer], JsonSettings.camelCase);
            var message        = MessagesPool.Instance.GetMessage(sensorsLength + BytesStack.GetMaxByteCount(enabledSensors));
            message.AddressKey = Key;
            message.Content.PushString(enabledSensors);
            message.Content.PushString(allSensors);
            message.Type = DistributedMessageType.ReliableOrdered;
            ((IMessageSender)this).UnicastMessage(client.Peer.PeerEndPoint, message);
        }

        SensorsChanged?.Invoke();
    }
예제 #5
0
    private void InstantiateSensors(SensorData[] sensors)
    {
        var parents = new Dictionary <string, GameObject>()
        {
            { string.Empty, gameObject },
        };

        var Controller = GetComponent <IAgentController>();
        var requested  = sensors.ToList();
        var baseLink   = transform.GetComponentInChildren <BaseLink>();

        while (requested.Count > 0)
        {
            // remember how many are still looking to find their parent
            int requestedCount = requested.Count;
            for (int i = 0; i < requested.Count(); i++)
            {
                var    item       = requested[i];
                string parentName = item.Parent != null ? item.Parent : string.Empty;
                if (!parents.ContainsKey(parentName))
                {
                    continue;
                }

                var        parentObject = parents[parentName];
                var        name         = item.Name;
                var        type         = item.Type;
                GameObject prefab       = null;
                if (item.Plugin.AssetGuid == null)
                {
                    prefab = Config.SensorPrefabs.FirstOrDefault(s => GetSensorType(s) == type).gameObject;
                }
                else if (Config.SensorTypeLookup.ContainsKey(item.Plugin.AssetGuid))
                {
                    prefab = Config.SensorTypeLookup[item.Plugin.AssetGuid]?.gameObject;
                }
                else
                {
                    var dir = Path.Combine(Config.PersistentDataPath, "Sensors");
                    var vfs = VfsEntry.makeRoot(dir);
                    Config.CheckDir(vfs.GetChild(item.Plugin.AssetGuid), Config.LoadSensorPlugin);
                    if (Config.SensorTypeLookup.ContainsKey(item.Plugin.AssetGuid))
                    {
                        prefab = Config.SensorTypeLookup[item.Plugin.AssetGuid]?.gameObject;
                    }
                }

                if (prefab == null)
                {
                    throw new Exception($"Issue loading sensor type {type} for gameobject {gameObject.name} check logs");
                }

                var sensor     = CreateSensor(gameObject, parentObject, prefab, item, baseLink);
                var sensorBase = sensor.GetComponent <SensorBase>();
                sensorBase.Name = name;
                sensor.name     = name;
                if (AgentBridgeClient != null)
                {
                    sensor.GetComponent <SensorBase>().OnBridgeSetup(AgentBridgeClient.Bridge);
                }

                parents.Add(name, sensor);
                requested.RemoveAt(i);
                i--;
                var sensorInstanceController = new SensorInstanceController(item, sensorBase);
                if (SimulatorManager.InstanceAvailable)
                {
                    SimulatorManager.Instance.Sensors.RegisterSensor(sensorBase);
                }

                sensorInstanceController.Enable();
                Controller?.AgentSensors.Add(sensorBase);
                sensorsInstances.Add(name, sensorInstanceController);
            }

            // no sensors found their parent this round, they also won't find it next round
            if (requestedCount == requested.Count)
            {
                throw new Exception($"Failed to create {requested.Count} sensor(s), cannot determine parent-child relationship");
            }

            SensorsChanged?.Invoke();
        }
    }
예제 #6
0
    private void InstantiateSensors(string sensors)
    {
        var available = Simulator.Web.Config.Sensors.ToDictionary(sensor => sensor.Name);
        var prefabs   = Simulator.Web.Config.SensorPrefabs.ToDictionary(sensor => GetSensorType(sensor));

        var parents = new Dictionary <string, GameObject>()
        {
            { string.Empty, gameObject },
        };

        var agentController = GetComponent <AgentController>();
        var requested       = JSONNode.Parse(sensors).Children.ToList();

        while (requested.Count != 0)
        {
            int requestedCount = requested.Count;

            foreach (var parent in parents.Keys.ToArray())
            {
                var parentObject = parents[parent];

                for (int i = 0; i < requested.Count; i++)
                {
                    var item = requested[i];
                    if (item["parent"].Value == parent)
                    {
                        var name = item["name"].Value;
                        var type = item["type"].Value;

                        SensorConfig config;
                        if (!available.TryGetValue(type, out config))
                        {
                            throw new Exception($"Unknown sensor type {type} for {gameObject.name} vehicle");
                        }

                        var sensor     = CreateSensor(gameObject, parentObject, prefabs[type].gameObject, item);
                        var sensorBase = sensor.GetComponent <SensorBase>();
                        sensorBase.Name = name;
                        sensor.name     = name;
                        SIM.LogSimulation(SIM.Simulation.SensorStart, name);
                        if (AgentBridgeClient != null)
                        {
                            sensor.GetComponent <SensorBase>().OnBridgeSetup(AgentBridgeClient.Bridge);
                        }

                        parents.Add(name, sensor);
                        requested.RemoveAt(i);
                        i--;
                        var sensorInstanceController = new SensorInstanceController(item, sensorBase);
                        sensorInstanceController.Enable();
                        agentController.AgentSensors.Add(sensorBase);
                        sensorsInstances.Add(name, sensorInstanceController);
                    }
                }
            }

            if (requestedCount == requested.Count)
            {
                throw new Exception(
                          $"Failed to create {requested.Count} sensor(s), cannot determine parent-child relationship");
            }
            SensorsChanged?.Invoke();
        }
    }
예제 #7
0
    private void DistributeSensors()
    {
        var network = Loader.Instance.Network;
        var master  = network.Master;
        var clients = master.Clients;

        if (!network.IsMaster || clients.Count <= 0)
        {
            return;
        }

        var clientsCount   = clients.Count;
        var clientsSensors = new List <SensorData> [clientsCount];

        for (var i = 0; i < clientsSensors.Length; i++)
        {
            clientsSensors[i] = new List <SensorData>();
        }

        //Order sensors by distribution type, so ultra high loads will be handled first
        var sensorsByDistributionType =
            sensorsInstances.Values
            .Where(controller =>
                   controller.Instance.DistributionType != SensorBase.SensorDistributionType.DoNotDistribute)
            .OrderByDescending(controller => controller.Instance.DistributionType);
        //Track the load of simulations
        var clientsLoad = new float[clientsCount];
        //Decrease master simulation sensors load
        var masterLoad = 0.15f;

        foreach (var sensorData in sensorsByDistributionType)
        {
            var lowestLoadIndex = 0;
            switch (sensorData.Instance.DistributionType)
            {
            case SensorBase.SensorDistributionType.LowLoad:
                var lowLoadValue = 0.05f;
                for (var i = 1; i < clientsCount; i++)
                {
                    if (clientsLoad[i] < clientsLoad[lowestLoadIndex])
                    {
                        lowestLoadIndex = i;
                    }
                }
                if (masterLoad >= clientsLoad[lowestLoadIndex])
                {
                    //Sensor will be distributed to lowest load client
                    clientsLoad[lowestLoadIndex] += lowLoadValue;
                    clientsSensors[lowestLoadIndex].Add(sensorData.Configuration);
                    sensorData.Disable();
                    SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint);
                }
                else
                {
                    //Sensor won't be distributed, instance on master is not disabled
                    masterLoad += lowLoadValue;
                }
                break;

            case SensorBase.SensorDistributionType.HighLoad:
                var highLoadValue = 0.1f;
                for (var i = 1; i < clientsCount; i++)
                {
                    if (clientsLoad[i] < clientsLoad[lowestLoadIndex])
                    {
                        lowestLoadIndex = i;
                    }
                }
                if (masterLoad >= clientsLoad[lowestLoadIndex])
                {
                    //Sensor will be distributed to lowest load client
                    clientsLoad[lowestLoadIndex] += highLoadValue;
                    clientsSensors[lowestLoadIndex].Add(sensorData.Configuration);
                    sensorData.Disable();
                    SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint);
                }
                else
                {
                    //Sensor won't be distributed, instance on master is not disabled
                    masterLoad += highLoadValue;
                }
                break;

            case SensorBase.SensorDistributionType.UltraHighLoad:
                var ultraHighLoadValue = 1.0f;
                for (var i = 1; i < clientsCount; i++)
                {
                    if (clientsLoad[i] < clientsLoad[lowestLoadIndex])
                    {
                        lowestLoadIndex = i;
                    }
                }

                //Sensor will be distributed to lowest load client
                clientsLoad[lowestLoadIndex] += ultraHighLoadValue;
                clientsSensors[lowestLoadIndex].Add(sensorData.Configuration);
                SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint);
                sensorData.Disable();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }

        //Check if any client is overloaded
        var overloadedClients = clientsLoad.Count(load => load > 1.0f);

        if (overloadedClients > 0)
        {
            if (masterLoad > 1.0f)
            {
                overloadedClients++;
            }

            Debug.LogWarning($"Running cluster simulation with {overloadedClients} overloaded instances. Decrease sensors count or extend the cluster for best performance.");
        }
        else if (masterLoad > 1.0f)
        {
            Debug.LogWarning($"Running cluster simulation with overloaded master simulation. Used sensors cannot be distributed to the clients.");
        }

        //Send sensors data to clients
        for (var i = 0; i < clientsCount; i++)
        {
            var client       = network.Master.Clients[i];
            var sensorString = JsonConvert.SerializeObject(clientsSensors[i], JsonSettings.camelCase);
            var message      = MessagesPool.Instance.GetMessage(BytesStack.GetMaxByteCount(sensorString));
            message.AddressKey = Key;
            message.Content.PushString(sensorString);
            message.Type = DistributedMessageType.ReliableOrdered;
            UnicastMessage(client.Peer.PeerEndPoint, message);
        }

        SensorsChanged?.Invoke();
    }
예제 #8
0
 protected void OnSensorsChanged()
 {
     SensorsChanged?.Invoke(this);
 }