比较提交

...
此合并请求有变更与目标分支冲突。
/com.unity.perception/Editor/Unity.Perception.Editor.asmdef
/com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
/com.unity.perception/Runtime/Randomization/Scenarios/Scenario.cs
/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
/com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs

4 次代码提交

作者 SHA1 备注 提交日期
Steven Leal 2753d943 need to fix async await stuff 4 年前
Steven Leal e7cf2a16 added usim status fields 4 年前
Steven Leal 62e505d4 added run in USim window 4 年前
Steven Leal 5ce535d7 added run in usim window 4 年前
共有 17 个文件被更改,包括 516 次插入43 次删除
  1. 30
      com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
  2. 7
      com.unity.perception/Runtime/Randomization/Scenarios/Scenario.cs
  3. 10
      com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
  4. 33
      com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
  5. 6
      com.unity.perception/Editor/Unity.Perception.Editor.asmdef
  6. 3
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs.meta
  7. 38
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenario.cs
  8. 7
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenarioBase.cs
  9. 3
      com.unity.perception/Runtime/Randomization/Scenarios/USimScenarioBase.cs.meta
  10. 3
      com.unity.perception/Editor/Randomization/RunInUSimWindow.cs.meta
  11. 59
      com.unity.perception/Editor/Randomization/PositiveIntegerField.cs
  12. 3
      com.unity.perception/Editor/Randomization/PositiveIntegerField.cs.meta
  13. 297
      com.unity.perception/Editor/Randomization/RunInUSimWindow.cs
  14. 6
      com.unity.perception/Editor/Randomization/Uss/RunInUSimStyles.uss
  15. 3
      com.unity.perception/Editor/Randomization/Uss/RunInUSimStyles.uss.meta
  16. 3
      com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml.meta
  17. 48
      com.unity.perception/Editor/Randomization/Uxml/RunInUSimWindow.uxml

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


// TODO: update this function once the perception camera doesn't skip the first frame
IEnumerator CreateNewScenario(int totalIterations, int framesPerIteration)
{
m_Scenario.constants.framesPerIteration = framesPerIteration;
m_Scenario.framesPerIteration = framesPerIteration;
yield return null; // Skip Start() frame
yield return null; // Skip first Update() frame
}

yield return CreateNewScenario(10, 10);
m_Scenario.serializedConstantsFileName = "perception_serialization_test";
var constants = new FixedLengthScenario.Constants
var constants = new USimConstants
framesPerIteration = 2,
startingIteration = 2,
totalIterations = 2
totalIterations = 2,
instanceCount = 2,
instanceIndex = 1
var changedConstants = new FixedLengthScenario.Constants
var changedConstants = new USimConstants
framesPerIteration = 0,
startingIteration = 0,
totalIterations = 0
totalIterations = 0,
instanceCount = 1,
instanceIndex = 0
};
// Serialize some values

// Change the values
m_Scenario.constants = changedConstants;
Assert.AreNotEqual(m_Scenario.constants.totalIterations, constants.totalIterations);
Assert.AreNotEqual(m_Scenario.constants.instanceCount, constants.instanceCount);
Assert.AreNotEqual(m_Scenario.constants.instanceIndex, constants.instanceIndex);
// Check if the values deserialize correctly
// 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.instanceCount, constants.instanceCount);
Assert.AreEqual(m_Scenario.constants.instanceIndex, constants.instanceIndex);
// Clean up serialized constants
File.Delete(m_Scenario.serializedConstantsFilePath);

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


using System.IO;
using System;
using System.IO;
namespace UnityEngine.Perception.Randomization.Scenarios
{

/// <summary>
/// Serializes this scenario's constants to a json file in the Unity StreamingAssets folder
/// </summary>
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}");

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


/// </summary>
public abstract void Deserialize();
/// <summary>
/// Increments the scenario's currentIteration. Can be overriden to increment by values other than 1.
/// </summary>
public virtual void IncrementIteration()
{
currentIteration++;
}
void OnEnable()
{
ActiveScenario = this;

framesSinceInitialization++;
if (isIterationComplete)
{
currentIteration++;
IncrementIteration();
currentIterationFrame = 0;
OnIterationTeardown();
}

33
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
/// <summary>
/// Constants describing the execution of this scenario
/// </summary>
[Serializable]
public class Constants
{
/// <summary>
/// The number of frames to generate per iteration
/// </summary>
public int framesPerIteration = 1;
/// <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;
}
public int framesPerIteration = 1;
public int startingIteration;
public override bool isIterationComplete => currentIterationFrame >= constants.framesPerIteration;
public override bool isIterationComplete => currentIterationFrame >= framesPerIteration;
/// <summary>
/// Returns whether the scenario has completed

/// </summary>
public override void OnInitialize()
{
currentIteration = constants.startingIteration;
#if UNITY_EDITOR
currentIteration = startingIteration;
#else
base.OnInitialize();
#endif
}
}
}

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


