diff --git a/Assets/AWSIM/Scenes/Main/AutowareSimulation.unity b/Assets/AWSIM/Scenes/Main/AutowareSimulation.unity index 193f1b6ae..f5c0cccd0 100644 --- a/Assets/AWSIM/Scenes/Main/AutowareSimulation.unity +++ b/Assets/AWSIM/Scenes/Main/AutowareSimulation.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 1519.6069, g: 1883.9946, b: 2490.9849, a: 1} + m_IndirectSpecularColor: {r: 1520.0924, g: 1884.674, b: 2491.8425, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -536,6 +536,7 @@ MonoBehaviour: m_EditorClassIdentifier: trafficManager: {fileID: 723377035} egoTransform: {fileID: 7808269042169720464} + timeSourceSelector: {fileID: 1259688278} commandLineConfigParam: --json_path useJsonConfig: 0 jsonPath: @@ -3239,6 +3240,17 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 830ab73cebda3db4580ebd3ece935931, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &1259688278 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 3077555317673241940, guid: 27181f17b3e1bb607a4b8fcb8a827e0f, type: 3} + m_PrefabInstance: {fileID: 1575276244} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0dde57169074a9c5c9780c80294b4427, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &1381324630 PrefabInstance: m_ObjectHideFlags: 0 @@ -4046,7 +4058,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 3077555317673241940, guid: 27181f17b3e1bb607a4b8fcb8a827e0f, type: 3} propertyPath: Type - value: 2 + value: 3 objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 27181f17b3e1bb607a4b8fcb8a827e0f, type: 3} @@ -4530,6 +4542,53 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 23c1ce4fb46143f46bc5cb5224c934f6, type: 3} m_Name: m_EditorClassIdentifier: + m_Version: 7 + m_ObsoleteRenderingPath: 0 + m_ObsoleteFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 clearColorMode: 0 backgroundColorHDR: {r: 0.025, g: 0.07, b: 0.19, a: 0} clearDepth: 1 @@ -4585,53 +4644,6 @@ MonoBehaviour: data1: 0 data2: 0 defaultFrameSettings: 0 - m_Version: 7 - m_ObsoleteRenderingPath: 0 - m_ObsoleteFrameSettings: - overrides: 0 - enableShadow: 0 - enableContactShadows: 0 - enableShadowMask: 0 - enableSSR: 0 - enableSSAO: 0 - enableSubsurfaceScattering: 0 - enableTransmission: 0 - enableAtmosphericScattering: 0 - enableVolumetrics: 0 - enableReprojectionForVolumetrics: 0 - enableLightLayers: 0 - enableExposureControl: 1 - diffuseGlobalDimmer: 0 - specularGlobalDimmer: 0 - shaderLitMode: 0 - enableDepthPrepassWithDeferredRendering: 0 - enableTransparentPrepass: 0 - enableMotionVectors: 0 - enableObjectMotionVectors: 0 - enableDecals: 0 - enableRoughRefraction: 0 - enableTransparentPostpass: 0 - enableDistortion: 0 - enablePostprocess: 0 - enableOpaqueObjects: 0 - enableTransparentObjects: 0 - enableRealtimePlanarReflection: 0 - enableMSAA: 0 - enableAsyncCompute: 0 - runLightListAsync: 0 - runSSRAsync: 0 - runSSAOAsync: 0 - runContactShadowsAsync: 0 - runVolumeVoxelizationAsync: 0 - lightLoopSettings: - overrides: 0 - enableDeferredTileAndCluster: 0 - enableComputeLightEvaluation: 0 - enableComputeLightVariants: 0 - enableComputeMaterialVariants: 0 - enableFptlForForwardOpaque: 0 - enableBigTilePrepass: 0 - isFptlEnabled: 0 --- !u!81 &2122627085 AudioListener: m_ObjectHideFlags: 0 diff --git a/Assets/AWSIM/Scenes/Main/AutowareSimulation/AutowareSimulation.cs b/Assets/AWSIM/Scenes/Main/AutowareSimulation/AutowareSimulation.cs index c81a736d9..fa269a691 100644 --- a/Assets/AWSIM/Scenes/Main/AutowareSimulation/AutowareSimulation.cs +++ b/Assets/AWSIM/Scenes/Main/AutowareSimulation/AutowareSimulation.cs @@ -12,6 +12,7 @@ public class AutowareSimulation : MonoBehaviour { [SerializeField] TrafficManager trafficManager; [SerializeField] Transform egoTransform; + [SerializeField] TimeSourceSelector timeSourceSelector; [Header("Player Config")] [SerializeField] string commandLineConfigParam = "--json_path"; @@ -33,6 +34,7 @@ public class EgoConfiguration public class Configuration { public float TimeScale; // Reflected in Time.timeScale + public string TimeSource; // Reflected in TimeSourceSelector public int RandomTrafficSeed; // Reflected in TrafficManager.seed public int MaxVehicleCount; // Reflected in TrafficManager.maxVehicleCount public EgoConfiguration Ego = new EgoConfiguration(); @@ -40,6 +42,11 @@ public class Configuration void Awake() { + // check if time source selector is present + if(timeSourceSelector == null) + { + Debug.LogWarning("TimeSource: There is no TimeSourceSelector object assigned in the inspector. The default time source will be used."); + } #if !UNITY_EDITOR // initialize @@ -62,6 +69,9 @@ void Awake() var rotation = Quaternion.Euler(config.Ego.EulerAngles); egoTransform.rotation = ROS2Utility.RosToUnityRotation(rotation); + + // set time source + timeSourceSelector?.SetType(config.TimeSource); } } } diff --git a/Assets/AWSIM/Scenes/Main/AutowareSimulation/config.json b/Assets/AWSIM/Scenes/Main/AutowareSimulation/config.json index fc2631494..f0bda86a2 100644 --- a/Assets/AWSIM/Scenes/Main/AutowareSimulation/config.json +++ b/Assets/AWSIM/Scenes/Main/AutowareSimulation/config.json @@ -1,5 +1,6 @@ { "TimeScale": 0.2, + "TimeSource": "simulation", "RandomTrafficSeed": 33, "MaxVehicleCount": 2, "Ego": { @@ -14,4 +15,4 @@ "z": 35.0 } } -} \ No newline at end of file +} diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs new file mode 100644 index 000000000..100d1130f --- /dev/null +++ b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs @@ -0,0 +1,48 @@ +using System; +using System.Threading; +using ROS2; + +namespace AWSIM +{ + /// + /// A thread-safe timesource class that provides simulation time based on the dot net system utc time. + /// This time source takes into account the value of the simulation timescale and + /// starts at zero value when the simulation is started. + /// + public class DotNetSimulationTimeSource : ITimeSource + { + private DateTime prevDateTime; + private double time; + private bool hasStarted = false; + + private readonly object lockObject = new object(); + + public DotNetSimulationTimeSource() + { + hasStarted = false; + } + + public void GetTime(out int seconds, out uint nanoseconds) + { + lock (lockObject) + { + DateTime currDateTime = DateTime.UtcNow; + + if(!hasStarted) + { + hasStarted = true; + time = 0.0; + + prevDateTime = currDateTime; + } + + TimeSpan timeSpan = currDateTime - prevDateTime; + prevDateTime = currDateTime; + + time += timeSpan.TotalMilliseconds * 0.001f * TimeScaleProvider.TimeScale; + TimeUtils.TimeFromTotalSeconds(time, out seconds, out nanoseconds); + } + } + } + +} diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs.meta b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs.meta new file mode 100644 index 000000000..42f090809 --- /dev/null +++ b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSimulationTimeSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d4d8d5d1c4ad4f8999b97cad5200dd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSystemTimeSource.cs b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSystemTimeSource.cs index 40c35c3ac..3a3f42078 100644 --- a/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSystemTimeSource.cs +++ b/Assets/AWSIM/Scripts/Clock/Scripts/DotNetSystemTimeSource.cs @@ -5,19 +5,20 @@ namespace AWSIM { /// - /// A thread-safe timesource class that provides the dot net system utc time. + /// A thread-safe timesource class that provides the dot net system utc time since epoch. + /// This timesource takes into account the value of the simulation timescale. /// public class DotNetSystemTimeSource : ITimeSource { private DateTime prevDateTime; private double time; + private bool hasStarted = false; private readonly object lockObject = new object(); public DotNetSystemTimeSource() { - prevDateTime = DateTime.UtcNow; - time = 0.0; + hasStarted = false; } public void GetTime(out int seconds, out uint nanoseconds) @@ -25,10 +26,22 @@ public void GetTime(out int seconds, out uint nanoseconds) lock (lockObject) { DateTime currDateTime = DateTime.UtcNow; + + if(!hasStarted) + { + hasStarted = true; + + // get the time in millisecond since epoch + long timeOffset = ((DateTimeOffset)currDateTime).ToUnixTimeMilliseconds(); + time = (double)timeOffset * 0.001; + + prevDateTime = currDateTime; + } + TimeSpan timeSpan = currDateTime - prevDateTime; prevDateTime = currDateTime; - time += timeSpan.TotalMilliseconds * 0.001f * TimeScaleProvider.TimeScale; + time += timeSpan.TotalMilliseconds * 0.001 * TimeScaleProvider.TimeScale; TimeUtils.TimeFromTotalSeconds(time, out seconds, out nanoseconds); } } diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs b/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs new file mode 100644 index 000000000..6a4a65131 --- /dev/null +++ b/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs @@ -0,0 +1,41 @@ +using UnityEngine; + +namespace AWSIM +{ + /// + /// A thread-safe static class to provide the value of the Unity time as double. + /// + public static class TimeAsDoubleProvider + { + private static readonly object lockObject = new object(); + + private static double timeAsDouble = 0.0; + public static double TimeAsDouble + { + get + { + lock(lockObject) + { + return timeAsDouble; + } + } + } + + + #region [Public Methods] + + /// + /// Synchronise the value of the timeAsDouble variable with the Time.timeAsDouble from the Unity thread. + /// + public static void DoUpdate() + { + lock(lockObject) + { + timeAsDouble = Time.timeAsDouble; + } + } + + #endregion + } +} + diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs.meta b/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs.meta new file mode 100644 index 000000000..af90baa82 --- /dev/null +++ b/Assets/AWSIM/Scripts/Clock/Scripts/TimeAsDoubleProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26a9b446c6fcc6ff08f19aa85f8c3330 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/TimeScaleProvider.cs b/Assets/AWSIM/Scripts/Clock/Scripts/TimeScaleProvider.cs index 0306d4cda..94bd6cf38 100644 --- a/Assets/AWSIM/Scripts/Clock/Scripts/TimeScaleProvider.cs +++ b/Assets/AWSIM/Scripts/Clock/Scripts/TimeScaleProvider.cs @@ -31,10 +31,7 @@ public static void DoUpdate() { lock(lockObject) { - if (Mathf.Abs(Time.timeScale - timeScale) > 0.01f) - { - timeScale = Time.timeScale; - } + timeScale = Time.timeScale; } } diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceProvider.cs b/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceProvider.cs index 8b8b22844..12fbd1344 100644 --- a/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceProvider.cs +++ b/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceProvider.cs @@ -1,3 +1,4 @@ +using AWSIM.Samples; using ROS2; using System; @@ -12,7 +13,9 @@ public enum TimeSourceType { UNITY, SS2, - DOTNET + DOTNET_SYSTEM, + DOTNET_SIMULATION, + ROS2, } #region [Event] @@ -96,7 +99,7 @@ public static void SetTimeSource(TimeSourceType type) } // dot net system time source - if(type == TimeSourceType.DOTNET) + if(type == TimeSourceType.DOTNET_SYSTEM) { if(currentTimeSource == null || !(currentTimeSource is DotNetSystemTimeSource)) { @@ -107,6 +110,30 @@ public static void SetTimeSource(TimeSourceType type) return; } + // dot net simulation time source + if(type == TimeSourceType.DOTNET_SIMULATION) + { + if(currentTimeSource == null || !(currentTimeSource is DotNetSimulationTimeSource)) + { + currentTimeSource = new DotNetSimulationTimeSource(); + onTimeSourceChanged?.Invoke(); + } + + return; + } + + // ros2 time source + if(type == TimeSourceType.ROS2) + { + if(currentTimeSource == null || !(currentTimeSource is ROS2TimeSource)) + { + currentTimeSource = new ROS2TimeSource(); + onTimeSourceChanged?.Invoke(); + } + + return; + } + // default time source if(currentTimeSource == null || !(currentTimeSource is UnityTimeSource)) { diff --git a/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceSelector.cs b/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceSelector.cs index 2dacd2f02..90181c5c0 100644 --- a/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceSelector.cs +++ b/Assets/AWSIM/Scripts/Clock/Scripts/TimeSourceSelector.cs @@ -20,6 +20,60 @@ private void Awake() TimeSourceProvider.SetTimeSource(Type); } + #region [Public Methods] + + /// + /// Set the time source of the desired type. + /// + /// Type of requested time source. + public void SetType(string type) + { + if(type == null || type == "") + { + return; + } + + if(string.CompareOrdinal(type.ToLower(), "unity") == 0) + { + SetType(TimeSourceProvider.TimeSourceType.UNITY); + } + else if(string.CompareOrdinal(type.ToLower(), "simulation") == 0) + { + SetType(TimeSourceProvider.TimeSourceType.DOTNET_SIMULATION); + } + else if(string.CompareOrdinal(type.ToLower(), "system") == 0) + { + SetType(TimeSourceProvider.TimeSourceType.DOTNET_SYSTEM); + } + else if(string.CompareOrdinal(type.ToLower(), "ss2") == 0) + { + SetType(TimeSourceProvider.TimeSourceType.SS2); + } + else if(string.CompareOrdinal(type.ToLower(), "ros2") == 0) + { + SetType(TimeSourceProvider.TimeSourceType.ROS2); + } + else + { + Debug.LogWarning("TimeSourceSelector: " + type + " is not recognized as a valid time source."); + } + } + + #endregion + + #region [Private Methods] + + /// + /// Set the time source of the desired type. + /// + /// Type of requested time source. + private void SetType(TimeSourceProvider.TimeSourceType type) + { + Type = type; + TimeSourceProvider.SetTimeSource(Type); + } + + #endregion } } diff --git a/Assets/AWSIM/Scripts/ROS/ClockPublisher.cs b/Assets/AWSIM/Scripts/ROS/ClockPublisher.cs index 33bc224a0..635cc502d 100644 --- a/Assets/AWSIM/Scripts/ROS/ClockPublisher.cs +++ b/Assets/AWSIM/Scripts/ROS/ClockPublisher.cs @@ -32,6 +32,7 @@ void Awake() void Start() { TimeScaleProvider.DoUpdate(); + TimeAsDoubleProvider.DoUpdate(); StartClockThread(); } @@ -43,6 +44,15 @@ void OnDestroy() #endregion + #region [Main Thread] + + void Update() + { + TimeAsDoubleProvider.DoUpdate(); + } + + #endregion + #region [Clock Thread] void StartClockThread() diff --git a/Assets/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs b/Assets/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs index 5fa9e99e4..cfc0dfe25 100644 --- a/Assets/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs +++ b/Assets/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs @@ -22,6 +22,7 @@ namespace ROS2 /// DateTime based clock that has resolution increased using Stopwatch. /// DateTime is used to synchronize since Stopwatch tends to drift. /// +[System.Obsolete("This TimeSource is deprecated and will be removed in the future versions. Please use DotNetSystemTimeSource instead.")] public class DotnetTimeSource : ITimeSource { private readonly double maxUnsyncedSeconds = 10; diff --git a/Assets/Ros2ForUnity/Scripts/Time/ROS2ScalableTimeSource.cs b/Assets/Ros2ForUnity/Scripts/Time/ROS2ScalableTimeSource.cs index 6c7c129ee..065d4141d 100644 --- a/Assets/Ros2ForUnity/Scripts/Time/ROS2ScalableTimeSource.cs +++ b/Assets/Ros2ForUnity/Scripts/Time/ROS2ScalableTimeSource.cs @@ -21,6 +21,7 @@ namespace ROS2 /// /// ros2 time source (system time by default). /// +[System.Obsolete("This TimeSource is deprecated and will be removed in the future versions. Please use DotNetSystemTimeSource instead.")] public class ROS2ScalableTimeSource : ITimeSource { private Thread mainThread; diff --git a/Assets/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs b/Assets/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs index 7a0ec7a8c..494b5ab8f 100644 --- a/Assets/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs +++ b/Assets/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs @@ -14,6 +14,7 @@ using System; using System.Threading; +using AWSIM; using UnityEngine; namespace ROS2 @@ -37,7 +38,7 @@ public UnityTimeSource() public void GetTime(out int seconds, out uint nanoseconds) { - lastReadingSecs = mainThread.Equals(Thread.CurrentThread) ? Time.timeAsDouble : lastReadingSecs; + lastReadingSecs = mainThread.Equals(Thread.CurrentThread) ? Time.timeAsDouble : TimeAsDoubleProvider.TimeAsDouble; TimeUtils.TimeFromTotalSeconds(lastReadingSecs, out seconds, out nanoseconds); } }