using Unity.Collections ;
using Unity.Simulation ;
using UnityEngine ;
using UnityEngine.Perception.GroundTruth.Exporters ;
using UnityEngine.Perception.GroundTruth.Exporters.Coco ;
using UnityEngine.Perception.GroundTruth.Exporters.PerceptionFormat ;
using UnityEngine.Perception.GroundTruth.Exporters.PerceptionNew ;
using UnityEngine.Perception.GroundTruth.Exporters.Solo ;
using UnityEngine.Perception.GroundTruth.SoloDesign ;
using UnityEngine.Profiling ;
{
HashSet < SensorHandle > m_ActiveSensors = new HashSet < SensorHandle > ( ) ;
Dictionary < SensorHandle , SensorData > m_Sensors = new Dictionary < SensorHandle , SensorData > ( ) ;
HashSet < EgoHandle > m_Egos = new HashSet < EgoHandle > ( ) ;
HashSet < Guid > m_Ids = new HashSet < Guid > ( ) ;
Guid m_SequenceId = Guid . NewGuid ( ) ;
//IDatasetExporter _ActiveReporter = null;
int m_SequenceId = - 1 ;
// PerceptionConsumer activeConsumer = null;
HashSet < string > _Ids = new HashSet < string > ( ) ;
// Always use the property SequenceTimeMs instead
int m_FrameCountLastUpdatedSequenceTime ;
bool m_HasStarted ;
int m_CaptureFileIndex ;
List < AdditionalInfoTypeData > m_AdditionalInfoTypeData = new List < AdditionalInfoTypeData > ( ) ;
List < PendingMetric > m_PendingMetrics = new List < PendingMetric > ( k_MinPendingMetricsBeforeWrite + 1 0 ) ;
// List<PendingMetric> m_PendingMetrics = new List<PendingMetric>(k_MinPendingMetricsBeforeWrite + 10);
int m_NextMetricId = 1 ;
// int m_NextMetricId = 1;
CustomSampler m_SerializeCapturesSampler = CustomSampler . Create ( "SerializeCaptures" ) ;
CustomSampler m_SerializeCapturesAsyncSampler = CustomSampler . Create ( "SerializeCapturesAsync" ) ;
CustomSampler m_SerializeMetricsAsyncSampler = CustomSampler . Create ( "SerializeMetricsAsync" ) ;
CustomSampler m_GetOrCreatePendingCaptureForThisFrameSampler = CustomSampler . Create ( "GetOrCreatePendingCaptureForThisFrame" ) ;
float m_LastTimeScale ;
readonly string m_OutputDirectoryName ;
string m_OutputDirectoryPath ;
public const string userBaseDirectoryKey = "userBaseDirectory" ;
public bool IsRunning { get ; private set ; }
public string OutputDirectory
{
get
{
if ( m_OutputDirectoryPath = = null )
m_OutputDirectoryPath = Manager . Instance . GetDirectoryFor ( m_OutputDirectoryName ) ;
return m_OutputDirectoryPath ;
}
}
public SimulationState ( string outputDirectory )
public SimulationState ( )
#if false
var go = GameObject . Find ( "SoloConsumer" ) ;
if ( go = = null )
{
go = new GameObject ( "SoloConsumer" ) ;
activeConsumer = go . AddComponent < SoloConsumer > ( ) ;
}
else
{
activeConsumer = go . GetComponent < SoloConsumer > ( ) ;
}
#endif
PlayerPrefs . SetString ( defaultOutputBaseDirectory , Configuration . Instance . GetStorageBasePath ( ) ) ;
m_OutputDirectoryName = outputDirectory ;
var basePath = PlayerPrefs . GetString ( userBaseDirectoryKey , string . Empty ) ;
if ( basePath ! = string . Empty )
{
if ( Directory . Exists ( basePath ) )
{
Configuration . localPersistentDataPath = basePath ;
}
else
{
Debug . LogWarning ( $"Passed in directory to store simulation artifacts: {basePath}, does not exist. Using default directory {Configuration.localPersistentDataPath} instead." ) ;
basePath = Configuration . localPersistentDataPath ;
}
}
/ *
//var activeReporterString = PlayerPrefs.GetString(activeReporterKey, defaultReporter);
var activeReporterString = "coco" ;
if ( activeReporterString = = "perceptionOutput" )
{
m_ActiveReporter = new PerceptionExporter ( ) ;
}
else
{
m_ActiveReporter = new CocoExporter ( ) ;
}
* /
PlayerPrefs . SetString ( latestOutputDirectoryKey , Manager . Instance . GetDirectoryFor ( "" , basePath ) ) ;
//IDatasetExporter GetActiveReporter()
PerceptionConsumer GetActiveConsumer ( )
static PerceptionConsumer GetActiveConsumer ( )
public string GetRgbCaptureFilename ( string defaultFilename , params ( string , object ) [ ] additionalSensorValues )
{
return string . Empty ;
}
/// <summary>
/// A self-sufficient container for all information about a reported capture. Capture writing should not depend on any
/// state outside of this container, as other state may have changed since the capture was reported.
public Guid Id ;
public string Path ;
public Guid SequenceId ;
public int SequenceId ;
public List < ( Annotation , AnnotationData ) > Annotations = new List < ( Annotation , AnnotationData ) > ( ) ;
public List < ( AnnotationHandle , Annotation ) > Annotations = new List < ( AnnotationHandle , Annotation ) > ( ) ;
public PendingCapture ( Guid id , SensorHandle sensorHandle , SensorData sensorData , Guid sequenceId , int frameCount , int step , float timestamp )
public ( int , int ) Id = > ( SequenceId , Step ) ;
public PendingCapture ( SensorHandle sensorHandle , SensorData sensorData , int sequenceId , int frameCount , int step , float timestamp )
{
SensorHandle = sensorHandle ;
FrameCount = frameCount ;
Id = id ;
#if false
public PendingMetric ( MetricDefinition metricDefinition , int metricId , SensorHandle sensorHandle , Guid captureId , Annotation annotation , Guid sequenceId , int step , JToken values = null )
public PendingMetric ( MetricDefinition metricDefinition , int metricId , SensorHandle sensorHandle , AnnotationHandle annotationHandle , int sequenceId , int step , JToken values = null )
Annotation = annotation ;
AnnotationHandle = annotationHandle ;
CaptureId = captureId ;
Values = values ;
}
public readonly int MetricId ;
public readonly Guid CaptureId ;
public readonly Annotation Annotation ;
public readonly Guid SequenceId ;
public ( int , int ) CaptureId = > ( SequenceId , Step ) ;
public readonly AnnotationHandle AnnotationHandle ;
public readonly int SequenceId ;
#endif
public struct SensorData
{
public string modality ;
public float sequenceTimeOfNextCapture ;
public float sequenceTimeOfNextRender ;
public int lastCaptureFrameCount ;
public EgoHandle egoHandle ;
}
public struct AnnotationData
{
public readonly AnnotationDefinition AnnotationDefinition ;
public string Path ;
public JArray ValuesJson ;
public IEnumerable < object > RawValues ;
public bool IsAssigned = > Path ! = null | | ValuesJson ! = null ;
public AnnotationData ( AnnotationDefinition annotationDefinition , string path , JArray valuesJson )
: this ( )
{
AnnotationDefinition = annotationDefinition ;
Path = path ;
ValuesJson = valuesJson ;
}
}
enum AdditionalInfoKind
throw new InvalidOperationException ( $"Capture for frame {Time.frameCount} already reported for sensor {this}" ) ;
pendingCapture . CaptureReported = true ;
pendingCapture . Path = filename ;
pendingCapture . AdditionalSensorValues = additionalSensorValues ;
pendingCapture . SensorSpatialData = sensorSpatialData ;
}
}
public string GetOutputDirectoryNoCreate ( ) = > Path . Combine ( Configuration . Instance . GetStoragePath ( ) , m_OutputDirectoryName ) ;
void EnsureSequenceTimingsUpdated ( )
{
if ( ! m_HasStarted )
m_Sensors [ kvp . Key ] = sensorData ;
}
m_SequenceId = Guid . NewGuid ( ) ;
m_SequenceId + + ;
}
void ResetTimings ( )
m_LastTimeScale = Time . timeScale ;
}
string RegisterId ( string requestedId )
{
var id = requestedId ;
var i = 0 ;
while ( _Ids . Contains ( id ) )
{
id = $"{requestedId}_{i++}" ;
}
_Ids . Add ( id ) ;
return id ;
}
public SensorHandle AddSensor ( SensorDefinition sensor , float renderingDeltaTime )
{
var sensorData = new SensorData ( )
{
modality = sensor . modality ,
description = sensor . definition ,
firstCaptureTime = UnscaledSequenceTime + sensor . firstCaptureFrame * renderingDeltaTime ,
captureTriggerMode = CaptureTriggerMode . Scheduled , // TODO fix this
renderingDeltaTime = renderingDeltaTime ,
framesBetweenCaptures = sensor . framesBetweenCaptures ,
manualSensorAffectSimulationTiming = sensor . manualSensorsAffectTiming ,
lastCaptureFrameCount = - 1
} ;
sensorData . sequenceTimeOfNextCapture = GetSequenceTimeOfNextCapture ( sensorData ) ;
sensorData . sequenceTimeOfNextRender = UnscaledSequenceTime ;
sensor . id = RegisterId ( sensor . id ) ;
var sensorHandle = new SensorHandle ( sensor . id , DatasetCapture . Instance ) ;
m_ActiveSensors . Add ( sensorHandle ) ;
m_Sensors . Add ( sensorHandle , sensorData ) ;
GetActiveConsumer ( ) ? . OnSensorRegistered ( sensor ) ;
return sensorHandle ;
}
#if false
public void AddSensor ( EgoHandle egoHandle , string modality , string description , float firstCaptureFrame , CaptureTriggerMode captureTriggerMode , float renderingDeltaTime , int framesBetweenCaptures , bool manualSensorAffectSimulationTiming , SensorHandle sensor )
{
var sensorData = new SensorData ( )
GetActiveConsumer ( ) ? . OnSensorRegistered ( new SensorDefinition ( "camera" , modality , description ) ) ;
}
#endif
float GetSequenceTimeOfNextCapture ( SensorData sensorData )
{
// If the first capture hasn't happened yet, sequenceTimeNextCapture field won't be valid
return sensorData . sequenceTimeOfNextCapture ;
}
public bool Contains ( Guid id ) = > m_Ids . Contains ( id ) ;
public void AddEgo ( EgoHandle egoHandle )
{
CheckDatasetAllowed ( ) ;
m_Egos . Add ( egoHandle ) ;
m_Ids . Add ( egoHandle . Id ) ;
}
public bool Contains ( string id ) = > _Ids . Contains ( id ) ;
public bool IsEnabled ( SensorHandle sensorHandle ) = > m_ActiveSensors . Contains ( sensorHandle ) ;
}
WritePendingCaptures ( ) ;
WritePendingMetrics ( ) ;
// WritePendingMetrics();
Time . captureDeltaTime = nextFrameDt ;
}
public void End ( )
{
if ( m _Ids. Count = = 0 )
if ( _Ids . Count = = 0 )
#if false
#endif
if ( m_AdditionalInfoTypeData . Any ( ) )
{
List < IdLabelConfig . LabelEntrySpec > labels = new List < IdLabelConfig . LabelEntrySpec > ( ) ;
GetActiveConsumer ( ) ? . OnSimulationCompleted ( metadata ) ;
}
public void RegisterAnnotationDefinition ( SoloDesign . AnnotationDefinition definition )
{
GetActiveConsumer ( ) ? . OnAnnotationRegistered ( definition ) ;
}
public void RegisterMetricDefinition ( SoloDesign . MetricDefinition definition )
{
GetActiveConsumer ( ) ? . OnMetricRegistered ( definition ) ;
}
#if false
public AnnotationDefinition RegisterAnnotationDefinition < TSpec > ( string name , TSpec [ ] specValues , string description , string format , Guid id )
{
if ( id = = Guid . Empty )
return new AnnotationDefinition ( id , this ) ;
}
#endif
BoundingBoxAnnotationDefinition ToBoundingBoxDef < TSpec > ( TSpec [ ] specValues )
{
return new BoundingBoxAnnotationDefinition ( entries ) ;
}
#if false
public MetricDefinition RegisterMetricDefinition < TSpec > ( string name , TSpec [ ] specValues , string description , Guid id )
{
if ( id = = Guid . Empty )
return new MetricDefinition ( id ) ;
}
#endif
void RegisterAdditionalInfoType < TSpec > ( string name , TSpec [ ] specValues , string description , string format , Guid id , AdditionalInfoKind additionalInfoKind )
{
CheckDatasetAllowed ( ) ;
id = id ,
specValues = specValues
} ;
if ( ! m_Ids . Add ( id ) )
#if false
if ( ! m_Ids . Add ( id . ToString ( ) ) )
{
foreach ( var existingAnnotationDefinition in m_AdditionalInfoTypeData )
{
throw new ArgumentException ( $"Id {id} is already in use. Ids must be unique." ) ;
}
#endif
public Annotation ReportAnnotationFile ( AnnotationDefinition annotationDefinition , SensorHandle sensorHandle , string filename )
public AnnotationHandle ReportAnnotation ( SensorHandle sensor , AnnotationDefinition definition , Annotation annotation )
{
var handle = new AnnotationHandle ( sensor , this , definition , AcquireStep ( ) ) ;
var pendingCapture = GetOrCreatePendingCaptureForThisFrame ( sensor ) ;
pendingCapture . Annotations . Add ( ( handle , null ) ) ;
return handle ;
}
#if false
public AnnotationHandle ReportAnnotationFile ( AnnotationHandle annotationHandle , SensorHandle sensorHandle )
var annotation = new Annotation ( sensorHandle , this , AcquireStep ( ) ) ;
var annotation = new AnnotationHandle ( sensorHandle , this , AcquireStep ( ) ) ;
pendingCapture . Annotations . Add ( ( annotation , new AnnotationData ( annotationDefinition , filename , null ) ) ) ;
pendingCapture . Annotations . Add ( ( annotation , new AnnotationData ( annotationHandle , null ) ) ) ;
public Annotation ReportAnnotationValues < T > ( AnnotationDefinition annotationDefinition , SensorHandle sensorHandle , T [ ] values )
public AnnotationHandle ReportAnnotationValues < T > ( AnnotationDefinition annotationDefinition , SensorHandle sensorHandle , T [ ] values )
var annotation = new Annotation ( sensorHandle , this , AcquireStep ( ) ) ;
var annotation = new AnnotationHandle ( sensorHandle , this , AcquireStep ( ) ) ;
var pendingCapture = GetOrCreatePendingCaptureForThisFrame ( sensorHandle ) ;
var valuesJson = new JArray ( ) ;
foreach ( var value in values )
pendingCapture . Annotations . Add ( ( annotation , new AnnotationData ( annotationDefinition , null , valuesJson ) ) ) ;
return annotation ;
}
#endif
PendingCapture GetOrCreatePendingCaptureForThisFrame ( SensorHandle sensorHandle )
{
return GetOrCreatePendingCaptureForThisFrame ( sensorHandle , out var _ ) ;
if ( pendingCapture = = null )
{
created = true ;
pendingCapture = new PendingCapture ( Guid . NewGuid ( ) , sensorHandle , m_Sensors [ sensorHandle ] , m_SequenceId , Time . frameCount , AcquireStep ( ) , SequenceTime ) ;
pendingCapture = new PendingCapture ( sensorHandle , m_Sensors [ sensorHandle ] , m_SequenceId , Time . frameCount , AcquireStep ( ) , SequenceTime ) ;
m_PendingCaptures . Add ( pendingCapture ) ;
}
public AsyncAnnotation ReportAnnotationAsync ( AnnotationDefinition annotationDefinition , SensorHandle sensorHandle )
{
return new AsyncAnnotation ( ReportAnnotation ( sensorHandle , annotationDefinition , null ) , this ) ;
}
#if false
public AsyncAnnotation ReportAnnotationAsync ( AnnotationDefinition annotationDefinition , SensorHandle sensorHandle )
{
#endif
public void ReportAsyncAnnotationResult ( AsyncAnnotation asyncAnnotation , SoloDesign . Annotation annotation )
{
if ( ! asyncAnnotation . IsPending )
throw new InvalidOperationException ( "AsyncAnnotation has already been reported and cannot be reported again." ) ;
PendingCapture pendingCapture = null ;
var annotationIndex = - 1 ;
foreach ( var c in m_PendingCaptures )
{
if ( c . Step = = asyncAnnotation . annotationHandle . Step & & c . SensorHandle = = asyncAnnotation . annotationHandle . SensorHandle )
{
pendingCapture = c ;
annotationIndex = pendingCapture . Annotations . FindIndex ( a = > a . Item1 . Equals ( asyncAnnotation . annotationHandle ) ) ;
if ( annotationIndex ! = - 1 )
break ;
}
}
Debug . Assert ( pendingCapture ! = null & & annotationIndex ! = - 1 ) ;
var annotationTuple = pendingCapture . Annotations [ annotationIndex ] ;
annotationTuple . Item2 = annotation ;
pendingCapture . Annotations [ annotationIndex ] = annotationTuple ;
}
#if false
public void ReportAsyncAnnotationResult < T > ( AsyncAnnotation asyncAnnotation , string filename = null , NativeSlice < T > values = default ) where T : struct
{
var jArray = new JArray ( ) ;
annotationTuple . Item2 = annotationData ;
pendingCapture . Annotations [ annotationIndex ] = annotationTuple ;
}
#endif
public bool IsPending ( Annotation annotation )
public bool IsPending ( AnnotationHandle annotationHandle )
foreach ( var a in c . Annotations )
foreach ( var ( handle , annotation ) in c . Annotations )
if ( a . Item1 . Equals ( annotation ) )
return ! a . Item2 . IsAssigned ;
if ( handle . Equals ( annotationHandle ) )
return annotation = = null ;
}
}
#if false
public bool IsPending ( ref AsyncMetric asyncMetric )
{
foreach ( var m in m_PendingMetrics )
pendingMetric . Values = values ;
m_PendingMetrics [ metricIndex ] = pendingMetric ;
}
static JArray JArrayFromArray < T > ( T [ ] values )
{
var jArray = new JArray ( ) ;
foreach ( var value in values )
jArray . Add ( DatasetJsonUtility . ToJToken ( value ) ) ;
return jArray ;
}
public AsyncMetric CreateAsyncMetric ( MetricDefinition metricDefinition , SensorHandle sensorHandle = default , Annotation annotation = default )
#endif
#if false
public AsyncMetric CreateAsyncMetric ( MetricDefinition metricDefinition , SensorHandle sensorHandle = default , AnnotationHandle annotationHandle = default )
var captureId = Guid . Empty ;
captureId = capture . Id ;
m_PendingMetrics . Add ( new PendingMetric ( metricDefinition , id , sensorHandle , captureId , annotation , m_SequenceId , AcquireStep ( ) ) ) ;
m_PendingMetrics . Add ( new PendingMetric ( metricDefinition , id , sensorHandle , annotationHandle , m_SequenceId , AcquireStep ( ) ) ) ;
public void ReportMetric < T > ( MetricDefinition metricDefinition , T [ ] values , SensorHandle sensorHandle , Annotation annotation )
public void ReportMetric < T > ( MetricDefinition metricDefinition , T [ ] values , SensorHandle sensorHandle , AnnotationHandle annotationHandle )
ReportMetric ( metricDefinition , jArray , sensorHandle , annotation ) ;
ReportMetric ( metricDefinition , jArray , sensorHandle , annotationHandle ) ;
public void ReportMetric ( MetricDefinition metricDefinition , JToken values , SensorHandle sensorHandle , Annotation annotation )
public void ReportMetric ( MetricDefinition metricDefinition , JToken values , SensorHandle sensorHandle , AnnotationHandle annotationHandle )
var captureId = sensorHandle . IsNil ? Guid . Empty : GetOrCreatePendingCaptureForThisFrame ( sensorHandle ) . Id ;
m_PendingMetrics . Add ( new PendingMetric ( metricDefinition , m_NextMetricId + + , sensorHandle , captureId , annotation , m_SequenceId , AcquireStep ( ) , values ) ) ;
var captureId = sensorHandle . IsNil ? ( - 1 , - 1 ) : GetOrCreatePendingCaptureForThisFrame ( sensorHandle ) . Id ;
m_PendingMetrics . Add ( new PendingMetric ( metricDefinition , m_NextMetricId + + , sensorHandle , annotationHandle , m_SequenceId , AcquireStep ( ) , values ) ) ;
#endif
}
}