"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": [],

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


fileFormatVersion: 2
guid: 1ef5313c07934eeabb46b852ab57ed79
timeCreated: 1597102599

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


using System;
namespace UnityEngine.Perception.Randomization.Scenarios
{
public abstract class USimScenario : Scenario<USimConstants>
{
public override bool isScenarioComplete => currentIteration >= constants.totalIterations;
public override void OnInitialize()
{
currentIteration = constants.instanceIndex;
}
public override void IncrementIteration()
{
currentIteration += constants.instanceCount;
}
public override void Deserialize()
{
if (!string.IsNullOrEmpty(Unity.Simulation.Configuration.Instance.SimulationConfig.app_param_uri))
{
Debug.Log("Reading app-params");
constants = Unity.Simulation.Configuration.Instance.GetAppParams<USimConstants>();
}
else
base.Deserialize();
}
}
[Serializable]
public class USimConstants
{
public int totalIterations = 100;
public int instanceCount = 1;
public int instanceIndex;
}
}

7
com.unity.perception/Runtime/Randomization/Scenarios/USimScenarioBase.cs


namespace UnityEngine.Perception.Randomization.Scenarios
{
public abstract class USimScenarioBase : ScenarioBase
{
}
}

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


fileFormatVersion: 2
guid: 6b9735d0324e476999f22e4731058861
timeCreated: 1597687928

3
com.unity.perception/Editor/Randomization/RunInUSimWindow.cs.meta


fileFormatVersion: 2
guid: 21e030e241504815a3dbaad77a144aca
timeCreated: 1596820769

59
com.unity.perception/Editor/Randomization/PositiveIntegerField.cs


using System;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
public class PositiveIntegerField : IntegerField
{
public int maxValue = int.MaxValue;
public PositiveIntegerField()
{
RegisterValueClamping();
}
public PositiveIntegerField(int maxValue)
{
this.maxValue = maxValue;
RegisterValueClamping();
}
public PositiveIntegerField(SerializedProperty property, int maxValue=int.MaxValue) : this(maxValue)
{
this.BindProperty(property);
}
void RegisterValueClamping()
{
this.RegisterValueChangedCallback(evt =>
{
value = math.clamp(evt.newValue, 0, maxValue);
evt.StopImmediatePropagation();
});
}
public new class UxmlFactory : UxmlFactory<PositiveIntegerField, UxmlTraits> { }
public new class UxmlTraits : IntegerField.UxmlTraits
{
UxmlIntAttributeDescription m_Int = new UxmlIntAttributeDescription { name = "max-value", defaultValue = int.MaxValue };
public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
get { yield break; }
}
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
if (!(ve is PositiveIntegerField positiveIntegerField))
return;
positiveIntegerField.maxValue = m_Int.GetValueFromBag(bag, cc);
}
}
}
}

3
com.unity.perception/Editor/Randomization/PositiveIntegerField.cs.meta


fileFormatVersion: 2
guid: ddab76638f764bac9bd4b213e5cf8ebe
timeCreated: 1597168414

