Steven Leal
4 年前
当前提交
c80e1d42
共有 13 个文件被更改,包括 347 次插入 和 35 次删除
-
13com.unity.perception/Editor/Randomization/StaticData.cs
-
7com.unity.perception/Editor/Unity.Perception.Editor.asmdef
-
27com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
-
6com.unity.perception/Runtime/Randomization/Scenarios/Scenario.cs
-
12com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
-
3com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
-
1com.unity.perception/package.json
-
233com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs
-
11com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs.meta
-
21com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml
-
10com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml.meta
-
35com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs
-
3com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs.meta
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Unity.Simulation.Client; |
|||
using UnityEditor; |
|||
using UnityEditor.Build.Reporting; |
|||
using UnityEditor.UIElements; |
|||
using UnityEngine.Experimental.Perception.Randomization.Editor; |
|||
using UnityEngine.Experimental.Perception.Randomization.Scenarios; |
|||
using UnityEngine.UIElements; |
|||
using ZipUtility; |
|||
|
|||
namespace UnityEngine.Perception.Randomization.Editor |
|||
{ |
|||
public class RunInUSimWindow : EditorWindow |
|||
{ |
|||
string m_BuildZipPath; |
|||
SysParamDefinition m_SysParam; |
|||
|
|||
TextField m_RunNameField; |
|||
IntegerField m_TotalIterationsField; |
|||
IntegerField m_InstanceCountField; |
|||
ObjectField m_MainSceneField; |
|||
ObjectField m_ScenarioField; |
|||
Button m_RunButton; |
|||
|
|||
[MenuItem("Window/Run in USim")] |
|||
public static void ShowWindow() |
|||
{ |
|||
var window = GetWindow<RunInUSimWindow>(); |
|||
window.titleContent = new GUIContent("Run In Unity Simulation"); |
|||
window.minSize = new Vector2(250, 50); |
|||
window.Show(); |
|||
} |
|||
|
|||
void OnEnable() |
|||
{ |
|||
Project.Activate(); |
|||
Project.clientReadyStateChanged += CreateEstablishingConnectionUI; |
|||
CreateEstablishingConnectionUI(Project.projectIdState); |
|||
} |
|||
|
|||
void OnFocus() |
|||
{ |
|||
Application.runInBackground = true; |
|||
} |
|||
|
|||
void OnLostFocus() |
|||
{ |
|||
Application.runInBackground = false; |
|||
} |
|||
|
|||
void CreateEstablishingConnectionUI(Project.State state) |
|||
{ |
|||
rootVisualElement.Clear(); |
|||
if (Project.projectIdState == Project.State.Pending) |
|||
{ |
|||
var waitingText = new TextElement(); |
|||
waitingText.text = "Waiting for connection to Unity Cloud..."; |
|||
rootVisualElement.Add(waitingText); |
|||
} |
|||
else if (Project.projectIdState == Project.State.Invalid) |
|||
{ |
|||
var waitingText = new TextElement(); |
|||
waitingText.text = "The current project must be associated with a valid Unity Cloud project " + |
|||
"to run in Unity Simulation"; |
|||
rootVisualElement.Add(waitingText); |
|||
} |
|||
else |
|||
{ |
|||
CreateRunInUSimUI(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Enables a visual element to remember values between editor sessions
|
|||
/// </summary>
|
|||
static void SetViewDataKey(VisualElement element) |
|||
{ |
|||
element.viewDataKey = $"RunInUSim_{element.name}"; |
|||
} |
|||
|
|||
void CreateRunInUSimUI() |
|||
{ |
|||
var root = rootVisualElement; |
|||
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>( |
|||
$"{StaticData.uxmlDir}/RunInUSimWindow.uxml").CloneTree(root); |
|||
|
|||
m_RunNameField = root.Q<TextField>("run-name"); |
|||
SetViewDataKey(m_RunNameField); |
|||
|
|||
m_TotalIterationsField = root.Q<IntegerField>("total-iterations"); |
|||
SetViewDataKey(m_TotalIterationsField); |
|||
|
|||
m_InstanceCountField = root.Q<IntegerField>("instance-count"); |
|||
SetViewDataKey(m_InstanceCountField); |
|||
|
|||
m_MainSceneField = root.Q<ObjectField>("main-scene"); |
|||
m_MainSceneField.objectType = typeof(SceneAsset); |
|||
|
|||
m_ScenarioField = root.Q<ObjectField>("scenario"); |
|||
m_ScenarioField.objectType = typeof(ScenarioBase); |
|||
|
|||
var sysParamDefinitions = API.GetSysParams(); |
|||
var sysParamMenu = root.Q<ToolbarMenu>("sys-param"); |
|||
foreach (var definition in sysParamDefinitions) |
|||
sysParamMenu.menu.AppendAction(definition.description, action => m_SysParam = definition); |
|||
sysParamMenu.text = sysParamDefinitions[0].description; |
|||
m_SysParam = sysParamDefinitions[0]; |
|||
|
|||
m_RunButton = root.Q<Button>("run-button"); |
|||
m_RunButton.clicked += RunInUSim; |
|||
} |
|||
|
|||
async void RunInUSim() |
|||
{ |
|||
ValidateSettings(); |
|||
CreateLinuxBuildAndZip(); |
|||
await StartUSimRun(); |
|||
} |
|||
|
|||
void ValidateSettings() |
|||
{ |
|||
if (string.IsNullOrEmpty(m_RunNameField.value)) |
|||
throw new MissingFieldException("Empty run name"); |
|||
if (m_MainSceneField.value == null) |
|||
throw new MissingFieldException("Main scene unselected"); |
|||
if (m_ScenarioField.value == null) |
|||
throw new MissingFieldException("Scenario unselected"); |
|||
var scenario = (ScenarioBase)m_ScenarioField.value; |
|||
if (!StaticData.IsSubclassOfRawGeneric(typeof(USimScenario<>), scenario.GetType())) |
|||
throw new NotSupportedException("Scenario class must be derived from USimScenario to run in USim"); |
|||
} |
|||
|
|||
void CreateLinuxBuildAndZip() |
|||
{ |
|||
// Ensure that scenario serialization is enabled
|
|||
var scenario = (ScenarioBase)m_ScenarioField.value; |
|||
scenario.deserializeOnStart = true; |
|||
|
|||
// Create build directory
|
|||
var pathToProjectBuild = Application.dataPath + "/../" + "Build/"; |
|||
if (!Directory.Exists(pathToProjectBuild + m_RunNameField.value)) |
|||
Directory.CreateDirectory(pathToProjectBuild + m_RunNameField.value); |
|||
|
|||
pathToProjectBuild = pathToProjectBuild + m_RunNameField.value + "/"; |
|||
|
|||
// Create Linux build
|
|||
Debug.Log("Creating Linux build..."); |
|||
var buildPlayerOptions = new BuildPlayerOptions |
|||
{ |
|||
scenes = new[] { AssetDatabase.GetAssetPath(m_MainSceneField.value) }, |
|||
locationPathName = Path.Combine(pathToProjectBuild, m_RunNameField.value + ".x86_64"), |
|||
target = BuildTarget.StandaloneLinux64 |
|||
}; |
|||
var report = BuildPipeline.BuildPlayer(buildPlayerOptions); |
|||
var summary = report.summary; |
|||
if (summary.result != BuildResult.Succeeded) |
|||
throw new Exception($"Build did not succeed: status = {summary.result}"); |
|||
Debug.Log("Created Linux build"); |
|||
|
|||
// Zip the build
|
|||
Debug.Log("Starting to zip..."); |
|||
var buildFolder = Application.dataPath + "/../" + "Build/" + m_RunNameField.value; |
|||
Zip.DirectoryContents(buildFolder, m_RunNameField.value); |
|||
m_BuildZipPath = buildFolder + ".zip"; |
|||
Debug.Log("Created build zip"); |
|||
} |
|||
|
|||
List<AppParam> GenerateAppParamIds(CancellationToken token) |
|||
{ |
|||
var appParamIds = new List<AppParam>(); |
|||
for (var i = 0; i < m_InstanceCountField.value; i++) |
|||
{ |
|||
if (token.IsCancellationRequested) |
|||
return null; |
|||
var appParamName = $"{m_RunNameField.value}_{i}"; |
|||
var appParamId = API.UploadAppParam(appParamName, new USimConstants |
|||
{ |
|||
totalIterations = m_TotalIterationsField.value, |
|||
instanceCount = m_InstanceCountField.value, |
|||
instanceIndex = i |
|||
}); |
|||
appParamIds.Add(new AppParam() |
|||
{ |
|||
id = appParamId, |
|||
name = appParamName, |
|||
num_instances = 1 |
|||
}); |
|||
} |
|||
return appParamIds; |
|||
} |
|||
|
|||
async Task StartUSimRun() |
|||
{ |
|||
m_RunButton.SetEnabled(false); |
|||
var cancellationTokenSource = new CancellationTokenSource(); |
|||
var token = cancellationTokenSource.Token; |
|||
|
|||
Debug.Log("Uploading build..."); |
|||
var buildId = await API.UploadBuildAsync( |
|||
m_RunNameField.value, |
|||
m_BuildZipPath, |
|||
cancellationTokenSource: cancellationTokenSource); |
|||
Debug.Log($"Build upload complete: build id {buildId}"); |
|||
|
|||
var appParams = GenerateAppParamIds(token); |
|||
if (token.IsCancellationRequested) |
|||
{ |
|||
Debug.Log("Run cancelled"); |
|||
return; |
|||
} |
|||
Debug.Log($"Generated app-param ids: {appParams.Count}"); |
|||
|
|||
var runDefinitionId = API.UploadRunDefinition(new RunDefinition |
|||
{ |
|||
app_params = appParams.ToArray(), |
|||
name = m_RunNameField.value, |
|||
sys_param_id = m_SysParam.id, |
|||
build_id = buildId |
|||
}); |
|||
Debug.Log($"Run definition upload complete: run definition id {runDefinitionId}"); |
|||
|
|||
var run = Run.CreateFromDefinitionId(runDefinitionId); |
|||
run.Execute(); |
|||
cancellationTokenSource.Dispose(); |
|||
Debug.Log($"Executing run: {run.executionId}"); |
|||
m_RunButton.SetEnabled(true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2744f10e153915b46a2f6a274914753d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" xmlns:randEditor="UnityEngine.Perception.Randomization.Editor"> |
|||
<VisualElement> |
|||
<Style src="../Uss/RunInUSimStyles.uss"/> |
|||
<VisualElement class="dark-viewport" style="margin-bottom: 20px;"> |
|||
<VisualElement style=""> |
|||
<TextField name="run-name" label="Run Name"/> |
|||
<editor:IntegerField name="total-iterations" label="Total Iterations"/> |
|||
<editor:IntegerField name="instance-count" label="Instance Count" max-value="10000"/> |
|||
<editor:ObjectField name="main-scene" label="Main Scene" allow-scene-objects="false"/> |
|||
<editor:ObjectField name="scenario" label="Scenario"/> |
|||
<VisualElement class="unity-base-field"> |
|||
<Label text="USim worker config" class="unity-base-field__label"/> |
|||
<editor:ToolbarMenu name="sys-param" class="unity-base-field__input" style="border-width: 1px;"/> |
|||
</VisualElement> |
|||
<VisualElement style="align-items: center;"> |
|||
<Button name="run-button" text="Build and Run" style="margin: 10px; padding: 2 20; font-size: 13px;"/> |
|||
</VisualElement> |
|||
</VisualElement> |
|||
</VisualElement> |
|||
</VisualElement> |
|||
</UXML> |
|
|||
fileFormatVersion: 2 |
|||
guid: 678c5d944639402c9c4d50de04c77561 |
|||
ScriptedImporter: |
|||
internalIDToNameTable: [] |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} |
|
|||
using System; |
|||
|
|||
namespace UnityEngine.Experimental.Perception.Randomization.Scenarios |
|||
{ |
|||
public abstract class USimScenario<T> : Scenario<T> where T : USimConstants, new() |
|||
{ |
|||
public override bool isScenarioComplete => currentIteration >= constants.totalIterations; |
|||
|
|||
protected override void OnAwake() |
|||
{ |
|||
currentIteration = constants.instanceIndex; |
|||
} |
|||
|
|||
protected override void IncrementIteration() |
|||
{ |
|||
currentIteration += constants.instanceCount; |
|||
} |
|||
|
|||
public override void Deserialize() |
|||
{ |
|||
if (string.IsNullOrEmpty(Unity.Simulation.Configuration.Instance.SimulationConfig.app_param_uri)) |
|||
base.Deserialize(); |
|||
else |
|||
constants = Unity.Simulation.Configuration.Instance.GetAppParams<T>(); |
|||
} |
|||
} |
|||
|
|||
[Serializable] |
|||
public class USimConstants |
|||
{ |
|||
public int totalIterations = 100; |
|||
public int instanceCount = 1; |
|||
public int instanceIndex; |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ee12a68b9b7b40aa9f60c97d6078a7cf |
|||
timeCreated: 1601067341 |
撰写
预览
正在加载...
取消
保存
Reference in new issue