您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
248 行
8.3 KiB
248 行
8.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Randomization.ParameterBehaviours;
|
|
using Unity.Simulation;
|
|
using UnityEngine;
|
|
using UnityEngine.Perception.GroundTruth;
|
|
using UnityEngine.Perception.Randomization.Parameters;
|
|
|
|
namespace UnityEngine.Perception.Randomization.Scenarios
|
|
{
|
|
/// <summary>
|
|
/// The base class of all scenario classes
|
|
/// </summary>
|
|
[DefaultExecutionOrder(-1)]
|
|
public abstract class ScenarioBase : MonoBehaviour
|
|
{
|
|
static ScenarioBase s_ActiveScenario;
|
|
|
|
List<ParameterBehaviour> m_Behaviours = new List<ParameterBehaviour>();
|
|
List<Parameter> m_Parameters = new List<Parameter>();
|
|
bool m_SkipFrame = true;
|
|
bool m_FirstScenarioFrame = true;
|
|
bool m_WaitingForFinalUploads;
|
|
|
|
IEnumerable<ParameterBehaviour> m_ActiveBehaviours
|
|
{
|
|
get
|
|
{
|
|
foreach (var behaviour in m_Behaviours)
|
|
if (behaviour.enabled)
|
|
yield return behaviour;
|
|
}
|
|
}
|
|
|
|
[SerializeReference] public ParameterAsset[] parameterAssets;
|
|
|
|
/// <summary>
|
|
/// If true, this scenario will quit the Unity application when it's finished executing
|
|
/// </summary>
|
|
[HideInInspector] public bool quitOnComplete = true;
|
|
|
|
/// <summary>
|
|
/// When true, this scenario will deserializes constants from a Json file before it begins executing
|
|
/// </summary>
|
|
[HideInInspector] public bool deserializeOnStart;
|
|
|
|
/// <summary>
|
|
/// The name of the Json file this scenario's constants are serialized to/from.
|
|
/// </summary>
|
|
[HideInInspector] public string serializedConstantsFileName = "constants";
|
|
|
|
/// <summary>
|
|
/// Returns the active parameter scenario in the scene
|
|
/// </summary>
|
|
public static ScenarioBase activeScenario
|
|
{
|
|
get => s_ActiveScenario;
|
|
private set
|
|
{
|
|
if (value != null && s_ActiveScenario != null && value != s_ActiveScenario)
|
|
throw new ScenarioException("There cannot be more than one active Scenario");
|
|
s_ActiveScenario = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the file location of the JSON serialized constants
|
|
/// </summary>
|
|
public string serializedConstantsFilePath =>
|
|
Application.dataPath + "/StreamingAssets/" + serializedConstantsFileName + ".json";
|
|
|
|
/// <summary>
|
|
/// The number of frames that have elapsed since the current scenario iteration was Setup
|
|
/// </summary>
|
|
public int currentIterationFrame { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The number of frames that have elapsed since the scenario was initialized
|
|
/// </summary>
|
|
public int framesSinceInitialization { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The current iteration index of the scenario
|
|
/// </summary>
|
|
public int currentIteration { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// Returns whether the current scenario iteration has completed
|
|
/// </summary>
|
|
public abstract bool isIterationComplete { get; }
|
|
|
|
/// <summary>
|
|
/// Returns whether the entire scenario has completed
|
|
/// </summary>
|
|
public abstract bool isScenarioComplete { get; }
|
|
|
|
/// <summary>
|
|
/// Serializes the scenario's constants to a JSON file located at serializedConstantsFilePath
|
|
/// </summary>
|
|
public abstract void Serialize();
|
|
|
|
/// <summary>
|
|
/// Deserializes constants saved in a JSON file located at serializedConstantsFilePath
|
|
/// </summary>
|
|
public abstract void Deserialize();
|
|
|
|
/// <summary>
|
|
/// This method executed directly after this scenario has been registered and initialized
|
|
/// </summary>
|
|
protected virtual void OnAwake() { }
|
|
|
|
void Awake()
|
|
{
|
|
activeScenario = this;
|
|
foreach (var asset in parameterAssets)
|
|
{
|
|
foreach (var parameter in asset.parameters)
|
|
{
|
|
parameter.Validate();
|
|
m_Parameters.Add(parameter);
|
|
}
|
|
}
|
|
OnAwake();
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
activeScenario = this;
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
s_ActiveScenario = null;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
if (deserializeOnStart)
|
|
Deserialize();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// TODO: remove this check when the perception camera can capture the first frame of output
|
|
if (m_SkipFrame)
|
|
{
|
|
m_SkipFrame = false;
|
|
return;
|
|
}
|
|
|
|
// Wait for any final uploads before exiting quitting
|
|
if (m_WaitingForFinalUploads)
|
|
{
|
|
if (!Manager.FinalUploadsDone)
|
|
return;
|
|
|
|
if (quitOnComplete)
|
|
#if UNITY_EDITOR
|
|
UnityEditor.EditorApplication.ExitPlaymode();
|
|
#else
|
|
Application.Quit();
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
// Iterate Scenario
|
|
if (m_FirstScenarioFrame)
|
|
{
|
|
m_FirstScenarioFrame = false;
|
|
}
|
|
else
|
|
{
|
|
currentIterationFrame++;
|
|
framesSinceInitialization++;
|
|
if (isIterationComplete)
|
|
{
|
|
currentIteration++;
|
|
currentIterationFrame = 0;
|
|
foreach (var behaviour in m_ActiveBehaviours)
|
|
behaviour.OnIterationEnd();
|
|
}
|
|
}
|
|
|
|
// Quit if scenario is complete
|
|
if (isScenarioComplete)
|
|
{
|
|
foreach (var behaviour in m_ActiveBehaviours)
|
|
behaviour.OnScenarioComplete();
|
|
Manager.Instance.Shutdown();
|
|
DatasetCapture.ResetSimulation();
|
|
m_WaitingForFinalUploads = true;
|
|
return;
|
|
}
|
|
|
|
// Perform new iteration tasks
|
|
if (currentIterationFrame == 0)
|
|
{
|
|
DatasetCapture.StartNewSequence();
|
|
foreach (var parameter in m_Parameters)
|
|
{
|
|
parameter.ResetState();
|
|
parameter.IterateState(currentIteration);
|
|
}
|
|
foreach (var behaviour in m_ActiveBehaviours)
|
|
behaviour.OnIterationStart();
|
|
}
|
|
|
|
// Perform new frame tasks
|
|
foreach (var behaviour in m_ActiveBehaviours)
|
|
behaviour.OnFrameStart();
|
|
}
|
|
|
|
public T GetParameterAsset<T>() where T : ParameterAsset
|
|
{
|
|
foreach (var asset in parameterAssets)
|
|
if (asset is T typedAsset)
|
|
return typedAsset;
|
|
throw new ScenarioException($"A ParameterAsset of type {typeof(T).Name} was not added to this scenario");
|
|
}
|
|
|
|
public T GetParameterBehaviour<T>() where T : ParameterBehaviour
|
|
{
|
|
foreach (var behaviour in m_Behaviours)
|
|
if (behaviour is T typedBehaviour)
|
|
return typedBehaviour;
|
|
throw new ScenarioException($"A ParameterBehaviour of type {typeof(T).Name} was not added to this scenario");
|
|
}
|
|
|
|
internal void AddBehaviour<T>(T newBehaviour) where T : ParameterBehaviour
|
|
{
|
|
foreach (var behaviour in m_Behaviours)
|
|
if (behaviour.GetType() == newBehaviour.GetType())
|
|
throw new ScenarioException(
|
|
$"Two ParameterBehaviours of the same type {typeof(T).Name} cannot both be active simultaneously");
|
|
m_Behaviours.Add(newBehaviour);
|
|
m_Behaviours.Sort((b1, b2) => b1.executionPriority.CompareTo(b2.executionPriority));
|
|
}
|
|
|
|
internal void RemoveBehaviour(ParameterBehaviour behaviour)
|
|
{
|
|
var removed = m_Behaviours.Remove(behaviour);
|
|
if (!removed)
|
|
throw new ScenarioException(
|
|
$"No active ParameterBehaviour of type {behaviour.GetType().Name} could be removed");
|
|
}
|
|
}
|
|
}
|