297
com.unity.perception/Editor/Randomization/RunInUSimWindow.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Boo.Lang.Runtime;
using Unity.Simulation.Client;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Scenarios;
using UnityEngine.UIElements;
using ZipUtility;
namespace UnityEngine.Perception.Randomization.Editor
{
public class RunInUSimWindow : EditorWindow
{
string m_BuildZipPath;
SysParamDefinition m_SysParam;
float m_LastRunStatusPing;
TextField m_RunNameField;
TextField m_RunExecutionIdField;
VisualElement m_RunStatusContainer;
IntegerField m_TotalIterationsField;
IntegerField m_InstanceCountField;
ObjectField m_MainSceneField;
ObjectField m_ScenarioField;
Button m_RunButton;
TextElement m_NumNotRun;
TextElement m_NumFailures;
TextElement m_NumInProgress;
TextElement m_NumSuccess;
TextElement m_RunState;
[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);
m_RunStatusContainer = root.Q<VisualElement>("run-status-container");
m_RunExecutionIdField = root.Q<TextField>("run-execution-id");
SetViewDataKey(m_RunExecutionIdField);
m_NumNotRun = root.Q<TextElement>("num-not-run");
m_NumFailures = root.Q<TextElement>("num-failures");
m_NumInProgress = root.Q<TextElement>("num-in-progress");
m_NumSuccess = root.Q<TextElement>("num-success");
m_RunState = root.Q<TextElement>("run-state");
var downloadManifestButton = root.Q<Button>("download-manifest");
downloadManifestButton.clicked += DownloadManifest;
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;
}
// void ToggleVisibility(VisualElement element, bool visible)
// {
// Debug.Log(visible);
// element.style.display = visible
// ? new StyleEnum<DisplayStyle>(DisplayStyle.Flex)
// : new StyleEnum<DisplayStyle>(DisplayStyle.None);
// }
void OnInspectorUpdate()
{
if (!string.IsNullOrEmpty(m_RunExecutionIdField.value) &&
m_LastRunStatusPing < Time.realtimeSinceStartup - 3f)
{
m_LastRunStatusPing = Time.realtimeSinceStartup;
UpdateRunStatus();
}
}
void UpdateRunStatus()
{
var summary = API.Summarize(m_RunExecutionIdField.value);
Debug.Log(summary.state.code);
m_NumNotRun.text = summary.num_not_run.ToString();
m_NumFailures.text = summary.num_failures.ToString();
m_NumInProgress.text = summary.num_in_progress.ToString();
m_NumSuccess.text = summary.num_success.ToString();
m_RunState.text = summary.state.code;
}
void DownloadManifest()
{
if (!string.IsNullOrEmpty(m_RunExecutionIdField.value))
{
var manifest = API.GetManifest(m_RunExecutionIdField.value);
var manifestFilePath = EditorUtility.SaveFilePanel("Save Manifest", Application.dataPath, "manifest", "csv");
var lines = new string[manifest.Count + 1];
lines[0] = "run_execution_id,app_param_id,instance_id,attempt_id,file_name,download_uri";
var i = 1;
foreach (var pair in manifest)
{
var e = pair.Value;
lines[i++] = $"{e.executionId},{e.appParamId},{e.instanceId},{e.attemptId},{e.fileName},{e.downloadUri}";
}
File.WriteAllLines(manifestFilePath, lines);
}
}
async void RunInUSim()
{
ValidateSettings();
CreateLinuxBuildAndZip();
var run = await StartUSimRun();
m_RunExecutionIdField.value = run.executionId;
}
void ValidateSettings()
{
if (string.IsNullOrEmpty(m_RunNameField.value))
throw new RuntimeException("Invalid run name");
if (m_ScenarioField.value == null)
throw new RuntimeException("Null scenario");
if (m_MainSceneField.value == null)
throw new RankException("Null main scene");
}
void CreateLinuxBuildAndZip()
{
// Ensure that scenario serialization is enabled
var scenario = (USimScenario)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 RuntimeException($"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<Run> 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)
return null;
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}");
return run;
}
}
}

6
com.unity.perception/Editor/Randomization/Uss/RunInUSimStyles.uss


.dark-viewport {
border-radius: 5px;
background-color: #191919;
padding: 2px;
margin: 2px;
}

3
com.unity.perception/Editor/Randomization/Uss/RunInUSimStyles.uss.meta


fileFormatVersion: 2
guid: 8ee39ab9c50a4f5db26869a0e40a54fa
timeCreated: 1597718729

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


fileFormatVersion: 2
guid: 678c5d944639402c9c4d50de04c77561
timeCreated: 1596821310

48
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"/>
<randEditor:PositiveIntegerField name="total-iterations" label="Total Iterations"/>
<randEditor:PositiveIntegerField 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 name="run-status-container" class="dark-viewport">
<TextField name="run-execution-id" label="Run Execution ID"/>
<VisualElement class="unity-base-field">
<Label text="Not Run" class="unity-base-field__label"/>
<TextElement name="num-not-run"/>
</VisualElement>
<VisualElement class="unity-base-field">
<Label text="Failed" class="unity-base-field__label"/>
<TextElement name="num-failures"/>
</VisualElement>
<VisualElement class="unity-base-field">
<Label text="In Progress" class="unity-base-field__label"/>
<TextElement name="num-in-progress"/>
</VisualElement>
<VisualElement class="unity-base-field">
<Label text="Succeeded" class="unity-base-field__label"/>
<TextElement name="num-success"/>
</VisualElement>
<VisualElement class="unity-base-field">
<Label text="State" class="unity-base-field__label"/>
<TextElement name="run-state"/>
</VisualElement>
<VisualElement style="align-items: center;">
<Button name="download-manifest" text="Download Manifest" style="margin: 10px; padding: 2 20; font-size: 13px;"/>
</VisualElement>
</VisualElement>
</VisualElement>
</UXML>
正在加载...
取消
保存