Ejemplo n.º 1
0
        /// <summary>
        /// Download required for the simulation vehicle bundles from the server
        /// </summary>
        /// <param name="load">Load command from the server</param>
        /// <param name="bundles">Paths where bundles will be saved</param>
        /// <param name="finished">Callback invoked when downloading is completed</param>
        private void DownloadVehicleBundles(Commands.Load load, List <string> bundles, Action finished)
        {
            try
            {
                int count = 0;

                var agents           = load.Agents;
                var agentsToDownload = load.Agents.Length;
                if (agentsToDownload == 0)
                {
                    finished();
                    return;
                }

                for (int i = 0; i < agentsToDownload; i++)
                {
                    //Check if downloading is already being processed, if true this may be a quick rerun of the simulation
                    if (processedDownloads.Contains(agents[i].Name))
                    {
                        Interlocked.Increment(ref count);
                        continue;
                    }
                    VehicleModel vehicleModel;
                    using (var db = DatabaseManager.Open())
                    {
                        var sql = Sql.Builder.Where("name = @0", agents[i].Name);
                        vehicleModel = db.SingleOrDefault <VehicleModel>(sql);
                    }

                    if (vehicleModel == null)
                    {
                        Debug.Log($"Downloading {agents[i].Name} from {agents[i].Url}");

                        vehicleModel = new VehicleModel()
                        {
                            Name       = agents[i].Name,
                            Url        = agents[i].Url,
                            BridgeType = agents[i].Bridge,
                            LocalPath  = WebUtilities.GenerateLocalPath("Vehicles"),
                            Sensors    = agents[i].Sensors,
                        };
                        bundles.Add(vehicleModel.LocalPath);

                        processedDownloads.Add(vehicleModel.Name);
                        DownloadManager.AddDownloadToQueue(new Uri(vehicleModel.Url), vehicleModel.LocalPath, null,
                                                           (success, ex) =>
                        {
                            //Check if downloaded vehicle model is still valid in current load command
                            if (CurrentLoadCommand.Agents.All(loadAgent => loadAgent.Name != vehicleModel.Name))
                            {
                                return;
                            }
                            processedDownloads.Remove(vehicleModel.Name);
                            if (ex != null)
                            {
                                var err = new Commands.LoadResult()
                                {
                                    Success      = false,
                                    ErrorMessage = ex.ToString(),
                                };
                                var errData        = PacketsProcessor.Write(err);
                                var message        = MessagesPool.Instance.GetMessage(errData.Length);
                                message.AddressKey = Key;
                                message.Content.PushBytes(errData);
                                message.Type = DistributedMessageType.ReliableOrdered;
                                UnicastMessage(MasterPeer.PeerEndPoint, message);
                                return;
                            }

                            using (var db = DatabaseManager.Open())
                            {
                                db.Insert(vehicleModel);
                            }

                            if (Interlocked.Increment(ref count) == agentsToDownload)
                            {
                                finished();
                            }
                        }
                                                           );
                    }
                    else
                    {
                        Debug.Log($"Vehicle {agents[i].Name} exists");

                        bundles.Add(vehicleModel.LocalPath);
                        if (Interlocked.Increment(ref count) == agentsToDownload)
                        {
                            finished();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                var errData = PacketsProcessor.Write(err);
                var message = MessagesPool.Instance.GetMessage(errData.Length);
                message.AddressKey = Key;
                message.Content.PushBytes(errData);
                message.Type = DistributedMessageType.ReliableOrdered;
                UnicastMessage(MasterPeer.PeerEndPoint, message);

                Loader.ResetLoaderScene();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Download required for the simulation vehicle bundles from the server
        /// </summary>
        /// <param name="load">Load command from the server</param>
        /// <param name="mapBundlePath">Path where the map bundle will be saved</param>
        private void LoadMapBundle(Commands.Load load, string mapBundlePath)
        {
            var vehicleBundles = new List <string>();

            DownloadVehicleBundles(load, vehicleBundles, () =>
            {
                if (MasterPeer == null)
                {
                    Debug.LogWarning("Master peer has disconnected while loading the simulation scene.");
                    Loader.ResetLoaderScene();
                    return;
                }
                var zip = new ZipFile(mapBundlePath);
                {
                    string manfile;
                    ZipEntry entry = zip.GetEntry("manifest");
                    using (var ms = zip.GetInputStream(entry))
                    {
                        int streamSize = (int)entry.Size;
                        byte[] buffer  = new byte[streamSize];
                        streamSize     = ms.Read(buffer, 0, streamSize);
                        manfile        = Encoding.UTF8.GetString(buffer);
                    }

                    Manifest manifest = new Deserializer().Deserialize <Manifest>(manfile);

                    AssetBundle textureBundle = null;

                    if (zip.FindEntry(($"{manifest.assetGuid}_environment_textures"), false) != -1)
                    {
                        var texStream = zip.GetInputStream(zip.GetEntry($"{manifest.assetGuid}_environment_textures"));
                        textureBundle = AssetBundle.LoadFromStream(texStream, 0, 1 << 20);
                    }

                    string platform = SystemInfo.operatingSystemFamily == OperatingSystemFamily.Windows
                        ? "windows"
                        : "linux";
                    var mapStream =
                        zip.GetInputStream(zip.GetEntry($"{manifest.assetGuid}_environment_main_{platform}"));
                    var mapBundle = AssetBundle.LoadFromStream(mapStream, 0, 1 << 20);

                    if (mapBundle == null)
                    {
                        throw new Exception($"Failed to load environment from '{load.MapName}' asset bundle");
                    }

                    textureBundle?.LoadAllAssets();

                    var scenes = mapBundle.GetAllScenePaths();
                    if (scenes.Length != 1)
                    {
                        throw new Exception(
                            $"Unsupported environment in '{load.MapName}' asset bundle, only 1 scene expected");
                    }

                    var sceneName = Path.GetFileNameWithoutExtension(scenes[0]);

                    var loader        = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
                    loader.completed += op =>
                    {
                        if (op.isDone)
                        {
                            SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName));
                            textureBundle?.Unload(false);
                            mapBundle.Unload(false);
                            zip.Close();

                            try
                            {
                                var prefabs = LoadVehicleBundles(vehicleBundles);

                                Loader.Instance.SimConfig = new SimulationConfig()
                                {
                                    Name           = load.Name,
                                    ApiOnly        = load.ApiOnly,
                                    Headless       = load.Headless,
                                    Interactive    = load.Interactive,
                                    TimeOfDay      = DateTime.ParseExact(load.TimeOfDay, "o", CultureInfo.InvariantCulture),
                                    Rain           = load.Rain,
                                    Fog            = load.Fog,
                                    Wetness        = load.Wetness,
                                    Cloudiness     = load.Cloudiness,
                                    UseTraffic     = load.UseTraffic,
                                    UsePedestrians = load.UsePedestrians,
                                    Agents         = load.Agents.Zip(prefabs, (agent, prefab) =>
                                    {
                                        var config = new AgentConfig()
                                        {
                                            Name       = agent.Name,
                                            Prefab     = prefab,
                                            Connection = agent.Connection,
                                            Sensors    = agent.Sensors,
                                        };

                                        if (!string.IsNullOrEmpty(agent.Bridge))
                                        {
                                            config.Bridge =
                                                Web.Config.Bridges.Find(bridge => bridge.Name == agent.Bridge);
                                            if (config.Bridge == null)
                                            {
                                                throw new Exception($"Bridge {agent.Bridge} not found");
                                            }
                                        }

                                        return(config);
                                    }).ToArray(),
                                };

                                Loader.Instance.CurrentSimulation        = CreateSimulationModel(Loader.Instance.SimConfig);
                                Loader.Instance.CurrentSimulation.Status = "Running";
                                if (Loader.Instance.SimConfig.ApiOnly)
                                {
                                    var api  = Instantiate(Loader.Instance.ApiManagerPrefab);
                                    api.name = "ApiManager";
                                }

                                var simulatorManager = Loader.CreateSimulatorManager();
                                if (load.UseSeed)
                                {
                                    simulatorManager.Init(load.Seed);
                                }
                                else
                                {
                                    simulatorManager.Init();
                                }
                                InitializeSimulation(simulatorManager.gameObject);

                                // Notify WebUI simulation is running
                                NotificationManager.SendNotification("simulation",
                                                                     SimulationResponse.Create(Loader.Instance.CurrentSimulation),
                                                                     Loader.Instance.CurrentSimulation.Owner);

                                Debug.Log($"Client ready to start");

                                var result = new Commands.LoadResult()
                                {
                                    Success = true,
                                };

                                Loader.Instance.LoaderUI.SetLoaderUIState(LoaderUI.LoaderUIStateType.READY);
                                if (MasterPeer == null)
                                {
                                    Debug.LogWarning("Master peer has disconnected while loading the simulation scene.");
                                    Loader.ResetLoaderScene();
                                    return;
                                }
                                var resultData     = PacketsProcessor.Write(result);
                                var message        = MessagesPool.Instance.GetMessage(resultData.Length);
                                message.AddressKey = Key;
                                message.Content.PushBytes(resultData);
                                message.Type = DistributedMessageType.ReliableOrdered;
                                UnicastMessage(MasterPeer.PeerEndPoint, message);

                                State = SimulationState.Ready;
                            }
                            catch (Exception ex)
                            {
                                Debug.LogException(ex);

                                var err = new Commands.LoadResult()
                                {
                                    Success      = false,
                                    ErrorMessage = ex.ToString(),
                                };
                                var errData        = PacketsProcessor.Write(err);
                                var message        = MessagesPool.Instance.GetMessage(errData.Length);
                                message.AddressKey = Key;
                                message.Content.PushBytes(errData);
                                message.Type = DistributedMessageType.ReliableOrdered;
                                UnicastMessage(MasterPeer.PeerEndPoint, message);

                                Loader.ResetLoaderScene();
                            }
                        }
                    };
                }
            });
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Method invoked when manager receives load command
        /// </summary>
        /// <param name="load">Received load command</param>
        private void OnLoadCommand(Commands.Load load)
        {
            Debug.Assert(State == SimulationState.Connected);
            CurrentLoadCommand = load;
            State = SimulationState.Loading;

            Debug.Log("Preparing simulation");

            try
            {
                //Check if downloading is already being processed, if true this may be a quick rerun of the simulation
                if (processedDownloads.Contains(load.MapUrl))
                {
                    return;
                }
                MapModel map;
                using (var db = DatabaseManager.Open())
                {
                    var sql = Sql.Builder.Where("name = @0", load.MapName);
                    map = db.SingleOrDefault <MapModel>(sql);
                }

                if (map == null)
                {
                    Debug.Log($"Downloading {load.MapName} from {load.MapUrl}");

                    map = new MapModel()
                    {
                        Name      = load.MapName,
                        Url       = load.MapUrl,
                        LocalPath = WebUtilities.GenerateLocalPath("Maps"),
                    };

                    using (var db = DatabaseManager.Open())
                    {
                        db.Insert(map);
                    }

                    processedDownloads.Add(map.Name);
                    DownloadManager.AddDownloadToQueue(new Uri(map.Url), map.LocalPath, null, (success, ex) =>
                    {
                        processedDownloads.Remove(map.Name);
                        //Check if downloaded map is still valid in current load command
                        if (CurrentLoadCommand.MapName != map.Name)
                        {
                            return;
                        }
                        if (ex != null)
                        {
                            map.Error = ex.Message;
                            using (var db = DatabaseManager.Open())
                            {
                                db.Update(map);
                            }

                            Debug.LogException(ex);
                        }

                        if (success)
                        {
                            LoadMapBundle(load, map.LocalPath);
                        }
                        else
                        {
                            var err = new Commands.LoadResult()
                            {
                                Success      = false,
                                ErrorMessage = ex.ToString(),
                            };
                            var errData        = PacketsProcessor.Write(err);
                            var message        = MessagesPool.Instance.GetMessage(errData.Length);
                            message.AddressKey = Key;
                            message.Content.PushBytes(errData);
                            message.Type = DistributedMessageType.ReliableOrdered;
                            UnicastMessage(MasterPeer.PeerEndPoint, message);
                        }
                    });
                }
                else
                {
                    Debug.Log($"Map {load.MapName} exists");
                    LoadMapBundle(load, map.LocalPath);
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                var errData = PacketsProcessor.Write(err);
                var message = MessagesPool.Instance.GetMessage(errData.Length);
                message.AddressKey = Key;
                message.Content.PushBytes(errData);
                message.Type = DistributedMessageType.ReliableOrdered;
                UnicastMessage(MasterPeer.PeerEndPoint, message);

                Loader.ResetLoaderScene();
            }
        }