3 using System.Collections.Generic;
18 namespace droid.Runtime.Managers {
22 [DisallowMultipleComponent]
33 if (this._configuration == null) {
37 return this._configuration;
86 void FetchCommandLineArguments() {
87 var arguments = Environment.GetCommandLineArgs();
89 for (var i = 0; i < arguments.Length; i++) {
90 if (arguments[i] ==
"-ip") {
94 if (arguments[i] ==
"-port") {
102 void CreateMessagingServer() {
112 }
catch (Exception exception) {
113 Debug.Log(exception);
123 void StartMessagingServer(
bool threaded =
false) {
134 this._Message_Server.ListenForClientToConnect(this.OnDebugCallback);
136 if (this.Debugging) {
137 Debug.Log(
" Messaging Server is listening for clients");
142 this.OnListeningCallback();
154 #region PrivateFields 158 [Header(
"Development", order = 110)]
169 bool _testing_Actuators;
172 const int _script_execution_order = -1000;
179 [Header(
"Simulation", order = 80)]
191 bool _syncing_environments;
196 bool _awaiting_reply;
198 [SerializeField]
bool _step;
200 WaitForEndOfFrame _wait_for_end_of_frame =
new WaitForEndOfFrame();
201 WaitForFixedUpdate _wait_for_fixed_update =
new WaitForFixedUpdate();
202 List<Reaction> _sample_reactions =
new List<Reaction>();
206 #region Getter And Setters 212 lock (this._send_lock) {
213 return this._Current_Reactions;
217 lock (this._send_lock) {
218 this._Current_Reactions = value;
225 public float SimulationTimeScale {
226 get {
return Time.timeScale; }
229 Time.timeScale = Math.Min(value, 99);
230 this._last_simulation_time = Math.Min(value, 99);
232 Time.timeScale = value;
233 this._last_simulation_time = value;
237 Time.fixedDeltaTime = 0.02F * Time.timeScale;
242 [SerializeField]
float _last_simulation_time;
246 public bool HasStepped {
get {
return this._has_stepped; }
set { this._has_stepped = value; } }
250 public bool TestActuators {
251 get {
return this._testing_Actuators; }
252 set { this._testing_Actuators = value; }
257 public bool Debugging {
258 get {
return this._debugging; }
260 if (this._Message_Server != null) {
261 this._Message_Server.Debugging = value;
264 this._debugging = value;
270 public bool AwaitingReply {
272 lock (this._send_lock) {
273 return this._awaiting_reply;
277 lock (this._send_lock) {
278 this._awaiting_reply = value;
287 public bool IsSyncingEnvironments {
288 get {
return this._syncing_environments; }
289 set { this._syncing_environments = value; }
294 public bool Stepping {
get {
return this._step; } }
298 #region PrivateMembers 302 protected Dictionary<string, IEnvironment> _Environments =
new Dictionary<string, IEnvironment>();
306 public void Clear() { this._Environments.Clear(); }
316 [SerializeField]
bool _has_stepped;
320 #region UnityCallbacks 325 if (Instance == null) {
327 }
else if (Instance ==
this) {
329 if (this.Debugging) {
330 Debug.Log(
"Using " + Instance);
334 Debug.LogWarning(
"WARNING! There are multiple SimulationManagers in the scene! Only using " 339 if (!Application.isPlaying) {
340 var manager_script = MonoScript.FromMonoBehaviour(
this);
341 if (MonoImporter.GetExecutionOrder(manager_script) != _script_execution_order) {
342 MonoImporter.SetExecutionOrder(manager_script,
343 _script_execution_order);
344 Debug.LogWarning(
"Execution Order changed, you will need to press play again to make everything function correctly!");
345 EditorApplication.isPlaying =
false;
355 this.FetchCommandLineArguments();
364 this.EarlyFixedUpdateEvent += this.OnPreTick;
365 this.FixedUpdateEvent += this.OnTick;
366 this.FixedUpdateEvent += this.Tick;
367 this.LateFixedUpdateEvent += this.OnPostTick;
368 this.StartCoroutine(this.LateFixedUpdateEventGenerator());
370 this.EarlyUpdateEvent += this.OnPreTick;
371 this.UpdateEvent += this.OnTick;
372 this.UpdateEvent += this.Tick;
375 this.LateUpdateEvent += this.OnPostTick;
378 this.OnPostRenderEvent += this.OnPostTick;
381 this.OnRenderImageEvent += this.OnPostTick;
384 this.StartCoroutine(this.EndOfFrameEventGenerator());
385 this.OnEndOfFrameEvent += this.OnPostTick;
387 default:
throw new ArgumentOutOfRangeException();
391 this.CreateMessagingServer();
393 this.StartMessagingServer();
395 this.StartMessagingServer(
true);
403 QualitySettings.SetQualityLevel(configuration.
QualityLevel,
true);
404 QualitySettings.vSyncCount = configuration.
VSyncCount;
407 this.SimulationTimeScale = configuration.
TimeScale;
411 Screen.SetResolution(1, 1,
false);
415 Screen.SetResolution(
416 width : configuration.
Width,
417 height : configuration.
Height,
423 PlayerSettings.colorSpace = configuration.
ColorSpace;
424 PlayerSettings.displayResolutionDialog = ResolutionDialogSetting.Disabled;
431 void OnPostRender() { this.OnPostRenderEvent?.Invoke(); }
437 void OnRenderImage(RenderTexture src, RenderTexture dest) {
438 this.OnRenderImageEvent?.Invoke();
444 this.EarlyFixedUpdateEvent?.Invoke();
445 this.FixedUpdateEvent?.Invoke();
451 IEnumerator LateFixedUpdateEventGenerator() {
453 yield
return this._wait_for_fixed_update;
455 if (this.Debugging) {
456 Debug.Log(
"LateFixedUpdate");
459 this.LateFixedUpdateEvent?.Invoke();
470 yield
return this._wait_for_end_of_frame;
473 if (this.Debugging) {
474 Debug.Log(
"EndOfFrameEvent");
477 this.OnEndOfFrameEvent?.Invoke();
479 #pragma warning disable 162 482 #pragma warning restore 162 489 this.EarlyUpdateEvent?.Invoke();
490 this.UpdateEvent?.Invoke();
495 protected void LateUpdate() { this.LateUpdateEvent?.Invoke(); }
499 #region PrivateMethods 505 if (this.Debugging) {
506 Debug.Log(
"OnPreTick");
519 if (this.Debugging) {
532 if (this.Debugging) {
533 Debug.Log(
"OnPostTick");
537 foreach (var environment
in this._Environments.Values) {
538 environment.PostStep();
545 if (this._has_stepped) {
546 this.ClearCurrentReactions();
553 if (!this._syncing_environments) {
554 this.React(this.CurrentReactions);
557 if (this.AwaitingReply) {
558 var states = this.CollectStates();
559 this.PostReact(states);
562 this.HasStepped =
true;
568 if (this.TestActuators) {
569 this.React(this.SampleRandomReactions());
570 this.CollectStates();
573 foreach (var environment
in this._Environments.Values) {
578 if (this.Debugging) {
588 lock (this._send_lock) {
589 foreach (var env
in this._Environments.Values) {
590 if (env.IsResetting) {
592 if (this.Debugging) {
593 Debug.Log($
"Environment {env} is resetting");
597 this._syncing_environments =
true;
602 this._syncing_environments =
false;
605 if (this.Debugging) {
606 Debug.Log(
"Not skipping frame, replying...");
611 this.AwaitingReply =
false;
612 this._skip_frame_i = 0;
614 this._skip_frame_i += 1;
616 if (this.Debugging) {
617 Debug.Log($
"Skipping frame, {this._skip_frame_i}/{this.Configuration.FrameSkips}");
629 this._sample_reactions.Clear();
630 foreach (var environment
in this._Environments.Values) {
631 this._sample_reactions.Add(environment.SampleReaction());
634 return this._sample_reactions.ToArray();
642 lock (this._send_lock) {
644 var describe =
false;
645 if (this.CurrentReactions != null) {
646 foreach (var reaction
in this.CurrentReactions) {
647 if (reaction.Parameters.Describe) {
654 simulator_configuration_message : configuration_message,
655 do_serialise_unobservables :
657 serialise_individual_observables :
658 describe ||
this.
Configuration.AlwaysSerialiseIndividualObservables,
659 serialise_aggregated_float_array : describe
660 ||
this._configuration
661 .AlwaysSerialiseAggregatedFloatArray);
663 if (this.Debugging) {
664 Debug.Log(
"Replying");
673 void ClearCurrentReactions() {
675 this.CurrentReactions =
new Reaction[] { };
680 #region PublicMethods 687 this.SetStepping(reaction);
690 foreach (var environment
in this._Environments.Values) {
691 if (reaction.RecipientEnvironment !=
"all") {
693 if (this.Debugging) {
694 Debug.Log($
"Applying reaction to {reaction.RecipientEnvironment} environment");
697 if (this._Environments.ContainsKey(reaction.RecipientEnvironment)) {
698 states[i++] = this._Environments[reaction.RecipientEnvironment].ReactAndCollectState(reaction);
702 if (this.Debugging) {
703 Debug.Log($
"Could not find environment: {reaction.RecipientEnvironment}");
709 if (this.Debugging) {
710 Debug.Log(
"Applying reaction to all environments");
713 states[i++] = environment.ReactAndCollectState(reaction);
725 this.SetStepping(reaction);
730 if (this.Debugging) {
731 Debug.Log($
"Could not find an environment with the identifier: {reaction.RecipientEnvironment}");
736 if (this.Debugging) {
737 Debug.Log(
"Applying to all environments");
741 foreach (var environment
in this._Environments.Values) {
742 environment.React(reaction);
752 this.SetStepping(reactions);
753 foreach (var reaction
in reactions) {
754 if (this._Environments.ContainsKey(reaction.RecipientEnvironment)) {
755 this._Environments[reaction.RecipientEnvironment].React(reaction);
756 }
else if (reaction.RecipientEnvironment ==
"all") {
758 if (this.Debugging) {
759 Debug.Log(
"Applying to all environments");
763 foreach (var environment
in this._Environments.Values) {
764 environment.React(reaction);
768 if (this.Debugging) {
769 Debug.Log($
"Could not find an environment with the identifier: {reaction.RecipientEnvironment}");
780 var environments = this._Environments.Values;
783 foreach (var environment
in environments) {
784 states[i++] = environment.CollectState();
790 void SetStepping(
Reaction reaction) {
792 this.SetStepping(
true);
796 void SetStepping(
bool step) {
799 if (this.Debugging) {
800 Debug.Log(
"Stepping from Reaction");
807 if (this.Debugging) {
808 Debug.Log(
"Not stepping from Reaction");
811 if (this.HasStepped) {
817 void SetStepping(
Reaction[] reactions) {
819 this.SetStepping(
true);
823 public void SetTesting(
bool arg0) { this.TestActuators = arg0; }
876 if (this._Message_Server != null) {
899 if (!this._Environments.ContainsKey(identifier)) {
901 if (this.Debugging) {
902 Debug.Log($
"Manager {this.name} already has an environment with the identifier: {identifier}");
906 this._Environments.Add(identifier, environment);
908 Debug.LogWarning($
"WARNING! Please check for duplicates, SimulationManager {this.name} " 909 + $
"already has environment {identifier} registered");
918 if (this._Environments.ContainsKey(identifier)) {
920 if (this.Debugging) {
921 Debug.Log($
"SimulationManager {this.name} unregistered Environment {identifier}");
925 this._Environments.Remove(identifier);
933 this.UnRegister(neodroid_environment, neodroid_environment.
Identifier);
938 #region MessageServerCallbacks 943 void OnReceiveCallback(
Reaction[] reactions) {
944 lock (this._send_lock) {
946 if (this.Debugging) {
947 Debug.Log($
"Received: {reactions.Select(r => r.ToString()).Aggregate((current, next) => $"{current}, {next}
")}");
951 this.SetReactionsFromExternalSource(reactions);
953 this.OnReceiveEvent?.Invoke();
961 lock (this._send_lock) {
962 if (reactions != null) {
963 if (this.AwaitingReply || !this.HasStepped) {
965 if (this.Debugging) {
966 Debug.Log($
"Got new reaction while not having stepped({!this.HasStepped}) or replied({this.AwaitingReply})");
971 this.CurrentReactions = reactions;
972 foreach (var current_reaction
in this.CurrentReactions) {
976 this.
Configuration.StepExecutionPhase = this.CurrentReactions[0].Parameters.Phase;
977 this.AwaitingReply =
true;
978 this.HasStepped =
false;
980 Debug.LogWarning(
"Reaction was null");
987 void OnDisconnectCallback() {
989 if (this.Debugging) {
990 Debug.Log(
"Client disconnected.");
998 void OnDebugCallback(
string error) {
1000 if (this.Debugging) {
1001 Debug.Log(
"DebugCallback: " + error);
1008 void OnListeningCallback() {
1010 if (this.Debugging) {
1011 Debug.Log(
"Client connected");
1016 this.OnDisconnectCallback,
1017 this.OnDebugCallback);
1022 #region Deconstruction 1026 void OnApplicationQuit() { this._Message_Server.
CleanUp(); }
1030 void OnDestroy() { this._Message_Server.
Destroy(); }
bool ApplyResolutionSettings
String RecipientEnvironment
bool ApplyQualitySettings
void ApplyConfigurationToUnity(ISimulatorConfiguration configuration)
abstract void PollData(dynamic data)
Action EarlyUpdateEvent
Can be subscribed to for pre update events (Will be called before any Update on any script) ...
EnvironmentState [] CollectStates()
void SendStates(EnvironmentState[] environment_states, bool do_serialise_unobservables=false, bool serialise_individual_observables=false, bool serialise_aggregated_float_array=false, SimulatorConfigurationMessage simulator_configuration_message=null, string api_version=_api_version)
void Register(IEnvironment environment, string identifier)
Action OnRenderImageEvent
void Register(IEnvironment environment)
Action LateFixedUpdateEvent
Contains everything relevant to configuring simulation environments engine specific settings ...
void StartReceiving(Action< Reaction[]> cmd_callback, Action disconnect_callback, Action< string > debug_callback)
MessageServer _Message_Server
FrameFinishes
Determines where in the monobehaviour cycle a frame/step is finished
Boolean OptimiseWindowForSpeed
ReactionParameters Parameters
EnvironmentState [] ReactAndCollectStates(Reaction reaction)
Reaction [] SampleRandomReactions()
void SetReactionsFromExternalSource(Reaction[] reactions)
void StatusString(DataPoller recipient)
Action EarlyFixedUpdateEvent
Can be subscribed to for pre fixed update events (Will be called before any FixedUpdate on any script...
bool _Listening_For_Clients
void UnRegister(IEnvironment neodroid_environment)
void ResetAllEnvironments()
void React(Reaction[] reactions)
void SetTesting(bool arg0)
Configuration(string configurable_name, float configurable_value, bool sample_random=false)
SimulationType
Determines the discrete timesteps of the simulation environment.
void React(Reaction reaction)
void PostReact(EnvironmentState[] states)
IEnumerator EndOfFrameEventGenerator()
void UnRegister(IEnvironment environment, string identifier)