public AgentConfig(VehicleData vehicleData) { Name = vehicleData.Name; Connection = vehicleData.Bridge != null ? vehicleData.Bridge.ConnectionString : ""; AssetGuid = vehicleData.AssetGuid; #if UNITY_EDITOR if (vehicleData.Id.EndsWith(".prefab")) { AssetBundle = vehicleData.Id; AssetGuid = vehicleData.Id; } else #endif { AssetBundle = Web.WebUtilities.GenerateLocalPath(vehicleData.AssetGuid, BundleConfig.BundleTypes.Vehicle); } Sensors = vehicleData.Sensors; //Load sensors from the configuration if no sensors are set if ((Sensors == null || Sensors.Length == 0) && vehicleData.SensorsConfigurations != null && vehicleData.SensorsConfigurations.Length > 0) { Sensors = vehicleData.SensorsConfigurations[0].Sensors; } if (vehicleData.Bridge != null && !string.IsNullOrEmpty(vehicleData.Bridge.Type)) { Bridge = BridgePlugins.Get(vehicleData.Bridge.Type); if (Bridge == null) { throw new Exception($"Bridge {vehicleData.Bridge.Type} not found"); } } }
static void Initialize() { Root = Path.Combine(Application.dataPath, ".."); PersistentDataPath = Application.persistentDataPath; AssetBundle.UnloadAllAssetBundles(false); SensorPrefabs = RuntimeSettings.Instance.SensorPrefabs.ToList(); if (SensorPrefabs.Any(s => s == null)) { Debug.LogError("Null Sensor Prefab Detected - Check RuntimeSettings SensorPrefabs List for missing Sensor Prefab"); #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else // return non-zero exit code Application.Quit(1); #endif return; } BridgePlugins.Load(); LoadBuiltinAssets(); LoadExternalAssets(); Sensors = SensorTypes.ListSensorFields(SensorPrefabs); ParseConfigFile(); if (!Application.isEditor) { ParseCommandLine(); } }
private static void Initialize() { Root = Path.Combine(Application.dataPath, ".."); PersistentDataPath = Application.persistentDataPath; ParseConfigFile(); if (!Application.isEditor) { ParseCommandLine(); CreateLockFile(); } AssetBundle.UnloadAllAssetBundles(false); Sensors = new List <SensorConfig>(); SensorPrefabs = new List <SensorBase>(); BridgePlugins.Load(); LoadBuiltinAssets(); LoadExternalAssets(); Sensors = SensorTypes.ListSensorFields(SensorPrefabs); DatabaseManager.Init(); ClientSettingsService csservice = new ClientSettingsService(); if (string.IsNullOrEmpty(SimID)) { SimID = csservice.GetOrMake().simid; } csservice.SetSimID(SimID); }
public static void LoadBridgePlugin(Manifest manifest, VfsEntry dir) { if (manifest.bundleFormat != BundleConfig.Versions[BundleConfig.BundleTypes.Bridge]) { throw new Exception($"manifest version mismatch, expected {BundleConfig.Versions[BundleConfig.BundleTypes.Sensor]}, got {manifest.bundleFormat}"); } var pluginSource = loadAssembly(dir, $"{manifest.assetName}.dll"); foreach (Type ty in pluginSource.GetTypes()) { if (typeof(IBridgeFactory).IsAssignableFrom(ty)) { var bridgeFactory = Activator.CreateInstance(ty) as IBridgeFactory; BridgePlugins.Add(bridgeFactory); } } }
public static void LoadBridgePlugin(Manifest manifest, VfsEntry dir) { #if UNITY_EDITOR if (EditorPrefs.GetBool("Simulator/Developer Debug Mode", false) == true) { Assembly bridgesAssembly = null; if (File.Exists(Path.Combine(BundleConfig.ExternalBase, "Bridges", manifest.assetName, $"{manifest.assetName}.cs"))) { if (bridgesAssembly == null) { bridgesAssembly = Assembly.Load("Simulator.Bridges"); } foreach (Type ty in bridgesAssembly.GetTypes()) { if (typeof(IBridgeFactory).IsAssignableFrom(ty) && !ty.IsAbstract && ty.GetCustomAttribute <BridgeNameAttribute>().Name == manifest.bridgeType) { Debug.LogWarning($"Loading {manifest.bridgeType} ({manifest.assetGuid}) in Developer Debug Mode. If you wish to use this bridge plugin from WISE, disable Developer Debug Mode in Simulator->Developer Debug Mode or remove the bridge from Assets/External/Bridges"); var bridgeFactory = Activator.CreateInstance(ty) as IBridgeFactory; BridgePlugins.Add(bridgeFactory); LoadedAssets.Add(manifest); } } return; } } #endif if (manifest.assetFormat != BundleConfig.Versions[BundleConfig.BundleTypes.Bridge]) { throw new Exception($"Manifest version mismatch, expected {BundleConfig.Versions[BundleConfig.BundleTypes.Bridge]}, got {manifest.assetFormat}"); } var pluginSource = LoadAssembly(dir, $"{manifest.assetName}.dll"); foreach (Type ty in pluginSource.GetTypes()) { if (typeof(IBridgeFactory).IsAssignableFrom(ty) && !ty.IsAbstract) { var bridgeFactory = Activator.CreateInstance(ty) as IBridgeFactory; BridgePlugins.Add(bridgeFactory); LoadedAssets.Add(manifest); } } }
private static void Initialize() { Root = Path.Combine(Application.dataPath, ".."); PersistentDataPath = Application.persistentDataPath; ParseConfigFile(); if (!Application.isEditor) { ParseCommandLine(); CreateLockFile(); } AssetBundle.UnloadAllAssetBundles(false); Sensors = new List <SensorConfig>(); SensorPrefabs = new List <SensorBase>(); if (SensorPrefabs.Any(s => s == null)) { Debug.LogError("!!! Null Sensor Prefab Detected - Check RuntimeSettings SensorPrefabs List for missing Sensor Prefab"); #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(1); // return non-zero exit code #endif } BridgePlugins.Load(); LoadBuiltinAssets(); LoadExternalAssets(); Sensors = SensorTypes.ListSensorFields(SensorPrefabs); DatabaseManager.Init(); ClientSettingsService csservice = new ClientSettingsService(); if (string.IsNullOrEmpty(SimID)) { SimID = csservice.GetOrMake().simid; } csservice.SetSimID(SimID); }
public static bool BeValidBridgeType(string bridgeType) { return(string.IsNullOrEmpty(bridgeType) || BridgePlugins.Get(bridgeType) != null); }
static void CreateDefaultDbAssets() { var info = Resources.Load <Utilities.BuildInfo>("BuildInfo"); if (info == null || info.DownloadHost == null) { Debug.Log("*** No debug info, or downloadhost is nulll"); return; } using (var db = Open()) { long?defaultMap = null; if (info.DownloadEnvironments != null) { foreach (var e in info.DownloadEnvironments) { var url = $"https://{info.DownloadHost}/{e.Id}/environment_{e.Name}"; var localPath = WebUtilities.GenerateLocalPath("Maps"); var map = new MapModel() { Name = e.Name, Status = "Downloading", Url = url, LocalPath = localPath, }; var id = db.Insert(map); if (map.Name == "BorregasAve") { defaultMap = map.Id; } } } long?autowareVehicle = null; long?noBridgeVehicle = null; long?apolloVehicle = null; if (info.DownloadVehicles != null) { foreach (var v in info.DownloadVehicles) { var localPath = WebUtilities.GenerateLocalPath("Vehicles"); if (v.Name == "Jaguar2015XE") { AddVehicle(db, info, v, localPath, DefaultSensors.Autoware, " (Autoware)", BridgePlugins.GetNameFromFactory(typeof(RosBridgeFactory))); AddVehicle(db, info, v, localPath, DefaultSensors.Apollo30, " (Apollo 3.0)", BridgePlugins.GetNameFromFactory(typeof(RosApolloBridgeFactory))); noBridgeVehicle = AddVehicle(db, info, v, localPath, DefaultSensors.DataCollection, " (No Bridge)"); } else if (v.Name == "Lexus2016RXHybrid") { autowareVehicle = AddVehicle(db, info, v, localPath, DefaultSensors.Autoware, " (Autoware)", BridgePlugins.GetNameFromFactory(typeof(RosBridgeFactory))); } else if (v.Name == "Lincoln2017MKZ") { apolloVehicle = AddVehicle(db, info, v, localPath, DefaultSensors.Apollo50, " (Apollo 5.0)", BridgePlugins.GetNameFromFactory(typeof(CyberBridgeFactory))); } else { apolloVehicle = AddVehicle(db, info, v, localPath, DefaultSensors.Apollo50, " (Apollo 5.0)", BridgePlugins.GetNameFromFactory(typeof(CyberBridgeFactory))); } } } if (defaultMap.HasValue) { var dt = DateTime.Now.Date + new TimeSpan(12, 0, 0); var dtEvening = DateTime.Now.Date + new TimeSpan(17, 20, 0); var sim1 = new SimulationModel() { Name = "BorregasAve, no bridge, data collection", Cluster = 0, Map = defaultMap.Value, ApiOnly = false, Interactive = true, TimeOfDay = dt, }; AddSimulation(db, sim1, noBridgeVehicle); var sim2 = new SimulationModel() { Name = "BorregasAve (with Autoware)", Cluster = 0, Map = defaultMap.Value, ApiOnly = false, Interactive = true, TimeOfDay = dt, }; AddSimulation(db, sim2, autowareVehicle); var sim3 = new SimulationModel() { Name = "BorregasAve, noninteractive (with Apollo 5.0)", Cluster = 0, Map = defaultMap.Value, ApiOnly = false, Seed = 12345, TimeOfDay = dt, Wetness = 0.4f, Cloudiness = 0.6f, Fog = 0.5f, UseTraffic = true, }; AddSimulation(db, sim3, apolloVehicle); var sim4 = new SimulationModel() { Name = "BorregasAve, evening (with Apollo 5.0)", Cluster = 0, Map = defaultMap.Value, ApiOnly = false, Interactive = true, TimeOfDay = dtEvening, UseTraffic = true, }; AddSimulation(db, sim4, apolloVehicle); var sim5 = new SimulationModel() { Name = "API Only", Cluster = 0, Map = defaultMap.Value, ApiOnly = true, }; db.Insert(sim5); } } }
async void Refresh() { if (EditorApplication.isPlayingOrWillChangePlaymode) { return; } try { updating = true; ErrorMessage = ""; Simulator.Web.Config.ParseConfigFile(); await UpdateVersions(); try { // FIXME also list and find bundles and cloud bridges? var bridgesAssembly = Assembly.Load("Simulator.Bridges"); Bridges = bridgesAssembly.GetTypes() .Where(ty => typeof(IBridgeFactory).IsAssignableFrom(ty) && !ty.IsAbstract) .Select(ty => BridgePlugins.GetNameFromFactory(ty)).ToArray(); } catch { } if (DeveloperSimulation.Cluster == null) { DeveloperSimulation.Cluster = new ClusterData() { Name = "DeveloperSettingsDummy", Instances = new[] { new InstanceData { HostName = "dummy.developer.settings", Ip = new [] { "127.0.0.1" }, MacAddress = "00:00:00:00:00:00" } } }; } if (string.IsNullOrEmpty(Config.CloudProxy)) { API = new CloudAPI(new Uri(Config.CloudUrl), Config.SimID); } else { API = new CloudAPI(new Uri(Config.CloudUrl), Config.SimID, new Uri(Config.CloudProxy)); } DatabaseManager.Init(); var csservice = new Simulator.Database.Services.ClientSettingsService(); ClientSettings cls = csservice.GetOrMake(); Config.SimID = cls.simid; if (string.IsNullOrEmpty(Config.CloudUrl)) { ErrorMessage = "Cloud URL not set"; return; } if (string.IsNullOrEmpty(Config.SimID)) { linked = false; ErrorMessage = "Simulator not linked"; return; } var ret = await API.GetLibrary <VehicleDetailData>(); CloudVehicles = ret.ToList(); string[] guids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets/External/Vehicles" }); LocalVehicles = guids.Select(g => AssetDatabase.GUIDToAssetPath(g)).ToList(); string idOrPath = null; if (DeveloperSimulation.Vehicles != null) // get previously selected thing { // we abuse VehicleData.Id to store the prefab path idOrPath = EgoVehicle.Id; } if (idOrPath != null) { // find index of previously selected thing in new dataset var foundIndex = VehicleChoices.FindIndex(v => v.cloudIdOrPrefabPath == idOrPath && (v.IsLocal || v.configId == Settings.VehicleConfigId)); SetVehicleFromSelectionIndex(foundIndex); updateVehicleDetails = true; await UpdateCloudVehicleDetails(); } DeveloperSimulation.NPCs = Config.NPCVehicles.Values.ToArray(); // TODO get from cloud and refresh config.cs LoadExternalAssets() } catch (CloudAPI.NoSuccessException ex) { if (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized) { ErrorMessage = "This instance requires linking to a cluster on " + Config.CloudUrl; linked = false; } else { Debug.LogException(ex); } } catch (Exception ex) { Debug.LogException(ex); ErrorMessage = ex.Message; if (ex.InnerException != null) { ErrorMessage += "\n" + ex.InnerException.Message; } } finally { updating = false; Repaint(); } }
public GameObject SpawnAgent(AgentConfig config) { var go = Instantiate(config.Prefab, transform); go.name = config.Name; // set it inactive until we can be sure setting up sensors etc worked without exceptions and it AgentController was initialized go.SetActive(false); var controller = go.GetComponent <IAgentController>(); if (controller == null) { Debug.LogWarning($"{nameof(IAgentController)} implementation not found on the {config.Name} vehicle. This vehicle can't be used as an ego vehicle."); } else { controller.Config = config; controller.Config.AgentGO = go; ActiveAgents.Add(controller.Config); controller.GTID = ++SimulatorManager.Instance.GTIDs; controller.Config.GTID = controller.GTID; } var lane = go.AddComponent <VehicleLane>(); var baseLink = go.GetComponentInChildren <BaseLink>(); if (baseLink == null) { baseLink = new GameObject("BaseLink").AddComponent <BaseLink>(); baseLink.transform.SetParent(go.transform, false); } var sensorsController = go.GetComponent <ISensorsController>() ?? go.AddComponent <SensorsController>(); if (controller != null) { controller.AgentSensorsController = sensorsController; } //Add required components for distributing rigidbody from master to clients var network = Loader.Instance.Network; if (network.IsClusterSimulation) { HierarchyUtilities.ChangeToUniqueName(go); //Add the rest required components for cluster simulation ClusterSimulationUtilities.AddDistributedComponents(go); if (network.IsClient) { controller?.DisableControl(); } } BridgeClient bridgeClient = null; if (config.BridgeData != null) { var dir = Path.Combine(Simulator.Web.Config.PersistentDataPath, "Bridges"); var vfs = VfsEntry.makeRoot(dir); Simulator.Web.Config.CheckDir(vfs.GetChild(config.BridgeData.AssetGuid), Simulator.Web.Config.LoadBridgePlugin); bridgeClient = go.AddComponent <BridgeClient>(); config.Bridge = BridgePlugins.Get(config.BridgeData.Type); bridgeClient.Init(config.Bridge); if (!String.IsNullOrEmpty(config.Connection)) { bridgeClient.Connect(config.Connection); } } go.transform.position = config.Position; go.transform.rotation = config.Rotation; sensorsController.SetupSensors(config.Sensors); controller?.Init(); if (SimulatorManager.Instance.IsAPI) { SimulatorManager.Instance.EnvironmentEffectsManager.InitRainVFX(go.transform); } go.SetActive(true); return(go); }
/// <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) { Log.Warning("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 = BridgePlugins.Get(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); Log.Info($"Client ready to start"); var result = new Commands.LoadResult() { Success = true, }; Loader.Instance.LoaderUI.SetLoaderUIState(LoaderUI.LoaderUIStateType.READY); if (MasterPeer == null) { Log.Warning("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(); } } }; } }); }
public static void StartAsync(SimulationModel simulation) { Debug.Assert(Instance.CurrentSimulation == null); Instance.Actions.Enqueue(() => { using (var db = DatabaseManager.Open()) { AssetBundle textureBundle = null; AssetBundle mapBundle = null; try { if (Config.Headless && (simulation.Headless.HasValue && !simulation.Headless.Value)) { throw new Exception("Simulator is configured to run in headless mode, only headless simulations are allowed"); } simulation.Status = "Starting"; NotificationManager.SendNotification("simulation", SimulationResponse.Create(simulation), simulation.Owner); Instance.LoaderUI.SetLoaderUIState(LoaderUI.LoaderUIStateType.PROGRESS); Instance.SimConfig = new SimulationConfig() { Name = simulation.Name, Clusters = db.Single <ClusterModel>(simulation.Cluster).Ips.Split(',').Where(c => c != "127.0.0.1").ToArray(), ClusterName = db.Single <ClusterModel>(simulation.Cluster).Name, ApiOnly = simulation.ApiOnly.GetValueOrDefault(), Headless = simulation.Headless.GetValueOrDefault(), Interactive = simulation.Interactive.GetValueOrDefault(), TimeOfDay = simulation.TimeOfDay.GetValueOrDefault(new DateTime(1980, 3, 24, 12, 0, 0)), Rain = simulation.Rain.GetValueOrDefault(), Fog = simulation.Fog.GetValueOrDefault(), Wetness = simulation.Wetness.GetValueOrDefault(), Cloudiness = simulation.Cloudiness.GetValueOrDefault(), UseTraffic = simulation.UseTraffic.GetValueOrDefault(), UsePedestrians = simulation.UsePedestrians.GetValueOrDefault(), Seed = simulation.Seed, }; if (simulation.Vehicles == null || simulation.Vehicles.Length == 0 || simulation.ApiOnly.GetValueOrDefault()) { Instance.SimConfig.Agents = Array.Empty <AgentConfig>(); } else { Instance.SimConfig.Agents = simulation.Vehicles.Select(v => { var vehicle = db.SingleOrDefault <VehicleModel>(v.Vehicle); var config = new AgentConfig() { Name = vehicle.Name, Url = vehicle.Url, AssetBundle = vehicle.LocalPath, Connection = v.Connection, Sensors = vehicle.Sensors, }; if (!string.IsNullOrEmpty(vehicle.BridgeType)) { config.Bridge = BridgePlugins.Get(vehicle.BridgeType); if (config.Bridge == null) { throw new Exception($"Bridge {vehicle.BridgeType} not found"); } } return(config); }).ToArray(); } //Initialize network for the master, client has initialized network since startup if (Instance.SimConfig.Clusters == null || Instance.SimConfig.Clusters.Length == 0) { if (Config.RunAsMaster) { Instance.Network.Initialize(SimulationNetwork.ClusterNodeType.NotClusterNode, Instance.NetworkSettings); } } else if (Config.RunAsMaster) { Instance.Network.Initialize(SimulationNetwork.ClusterNodeType.Master, Instance.NetworkSettings); Instance.Network.Master.Simulation = Instance.SimConfig; } // load environment if (Instance.SimConfig.ApiOnly) { var api = Instantiate(Instance.ApiManagerPrefab); api.name = "ApiManager"; Instance.CurrentSimulation = simulation; // ready to go! Instance.CurrentSimulation.Status = "Running"; NotificationManager.SendNotification("simulation", SimulationResponse.Create(simulation), simulation.Owner); Instance.LoaderUI.SetLoaderUIState(LoaderUI.LoaderUIStateType.READY); } else { var mapModel = db.Single <MapModel>(simulation.Map); var mapBundlePath = mapModel.LocalPath; mapBundle = null; textureBundle = null; ZipFile 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; try { manifest = new Deserializer().Deserialize <Manifest>(manfile); } catch { throw new Exception("Out of date AssetBundle, rebuild or download latest AssetBundle."); } if (manifest.additionalFiles != null) { foreach (string key in manifest.additionalFiles.Keys) { if (key.Contains("pointcloud")) { if (!Directory.Exists(Path.Combine(Application.persistentDataPath, manifest.assetGuid))) { Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, manifest.assetGuid)); FastZip fastZip = new FastZip(); fastZip.ExtractZip(mapBundlePath, Path.Combine(Application.persistentDataPath, manifest.assetGuid), ".*\\.(pcnode|pcindex|pcmesh)$"); } } } } if (manifest.bundleFormat != BundleConfig.Versions[BundleConfig.BundleTypes.Environment]) { zip.Close(); // TODO: proper exception throw new ZipException("BundleFormat version mismatch"); } 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}")); mapBundle = AssetBundle.LoadFromStream(mapStream, 0, 1 << 20); if (mapBundle == null) { throw new Exception($"Failed to load environment from '{mapModel.Name}' asset bundle"); } textureBundle?.LoadAllAssets(); var scenes = mapBundle.GetAllScenePaths(); if (scenes.Length != 1) { throw new Exception($"Unsupported environment in '{mapModel.Name}' asset bundle, only 1 scene expected"); } var sceneName = Path.GetFileNameWithoutExtension(scenes[0]); Instance.SimConfig.MapName = sceneName; Instance.SimConfig.MapUrl = mapModel.Url; var isMasterSimulation = Instance.SimConfig.Clusters.Length > 0; var loader = SceneManager.LoadSceneAsync(sceneName, isMasterSimulation ? LoadSceneMode.Additive : LoadSceneMode.Single); loader.completed += op => { if (op.isDone) { if (isMasterSimulation) { SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName)); } textureBundle?.Unload(false); mapBundle.Unload(false); zip.Close(); NodeTreeLoader[] loaders = FindObjectsOfType <NodeTreeLoader>(); foreach (NodeTreeLoader l in loaders) { l.UpdateData(Path.Combine(Application.persistentDataPath, manifest.assetGuid, $"pointcloud_{Utilities.Utility.StringToGUID(l.GetDataPath())}".ToString())); } SetupScene(simulation); } }; } } } catch (ZipException ex) { Debug.Log($"Failed to start '{simulation.Name}' simulation"); Debug.LogException(ex); // NOTE: In case of failure we have to update Simulation state simulation.Status = "Invalid"; simulation.Error = "Out of date Map AssetBundle. Please check content website for updated bundle or rebuild the bundle."; db.Update(simulation); if (SceneManager.GetActiveScene().name != Instance.LoaderScene) { SceneManager.LoadScene(Instance.LoaderScene); } textureBundle?.Unload(false); mapBundle?.Unload(false); AssetBundle.UnloadAllAssetBundles(true); Instance.CurrentSimulation = null; // TODO: take ex.Message and append it to response here NotificationManager.SendNotification("simulation", SimulationResponse.Create(simulation), simulation.Owner); } catch (Exception ex) { Debug.Log($"Failed to start '{simulation.Name}' simulation"); Debug.LogException(ex); // NOTE: In case of failure we have to update Simulation state simulation.Status = "Invalid"; simulation.Error = ex.Message; db.Update(simulation); if (SceneManager.GetActiveScene().name != Instance.LoaderScene) { SceneManager.LoadScene(Instance.LoaderScene); } textureBundle?.Unload(false); mapBundle?.Unload(false); AssetBundle.UnloadAllAssetBundles(true); Instance.CurrentSimulation = null; // TODO: take ex.Message and append it to response here NotificationManager.SendNotification("simulation", SimulationResponse.Create(simulation), simulation.Owner); } } }); }
public void SetupDevAgents() { var sceneAgents = GameObject.FindGameObjectsWithTag("Player"); foreach (var agent in sceneAgents) { var config = agent.GetComponent <AgentController>().Config; config.AgentGO = agent; ActiveAgents.Add(config); } if (ActiveAgents.Count == 0) { string data = null; #if UNITY_EDITOR data = UnityEditor.EditorPrefs.GetString("Simulator/DevelopmentSettings"); #endif if (data != null) { try { var json = JSONNode.Parse(data); var createVehicle = json["CreateVehicle"]; var vehicleName = json["VehicleName"]; if (createVehicle != null && createVehicle.AsBool && vehicleName != null) { using (var db = DatabaseManager.GetConfig(DatabaseManager.GetConnectionString()).Create()) { var sql = Sql.Builder.From("vehicles").Where("name = @0", vehicleName.Value); var vehicle = db.SingleOrDefault <VehicleModel>(sql); if (vehicle == null) { Debug.LogError($"Cannot find '{vehicleName.Value}' vehicle in database!"); } else { var bundlePath = vehicle.LocalPath; using (ZipFile zip = new ZipFile(bundlePath)) { Manifest manifest; 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); manifest = new Deserializer().Deserialize <Manifest>(Encoding.UTF8.GetString(buffer, 0, streamSize)); } if (manifest.bundleFormat != BundleConfig.Versions[BundleConfig.BundleTypes.Vehicle]) { throw new Exception("Out of date Vehicle AssetBundle. Please check content website for updated bundle or rebuild the bundle."); } AssetBundle textureBundle = null; if (zip.FindEntry($"{manifest.assetGuid}_vehicle_textures", true) != -1) { var texStream = zip.GetInputStream(zip.GetEntry($"{manifest.assetGuid}_vehicle_textures")); textureBundle = AssetBundle.LoadFromStream(texStream, 0, 1 << 20); } string platform = SystemInfo.operatingSystemFamily == OperatingSystemFamily.Windows ? "windows" : "linux"; var mapStream = zip.GetInputStream(zip.GetEntry($"{manifest.assetGuid}_vehicle_main_{platform}")); var vehicleBundle = AssetBundle.LoadFromStream(mapStream, 0, 1 << 20); if (vehicleBundle == null) { throw new Exception($"Failed to load '{bundlePath}' vehicle asset bundle"); } try { var vehicleAssets = vehicleBundle.GetAllAssetNames(); if (vehicleAssets.Length != 1) { throw new Exception($"Unsupported '{bundlePath}' vehicle asset bundle, only 1 asset expected"); } textureBundle?.LoadAllAssets(); if (manifest.fmuName != "") { var fmuDirectory = Path.Combine(Application.persistentDataPath, manifest.assetName); if (platform == "windows") { var dll = zip.GetEntry($"{manifest.fmuName}_windows.dll"); if (dll == null) { throw new ArgumentException($"{manifest.fmuName}.dll not found in Zip"); } using (Stream s = zip.GetInputStream(dll)) { byte[] buffer = new byte[4096]; Directory.CreateDirectory(fmuDirectory); var path = Path.Combine(Application.persistentDataPath, manifest.assetName, $"{manifest.fmuName}.dll"); using (FileStream streamWriter = File.Create(path)) { StreamUtils.Copy(s, streamWriter, buffer); } vehicleBundle.LoadAsset <GameObject>(vehicleAssets[0]).GetComponent <VehicleFMU>().FMUData.Path = path; } } else { var dll = zip.GetEntry($"{manifest.fmuName}_linux.so"); if (dll == null) { throw new ArgumentException($"{manifest.fmuName}.so not found in Zip"); } using (Stream s = zip.GetInputStream(dll)) { byte[] buffer = new byte[4096]; Directory.CreateDirectory(fmuDirectory); var path = Path.Combine(Application.persistentDataPath, manifest.assetName, $"{manifest.fmuName}.so"); using (FileStream streamWriter = File.Create(path)) { StreamUtils.Copy(s, streamWriter, buffer); } vehicleBundle.LoadAsset <GameObject>(vehicleAssets[0]).GetComponent <VehicleFMU>().FMUData.Path = path; } } } var prefab = vehicleBundle.LoadAsset <GameObject>(vehicleAssets[0]); var config = new AgentConfig() { Name = vehicle.Name, Prefab = prefab, Sensors = vehicle.Sensors, Connection = json["Connection"].Value, }; if (!string.IsNullOrEmpty(vehicle.BridgeType)) { config.Bridge = BridgePlugins.Get(vehicle.BridgeType); if (config.Bridge == null) { throw new Exception($"Bridge {vehicle.BridgeType} not found"); } } var spawn = FindObjectsOfType <SpawnInfo>().OrderBy(s => s.name).FirstOrDefault(); config.Position = spawn != null ? spawn.transform.position : Vector3.zero; config.Rotation = spawn != null ? spawn.transform.rotation : Quaternion.identity; SpawnAgent(config); } finally { textureBundle?.Unload(false); vehicleBundle.Unload(false); } } } } } } catch (Exception ex) { Debug.LogException(ex); } } } else { var config = ActiveAgents[0]; var bridgeClient = config.AgentGO.AddComponent <BridgeClient>(); bridgeClient.Init(BridgePlugins.Get(BridgePlugins.GetNameFromFactory(typeof(Simulator.Bridge.Ros.RosApolloBridgeFactory)))); bridgeClient.Connect("localhost:9090"); var sensorsController = config.AgentGO.GetComponent <SensorsController>(); if (sensorsController == null) { sensorsController = config.AgentGO.AddComponent <SensorsController>(); var agentController = config.AgentGO.GetComponent <AgentController>(); if (agentController != null) { agentController.AgentSensorsController = sensorsController; } } sensorsController.SetupSensors(DefaultSensors.Apollo30); } ActiveAgents.ForEach(agent => agent.AgentGO.GetComponent <AgentController>().Init()); SetCurrentActiveAgent(0); }
public void Execute(JSONNode args) { var sim = Object.FindObjectOfType <SimulatorManager>(); var api = ApiManager.Instance; if (sim == null) { api.SendError(this, "SimulatorManager not found! Is scene loaded?"); return; } var name = args["name"].Value; var type = args["type"].AsInt; var position = args["state"]["transform"]["position"].ReadVector3(); var rotation = args["state"]["transform"]["rotation"].ReadVector3(); var velocity = args["state"]["velocity"].ReadVector3(); var angular_velocity = args["state"]["angular_velocity"].ReadVector3(); string uid; var argsUid = args["uid"]; if (argsUid == null) { uid = System.Guid.NewGuid().ToString(); // Add uid key to arguments, as it will be distributed to the clients' simulations if (Loader.Instance.Network.IsMaster) { args.Add("uid", uid); } } else { uid = argsUid.Value; } if (type == (int)AgentType.Ego) { var agents = SimulatorManager.Instance.AgentManager; GameObject agentGO = null; using (var db = DatabaseManager.Open()) { var sql = Sql.Builder.From("vehicles").Where("name = @0", name); var vehicle = db.FirstOrDefault <VehicleModel>(sql); if (vehicle == null) { var url = args["url"]; //Disable using url on master simulation if (Loader.Instance.Network.IsMaster || string.IsNullOrEmpty(url)) { api.SendError(this, $"Vehicle '{name}' is not available"); return; } DownloadVehicleFromUrl(args, name, url); return; } else { var prefab = AquirePrefab(vehicle); if (prefab == null) { return; } var config = new AgentConfig() { Name = vehicle.Name, Prefab = prefab, Sensors = vehicle.Sensors, }; if (!string.IsNullOrEmpty(vehicle.BridgeType)) { config.Bridge = BridgePlugins.Get(vehicle.BridgeType); if (config.Bridge == null) { api.SendError(this, $"Bridge '{vehicle.BridgeType}' not available"); return; } } agentGO = agents.SpawnAgent(config); agentGO.transform.position = position; agentGO.transform.rotation = Quaternion.Euler(rotation); if (agents.ActiveAgents.Count == 1) { agents.SetCurrentActiveAgent(agentGO); } var rb = agentGO.GetComponent <Rigidbody>(); rb.velocity = velocity; rb.angularVelocity = angular_velocity; // Add url key to arguments, as it will be distributed to the clients' simulations if (Loader.Instance.Network.IsMaster) { args.Add("url", vehicle.Url); } } } Debug.Assert(agentGO != null); api.Agents.Add(uid, agentGO); api.AgentUID.Add(agentGO, uid); var sensors = agentGO.GetComponentsInChildren <SensorBase>(true); foreach (var sensor in sensors) { var sensorUid = System.Guid.NewGuid().ToString(); if (SimulatorManager.InstanceAvailable) { SimulatorManager.Instance.Sensors.AppendUid(sensor, sensorUid); } } api.SendResult(this, new JSONString(uid)); SIM.LogAPI(SIM.API.AddAgentEgo, name); } else if (type == (int)AgentType.Npc) { var colorData = args["color"].ReadVector3(); var template = sim.NPCManager.NPCVehicles.Find(obj => obj.Prefab.name == name); // TODO need to search all available npcs including npc bundles if (template.Prefab == null) { api.SendError(this, $"Unknown '{name}' NPC name"); return; } var spawnData = new NPCManager.NPCSpawnData { Active = true, GenId = uid, Template = template, Position = position, Rotation = Quaternion.Euler(rotation), Color = colorData == new Vector3(-1, -1, -1) ? sim.NPCManager.GetWeightedRandomColor(template.NPCType) : new Color(colorData.x, colorData.y, colorData.z), Seed = sim.NPCManager.NPCSeedGenerator.Next(), }; var npcController = SimulatorManager.Instance.NPCManager.SpawnNPC(spawnData); npcController.SetBehaviour <NPCManualBehaviour>(); var body = npcController.GetComponent <Rigidbody>(); body.velocity = velocity; body.angularVelocity = angular_velocity; uid = npcController.name; api.Agents.Add(uid, npcController.gameObject); api.AgentUID.Add(npcController.gameObject, uid); api.SendResult(this, new JSONString(uid)); SIM.LogAPI(SIM.API.AddAgentNPC, name); // Override the color argument as NPCController may change the NPC color if (Loader.Instance.Network.IsMaster) { var colorVector = new Vector3(npcController.NPCColor.r, npcController.NPCColor.g, npcController.NPCColor.b); args["color"].WriteVector3(colorVector); } } else if (type == (int)AgentType.Pedestrian) { var pedManager = SimulatorManager.Instance.PedestrianManager; if (!pedManager.gameObject.activeSelf) { var sceneName = SceneManager.GetActiveScene().name; api.SendError(this, $"{sceneName} is missing Pedestrian NavMesh"); return; } var model = sim.PedestrianManager.pedModels.Find(obj => obj.name == name); if (model == null) { api.SendError(this, $"Unknown '{name}' pedestrian name"); return; } var spawnData = new PedestrianManager.PedSpawnData { Active = true, API = true, GenId = uid, Model = model, Position = position, Rotation = Quaternion.Euler(rotation), Seed = sim.PedestrianManager.PEDSeedGenerator.Next(), }; var pedController = pedManager.SpawnPedestrian(spawnData); if (pedController == null) { api.SendError(this, $"Pedestrian controller error for '{name}'"); return; } api.Agents.Add(uid, pedController.gameObject); api.AgentUID.Add(pedController.gameObject, uid); api.SendResult(this, new JSONString(uid)); SIM.LogAPI(SIM.API.AddAgentPedestrian, name); } else { api.SendError(this, $"Unsupported '{args["type"]}' type"); } }