浏览代码

added run in usim window

/main
Steven Leal 4 年前
当前提交
3e0d6c6e
共有 13 个文件被更改,包括 347 次插入35 次删除
  1. 13
      com.unity.perception/Editor/Randomization/StaticData.cs
  2. 7
      com.unity.perception/Editor/Unity.Perception.Editor.asmdef
  3. 27
      com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
  4. 6
      com.unity.perception/Runtime/Randomization/Scenarios/Scenario.cs
  5. 12
      com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
  6. 3
      com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
  7. 1
      com.unity.perception/package.json
  8. 233
      com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs
  9. 11
      com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs.meta
  10. 21
      com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml
  11. 10
      com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml.meta
  12. 35
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs
  13. 3
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs.meta

13
com.unity.perception/Editor/Randomization/StaticData.cs


internal static readonly string samplerSerializedFieldType;
internal static Type[] parameterTypes;
parameterTypes = GetConstructableDerivedTypes<Parameter>();
randomizerTypes = GetConstructableDerivedTypes<Randomizer>();
samplerTypes = GetConstructableDerivedTypes<ISampler>();
var samplerType = typeof(ISampler);

while (index-- >= 0)
enumerator.MoveNext();
return enumerator.Current;
}
public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
while (toCheck != null && toCheck != typeof(object)) {
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur) {
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
}
}

7
com.unity.perception/Editor/Unity.Perception.Editor.asmdef


{
"name": "Unity.Perception.Editor",
"rootNamespace": "",
"references": [
"Unity.RenderPipelines.Core.Runtime",
"Unity.RenderPipelines.HighDefinition.Runtime",

"Unity.Perception.Runtime",
"PathCreatorEditor",
"PathCreator",
"UnityEngine.UI"
"UnityEngine.UI",
"Unity.Simulation.Client.Editor"
],
"includePlatforms": [
"Editor"

"overrideReferences": true,
"precompiledReferences": [
"Newtonsoft.Json.dll"
"Newtonsoft.Json.dll",
"ZipUtility.dll"
],
"autoReferenced": true,
"defineConstraints": [],

27
com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs


/// A scenario that runs for a fixed number of frames during each iteration
/// </summary>
[AddComponentMenu("Perception/Randomization/Scenarios/Fixed Length Scenario")]
public class FixedLengthScenario: Scenario<FixedLengthScenario.Constants>
public class FixedLengthScenario: USimScenario<FixedLengthScenario.Constants>
public class Constants
public class Constants : USimConstants
/// <summary>
/// The iteration index begin the simulation on
/// </summary>
public int startingIteration;
/// <summary>
/// The total number of iterations to complete before the simulation terminates
/// </summary>
public int totalIterations = 1000;
}
/// <summary>

/// <summary>
/// Returns whether the scenario has completed
/// </summary>
public override bool isScenarioComplete => currentIteration >= constants.totalIterations;
/// <summary>
/// Fast forwards the current scenario iteration to the starting iteration indicated in this scenario's constants
/// </summary>
protected override void OnAwake()
{
currentIteration = constants.startingIteration;
}
}
}

6
com.unity.perception/Runtime/Randomization/Scenarios/Scenario.cs


/// </summary>
public T constants = new T();
public override object genericConstants => constants;
public sealed override void Serialize()
public override void Serialize()
{
Directory.CreateDirectory(Application.dataPath + "/StreamingAssets/");
using (var writer = new StreamWriter(serializedConstantsFilePath, false))

/// Deserializes this scenario's constants from a json file in the Unity StreamingAssets folder
/// </summary>
/// <exception cref="ScenarioException"></exception>
public sealed override void Deserialize()
public override void Deserialize()
{
if (!File.Exists(serializedConstantsFilePath))
throw new ScenarioException($"JSON scenario constants file does not exist at path {serializedConstantsFilePath}");

12
com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs


public string serializedConstantsFilePath =>
Application.dataPath + "/StreamingAssets/" + serializedConstantsFileName + ".json";
public abstract object genericConstants { get; }
/// <summary>
/// The number of frames that have elapsed since the current scenario iteration was Setup
/// </summary>

/// Returns whether the entire scenario has completed
/// </summary>
public abstract bool isScenarioComplete { get; }
/// <summary>
/// Progresses the current scenario iteration.
/// </summary>
protected virtual void IncrementIteration()
{
currentIteration++;
}
/// <summary>
/// Serializes the scenario's constants to a JSON file located at serializedConstantsFilePath

framesSinceInitialization++;
if (isIterationComplete)
{
currentIteration++;
IncrementIteration();
currentIterationFrame = 0;
foreach (var randomizer in activeRandomizers)
randomizer.IterationEnd();

3
com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs


var constants = new FixedLengthScenario.Constants
{
framesPerIteration = 2,
startingIteration = 2,
totalIterations = 2
};

startingIteration = 0,
totalIterations = 0
};

// Check if the values reverted correctly
Assert.AreEqual(m_Scenario.constants.framesPerIteration, constants.framesPerIteration);
Assert.AreEqual(m_Scenario.constants.startingIteration, constants.startingIteration);
Assert.AreEqual(m_Scenario.constants.totalIterations, constants.totalIterations);
// Clean up serialized constants

1
com.unity.perception/package.json


"com.unity.nuget.newtonsoft-json": "1.1.2",
"com.unity.render-pipelines.core": "7.1.6",
"com.unity.entities": "0.8.0-preview.8",
"com.unity.simulation.client": "0.0.10-preview.9",
"com.unity.simulation.capture": "0.0.10-preview.13",
"com.unity.simulation.core": "0.0.10-preview.19"
},

233
com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs


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);
}
}
}

11
com.unity.perception/Editor/Randomization/Editors/RunInUSimWindow.cs.meta


fileFormatVersion: 2
guid: 2744f10e153915b46a2f6a274914753d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

21
com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml


<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>

10
com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml.meta


fileFormatVersion: 2
guid: 678c5d944639402c9c4d50de04c77561
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

35
com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs


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;
}
}

3
com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs.meta


fileFormatVersion: 2
guid: ee12a68b9b7b40aa9f60c97d6078a7cf
timeCreated: 1601067341
正在加载...
取消
保存