From 963a60dc15041c6cc08e18cf866fc910d26a8c97 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 08:58:02 -0700 Subject: [PATCH 01/23] Make EnvironmentParameters a first-class citizen in the API Missing: Python conterparts and testing. --- .../Examples/3DBall/Scripts/Ball3DAgent.cs | 8 +- .../3DBall/Scripts/Ball3DHardAgent.cs | 8 +- .../Examples/Bouncer/Scripts/BouncerAgent.cs | 6 +- .../Scripts/FoodCollectorAgent.cs | 7 +- .../Examples/GridWorld/Scripts/GridAgent.cs | 9 ++- .../Examples/GridWorld/Scripts/GridArea.cs | 20 ++--- .../GridWorld/Scripts/GridSettings.cs | 2 +- .../PushBlock/Scripts/PushAgentBasic.cs | 18 ++--- .../Examples/Reacher/Scripts/ReacherAgent.cs | 13 +-- .../Scripts/ProjectSettingsOverrides.cs | 2 +- .../Examples/Soccer/Scripts/AgentSoccer.cs | 8 +- .../Soccer/Scripts/SoccerFieldArea.cs | 6 +- .../Examples/Tennis/Scripts/TennisAgent.cs | 8 +- .../Examples/Walker/Scripts/WalkerAgent.cs | 10 +-- .../WallJump/Scripts/WallJumpAgent.cs | 12 +-- com.unity.ml-agents/Runtime/Academy.cs | 16 +++- .../Runtime/EnvironmentParameters.cs | 81 +++++++++++++++++++ .../EnvironmentParametersChannel.cs | 74 +++++++++++++++++ 18 files changed, 248 insertions(+), 60 deletions(-) create mode 100644 com.unity.ml-agents/Runtime/EnvironmentParameters.cs create mode 100644 com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs index 84fa7d2c5b..d11b503e7f 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs @@ -8,12 +8,12 @@ public class Ball3DAgent : Agent [Header("Specific to Ball3D")] public GameObject ball; Rigidbody m_BallRb; - FloatPropertiesChannel m_ResetParams; + EnvironmentParameters m_ResetParams; public override void Initialize() { m_BallRb = ball.GetComponent(); - m_ResetParams = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; SetResetParameters(); } @@ -75,8 +75,8 @@ public override void Heuristic(float[] actionsOut) public void SetBall() { //Set the attributes of the ball by fetching the information from the academy - m_BallRb.mass = m_ResetParams.GetPropertyWithDefault("mass", 1.0f); - var scale = m_ResetParams.GetPropertyWithDefault("scale", 1.0f); + m_BallRb.mass = m_ResetParams.GetParameterWithDefault("mass", 1.0f); + var scale = m_ResetParams.GetParameterWithDefault("scale", 1.0f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs index c9c8b0b512..bfe98bc355 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs @@ -8,12 +8,12 @@ public class Ball3DHardAgent : Agent [Header("Specific to Ball3DHard")] public GameObject ball; Rigidbody m_BallRb; - FloatPropertiesChannel m_ResetParams; + EnvironmentParameters m_ResetParams; public override void Initialize() { m_BallRb = ball.GetComponent(); - m_ResetParams = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; SetResetParameters(); } @@ -66,8 +66,8 @@ public override void OnEpisodeBegin() public void SetBall() { //Set the attributes of the ball by fetching the information from the academy - m_BallRb.mass = m_ResetParams.GetPropertyWithDefault("mass", 1.0f); - var scale = m_ResetParams.GetPropertyWithDefault("scale", 1.0f); + m_BallRb.mass = m_ResetParams.GetParameterWithDefault("mass", 1.0f); + var scale = m_ResetParams.GetParameterWithDefault("scale", 1.0f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs index 6e09fb86dc..2b09f846de 100644 --- a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs @@ -15,14 +15,14 @@ public class BouncerAgent : Agent int m_NumberJumps = 20; int m_JumpLeft = 20; - FloatPropertiesChannel m_ResetParams; + EnvironmentParameters m_ResetParams; public override void Initialize() { m_Rb = gameObject.GetComponent(); m_LookDir = Vector3.zero; - m_ResetParams = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; SetResetParameters(); } @@ -121,7 +121,7 @@ void Update() public void SetTargetScale() { - var targetScale = m_ResetParams.GetPropertyWithDefault("target_scale", 1.0f); + var targetScale = m_ResetParams.GetParameterWithDefault("target_scale", 1.0f); target.transform.localScale = new Vector3(targetScale, targetScale, targetScale); } diff --git a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs index 83f38bbef5..33545fcc51 100644 --- a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs +++ b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs @@ -29,13 +29,14 @@ public class FoodCollectorAgent : Agent public bool contribute; public bool useVectorObs; + EnvironmentParameters m_ResetParams; public override void Initialize() { m_AgentRb = GetComponent(); m_MyArea = area.GetComponent(); m_FoodCollecterSettings = FindObjectOfType(); - + m_ResetParams = Academy.EnvironmentParameters; SetResetParameters(); } @@ -271,12 +272,12 @@ void OnCollisionEnter(Collision collision) public void SetLaserLengths() { - m_LaserLength = SideChannelUtils.GetSideChannel().GetPropertyWithDefault("laser_length", 1.0f); + m_LaserLength = m_ResetParams.GetParameterWithDefault("laser_length", 1.0f); } public void SetAgentScale() { - float agentScale = SideChannelUtils.GetSideChannel().GetPropertyWithDefault("agent_scale", 1.0f); + float agentScale = m_ResetParams.GetParameterWithDefault("agent_scale", 1.0f); gameObject.transform.localScale = new Vector3(agentScale, agentScale, agentScale); } diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs index e2dd63cd1a..a0bac01158 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs @@ -29,6 +29,13 @@ public class GridAgent : Agent const int k_Left = 3; const int k_Right = 4; + EnvironmentParameters m_ResetParams; + + public override void Initialize() + { + m_ResetParams = Academy.EnvironmentParameters; + } + public override void CollectDiscreteActionMasks(DiscreteActionMasker actionMasker) { // Mask the necessary actions if selected by the user. @@ -37,7 +44,7 @@ public override void CollectDiscreteActionMasks(DiscreteActionMasker actionMaske // Prevents the agent from picking an action that would make it collide with a wall var positionX = (int)transform.position.x; var positionZ = (int)transform.position.z; - var maxPosition = (int)SideChannelUtils.GetSideChannel().GetPropertyWithDefault("gridSize", 5f) - 1; + var maxPosition = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f) - 1; if (positionX == 0) { diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs index 126cb00b0d..bba3e6efd5 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs @@ -14,8 +14,6 @@ public class GridArea : MonoBehaviour public GameObject trueAgent; - FloatPropertiesChannel m_ResetParameters; - Camera m_AgentCam; public GameObject goalPref; @@ -30,9 +28,11 @@ public class GridArea : MonoBehaviour Vector3 m_InitialPosition; + EnvironmentParameters m_ResetParams; + public void Start() { - m_ResetParameters = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; m_Objects = new[] { goalPref, pitPref }; @@ -50,23 +50,23 @@ public void Start() m_InitialPosition = transform.position; } - public void SetEnvironment() + private void SetEnvironment() { - transform.position = m_InitialPosition * (m_ResetParameters.GetPropertyWithDefault("gridSize", 5f) + 1); + transform.position = m_InitialPosition * (m_ResetParams.GetParameterWithDefault("gridSize", 5f) + 1); var playersList = new List(); - for (var i = 0; i < (int)m_ResetParameters.GetPropertyWithDefault("numObstacles", 1); i++) + for (var i = 0; i < (int)m_ResetParams.GetParameterWithDefault("numObstacles", 1); i++) { playersList.Add(1); } - for (var i = 0; i < (int)m_ResetParameters.GetPropertyWithDefault("numGoals", 1f); i++) + for (var i = 0; i < (int)m_ResetParams.GetParameterWithDefault("numGoals", 1f); i++) { playersList.Add(0); } players = playersList.ToArray(); - var gridSize = (int)m_ResetParameters.GetPropertyWithDefault("gridSize", 5f); + var gridSize = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f); m_Plane.transform.localScale = new Vector3(gridSize / 10.0f, 1f, gridSize / 10.0f); m_Plane.transform.localPosition = new Vector3((gridSize - 1) / 2f, -0.5f, (gridSize - 1) / 2f); m_Sn.transform.localScale = new Vector3(1, 1, gridSize + 2); @@ -84,7 +84,7 @@ public void SetEnvironment() public void AreaReset() { - var gridSize = (int)m_ResetParameters.GetPropertyWithDefault("gridSize", 5f); + var gridSize = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f); foreach (var actor in actorObjs) { DestroyImmediate(actor); @@ -98,7 +98,7 @@ public void AreaReset() { numbers.Add(Random.Range(0, gridSize * gridSize)); } - var numbersA = Enumerable.ToArray(numbers); + var numbersA = numbers.ToArray(); for (var i = 0; i < players.Length; i++) { diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs index d2ae6f6dda..2b7f869a9a 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs @@ -8,7 +8,7 @@ public class GridSettings : MonoBehaviour public void Awake() { - SideChannelUtils.GetSideChannel().RegisterCallback("gridSize", f => + Academy.EnvironmentParameters.RegisterCallback("gridSize", f => { MainCamera.transform.position = new Vector3(-(f - 1) / 2f, f * 1.25f, -(f - 1) / 2f); MainCamera.orthographicSize = (f + 5f) / 2f; diff --git a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs index 7c14b6dc8a..6c23d20d1f 100644 --- a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs +++ b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs @@ -49,6 +49,8 @@ public class PushAgentBasic : Agent /// Renderer m_GroundRenderer; + private EnvironmentParameters m_ResetParams; + void Awake() { m_PushBlockSettings = FindObjectOfType(); @@ -70,6 +72,8 @@ public override void Initialize() // Starting material m_GroundMaterial = m_GroundRenderer.material; + m_ResetParams = Academy.EnvironmentParameters; + SetResetParameters(); } @@ -226,27 +230,23 @@ public override void OnEpisodeBegin() public void SetGroundMaterialFriction() { - var resetParams = SideChannelUtils.GetSideChannel(); - var groundCollider = ground.GetComponent(); - groundCollider.material.dynamicFriction = resetParams.GetPropertyWithDefault("dynamic_friction", 0); - groundCollider.material.staticFriction = resetParams.GetPropertyWithDefault("static_friction", 0); + groundCollider.material.dynamicFriction = m_ResetParams.GetParameterWithDefault("dynamic_friction", 0); + groundCollider.material.staticFriction = m_ResetParams.GetParameterWithDefault("static_friction", 0); } public void SetBlockProperties() { - var resetParams = SideChannelUtils.GetSideChannel(); - - var scale = resetParams.GetPropertyWithDefault("block_scale", 2); + var scale = m_ResetParams.GetParameterWithDefault("block_scale", 2); //Set the scale of the block m_BlockRb.transform.localScale = new Vector3(scale, 0.75f, scale); // Set the drag of the block - m_BlockRb.drag = resetParams.GetPropertyWithDefault("block_drag", 0.5f); + m_BlockRb.drag = m_ResetParams.GetParameterWithDefault("block_drag", 0.5f); } - public void SetResetParameters() + private void SetResetParameters() { SetGroundMaterialFriction(); SetBlockProperties(); diff --git a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs index 2f67598829..748e13f6b7 100644 --- a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs @@ -21,6 +21,8 @@ public class ReacherAgent : Agent // Frequency of the cosine deviation of the goal along the vertical dimension float m_DeviationFreq; + private EnvironmentParameters m_ResetParams; + /// /// Collect the rigidbodies of the reacher in order to resue them for /// observations and actions. @@ -30,6 +32,8 @@ public override void Initialize() m_RbA = pendulumA.GetComponent(); m_RbB = pendulumB.GetComponent(); + m_ResetParams = Academy.EnvironmentParameters; + SetResetParameters(); } @@ -110,10 +114,9 @@ public override void OnEpisodeBegin() public void SetResetParameters() { - var fp = SideChannelUtils.GetSideChannel(); - m_GoalSize = fp.GetPropertyWithDefault("goal_size", 5); - m_GoalSpeed = Random.Range(-1f, 1f) * fp.GetPropertyWithDefault("goal_speed", 1); - m_Deviation = fp.GetPropertyWithDefault("deviation", 0); - m_DeviationFreq = fp.GetPropertyWithDefault("deviation_freq", 0); + m_GoalSize = m_ResetParams.GetParameterWithDefault("goal_size", 5); + m_GoalSpeed = Random.Range(-1f, 1f) * m_ResetParams.GetParameterWithDefault("goal_speed", 1); + m_Deviation = m_ResetParams.GetParameterWithDefault("deviation", 0); + m_DeviationFreq = m_ResetParams.GetParameterWithDefault("deviation_freq", 0); } } diff --git a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs index 4b1ff4279c..81fd25df42 100644 --- a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs +++ b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs @@ -45,7 +45,7 @@ public void Awake() // Make sure the Academy singleton is initialized first, since it will create the SideChannels. var academy = Academy.Instance; - SideChannelUtils.GetSideChannel().RegisterCallback("gravity", f => { Physics.gravity = new Vector3(0, -f, 0); }); + Academy.EnvironmentParameters.RegisterCallback("gravity", f => { Physics.gravity = new Vector3(0, -f, 0); }); } public void OnDestroy() diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs index e85a8560a3..d560dc1135 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs @@ -49,6 +49,8 @@ public enum Position BehaviorParameters m_BehaviorParameters; Vector3 m_Transform; + private EnvironmentParameters m_ResetParams; + public override void Initialize() { m_Existential = 1f / maxStep; @@ -73,7 +75,7 @@ public override void Initialize() m_LateralSpeed = 0.3f; m_ForwardSpeed = 1.3f; } - else + else { m_LateralSpeed = 0.3f; m_ForwardSpeed = 1.0f; @@ -91,6 +93,8 @@ public override void Initialize() area.playerStates.Add(playerState); m_PlayerIndex = area.playerStates.IndexOf(playerState); playerState.playerIndex = m_PlayerIndex; + + m_ResetParams = Academy.EnvironmentParameters; } public void MoveAgent(float[] act) @@ -214,7 +218,7 @@ public override void OnEpisodeBegin() { timePenalty = 0; - m_BallTouch = SideChannelUtils.GetSideChannel().GetPropertyWithDefault("ball_touch", 0); + m_BallTouch = m_ResetParams.GetParameterWithDefault("ball_touch", 0); if (team == Team.Purple) { transform.rotation = Quaternion.Euler(0f, -90f, 0f); diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs index a435f4eb9f..1644658df8 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs @@ -32,6 +32,8 @@ public class SoccerFieldArea : MonoBehaviour [HideInInspector] public bool canResetBall; + private EnvironmentParameters m_ResetParams; + void Awake() { canResetBall = true; @@ -40,6 +42,8 @@ void Awake() m_BallController = ball.GetComponent(); m_BallController.area = this; ballStartingPos = ball.transform.position; + + m_ResetParams = Academy.EnvironmentParameters; } IEnumerator ShowGoalUI() @@ -76,7 +80,7 @@ public void ResetBall() ballRb.velocity = Vector3.zero; ballRb.angularVelocity = Vector3.zero; - var ballScale = SideChannelUtils.GetSideChannel().GetPropertyWithDefault("ball_scale", 0.015f); + var ballScale = m_ResetParams.GetParameterWithDefault("ball_scale", 0.015f); ballRb.transform.localScale = new Vector3(ballScale, ballScale, ballScale); } } diff --git a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs index 9d99f75c43..4e6542c30a 100644 --- a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs @@ -18,7 +18,7 @@ public class TennisAgent : Agent Rigidbody m_AgentRb; Rigidbody m_BallRb; float m_InvertMult; - FloatPropertiesChannel m_ResetParams; + EnvironmentParameters m_ResetParams; // Looks for the scoreboard based on the name of the gameObjects. // Do not modify the names of the Score GameObjects @@ -32,7 +32,7 @@ public override void Initialize() m_BallRb = ball.GetComponent(); var canvas = GameObject.Find(k_CanvasName); GameObject scoreBoard; - m_ResetParams = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; if (invertX) { scoreBoard = canvas.transform.Find(k_ScoreBoardBName).gameObject; @@ -105,7 +105,7 @@ public override void OnEpisodeBegin() public void SetRacket() { - angle = m_ResetParams.GetPropertyWithDefault("angle", 55); + angle = m_ResetParams.GetParameterWithDefault("angle", 55); gameObject.transform.eulerAngles = new Vector3( gameObject.transform.eulerAngles.x, gameObject.transform.eulerAngles.y, @@ -115,7 +115,7 @@ public void SetRacket() public void SetBall() { - scale = m_ResetParams.GetPropertyWithDefault("scale", .5f); + scale = m_ResetParams.GetParameterWithDefault("scale", .5f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs index 3593dc12ec..ef3856c359 100644 --- a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs @@ -34,7 +34,7 @@ public class WalkerAgent : Agent Rigidbody m_ChestRb; Rigidbody m_SpineRb; - FloatPropertiesChannel m_ResetParams; + EnvironmentParameters m_ResetParams; public override void Initialize() { @@ -60,7 +60,7 @@ public override void Initialize() m_ChestRb = chest.GetComponent(); m_SpineRb = spine.GetComponent(); - m_ResetParams = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; SetResetParameters(); } @@ -179,9 +179,9 @@ public override void OnEpisodeBegin() public void SetTorsoMass() { - m_ChestRb.mass = m_ResetParams.GetPropertyWithDefault("chest_mass", 8); - m_SpineRb.mass = m_ResetParams.GetPropertyWithDefault("spine_mass", 10); - m_HipsRb.mass = m_ResetParams.GetPropertyWithDefault("hip_mass", 15); + m_ChestRb.mass = m_ResetParams.GetParameterWithDefault("chest_mass", 8); + m_SpineRb.mass = m_ResetParams.GetParameterWithDefault("spine_mass", 10); + m_HipsRb.mass = m_ResetParams.GetParameterWithDefault("hip_mass", 15); } public void SetResetParameters() diff --git a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs index db522b6746..122cc95e2f 100644 --- a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs +++ b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs @@ -42,7 +42,7 @@ public class WallJumpAgent : Agent Vector3 m_JumpTargetPos; Vector3 m_JumpStartingPos; - FloatPropertiesChannel m_FloatProperties; + EnvironmentParameters m_ResetParams; public override void Initialize() { @@ -57,7 +57,7 @@ public override void Initialize() spawnArea.SetActive(false); - m_FloatProperties = SideChannelUtils.GetSideChannel(); + m_ResetParams = Academy.EnvironmentParameters; } // Begin the jump sequence @@ -316,7 +316,7 @@ void ConfigureAgent(int config) { localScale = new Vector3( localScale.x, - m_FloatProperties.GetPropertyWithDefault("no_wall_height", 0), + m_ResetParams.GetParameterWithDefault("no_wall_height", 0), localScale.z); wall.transform.localScale = localScale; SetModel("SmallWallJump", noWallBrain); @@ -325,15 +325,15 @@ void ConfigureAgent(int config) { localScale = new Vector3( localScale.x, - m_FloatProperties.GetPropertyWithDefault("small_wall_height", 4), + m_ResetParams.GetParameterWithDefault("small_wall_height", 4), localScale.z); wall.transform.localScale = localScale; SetModel("SmallWallJump", smallWallBrain); } else { - var min = m_FloatProperties.GetPropertyWithDefault("big_wall_min_height", 8); - var max = m_FloatProperties.GetPropertyWithDefault("big_wall_max_height", 8); + var min = m_ResetParams.GetParameterWithDefault("big_wall_min_height", 8); + var max = m_ResetParams.GetParameterWithDefault("big_wall_max_height", 8); var height = min + Random.value * (max - min); localScale = new Vector3( localScale.x, diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index 0d9af5e5a0..c0386c1368 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -290,6 +290,20 @@ static int ReadPortFromArgs() } } + private static EnvironmentParameters s_EnvironmentParameters; + + /// + /// Returns the singleton instance. If training + /// features such as Curriculum Learning or Environment Parameter Randomization are used, + /// then the values of the parameters generated from the training process can be + /// retrieved here. + /// + /// + public static EnvironmentParameters EnvironmentParameters + { + get { return s_EnvironmentParameters; } + } + /// /// Initializes the environment, configures it and initialized the Academy. /// @@ -301,8 +315,8 @@ void InitializeEnvironment() EnableAutomaticStepping(); SideChannelUtils.RegisterSideChannel(new EngineConfigurationChannel()); - SideChannelUtils.RegisterSideChannel(new FloatPropertiesChannel()); SideChannelUtils.RegisterSideChannel(new StatsSideChannel()); + s_EnvironmentParameters = EnvironmentParameters.Instance; // Try to launch the communicator by using the arguments passed at launch var port = ReadPortFromArgs(); diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs new file mode 100644 index 0000000000..5b619075fc --- /dev/null +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using MLAgents.SideChannels; + +namespace MLAgents +{ + /// + /// A singleton container for the Environment Parameters that may be modified during training. + /// The keys for those parameters are defined in the trainer configurations and the + /// the values are generated from the training process in features such as Curriculum Learning + /// and Environment Parameter Randomization. + /// + /// One current assumption for all the environment parameters is that they are of type float. + /// + public sealed class EnvironmentParameters + { + /// + /// The side channel that is used to receive the new parameter values. + /// + readonly EnvironmentParametersChannel m_Channel; + + /// + /// The singleton instance for this class. + /// + private static EnvironmentParameters s_Instance; + + /// + /// Constructor, kept private to make this class a singleton. + /// + private EnvironmentParameters() + { + m_Channel = new EnvironmentParametersChannel(); + SideChannelUtils.RegisterSideChannel(m_Channel); + } + + /// + /// Internal Getter for the singleton instance. Initializes if not already initialized. + /// This method is kept internal to ensure that the initialization is managed by the + /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via + /// . + /// + internal static EnvironmentParameters Instance + { + get { return s_Instance ?? (s_Instance = new EnvironmentParameters()); } + } + + /// + /// Returns the parameter value for the specified key. Returns the default value provided + /// if this parameter key does not have a value. Only returns a parameter value if it is + /// of type float. + /// + /// The parameter key + /// Default value for this parameter. + /// + public float GetParameterWithDefault(string key, float defaultValue) + { + return m_Channel.GetParameterWithDefault(key, defaultValue); + } + + /// + /// Registers a callback action for the provided parameter key. Will overwrite any + /// existing action for that parameter. The callback will be called whenever the parameter + /// receives a value from the training process. + /// + /// The parameter key + /// The callback action + public void RegisterCallback(string key, Action action) + { + m_Channel.RegisterCallback(key, action); + } + + /// + /// Returns a list of all the parameter keys that have received values. + /// + /// List of parameter keys. + public IList ListParameters() + { + return m_Channel.ListParameters(); + } + } +} diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs new file mode 100644 index 0000000000..616da8ade6 --- /dev/null +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System; + +namespace MLAgents.SideChannels +{ + /// + /// A side channel that manages the environment parameter values from Python. Currently + /// limited to parameters of type float. + /// + internal class EnvironmentParametersChannel : SideChannel + { + Dictionary m_Parameters = new Dictionary(); + Dictionary> m_RegisteredActions = + new Dictionary>(); + + const string k_EnvParamsId = "534c891e-810f-11ea-a9d0-822485860400"; + + /// + /// Initializes the side channel. The constructor is internal because only one instance is + /// supported at a time, and is created by the Academy. + /// + internal EnvironmentParametersChannel() + { + ChannelId = new Guid(k_EnvParamsId); + } + + /// + public override void OnMessageReceived(IncomingMessage msg) + { + var key = msg.ReadString(); + var value = msg.ReadFloat32(); + + m_Parameters[key] = value; + + Action action; + m_RegisteredActions.TryGetValue(key, out action); + action?.Invoke(value); + } + + /// + /// Returns the parameter value associated with the provided key. Returns the default + /// value if one doesn't exist. + /// + /// Parameter key. + /// Default value to return. + /// + public float GetParameterWithDefault(string key, float defaultValue) + { + float valueOut; + bool hasKey = m_Parameters.TryGetValue(key, out valueOut); + return hasKey ? valueOut : defaultValue; + } + + /// + /// Registers a callback for the associated parameter key. Will overwrite any existing + /// actions for this parameter key. + /// + /// The parameter key. + /// The callback. + public void RegisterCallback(string key, Action action) + { + m_RegisteredActions[key] = action; + } + + /// + /// Returns all parameter keys that have a registered value. + /// + /// + public IList ListParameters() + { + return new List(m_Parameters.Keys); + } + } +} From ce1525ed0caa2b96312d4646f639c1668dd7878b Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 09:15:36 -0700 Subject: [PATCH 02/23] Minor comment fix to Engine Parameters --- com.unity.ml-agents/Runtime/EnvironmentParameters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index 5b619075fc..f7107bbc1c 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -37,7 +37,7 @@ private EnvironmentParameters() /// Internal Getter for the singleton instance. Initializes if not already initialized. /// This method is kept internal to ensure that the initialization is managed by the /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via - /// . + /// . /// internal static EnvironmentParameters Instance { From 62c868b309991b4465d1fe957ccd1c1e97c8e04e Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 10:34:16 -0700 Subject: [PATCH 03/23] A second minor fix. --- com.unity.ml-agents/Runtime/Academy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index c0386c1368..a6bf0b14d2 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -293,7 +293,7 @@ static int ReadPortFromArgs() private static EnvironmentParameters s_EnvironmentParameters; /// - /// Returns the singleton instance. If training + /// Returns the singleton instance. If training /// features such as Curriculum Learning or Environment Parameter Randomization are used, /// then the values of the parameters generated from the training process can be /// retrieved here. From 53f9850366118502c54526ac40dafb2b80c64c0b Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 10:43:05 -0700 Subject: [PATCH 04/23] Make EngineConfigChannel Internal and add a singleton/sealed accessor --- com.unity.ml-agents/Runtime/Academy.cs | 14 ++- .../Runtime/EngineParameters.cs | 102 ++++++++++++++++++ .../EngineConfigurationChannel.cs | 55 ++++++++-- 3 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 com.unity.ml-agents/Runtime/EngineParameters.cs diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index a6bf0b14d2..e13ee046f8 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -290,8 +290,20 @@ static int ReadPortFromArgs() } } + private static EngineParameters s_EngineParameters; private static EnvironmentParameters s_EnvironmentParameters; + /// + /// Returns the singleton instance. It contains the + /// Engine configurations that were specified at the start of training and that have + /// been applied to the Unity Engine. + /// + /// + public static EngineParameters EngineParameters + { + get { return s_EngineParameters; } + } + /// /// Returns the singleton instance. If training /// features such as Curriculum Learning or Environment Parameter Randomization are used, @@ -314,8 +326,8 @@ void InitializeEnvironment() EnableAutomaticStepping(); - SideChannelUtils.RegisterSideChannel(new EngineConfigurationChannel()); SideChannelUtils.RegisterSideChannel(new StatsSideChannel()); + s_EngineParameters = EngineParameters.Instance; s_EnvironmentParameters = EnvironmentParameters.Instance; // Try to launch the communicator by using the arguments passed at launch diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs b/com.unity.ml-agents/Runtime/EngineParameters.cs new file mode 100644 index 0000000000..aca9958180 --- /dev/null +++ b/com.unity.ml-agents/Runtime/EngineParameters.cs @@ -0,0 +1,102 @@ +using MLAgents.SideChannels; +using UnityEngine; + +namespace MLAgents +{ + /// + /// A singleton container for the Engine Settings that can be specified at the start of + /// training. These Engine settings are set once at the start of training based on the + /// training configuration. The actual Engine settings applied may be slightly different + /// (e.g. TimeScale is clamped). This class enables the retrieval of the final settings. Note + /// that if the Engine settings are directly changed anywhere in your Project, then the values + /// returned here may not be reflective of the actual Engine settings. + /// + public sealed class EngineParameters + { + /// + /// The side channel that is used to receive the engine configurations. + /// + readonly EngineConfigurationChannel m_Channel; + + /// + /// The singleton instance for this class. + /// + private static EngineParameters s_Instance; + + /// + /// Constructor, kept private to make this class a singleton. + /// + private EngineParameters() + { + m_Channel = new EngineConfigurationChannel(); + SideChannelUtils.RegisterSideChannel(m_Channel); + } + + /// + /// Internal Getter for the singleton instance. Initializes if not already initialized. + /// This method is kept internal to ensure that the initialization is managed by the + /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via + /// . + /// + internal static EngineParameters Instance + { + get { return s_Instance ?? (s_Instance = new EngineParameters()); } + } + + /// + /// Returns the Width of the Screen resolution. + /// See . + /// + /// + public int GetScreenWidth() + { + return s_Instance.GetScreenWidth(); + } + + /// + /// Returns the Height of the Screen resolution. + /// See . + /// + /// + public int GetScreenHeight() + { + return s_Instance.GetScreenHeight(); + } + + /// + /// Returns the quality level. See . + /// + /// + public int GetQualityLevel() + { + return s_Instance.GetQualityLevel(); + } + + /// + /// Returns the time scale. See . + /// + /// + public float GetTimeScale() + { + return s_Instance.GetTimeScale(); + } + + /// + /// Returns the target frame rate. See . + /// + /// + public int GetTargetFrameRate() + { + return s_Instance.GetTargetFrameRate(); + } + + /// + /// Returns the capture frame rate. See . + /// + /// + public int GetCaptureFrameRate() + { + return s_Instance.GetCaptureFrameRate(); + } + } +} diff --git a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs index 140010867a..7feb3e4007 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs @@ -6,7 +6,7 @@ namespace MLAgents.SideChannels /// /// Side channel that supports modifying attributes specific to the Unity Engine. /// - public class EngineConfigurationChannel : SideChannel + internal class EngineConfigurationChannel : SideChannel { const string k_EngineConfigId = "e951342c-4f7e-11ea-b238-784f4387d1f7"; @@ -19,22 +19,63 @@ internal EngineConfigurationChannel() ChannelId = new Guid(k_EngineConfigId); } + // internal storage of the configs received from Python + int width; + int height; + int qualityLevel; + float timeScale; + int targetFrameRate; + const int k_CaptureFramerate = 60; + /// public override void OnMessageReceived(IncomingMessage msg) { - var width = msg.ReadInt32(); - var height = msg.ReadInt32(); - var qualityLevel = msg.ReadInt32(); - var timeScale = msg.ReadFloat32(); - var targetFrameRate = msg.ReadInt32(); + width = msg.ReadInt32(); + height = msg.ReadInt32(); + qualityLevel = msg.ReadInt32(); + timeScale = msg.ReadFloat32(); + targetFrameRate = msg.ReadInt32(); timeScale = Mathf.Clamp(timeScale, 1, 100); Screen.SetResolution(width, height, false); QualitySettings.SetQualityLevel(qualityLevel, true); Time.timeScale = timeScale; - Time.captureFramerate = 60; + Time.captureFramerate = k_CaptureFramerate; Application.targetFrameRate = targetFrameRate; } + + // accessors for all the engine configs. For each new config added, we'll need to add + // a new accessor. + + public int GetScreenWidth() + { + return width; + } + + public int GetScreenHeight() + { + return height; + } + + public int GetQualityLevel() + { + return qualityLevel; + } + + public float GetTimeScale() + { + return timeScale; + } + + public int GetTargetFrameRate() + { + return targetFrameRate; + } + + public int GetCaptureFrameRate() + { + return k_CaptureFramerate; + } } } From fc28824e5c3c374c4e72174b9a5cb3bb33a40202 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 14:21:32 -0700 Subject: [PATCH 05/23] Make StatsSideChannel Internal and add a singleton/sealed accessor --- .../Scripts/FoodCollectorSettings.cs | 10 +-- com.unity.ml-agents/Runtime/Academy.cs | 13 ++- .../Runtime/SideChannels/StatsSideChannel.cs | 43 ++-------- com.unity.ml-agents/Runtime/StatsRecorder.cs | 82 +++++++++++++++++++ 4 files changed, 105 insertions(+), 43 deletions(-) create mode 100644 com.unity.ml-agents/Runtime/StatsRecorder.cs diff --git a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs index f4789b003d..03cec5fdbc 100644 --- a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs +++ b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs @@ -1,8 +1,6 @@ -using System; using UnityEngine; using UnityEngine.UI; using MLAgents; -using MLAgents.SideChannels; public class FoodCollectorSettings : MonoBehaviour { @@ -14,15 +12,15 @@ public class FoodCollectorSettings : MonoBehaviour public int totalScore; public Text scoreText; - StatsSideChannel m_statsSideChannel; + StatsRecorder m_Recorder; public void Awake() { Academy.Instance.OnEnvironmentReset += EnvironmentReset; - m_statsSideChannel = SideChannelUtils.GetSideChannel(); + m_Recorder = Academy.StatsRecorder; } - public void EnvironmentReset() + private void EnvironmentReset() { ClearObjects(GameObject.FindGameObjectsWithTag("food")); ClearObjects(GameObject.FindGameObjectsWithTag("badFood")); @@ -54,7 +52,7 @@ public void Update() // need to send every Update() call. if ((Time.frameCount % 100)== 0) { - m_statsSideChannel?.AddStat("TotalScore", totalScore); + m_Recorder.Add("TotalScore", totalScore); } } } diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index e13ee046f8..ca163dbafc 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -292,6 +292,7 @@ static int ReadPortFromArgs() private static EngineParameters s_EngineParameters; private static EnvironmentParameters s_EnvironmentParameters; + private static StatsRecorder s_StatsRecorder; /// /// Returns the singleton instance. It contains the @@ -316,6 +317,16 @@ public static EnvironmentParameters EnvironmentParameters get { return s_EnvironmentParameters; } } + /// + /// Returns the singleton instance. This instance can be used + /// to record any statistics from the Unity environment. + /// + /// + public static StatsRecorder StatsRecorder + { + get { return s_StatsRecorder; } + } + /// /// Initializes the environment, configures it and initialized the Academy. /// @@ -326,9 +337,9 @@ void InitializeEnvironment() EnableAutomaticStepping(); - SideChannelUtils.RegisterSideChannel(new StatsSideChannel()); s_EngineParameters = EngineParameters.Instance; s_EnvironmentParameters = EnvironmentParameters.Instance; + s_StatsRecorder = StatsRecorder.Instance; // Try to launch the communicator by using the arguments passed at launch var port = ReadPortFromArgs(); diff --git a/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs index 52a46499e4..72c1f3fdfd 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs @@ -2,38 +2,15 @@ namespace MLAgents.SideChannels { /// - /// Determines the behavior of how multiple stats within the same summary period are combined. + /// A Side Channel for sending data. /// - public enum StatAggregationMethod - { - /// - /// Values within the summary period are averaged before reporting. - /// Note that values from the same C# environment in the same step may replace each other. - /// - Average = 0, - - /// - /// Only the most recent value is reported. - /// To avoid conflicts between multiple environments, the ML Agents environment will only - /// keep stats from worker index 0. - /// - MostRecent = 1 - } - - /// - /// Add stats (key-value pairs) for reporting. The ML Agents environment will send these to a StatsReporter - /// instance, which means the values will appear in the Tensorboard summary, as well as trainer gauges. - /// Note that stats are only written every summary_frequency steps; See - /// for options on how multiple values are handled. - /// - public class StatsSideChannel : SideChannel + internal class StatsSideChannel : SideChannel { const string k_StatsSideChannelDefaultId = "a1d8f7b7-cec8-50f9-b78b-d3e165a78520"; /// - /// Initializes the side channel with the provided channel ID. - /// The constructor is internal because only one instance is - /// supported at a time, and is created by the Academy. + /// Initializes the side channel. The constructor is internal because only one instance is + /// supported at a time. /// internal StatsSideChannel() { @@ -41,18 +18,12 @@ internal StatsSideChannel() } /// - /// Add a stat value for reporting. This will appear in the Tensorboard summary and trainer gauges. - /// You can nest stats in Tensorboard with "/". - /// Note that stats are only written to Tensorboard each summary_frequency steps; if a stat is - /// received multiple times, only the most recent version is used. - /// To avoid conflicts between multiple environments, only stats from worker index 0 are used. + /// Add a stat value for reporting. /// /// The stat name. - /// The stat value. You can nest stats in Tensorboard by using "/". + /// The stat value. /// How multiple values should be treated. - public void AddStat( - string key, float value, StatAggregationMethod aggregationMethod = StatAggregationMethod.Average - ) + public void AddStat(string key, float value, StatAggregationMethod aggregationMethod) { using (var msg = new OutgoingMessage()) { diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs b/com.unity.ml-agents/Runtime/StatsRecorder.cs new file mode 100644 index 0000000000..55be76a652 --- /dev/null +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs @@ -0,0 +1,82 @@ +using MLAgents.SideChannels; + +namespace MLAgents +{ + /// + /// Determines the behavior of how multiple stats within the same summary period are combined. + /// + public enum StatAggregationMethod + { + /// + /// Values within the summary period are averaged before reporting. + /// Note that values from the same C# environment in the same step may replace each other. + /// + Average = 0, + + /// + /// Only the most recent value is reported. + /// To avoid conflicts when training with multiple concurrent environments, only + /// stats from worker index 0 will be tracked. + /// + MostRecent = 1 + } + + /// + /// Add stats (key-value pairs) for reporting. These values will sent these to a StatsReporter + /// instance, which means the values will appear in the TensorBoard summary, as well as trainer + /// gauges. You can nest stats in TensorBoard by adding "/" in the name (e.g. "Agent/Health" + /// and "Agent/Wallet"). Note that stats are only written to TensorBoard each summary_frequency + /// steps (a trainer configuration). If a stat is received multiple times, within that period + /// then the values will be aggregated using the provided. + /// + public sealed class StatsRecorder + { + /// + /// The side channel that is used to receive the new parameter values. + /// + readonly StatsSideChannel m_Channel; + + /// + /// The singleton instance for this class. + /// + private static StatsRecorder s_Instance; + + /// + /// Constructor, kept private to make this class a singleton. + /// + private StatsRecorder() + { + m_Channel = new StatsSideChannel(); + SideChannelUtils.RegisterSideChannel(m_Channel); + } + + /// + /// Internal Getter for the singleton instance. Initializes if not already initialized. + /// This method is kept internal to ensure that the initialization is managed by the + /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via + /// . + /// + internal static StatsRecorder Instance + { + get { return s_Instance ?? (s_Instance = new StatsRecorder()); } + } + + /// + /// Add a stat value for reporting. + /// + /// The stat name. + /// + /// The stat value. You can nest stats in TensorBoard by using "/". + /// + /// + /// How multiple values sent in the same summary window should be treated. + /// + public void Add( + string key, + float value, + StatAggregationMethod aggregationMethod = StatAggregationMethod.Average) + { + m_Channel.AddStat(key, value, aggregationMethod); + } + } +} From 12e88f9f805e042e7029bef3375f558d8431034b Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 15:34:13 -0700 Subject: [PATCH 06/23] Changes to SideChannelUtils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Disallow two sidechannels of the same type to be added - Remove GetSideChannels that return a list as that is now unnecessary - Make most methods except (register/unregister) internal to limit users impacting the “system-level” side channels - Add an improved comment to SideChannel.cs --- .../Runtime/SideChannels/SideChannel.cs | 7 ++ .../Runtime/SideChannels/SideChannelUtils.cs | 68 +++++++++---------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs index 0637a0c01b..ebe12c518a 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs @@ -7,6 +7,13 @@ namespace MLAgents.SideChannels /// Side channels provide an alternative mechanism of sending/receiving data from Unity /// to Python that is outside of the traditional machine learning loop. ML-Agents provides /// some specific implementations of side channels, but users can create their own. + /// + /// To create your own, you'll need to create two, new mirrored classes, one in Unity (by + /// extending ) and another in Python by extending a Python class + /// also called SideChannel. Then, within your project, use + /// and + /// to register and unregister your + /// custom side channel. /// public abstract class SideChannel { diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs index 5e8e569bf3..ee13d4ff2a 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs @@ -7,7 +7,6 @@ namespace MLAgents.SideChannels { public static class SideChannelUtils { - private static Dictionary RegisteredChannels = new Dictionary(); private struct CachedSideChannelMessage @@ -16,26 +15,41 @@ private struct CachedSideChannelMessage public byte[] Message; } - private static Queue m_CachedMessages = new Queue(); + private static readonly Queue m_CachedMessages = + new Queue(); /// - /// Registers a side channel to the communicator. The side channel will exchange - /// messages with its Python equivalent. + /// Register a side channel to begin sending and receiving messages. This method is + /// available for environments that have custom side channels. All built-in side + /// channels within the ML-Agents Toolkit are managed internally and do not need to + /// be explicitly registered/unregistered. A side channel may only be registered once. + /// Additionally, only one side channel of each type is allowed. /// - /// The side channel to be registered. + /// The side channel to register. public static void RegisterSideChannel(SideChannel sideChannel) { var channelId = sideChannel.ChannelId; + Debug.Log($"adding {channelId}"); if (RegisteredChannels.ContainsKey(channelId)) { - throw new UnityAgentsException(string.Format( - "A side channel with type index {0} is already registered. You cannot register multiple " + - "side channels of the same id.", channelId)); + throw new UnityAgentsException( + $"A side channel with id {channelId} is already registered. " + + "You cannot register multiple side channels of the same id."); + } + + foreach (var sc in RegisteredChannels.Values) + { + if (sc.GetType() == sideChannel.GetType()) + { + throw new UnityAgentsException( + $"A side channel with type {sc.GetType()} is already registered. " + + "You cannot register multiple side channels of the same type."); + } } // Process any messages that we've already received for this channel ID. var numMessages = m_CachedMessages.Count; - for (int i = 0; i < numMessages; i++) + for (var i = 0; i < numMessages; i++) { var cachedMessage = m_CachedMessages.Dequeue(); if (channelId == cachedMessage.ChannelId) @@ -54,9 +68,16 @@ public static void RegisterSideChannel(SideChannel sideChannel) } /// - /// Unregisters a side channel from the communicator. + /// Unregister a side channel to stop sending and receiving messages. This method is + /// available for environments that have custom side channels. All built-in side + /// channels within the ML-Agents Toolkit are managed internally and do not need to + /// be explicitly registered/unregistered. A side channel may only be unregistered + /// multiple times. Note that unregistering a side channel may not stop the Python side + /// from sending them, but it does mean that sent messages with not result in a call + /// to . Furthermore, + /// those messages will not be buffered and will, in essence, be lost. /// - /// The side channel to be unregistered. + /// The side channel to unregister. public static void UnregisterSideChannel(SideChannel sideChannel) { if (RegisteredChannels.ContainsKey(sideChannel.ChannelId)) @@ -68,7 +89,7 @@ public static void UnregisterSideChannel(SideChannel sideChannel) /// /// Unregisters all the side channels from the communicator. /// - public static void UnregisterAllSideChannels() + internal static void UnregisterAllSideChannels() { RegisteredChannels = new Dictionary(); } @@ -79,7 +100,7 @@ public static void UnregisterAllSideChannels() /// /// /// - public static T GetSideChannel() where T: SideChannel + internal static T GetSideChannel() where T: SideChannel { foreach (var sc in RegisteredChannels.Values) { @@ -91,26 +112,6 @@ public static T GetSideChannel() where T: SideChannel return null; } - /// - /// Returns all SideChannels of Type T that are registered. Use if possible, - /// as that does not make any memory allocations. - /// - /// - /// - public static List GetSideChannels() where T: SideChannel - { - var output = new List(); - - foreach (var sc in RegisteredChannels.Values) - { - if (sc.GetType() == typeof(T)) - { - output.Add((T) sc); - } - } - return output; - } - /// /// Grabs the messages that the registered side channels will send to Python at the current step /// into a singe byte array. @@ -229,6 +230,5 @@ internal static void ProcessSideChannelData(Dictionary sideCh } } } - } } From cbe21ad59c20df0071c23a091acea7092df694fa Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 15:59:44 -0700 Subject: [PATCH 07/23] Added Dispose methods to system-level sidechannel wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Specifically to StatsRecorder, EnvironmentParameters and EngineParameters. - Updated Academy.Dispose to take advantage of these. - Updated Editor tests to cover all three “system-level” side channels. Kudos to Unit Tests (TestAcademy / TestAcademyDispose) for catching these. --- com.unity.ml-agents/Runtime/Academy.cs | 6 +++++- com.unity.ml-agents/Runtime/EngineParameters.cs | 6 ++++++ .../Runtime/EnvironmentParameters.cs | 6 ++++++ com.unity.ml-agents/Runtime/StatsRecorder.cs | 6 ++++++ .../Tests/Editor/MLAgentsEditModeTest.cs | 16 ++++++++++++---- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index ca163dbafc..a995a6627a 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -545,7 +545,11 @@ public void Dispose() Communicator?.Dispose(); Communicator = null; - SideChannelUtils.UnregisterAllSideChannels(); + + EngineParameters.Dispose(); + EnvironmentParameters.Dispose(); + StatsRecorder.Dispose(); + SideChannelUtils.UnregisterAllSideChannels(); // unregister custom side channels if (m_ModelRunners != null) { diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs b/com.unity.ml-agents/Runtime/EngineParameters.cs index aca9958180..c2d289fa67 100644 --- a/com.unity.ml-agents/Runtime/EngineParameters.cs +++ b/com.unity.ml-agents/Runtime/EngineParameters.cs @@ -98,5 +98,11 @@ public int GetCaptureFrameRate() { return s_Instance.GetCaptureFrameRate(); } + + internal void Dispose() + { + SideChannelUtils.UnregisterSideChannel(m_Channel); + s_Instance = null; + } } } diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index f7107bbc1c..5c2a89ef01 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -77,5 +77,11 @@ public IList ListParameters() { return m_Channel.ListParameters(); } + + internal void Dispose() + { + SideChannelUtils.UnregisterSideChannel(m_Channel); + s_Instance = null; + } } } diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs b/com.unity.ml-agents/Runtime/StatsRecorder.cs index 55be76a652..9a65c30a64 100644 --- a/com.unity.ml-agents/Runtime/StatsRecorder.cs +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs @@ -78,5 +78,11 @@ public void Add( { m_Channel.AddStat(key, value, aggregationMethod); } + + internal void Dispose() + { + SideChannelUtils.UnregisterSideChannel(m_Channel); + s_Instance = null; + } } } diff --git a/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs b/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs index a439b48bf5..21db2ce7b8 100644 --- a/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs +++ b/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs @@ -208,7 +208,9 @@ public void TestAcademy() Assert.AreEqual(0, aca.EpisodeCount); Assert.AreEqual(0, aca.StepCount); Assert.AreEqual(0, aca.TotalStepCount); - Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); // Check that Dispose is idempotent aca.Dispose(); @@ -219,14 +221,20 @@ public void TestAcademy() [Test] public void TestAcademyDispose() { - var floatProperties1 = SideChannelUtils.GetSideChannel(); + var envParams1 = SideChannelUtils.GetSideChannel(); + var engineParams1 = SideChannelUtils.GetSideChannel(); + var statsParams1 = SideChannelUtils.GetSideChannel(); Academy.Instance.Dispose(); Academy.Instance.LazyInitialize(); - var floatProperties2 = SideChannelUtils.GetSideChannel(); + var envParams2 = SideChannelUtils.GetSideChannel(); + var engineParams2 = SideChannelUtils.GetSideChannel(); + var statsParams2 = SideChannelUtils.GetSideChannel(); Academy.Instance.Dispose(); - Assert.AreNotEqual(floatProperties1, floatProperties2); + Assert.AreNotEqual(envParams1, envParams2); + Assert.AreNotEqual(engineParams1, engineParams2); + Assert.AreNotEqual(statsParams1, statsParams2); } [Test] From 194cea4e3d4d7eaea10cb8cfb93edf5ef2dd939a Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Sun, 19 Apr 2020 16:00:38 -0700 Subject: [PATCH 08/23] Removed debub log. --- com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs index ee13d4ff2a..d6a23e884b 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs @@ -29,7 +29,6 @@ private struct CachedSideChannelMessage public static void RegisterSideChannel(SideChannel sideChannel) { var channelId = sideChannel.ChannelId; - Debug.Log($"adding {channelId}"); if (RegisteredChannels.ContainsKey(channelId)) { throw new UnityAgentsException( From f81e835cd314cb14cbc489feb75e430606e0419c Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 08:07:27 -0700 Subject: [PATCH 09/23] Back-up commit. --- .../EnvironmentParametersChannel.cs | 26 ++++++-- .../environment_parameters_channel.py | 65 +++++++++++++++++++ .../mlagents/trainers/simple_env_manager.py | 6 +- .../trainers/subprocess_env_manager.py | 8 +-- 4 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs index 616da8ade6..33576e459b 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -3,6 +3,14 @@ namespace MLAgents.SideChannels { + /// + /// Lists the different data types supported. + /// + internal enum EnvironmentDataTypes + { + Float = 0 + } + /// /// A side channel that manages the environment parameter values from Python. Currently /// limited to parameters of type float. @@ -28,13 +36,21 @@ internal EnvironmentParametersChannel() public override void OnMessageReceived(IncomingMessage msg) { var key = msg.ReadString(); - var value = msg.ReadFloat32(); + var type = msg.ReadInt32(); + if ((int)EnvironmentDataTypes.Float == type) + { + var value = msg.ReadFloat32(); - m_Parameters[key] = value; + m_Parameters[key] = value; - Action action; - m_RegisteredActions.TryGetValue(key, out action); - action?.Invoke(value); + Action action; + m_RegisteredActions.TryGetValue(key, out action); + action?.Invoke(value); + } + else + { + throw new UnityAgentsException("EnvironmentParametersChannel only supports floats."); + } } /// diff --git a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py new file mode 100644 index 0000000000..49ededd8c4 --- /dev/null +++ b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py @@ -0,0 +1,65 @@ +from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage +import uuid +from typing import Dict, Optional, List + + +class EnvironmentParametersChannel(SideChannel): + """ + This is the SideChannel for float properties shared with Unity. + You can modify the float properties of an environment with the commands + set_property, get_property and list_properties. + """ + + def __init__(self, channel_id: uuid.UUID = None) -> None: + self._float_properties: Dict[str, float] = {} + if channel_id is None: + channel_id = uuid.UUID(("534c891e-810f-11ea-a9d0-822485860400")) + super().__init__(channel_id) + + def on_message_received(self, msg: IncomingMessage) -> None: + """ + Is called by the environment to the side channel. Can be called + multiple times per step if multiple messages are meant for that + SideChannel. + Note that Python should never receive an environment parameters from + Unity + """ + raise UnityCommunicationException( + "The EnvironmentParametersChannel received a message from Unity, " + + "this should not have happend." + ) + + def set_float_property(self, key: str, value: float) -> None: + """ + Sets a property in the Unity Environment. + :param key: The string identifier of the property. + :param value: The float value of the property. + """ + self._float_properties[key] = value + msg = OutgoingMessage() + msg.write_string(key) + msg.write_float32(value) + super().queue_message_to_send(msg) + + def get_float_property(self, key: str) -> Optional[float]: + """ + Gets a property in the Unity Environment. If the property was not + found, will return None. + :param key: The string identifier of the property. + :return: The float value of the property or None. + """ + return self._float_properties.get(key) + + def list_properties(self) -> List[str]: + """ + Returns a list of all the string identifiers of the properties + currently present in the Unity Environment. + """ + return list(self._float_properties.keys()) + + def get_property_dict_copy(self) -> Dict[str, float]: + """ + Returns a copy of the float properties. + :return: + """ + return dict(self._float_properties) diff --git a/ml-agents/mlagents/trainers/simple_env_manager.py b/ml-agents/mlagents/trainers/simple_env_manager.py index e3ea815553..a05bf4276d 100644 --- a/ml-agents/mlagents/trainers/simple_env_manager.py +++ b/ml-agents/mlagents/trainers/simple_env_manager.py @@ -5,7 +5,7 @@ from mlagents_envs.timers import timed from mlagents.trainers.action_info import ActionInfo from mlagents.trainers.brain import BrainParameters -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel +from mlagents_envs.side_channel.environment_parameters_channel import EnvironmentParameters from mlagents.trainers.brain_conversion_utils import behavior_spec_to_brain_parameters @@ -15,9 +15,9 @@ class SimpleEnvManager(EnvManager): This is generally only useful for testing; see SubprocessEnvManager for a production-quality implementation. """ - def __init__(self, env: BaseEnv, float_prop_channel: FloatPropertiesChannel): + def __init__(self, env: BaseEnv, environment_parameters_channel: EnvironmentParameters): super().__init__() - self.shared_float_properties = float_prop_channel + self.environment_parameters_channel = environment_parameters_channel self.env = env self.previous_step: EnvironmentStep = EnvironmentStep.empty(0) self.previous_all_action_info: Dict[str, ActionInfo] = {} diff --git a/ml-agents/mlagents/trainers/subprocess_env_manager.py b/ml-agents/mlagents/trainers/subprocess_env_manager.py index dbb042ae36..2d410c554a 100644 --- a/ml-agents/mlagents/trainers/subprocess_env_manager.py +++ b/ml-agents/mlagents/trainers/subprocess_env_manager.py @@ -113,7 +113,7 @@ def worker( env_factory: Callable[ [int, List[SideChannel]], UnityEnvironment ] = cloudpickle.loads(pickled_env_factory) - shared_float_properties = FloatPropertiesChannel() + environment_parameters_channel = EnvironmentParametersChannel() engine_configuration_channel = EngineConfigurationChannel() engine_configuration_channel.set_configuration(engine_configuration) stats_channel = StatsSideChannel() @@ -139,7 +139,7 @@ def external_brains(): try: env = env_factory( worker_id, - [shared_float_properties, engine_configuration_channel, stats_channel], + [environment_parameters_channel, engine_configuration_channel, stats_channel], ) while True: req: EnvironmentRequest = parent_conn.recv() @@ -168,11 +168,9 @@ def external_brains(): elif req.cmd == EnvironmentCommand.EXTERNAL_BRAINS: _send_response(EnvironmentCommand.EXTERNAL_BRAINS, external_brains()) elif req.cmd == EnvironmentCommand.GET_PROPERTIES: - reset_params = shared_float_properties.get_property_dict_copy() + reset_params = environment_parameters_channel.get_property_dict_copy() _send_response(EnvironmentCommand.GET_PROPERTIES, reset_params) elif req.cmd == EnvironmentCommand.RESET: - for k, v in req.payload.items(): - shared_float_properties.set_property(k, v) env.reset() all_step_result = _generate_all_results() _send_response(EnvironmentCommand.RESET, all_step_result) From 26bad992abe26a60e5644c10a15e1a6322fcf8be Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 18:30:20 -0700 Subject: [PATCH 10/23] Revert "Back-up commit." This reverts commit f81e835cd314cb14cbc489feb75e430606e0419c. --- .../EnvironmentParametersChannel.cs | 26 ++------ .../environment_parameters_channel.py | 65 ------------------- .../mlagents/trainers/simple_env_manager.py | 6 +- .../trainers/subprocess_env_manager.py | 8 ++- 4 files changed, 13 insertions(+), 92 deletions(-) delete mode 100644 ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs index 33576e459b..616da8ade6 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -3,14 +3,6 @@ namespace MLAgents.SideChannels { - /// - /// Lists the different data types supported. - /// - internal enum EnvironmentDataTypes - { - Float = 0 - } - /// /// A side channel that manages the environment parameter values from Python. Currently /// limited to parameters of type float. @@ -36,21 +28,13 @@ internal EnvironmentParametersChannel() public override void OnMessageReceived(IncomingMessage msg) { var key = msg.ReadString(); - var type = msg.ReadInt32(); - if ((int)EnvironmentDataTypes.Float == type) - { - var value = msg.ReadFloat32(); + var value = msg.ReadFloat32(); - m_Parameters[key] = value; + m_Parameters[key] = value; - Action action; - m_RegisteredActions.TryGetValue(key, out action); - action?.Invoke(value); - } - else - { - throw new UnityAgentsException("EnvironmentParametersChannel only supports floats."); - } + Action action; + m_RegisteredActions.TryGetValue(key, out action); + action?.Invoke(value); } /// diff --git a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py deleted file mode 100644 index 49ededd8c4..0000000000 --- a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py +++ /dev/null @@ -1,65 +0,0 @@ -from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage -import uuid -from typing import Dict, Optional, List - - -class EnvironmentParametersChannel(SideChannel): - """ - This is the SideChannel for float properties shared with Unity. - You can modify the float properties of an environment with the commands - set_property, get_property and list_properties. - """ - - def __init__(self, channel_id: uuid.UUID = None) -> None: - self._float_properties: Dict[str, float] = {} - if channel_id is None: - channel_id = uuid.UUID(("534c891e-810f-11ea-a9d0-822485860400")) - super().__init__(channel_id) - - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Is called by the environment to the side channel. Can be called - multiple times per step if multiple messages are meant for that - SideChannel. - Note that Python should never receive an environment parameters from - Unity - """ - raise UnityCommunicationException( - "The EnvironmentParametersChannel received a message from Unity, " - + "this should not have happend." - ) - - def set_float_property(self, key: str, value: float) -> None: - """ - Sets a property in the Unity Environment. - :param key: The string identifier of the property. - :param value: The float value of the property. - """ - self._float_properties[key] = value - msg = OutgoingMessage() - msg.write_string(key) - msg.write_float32(value) - super().queue_message_to_send(msg) - - def get_float_property(self, key: str) -> Optional[float]: - """ - Gets a property in the Unity Environment. If the property was not - found, will return None. - :param key: The string identifier of the property. - :return: The float value of the property or None. - """ - return self._float_properties.get(key) - - def list_properties(self) -> List[str]: - """ - Returns a list of all the string identifiers of the properties - currently present in the Unity Environment. - """ - return list(self._float_properties.keys()) - - def get_property_dict_copy(self) -> Dict[str, float]: - """ - Returns a copy of the float properties. - :return: - """ - return dict(self._float_properties) diff --git a/ml-agents/mlagents/trainers/simple_env_manager.py b/ml-agents/mlagents/trainers/simple_env_manager.py index a05bf4276d..e3ea815553 100644 --- a/ml-agents/mlagents/trainers/simple_env_manager.py +++ b/ml-agents/mlagents/trainers/simple_env_manager.py @@ -5,7 +5,7 @@ from mlagents_envs.timers import timed from mlagents.trainers.action_info import ActionInfo from mlagents.trainers.brain import BrainParameters -from mlagents_envs.side_channel.environment_parameters_channel import EnvironmentParameters +from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel from mlagents.trainers.brain_conversion_utils import behavior_spec_to_brain_parameters @@ -15,9 +15,9 @@ class SimpleEnvManager(EnvManager): This is generally only useful for testing; see SubprocessEnvManager for a production-quality implementation. """ - def __init__(self, env: BaseEnv, environment_parameters_channel: EnvironmentParameters): + def __init__(self, env: BaseEnv, float_prop_channel: FloatPropertiesChannel): super().__init__() - self.environment_parameters_channel = environment_parameters_channel + self.shared_float_properties = float_prop_channel self.env = env self.previous_step: EnvironmentStep = EnvironmentStep.empty(0) self.previous_all_action_info: Dict[str, ActionInfo] = {} diff --git a/ml-agents/mlagents/trainers/subprocess_env_manager.py b/ml-agents/mlagents/trainers/subprocess_env_manager.py index 2d410c554a..dbb042ae36 100644 --- a/ml-agents/mlagents/trainers/subprocess_env_manager.py +++ b/ml-agents/mlagents/trainers/subprocess_env_manager.py @@ -113,7 +113,7 @@ def worker( env_factory: Callable[ [int, List[SideChannel]], UnityEnvironment ] = cloudpickle.loads(pickled_env_factory) - environment_parameters_channel = EnvironmentParametersChannel() + shared_float_properties = FloatPropertiesChannel() engine_configuration_channel = EngineConfigurationChannel() engine_configuration_channel.set_configuration(engine_configuration) stats_channel = StatsSideChannel() @@ -139,7 +139,7 @@ def external_brains(): try: env = env_factory( worker_id, - [environment_parameters_channel, engine_configuration_channel, stats_channel], + [shared_float_properties, engine_configuration_channel, stats_channel], ) while True: req: EnvironmentRequest = parent_conn.recv() @@ -168,9 +168,11 @@ def external_brains(): elif req.cmd == EnvironmentCommand.EXTERNAL_BRAINS: _send_response(EnvironmentCommand.EXTERNAL_BRAINS, external_brains()) elif req.cmd == EnvironmentCommand.GET_PROPERTIES: - reset_params = environment_parameters_channel.get_property_dict_copy() + reset_params = shared_float_properties.get_property_dict_copy() _send_response(EnvironmentCommand.GET_PROPERTIES, reset_params) elif req.cmd == EnvironmentCommand.RESET: + for k, v in req.payload.items(): + shared_float_properties.set_property(k, v) env.reset() all_step_result = _generate_all_results() _send_response(EnvironmentCommand.RESET, all_step_result) From c1b7bc50c5c787a4df46f766c0ec4f816c068ea1 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 18:48:53 -0700 Subject: [PATCH 11/23] key changes to wrapper classes made the wrapper classes non-singleton (but internal constructors) made EngineParameters internal --- .../Examples/3DBall/Scripts/Ball3DAgent.cs | 2 +- .../3DBall/Scripts/Ball3DHardAgent.cs | 2 +- .../Examples/Bouncer/Scripts/BouncerAgent.cs | 2 +- .../Scripts/FoodCollectorAgent.cs | 2 +- .../Examples/GridWorld/Scripts/GridAgent.cs | 2 +- .../Examples/GridWorld/Scripts/GridArea.cs | 2 +- .../GridWorld/Scripts/GridSettings.cs | 2 +- .../PushBlock/Scripts/PushAgentBasic.cs | 2 +- .../Examples/Reacher/Scripts/ReacherAgent.cs | 2 +- .../Scripts/ProjectSettingsOverrides.cs | 2 +- .../Examples/Soccer/Scripts/AgentSoccer.cs | 2 +- .../Soccer/Scripts/SoccerFieldArea.cs | 2 +- .../Examples/Tennis/Scripts/TennisAgent.cs | 2 +- .../Examples/Walker/Scripts/WalkerAgent.cs | 2 +- .../WallJump/Scripts/WallJumpAgent.cs | 2 +- com.unity.ml-agents/Runtime/Academy.cs | 33 +++----- .../Runtime/EngineParameters.cs | 81 +------------------ .../Runtime/EnvironmentParameters.cs | 23 +----- com.unity.ml-agents/Runtime/StatsRecorder.cs | 21 +---- 19 files changed, 35 insertions(+), 153 deletions(-) diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs index d11b503e7f..f5f603b165 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs @@ -13,7 +13,7 @@ public class Ball3DAgent : Agent public override void Initialize() { m_BallRb = ball.GetComponent(); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs index bfe98bc355..dbc7e1b027 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs @@ -13,7 +13,7 @@ public class Ball3DHardAgent : Agent public override void Initialize() { m_BallRb = ball.GetComponent(); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs index 2b09f846de..157eba8ab6 100644 --- a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs @@ -22,7 +22,7 @@ public override void Initialize() m_Rb = gameObject.GetComponent(); m_LookDir = Vector3.zero; - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs index 33545fcc51..04d68fcc53 100644 --- a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs +++ b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs @@ -36,7 +36,7 @@ public override void Initialize() m_AgentRb = GetComponent(); m_MyArea = area.GetComponent(); m_FoodCollecterSettings = FindObjectOfType(); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs index a0bac01158..2343dbd678 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs @@ -33,7 +33,7 @@ public class GridAgent : Agent public override void Initialize() { - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; } public override void CollectDiscreteActionMasks(DiscreteActionMasker actionMasker) diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs index bba3e6efd5..adb3e3338b 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs @@ -32,7 +32,7 @@ public class GridArea : MonoBehaviour public void Start() { - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; m_Objects = new[] { goalPref, pitPref }; diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs index 2b7f869a9a..2baee93b3a 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs @@ -8,7 +8,7 @@ public class GridSettings : MonoBehaviour public void Awake() { - Academy.EnvironmentParameters.RegisterCallback("gridSize", f => + Academy.Instance.EnvironmentParameters.RegisterCallback("gridSize", f => { MainCamera.transform.position = new Vector3(-(f - 1) / 2f, f * 1.25f, -(f - 1) / 2f); MainCamera.orthographicSize = (f + 5f) / 2f; diff --git a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs index 6c23d20d1f..62968a5630 100644 --- a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs +++ b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs @@ -72,7 +72,7 @@ public override void Initialize() // Starting material m_GroundMaterial = m_GroundRenderer.material; - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs index 748e13f6b7..6a8e001070 100644 --- a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs @@ -32,7 +32,7 @@ public override void Initialize() m_RbA = pendulumA.GetComponent(); m_RbB = pendulumB.GetComponent(); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs index 81fd25df42..9c26041443 100644 --- a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs +++ b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs @@ -45,7 +45,7 @@ public void Awake() // Make sure the Academy singleton is initialized first, since it will create the SideChannels. var academy = Academy.Instance; - Academy.EnvironmentParameters.RegisterCallback("gravity", f => { Physics.gravity = new Vector3(0, -f, 0); }); + Academy.Instance.EnvironmentParameters.RegisterCallback("gravity", f => { Physics.gravity = new Vector3(0, -f, 0); }); } public void OnDestroy() diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs index d560dc1135..419667b6e1 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs @@ -94,7 +94,7 @@ public override void Initialize() m_PlayerIndex = area.playerStates.IndexOf(playerState); playerState.playerIndex = m_PlayerIndex; - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; } public void MoveAgent(float[] act) diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs index 1644658df8..c6261ce8e0 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs @@ -43,7 +43,7 @@ void Awake() m_BallController.area = this; ballStartingPos = ball.transform.position; - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; } IEnumerator ShowGoalUI() diff --git a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs index 4e6542c30a..9202cb72f3 100644 --- a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs @@ -32,7 +32,7 @@ public override void Initialize() m_BallRb = ball.GetComponent(); var canvas = GameObject.Find(k_CanvasName); GameObject scoreBoard; - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; if (invertX) { scoreBoard = canvas.transform.Find(k_ScoreBoardBName).gameObject; diff --git a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs index ef3856c359..dd32576d78 100644 --- a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs @@ -60,7 +60,7 @@ public override void Initialize() m_ChestRb = chest.GetComponent(); m_SpineRb = spine.GetComponent(); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; SetResetParameters(); } diff --git a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs index 122cc95e2f..dde2547838 100644 --- a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs +++ b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs @@ -57,7 +57,7 @@ public override void Initialize() spawnArea.SetActive(false); - m_ResetParams = Academy.EnvironmentParameters; + m_ResetParams = Academy.Instance.EnvironmentParameters; } // Begin the jump sequence diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index a995a6627a..34ab28ff88 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -290,20 +290,9 @@ static int ReadPortFromArgs() } } - private static EngineParameters s_EngineParameters; - private static EnvironmentParameters s_EnvironmentParameters; - private static StatsRecorder s_StatsRecorder; - - /// - /// Returns the singleton instance. It contains the - /// Engine configurations that were specified at the start of training and that have - /// been applied to the Unity Engine. - /// - /// - public static EngineParameters EngineParameters - { - get { return s_EngineParameters; } - } + private EngineParameters s_EngineParameters; + private EnvironmentParameters s_EnvironmentParameters; + private StatsRecorder s_StatsRecorder; /// /// Returns the singleton instance. If training @@ -312,7 +301,7 @@ public static EngineParameters EngineParameters /// retrieved here. /// /// - public static EnvironmentParameters EnvironmentParameters + public EnvironmentParameters EnvironmentParameters { get { return s_EnvironmentParameters; } } @@ -322,7 +311,7 @@ public static EnvironmentParameters EnvironmentParameters /// to record any statistics from the Unity environment. /// /// - public static StatsRecorder StatsRecorder + public StatsRecorder StatsRecorder { get { return s_StatsRecorder; } } @@ -337,9 +326,9 @@ void InitializeEnvironment() EnableAutomaticStepping(); - s_EngineParameters = EngineParameters.Instance; - s_EnvironmentParameters = EnvironmentParameters.Instance; - s_StatsRecorder = StatsRecorder.Instance; + s_EngineParameters = new EngineParameters(); + s_EnvironmentParameters = new EnvironmentParameters(); + s_StatsRecorder = new StatsRecorder(); // Try to launch the communicator by using the arguments passed at launch var port = ReadPortFromArgs(); @@ -546,9 +535,9 @@ public void Dispose() Communicator?.Dispose(); Communicator = null; - EngineParameters.Dispose(); - EnvironmentParameters.Dispose(); - StatsRecorder.Dispose(); + s_EngineParameters.Dispose(); + s_EnvironmentParameters.Dispose(); + s_StatsRecorder.Dispose(); SideChannelUtils.UnregisterAllSideChannels(); // unregister custom side channels if (m_ModelRunners != null) diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs b/com.unity.ml-agents/Runtime/EngineParameters.cs index c2d289fa67..75b9ff63a1 100644 --- a/com.unity.ml-agents/Runtime/EngineParameters.cs +++ b/com.unity.ml-agents/Runtime/EngineParameters.cs @@ -4,14 +4,14 @@ namespace MLAgents { /// - /// A singleton container for the Engine Settings that can be specified at the start of + /// A container for the Engine Settings that can be specified at the start of /// training. These Engine settings are set once at the start of training based on the /// training configuration. The actual Engine settings applied may be slightly different /// (e.g. TimeScale is clamped). This class enables the retrieval of the final settings. Note /// that if the Engine settings are directly changed anywhere in your Project, then the values /// returned here may not be reflective of the actual Engine settings. /// - public sealed class EngineParameters + internal sealed class EngineParameters { /// /// The side channel that is used to receive the engine configurations. @@ -19,90 +19,17 @@ public sealed class EngineParameters readonly EngineConfigurationChannel m_Channel; /// - /// The singleton instance for this class. + /// Constructor. /// - private static EngineParameters s_Instance; - - /// - /// Constructor, kept private to make this class a singleton. - /// - private EngineParameters() + public EngineParameters() { m_Channel = new EngineConfigurationChannel(); SideChannelUtils.RegisterSideChannel(m_Channel); } - /// - /// Internal Getter for the singleton instance. Initializes if not already initialized. - /// This method is kept internal to ensure that the initialization is managed by the - /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via - /// . - /// - internal static EngineParameters Instance - { - get { return s_Instance ?? (s_Instance = new EngineParameters()); } - } - - /// - /// Returns the Width of the Screen resolution. - /// See . - /// - /// - public int GetScreenWidth() - { - return s_Instance.GetScreenWidth(); - } - - /// - /// Returns the Height of the Screen resolution. - /// See . - /// - /// - public int GetScreenHeight() - { - return s_Instance.GetScreenHeight(); - } - - /// - /// Returns the quality level. See . - /// - /// - public int GetQualityLevel() - { - return s_Instance.GetQualityLevel(); - } - - /// - /// Returns the time scale. See . - /// - /// - public float GetTimeScale() - { - return s_Instance.GetTimeScale(); - } - - /// - /// Returns the target frame rate. See . - /// - /// - public int GetTargetFrameRate() - { - return s_Instance.GetTargetFrameRate(); - } - - /// - /// Returns the capture frame rate. See . - /// - /// - public int GetCaptureFrameRate() - { - return s_Instance.GetCaptureFrameRate(); - } - internal void Dispose() { SideChannelUtils.UnregisterSideChannel(m_Channel); - s_Instance = null; } } } diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index 5c2a89ef01..64ae7375e6 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -5,7 +5,7 @@ namespace MLAgents { /// - /// A singleton container for the Environment Parameters that may be modified during training. + /// A container for the Environment Parameters that may be modified during training. /// The keys for those parameters are defined in the trainer configurations and the /// the values are generated from the training process in features such as Curriculum Learning /// and Environment Parameter Randomization. @@ -20,30 +20,14 @@ public sealed class EnvironmentParameters readonly EnvironmentParametersChannel m_Channel; /// - /// The singleton instance for this class. + /// Constructor. /// - private static EnvironmentParameters s_Instance; - - /// - /// Constructor, kept private to make this class a singleton. - /// - private EnvironmentParameters() + internal EnvironmentParameters() { m_Channel = new EnvironmentParametersChannel(); SideChannelUtils.RegisterSideChannel(m_Channel); } - /// - /// Internal Getter for the singleton instance. Initializes if not already initialized. - /// This method is kept internal to ensure that the initialization is managed by the - /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via - /// . - /// - internal static EnvironmentParameters Instance - { - get { return s_Instance ?? (s_Instance = new EnvironmentParameters()); } - } - /// /// Returns the parameter value for the specified key. Returns the default value provided /// if this parameter key does not have a value. Only returns a parameter value if it is @@ -81,7 +65,6 @@ public IList ListParameters() internal void Dispose() { SideChannelUtils.UnregisterSideChannel(m_Channel); - s_Instance = null; } } } diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs b/com.unity.ml-agents/Runtime/StatsRecorder.cs index 9a65c30a64..9e2e9d1ad9 100644 --- a/com.unity.ml-agents/Runtime/StatsRecorder.cs +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs @@ -37,30 +37,14 @@ public sealed class StatsRecorder readonly StatsSideChannel m_Channel; /// - /// The singleton instance for this class. + /// Constructor. /// - private static StatsRecorder s_Instance; - - /// - /// Constructor, kept private to make this class a singleton. - /// - private StatsRecorder() + internal StatsRecorder() { m_Channel = new StatsSideChannel(); SideChannelUtils.RegisterSideChannel(m_Channel); } - /// - /// Internal Getter for the singleton instance. Initializes if not already initialized. - /// This method is kept internal to ensure that the initialization is managed by the - /// Academy. Projects that import the ML-Agents SDK can retrieve the instance via - /// . - /// - internal static StatsRecorder Instance - { - get { return s_Instance ?? (s_Instance = new StatsRecorder()); } - } - /// /// Add a stat value for reporting. /// @@ -82,7 +66,6 @@ public void Add( internal void Dispose() { SideChannelUtils.UnregisterSideChannel(m_Channel); - s_Instance = null; } } } From 8c33551a05d025ab1411d43a0d7a432b9f3d8926 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 18:49:17 -0700 Subject: [PATCH 12/23] Re-enabled the option to add multiple side channels of the same type --- .../Runtime/SideChannels/SideChannelUtils.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs index d6a23e884b..1177bf5624 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs @@ -35,17 +35,7 @@ public static void RegisterSideChannel(SideChannel sideChannel) $"A side channel with id {channelId} is already registered. " + "You cannot register multiple side channels of the same id."); } - - foreach (var sc in RegisteredChannels.Values) - { - if (sc.GetType() == sideChannel.GetType()) - { - throw new UnityAgentsException( - $"A side channel with type {sc.GetType()} is already registered. " + - "You cannot register multiple side channels of the same type."); - } - } - + // Process any messages that we've already received for this channel ID. var numMessages = m_CachedMessages.Count; for (var i = 0; i < numMessages; i++) From 1dce6366b6fdcce099f91a1ca011f756d2a6bd3b Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 18:52:22 -0700 Subject: [PATCH 13/23] Fixed example env --- .../Examples/FoodCollector/Scripts/FoodCollectorSettings.cs | 2 +- com.unity.ml-agents/Runtime/StatsRecorder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs index 03cec5fdbc..0953ddd747 100644 --- a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs +++ b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs @@ -17,7 +17,7 @@ public class FoodCollectorSettings : MonoBehaviour public void Awake() { Academy.Instance.OnEnvironmentReset += EnvironmentReset; - m_Recorder = Academy.StatsRecorder; + m_Recorder = Academy.Instance.StatsRecorder; } private void EnvironmentReset() diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs b/com.unity.ml-agents/Runtime/StatsRecorder.cs index 9e2e9d1ad9..782b290307 100644 --- a/com.unity.ml-agents/Runtime/StatsRecorder.cs +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs @@ -15,7 +15,7 @@ public enum StatAggregationMethod /// /// Only the most recent value is reported. - /// To avoid conflicts when training with multiple concurrent environments, only + /// To avoid conflicts when training with multiple concurrent environments, only /// stats from worker index 0 will be tracked. /// MostRecent = 1 From bbea5855d0bfa1c1f7bfb1f2b027a3860841efc9 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 18:54:33 -0700 Subject: [PATCH 14/23] Add an enum flag to the EnvParamsChannel --- .../EnvironmentParametersChannel.cs | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs index 616da8ade6..33576e459b 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -3,6 +3,14 @@ namespace MLAgents.SideChannels { + /// + /// Lists the different data types supported. + /// + internal enum EnvironmentDataTypes + { + Float = 0 + } + /// /// A side channel that manages the environment parameter values from Python. Currently /// limited to parameters of type float. @@ -28,13 +36,21 @@ internal EnvironmentParametersChannel() public override void OnMessageReceived(IncomingMessage msg) { var key = msg.ReadString(); - var value = msg.ReadFloat32(); + var type = msg.ReadInt32(); + if ((int)EnvironmentDataTypes.Float == type) + { + var value = msg.ReadFloat32(); - m_Parameters[key] = value; + m_Parameters[key] = value; - Action action; - m_RegisteredActions.TryGetValue(key, out action); - action?.Invoke(value); + Action action; + m_RegisteredActions.TryGetValue(key, out action); + action?.Invoke(value); + } + else + { + throw new UnityAgentsException("EnvironmentParametersChannel only supports floats."); + } } /// From 797cf1288b60b6ac7d692f96ac291c62fc592ce2 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 19:02:27 -0700 Subject: [PATCH 15/23] Adding .cs.meta files --- com.unity.ml-agents/Runtime/EngineParameters.cs.meta | 11 +++++++++++ .../Runtime/EnvironmentParameters.cs.meta | 11 +++++++++++ .../SideChannels/EnvironmentParametersChannel.cs.meta | 11 +++++++++++ com.unity.ml-agents/Runtime/StatsRecorder.cs.meta | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 com.unity.ml-agents/Runtime/EngineParameters.cs.meta create mode 100644 com.unity.ml-agents/Runtime/EnvironmentParameters.cs.meta create mode 100644 com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs.meta create mode 100644 com.unity.ml-agents/Runtime/StatsRecorder.cs.meta diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs.meta b/com.unity.ml-agents/Runtime/EngineParameters.cs.meta new file mode 100644 index 0000000000..3d5cf01220 --- /dev/null +++ b/com.unity.ml-agents/Runtime/EngineParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de156bd22d1b24f7aa2419409c82dacd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs.meta b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs.meta new file mode 100644 index 0000000000..9e7a85f810 --- /dev/null +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90ce0b26bef35484890eac0633b85eed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs.meta b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs.meta new file mode 100644 index 0000000000..f118b1f99f --- /dev/null +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a849760d5bec946b884984e35c66fcfa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs.meta b/com.unity.ml-agents/Runtime/StatsRecorder.cs.meta new file mode 100644 index 0000000000..bfc4addbb1 --- /dev/null +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9add8900e8a746e6a4cb410cb27d664 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From c9b5cbc0f93530b3ab5e41a1a2d921c5a1fb7346 Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 19:06:19 -0700 Subject: [PATCH 16/23] Update engine config side channel Removed unnecessary accessors Made capture frame rate a parameter --- .../EngineConfigurationChannel.cs | 54 +++---------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs index 7feb3e4007..a452ba9145 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs @@ -19,63 +19,23 @@ internal EngineConfigurationChannel() ChannelId = new Guid(k_EngineConfigId); } - // internal storage of the configs received from Python - int width; - int height; - int qualityLevel; - float timeScale; - int targetFrameRate; - const int k_CaptureFramerate = 60; - /// public override void OnMessageReceived(IncomingMessage msg) { - width = msg.ReadInt32(); - height = msg.ReadInt32(); - qualityLevel = msg.ReadInt32(); - timeScale = msg.ReadFloat32(); - targetFrameRate = msg.ReadInt32(); + var width = msg.ReadInt32(); + var height = msg.ReadInt32(); + var qualityLevel = msg.ReadInt32(); + var timeScale = msg.ReadFloat32(); + var targetFrameRate = msg.ReadInt32(); + var captureFrameRate = msg.ReadInt32(); timeScale = Mathf.Clamp(timeScale, 1, 100); Screen.SetResolution(width, height, false); QualitySettings.SetQualityLevel(qualityLevel, true); Time.timeScale = timeScale; - Time.captureFramerate = k_CaptureFramerate; + Time.captureFramerate = captureFrameRate; Application.targetFrameRate = targetFrameRate; } - - // accessors for all the engine configs. For each new config added, we'll need to add - // a new accessor. - - public int GetScreenWidth() - { - return width; - } - - public int GetScreenHeight() - { - return height; - } - - public int GetQualityLevel() - { - return qualityLevel; - } - - public float GetTimeScale() - { - return timeScale; - } - - public int GetTargetFrameRate() - { - return targetFrameRate; - } - - public int GetCaptureFrameRate() - { - return k_CaptureFramerate; - } } } From 5a8351dfeab755078061868b41ff0dc40eda0c1c Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 19:08:16 -0700 Subject: [PATCH 17/23] =?UTF-8?q?Rename=20SideChannelUtils=20=E2=80=94>=20?= =?UTF-8?q?SideChannelsManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.unity.ml-agents/Runtime/Academy.cs | 4 ++-- .../Runtime/Communicator/RpcCommunicator.cs | 4 ++-- .../Runtime/EngineParameters.cs | 4 ++-- .../Runtime/EnvironmentParameters.cs | 4 ++-- .../Runtime/SideChannels/SideChannel.cs | 4 ++-- ...eChannelUtils.cs => SideChannelsManager.cs} | 4 ++-- ...ils.cs.meta => SideChannelsManager.cs.meta} | 2 +- com.unity.ml-agents/Runtime/StatsRecorder.cs | 4 ++-- .../Tests/Editor/MLAgentsEditModeTest.cs | 18 +++++++++--------- .../Tests/Editor/SideChannelTests.cs | 16 ++++++++-------- 10 files changed, 32 insertions(+), 32 deletions(-) rename com.unity.ml-agents/Runtime/SideChannels/{SideChannelUtils.cs => SideChannelsManager.cs} (99%) rename com.unity.ml-agents/Runtime/SideChannels/{SideChannelUtils.cs.meta => SideChannelsManager.cs.meta} (83%) diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index 34ab28ff88..855e4158cc 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -480,7 +480,7 @@ public void EnvironmentStep() // If the communicator is not on, we need to clear the SideChannel sending queue if (!IsCommunicatorOn) { - SideChannelUtils.GetSideChannelMessage(); + SideChannelsManager.GetSideChannelMessage(); } using (TimerStack.Instance.Scoped("AgentAct")) @@ -538,7 +538,7 @@ public void Dispose() s_EngineParameters.Dispose(); s_EnvironmentParameters.Dispose(); s_StatsRecorder.Dispose(); - SideChannelUtils.UnregisterAllSideChannels(); // unregister custom side channels + SideChannelsManager.UnregisterAllSideChannels(); // unregister custom side channels if (m_ModelRunners != null) { diff --git a/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs b/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs index 090ae08f18..bcf8b940ac 100644 --- a/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs +++ b/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs @@ -198,7 +198,7 @@ public void SubscribeBrain(string brainKey, BrainParameters brainParameters) void UpdateEnvironmentWithInput(UnityRLInputProto rlInput) { - SideChannelUtils.ProcessSideChannelData(rlInput.SideChannel.ToArray()); + SideChannelsManager.ProcessSideChannelData(rlInput.SideChannel.ToArray()); SendCommandEvent(rlInput.Command); } @@ -365,7 +365,7 @@ void SendBatchedMessageHelper() message.RlInitializationOutput = tempUnityRlInitializationOutput; } - byte[] messageAggregated = SideChannelUtils.GetSideChannelMessage(); + byte[] messageAggregated = SideChannelsManager.GetSideChannelMessage(); message.RlOutput.SideChannel = ByteString.CopyFrom(messageAggregated); var input = Exchange(message); diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs b/com.unity.ml-agents/Runtime/EngineParameters.cs index 75b9ff63a1..d7c0eec167 100644 --- a/com.unity.ml-agents/Runtime/EngineParameters.cs +++ b/com.unity.ml-agents/Runtime/EngineParameters.cs @@ -24,12 +24,12 @@ internal sealed class EngineParameters public EngineParameters() { m_Channel = new EngineConfigurationChannel(); - SideChannelUtils.RegisterSideChannel(m_Channel); + SideChannelsManager.RegisterSideChannel(m_Channel); } internal void Dispose() { - SideChannelUtils.UnregisterSideChannel(m_Channel); + SideChannelsManager.UnregisterSideChannel(m_Channel); } } } diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index 64ae7375e6..a86642cedc 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -25,7 +25,7 @@ public sealed class EnvironmentParameters internal EnvironmentParameters() { m_Channel = new EnvironmentParametersChannel(); - SideChannelUtils.RegisterSideChannel(m_Channel); + SideChannelsManager.RegisterSideChannel(m_Channel); } /// @@ -64,7 +64,7 @@ public IList ListParameters() internal void Dispose() { - SideChannelUtils.UnregisterSideChannel(m_Channel); + SideChannelsManager.UnregisterSideChannel(m_Channel); } } } diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs index ebe12c518a..eed6e965a4 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs @@ -11,8 +11,8 @@ namespace MLAgents.SideChannels /// To create your own, you'll need to create two, new mirrored classes, one in Unity (by /// extending ) and another in Python by extending a Python class /// also called SideChannel. Then, within your project, use - /// and - /// to register and unregister your + /// and + /// to register and unregister your /// custom side channel. /// public abstract class SideChannel diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs similarity index 99% rename from com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs rename to com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs index 1177bf5624..753db84d07 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs @@ -5,7 +5,7 @@ namespace MLAgents.SideChannels { - public static class SideChannelUtils + public static class SideChannelsManager { private static Dictionary RegisteredChannels = new Dictionary(); @@ -35,7 +35,7 @@ public static void RegisterSideChannel(SideChannel sideChannel) $"A side channel with id {channelId} is already registered. " + "You cannot register multiple side channels of the same id."); } - + // Process any messages that we've already received for this channel ID. var numMessages = m_CachedMessages.Count; for (var i = 0; i < numMessages; i++) diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs.meta b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs.meta similarity index 83% rename from com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs.meta rename to com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs.meta index 3b50458ea1..251cc14632 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs.meta +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2506dff31271f49298fbff21e13fa8b6 +guid: ccc0d134445f947349c68a6d07e3cdc2 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/com.unity.ml-agents/Runtime/StatsRecorder.cs b/com.unity.ml-agents/Runtime/StatsRecorder.cs index 782b290307..a4c6af352e 100644 --- a/com.unity.ml-agents/Runtime/StatsRecorder.cs +++ b/com.unity.ml-agents/Runtime/StatsRecorder.cs @@ -42,7 +42,7 @@ public sealed class StatsRecorder internal StatsRecorder() { m_Channel = new StatsSideChannel(); - SideChannelUtils.RegisterSideChannel(m_Channel); + SideChannelsManager.RegisterSideChannel(m_Channel); } /// @@ -65,7 +65,7 @@ public void Add( internal void Dispose() { - SideChannelUtils.UnregisterSideChannel(m_Channel); + SideChannelsManager.UnregisterSideChannel(m_Channel); } } } diff --git a/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs b/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs index 21db2ce7b8..865ab0fb0b 100644 --- a/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs +++ b/com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs @@ -208,9 +208,9 @@ public void TestAcademy() Assert.AreEqual(0, aca.EpisodeCount); Assert.AreEqual(0, aca.StepCount); Assert.AreEqual(0, aca.TotalStepCount); - Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); - Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); - Assert.AreNotEqual(null, SideChannelUtils.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelsManager.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelsManager.GetSideChannel()); + Assert.AreNotEqual(null, SideChannelsManager.GetSideChannel()); // Check that Dispose is idempotent aca.Dispose(); @@ -221,15 +221,15 @@ public void TestAcademy() [Test] public void TestAcademyDispose() { - var envParams1 = SideChannelUtils.GetSideChannel(); - var engineParams1 = SideChannelUtils.GetSideChannel(); - var statsParams1 = SideChannelUtils.GetSideChannel(); + var envParams1 = SideChannelsManager.GetSideChannel(); + var engineParams1 = SideChannelsManager.GetSideChannel(); + var statsParams1 = SideChannelsManager.GetSideChannel(); Academy.Instance.Dispose(); Academy.Instance.LazyInitialize(); - var envParams2 = SideChannelUtils.GetSideChannel(); - var engineParams2 = SideChannelUtils.GetSideChannel(); - var statsParams2 = SideChannelUtils.GetSideChannel(); + var envParams2 = SideChannelsManager.GetSideChannel(); + var engineParams2 = SideChannelsManager.GetSideChannel(); + var statsParams2 = SideChannelsManager.GetSideChannel(); Academy.Instance.Dispose(); Assert.AreNotEqual(envParams1, envParams2); diff --git a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs index 3a236bfcfe..99737479c2 100644 --- a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs +++ b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs @@ -45,8 +45,8 @@ public void TestIntegerSideChannel() intSender.SendInt(5); intSender.SendInt(6); - byte[] fakeData = SideChannelUtils.GetSideChannelMessage(dictSender); - SideChannelUtils.ProcessSideChannelData(dictReceiver, fakeData); + byte[] fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); + SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); Assert.AreEqual(intReceiver.messagesReceived[0], 4); Assert.AreEqual(intReceiver.messagesReceived[1], 5); @@ -67,8 +67,8 @@ public void TestRawBytesSideChannel() strSender.SendRawBytes(Encoding.ASCII.GetBytes(str1)); strSender.SendRawBytes(Encoding.ASCII.GetBytes(str2)); - byte[] fakeData = SideChannelUtils.GetSideChannelMessage(dictSender); - SideChannelUtils.ProcessSideChannelData(dictReceiver, fakeData); + byte[] fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); + SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); var messages = strReceiver.GetAndClearReceivedMessages(); @@ -96,8 +96,8 @@ public void TestFloatPropertiesSideChannel() tmp = propB.GetPropertyWithDefault(k2, 3.0f); Assert.AreEqual(tmp, 1.0f); - byte[] fakeData = SideChannelUtils.GetSideChannelMessage(dictSender); - SideChannelUtils.ProcessSideChannelData(dictReceiver, fakeData); + byte[] fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); + SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); tmp = propA.GetPropertyWithDefault(k2, 3.0f); Assert.AreEqual(tmp, 1.0f); @@ -105,8 +105,8 @@ public void TestFloatPropertiesSideChannel() Assert.AreEqual(wasCalled, 0); propB.SetProperty(k1, 1.0f); Assert.AreEqual(wasCalled, 0); - fakeData = SideChannelUtils.GetSideChannelMessage(dictSender); - SideChannelUtils.ProcessSideChannelData(dictReceiver, fakeData); + fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); + SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); Assert.AreEqual(wasCalled, 1); var keysA = propA.ListProperties(); From 8ed980af7174615ef018d2c225d4f1223631fc9c Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 21:08:30 -0700 Subject: [PATCH 18/23] PR feedback --- com.unity.ml-agents/Runtime/Academy.cs | 26 +++++++++---------- .../SideChannels/SideChannelsManager.cs | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index 855e4158cc..045c87b445 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -290,12 +290,12 @@ static int ReadPortFromArgs() } } - private EngineParameters s_EngineParameters; - private EnvironmentParameters s_EnvironmentParameters; - private StatsRecorder s_StatsRecorder; + private EngineParameters m_EngineParameters; + private EnvironmentParameters m_EnvironmentParameters; + private StatsRecorder m_StatsRecorder; /// - /// Returns the singleton instance. If training + /// Returns the instance. If training /// features such as Curriculum Learning or Environment Parameter Randomization are used, /// then the values of the parameters generated from the training process can be /// retrieved here. @@ -303,17 +303,17 @@ static int ReadPortFromArgs() /// public EnvironmentParameters EnvironmentParameters { - get { return s_EnvironmentParameters; } + get { return m_EnvironmentParameters; } } /// - /// Returns the singleton instance. This instance can be used + /// Returns the instance. This instance can be used /// to record any statistics from the Unity environment. /// /// public StatsRecorder StatsRecorder { - get { return s_StatsRecorder; } + get { return m_StatsRecorder; } } /// @@ -326,9 +326,9 @@ void InitializeEnvironment() EnableAutomaticStepping(); - s_EngineParameters = new EngineParameters(); - s_EnvironmentParameters = new EnvironmentParameters(); - s_StatsRecorder = new StatsRecorder(); + m_EngineParameters = new EngineParameters(); + m_EnvironmentParameters = new EnvironmentParameters(); + m_StatsRecorder = new StatsRecorder(); // Try to launch the communicator by using the arguments passed at launch var port = ReadPortFromArgs(); @@ -535,9 +535,9 @@ public void Dispose() Communicator?.Dispose(); Communicator = null; - s_EngineParameters.Dispose(); - s_EnvironmentParameters.Dispose(); - s_StatsRecorder.Dispose(); + m_EngineParameters.Dispose(); + m_EnvironmentParameters.Dispose(); + m_StatsRecorder.Dispose(); SideChannelsManager.UnregisterAllSideChannels(); // unregister custom side channels if (m_ModelRunners != null) diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs index 753db84d07..2a5164dfaa 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs @@ -23,7 +23,6 @@ private struct CachedSideChannelMessage /// available for environments that have custom side channels. All built-in side /// channels within the ML-Agents Toolkit are managed internally and do not need to /// be explicitly registered/unregistered. A side channel may only be registered once. - /// Additionally, only one side channel of each type is allowed. /// /// The side channel to register. public static void RegisterSideChannel(SideChannel sideChannel) @@ -60,9 +59,10 @@ public static void RegisterSideChannel(SideChannel sideChannel) /// Unregister a side channel to stop sending and receiving messages. This method is /// available for environments that have custom side channels. All built-in side /// channels within the ML-Agents Toolkit are managed internally and do not need to - /// be explicitly registered/unregistered. A side channel may only be unregistered - /// multiple times. Note that unregistering a side channel may not stop the Python side - /// from sending them, but it does mean that sent messages with not result in a call + /// be explicitly registered/unregistered. Unregistering a side channel that has already + /// been unregistered (or never registered in the first place) has no negative side effects. + /// Note that unregistering a side channel may not stop the Python side + /// from sending messages, but it does mean that sent messages with not result in a call /// to . Furthermore, /// those messages will not be buffered and will, in essence, be lost. /// From 2db13f0ecd0613b4dd8eea40020a049d8991d4bf Mon Sep 17 00:00:00 2001 From: Marwan Mattar Date: Tue, 21 Apr 2020 21:17:53 -0700 Subject: [PATCH 19/23] Minor PR feedback. --- .../Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs index 9c26041443..ab6eb10264 100644 --- a/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs +++ b/Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs @@ -44,7 +44,6 @@ public void Awake() Physics.defaultSolverVelocityIterations = solverVelocityIterations; // Make sure the Academy singleton is initialized first, since it will create the SideChannels. - var academy = Academy.Instance; Academy.Instance.EnvironmentParameters.RegisterCallback("gravity", f => { Physics.gravity = new Vector3(0, -f, 0); }); } From ab9dc93a68089a145d2b46420c3c57c58432da69 Mon Sep 17 00:00:00 2001 From: Vincent-Pierre BERGES Date: Wed, 22 Apr 2020 15:40:55 -0700 Subject: [PATCH 20/23] Python side changes to the SideChannel redesign (#3826) * Modified the EngineConfig to send one message per field * Created the Python Environment Parameters Channel and hooked it in * Make OnMessageReceived protected * addressing comments --- .../EngineConfigurationChannel.cs | 57 ++++++++---- .../EnvironmentParametersChannel.cs | 2 +- .../SideChannels/FloatPropertiesChannel.cs | 2 +- .../Runtime/SideChannels/RawBytesChannel.cs | 2 +- .../Runtime/SideChannels/SideChannel.cs | 10 ++- .../SideChannels/SideChannelsManager.cs | 15 +--- .../Runtime/SideChannels/StatsSideChannel.cs | 2 +- .../Tests/Editor/SideChannelTests.cs | 2 +- docs/Python-API.md | 11 +-- .../engine_configuration_channel.py | 88 ++++++++++++++----- .../environment_parameters_channel.py | 37 ++++++++ ml-agents/mlagents/trainers/env_manager.py | 5 -- ml-agents/mlagents/trainers/learn.py | 19 ++-- .../mlagents/trainers/simple_env_manager.py | 14 ++- .../trainers/subprocess_env_manager.py | 19 ++-- .../mlagents/trainers/tests/test_simple_rl.py | 6 +- 16 files changed, 200 insertions(+), 91 deletions(-) create mode 100644 ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py diff --git a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs index a452ba9145..530656e711 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EngineConfigurationChannel.cs @@ -3,11 +3,21 @@ namespace MLAgents.SideChannels { + /// /// Side channel that supports modifying attributes specific to the Unity Engine. /// internal class EngineConfigurationChannel : SideChannel { + private enum ConfigurationType : int + { + ScreenResolution = 0, + QualityLevel = 1, + TimeScale = 2, + TargetFrameRate = 3, + CaptureFrameRate = 4 + } + const string k_EngineConfigId = "e951342c-4f7e-11ea-b238-784f4387d1f7"; /// @@ -20,22 +30,39 @@ internal EngineConfigurationChannel() } /// - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { - var width = msg.ReadInt32(); - var height = msg.ReadInt32(); - var qualityLevel = msg.ReadInt32(); - var timeScale = msg.ReadFloat32(); - var targetFrameRate = msg.ReadInt32(); - var captureFrameRate = msg.ReadInt32(); - - timeScale = Mathf.Clamp(timeScale, 1, 100); - - Screen.SetResolution(width, height, false); - QualitySettings.SetQualityLevel(qualityLevel, true); - Time.timeScale = timeScale; - Time.captureFramerate = captureFrameRate; - Application.targetFrameRate = targetFrameRate; + var messageType = (ConfigurationType)msg.ReadInt32(); + switch (messageType) + { + case ConfigurationType.ScreenResolution: + var width = msg.ReadInt32(); + var height = msg.ReadInt32(); + Screen.SetResolution(width, height, false); + break; + case ConfigurationType.QualityLevel: + var qualityLevel = msg.ReadInt32(); + QualitySettings.SetQualityLevel(qualityLevel, true); + break; + case ConfigurationType.TimeScale: + var timeScale = msg.ReadFloat32(); + timeScale = Mathf.Clamp(timeScale, 1, 100); + Time.timeScale = timeScale; + break; + case ConfigurationType.TargetFrameRate: + var targetFrameRate = msg.ReadInt32(); + Application.targetFrameRate = targetFrameRate; + break; + case ConfigurationType.CaptureFrameRate: + var captureFrameRate = msg.ReadInt32(); + Time.captureFramerate = captureFrameRate; + break; + default: + Debug.LogWarning( + "Unknown engine configuration received from Python. Make sure" + + " your Unity and Python versions are compatible."); + break; + } } } } diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs index 33576e459b..23710f68c4 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -33,7 +33,7 @@ internal EnvironmentParametersChannel() } /// - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { var key = msg.ReadString(); var type = msg.ReadInt32(); diff --git a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs index 8c98c7b2c1..f9c402fb39 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs @@ -30,7 +30,7 @@ public class FloatPropertiesChannel : SideChannel } /// - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { var key = msg.ReadString(); var value = msg.ReadFloat32(); diff --git a/com.unity.ml-agents/Runtime/SideChannels/RawBytesChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/RawBytesChannel.cs index 298e4d31da..4720c4c7d6 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/RawBytesChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/RawBytesChannel.cs @@ -22,7 +22,7 @@ public RawBytesChannel(Guid channelId) } /// - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { m_MessagesReceived.Add(msg.GetRawBytes()); } diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs index eed6e965a4..b14357f88f 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs @@ -32,12 +32,20 @@ public Guid ChannelId protected set; } + internal void ProcessMessage(byte[] msg) + { + using (var incomingMsg = new IncomingMessage(msg)) + { + OnMessageReceived(incomingMsg); + } + } + /// /// Is called by the communicator every time a message is received from Python by the SideChannel. /// Can be called multiple times per simulation step if multiple messages were sent. /// /// The incoming message. - public abstract void OnMessageReceived(IncomingMessage msg); + protected abstract void OnMessageReceived(IncomingMessage msg); /// /// Queues a message to be sent to Python during the next simulation step. diff --git a/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs index 2a5164dfaa..6b9afaef0d 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/SideChannelsManager.cs @@ -42,10 +42,7 @@ public static void RegisterSideChannel(SideChannel sideChannel) var cachedMessage = m_CachedMessages.Dequeue(); if (channelId == cachedMessage.ChannelId) { - using (var incomingMsg = new IncomingMessage(cachedMessage.Message)) - { - sideChannel.OnMessageReceived(incomingMsg); - } + sideChannel.ProcessMessage(cachedMessage.Message); } else { @@ -160,10 +157,7 @@ internal static void ProcessSideChannelData(Dictionary sideCh var cachedMessage = m_CachedMessages.Dequeue(); if (sideChannels.ContainsKey(cachedMessage.ChannelId)) { - using (var incomingMsg = new IncomingMessage(cachedMessage.Message)) - { - sideChannels[cachedMessage.ChannelId].OnMessageReceived(incomingMsg); - } + sideChannels[cachedMessage.ChannelId].ProcessMessage(cachedMessage.Message); } else { @@ -200,10 +194,7 @@ internal static void ProcessSideChannelData(Dictionary sideCh } if (sideChannels.ContainsKey(channelId)) { - using (var incomingMsg = new IncomingMessage(message)) - { - sideChannels[channelId].OnMessageReceived(incomingMsg); - } + sideChannels[channelId].ProcessMessage(message); } else { diff --git a/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs index 72c1f3fdfd..5ab776d2bb 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/StatsSideChannel.cs @@ -35,7 +35,7 @@ public void AddStat(string key, float value, StatAggregationMethod aggregationMe } /// - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { throw new UnityAgentsException("StatsSideChannel should never receive messages."); } diff --git a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs index 99737479c2..5f7f7a2fb7 100644 --- a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs +++ b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs @@ -18,7 +18,7 @@ public TestSideChannel() ChannelId = new Guid("6afa2c06-4f82-11ea-b238-784f4387d1f7"); } - public override void OnMessageReceived(IncomingMessage msg) + protected override void OnMessageReceived(IncomingMessage msg) { messagesReceived.Add(msg.ReadInt32()); } diff --git a/docs/Python-API.md b/docs/Python-API.md index 1da4abdf13..4cbee7f06f 100644 --- a/docs/Python-API.md +++ b/docs/Python-API.md @@ -281,11 +281,12 @@ The `EngineConfiguration` side channel allows you to modify the time-scale, reso `EngineConfigurationChannel` has two methods : * `set_configuration_parameters` which takes the following arguments: - * `width`: Defines the width of the display. Default 80. - * `height`: Defines the height of the display. Default 80. - * `quality_level`: Defines the quality level of the simulation. Default 1. - * `time_scale`: Defines the multiplier for the deltatime in the simulation. If set to a higher value, time will pass faster in the simulation but the physics may perform unpredictably. Default 20. - * `target_frame_rate`: Instructs simulation to try to render at a specified frame rate. Default -1. + * `width`: Defines the width of the display. (Must be set alongside height) + * `height`: Defines the height of the display. (Must be set alongside width) + * `quality_level`: Defines the quality level of the simulation. + * `time_scale`: Defines the multiplier for the deltatime in the simulation. If set to a higher value, time will pass faster in the simulation but the physics may perform unpredictably. + * `target_frame_rate`: Instructs simulation to try to render at a specified frame rate. + * `capture_frame_rate` Instructs the simulation to consider time between updates to always be constant, regardless of the actual frame rate. * `set_configuration` with argument config which is an `EngineConfig` NamedTuple object. diff --git a/ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py b/ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py index a8eef624c2..c9315433f9 100644 --- a/ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py +++ b/ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py @@ -1,7 +1,11 @@ from mlagents_envs.side_channel import SideChannel, OutgoingMessage, IncomingMessage -from mlagents_envs.exception import UnityCommunicationException +from mlagents_envs.exception import ( + UnityCommunicationException, + UnitySideChannelException, +) import uuid -from typing import NamedTuple +from typing import NamedTuple, Optional +from enum import IntEnum class EngineConfig(NamedTuple): @@ -10,10 +14,11 @@ class EngineConfig(NamedTuple): quality_level: int time_scale: float target_frame_rate: int + capture_frame_rate: int @staticmethod def default_config(): - return EngineConfig(80, 80, 1, 20.0, -1) + return EngineConfig(80, 80, 1, 20.0, -1, 60) class EngineConfigurationChannel(SideChannel): @@ -25,8 +30,16 @@ class EngineConfigurationChannel(SideChannel): - int qualityLevel; - float timeScale; - int targetFrameRate; + - int captureFrameRate; """ + class ConfigurationType(IntEnum): + SCREEN_RESOLUTION = 0 + QUALITY_LEVEL = 1 + TIME_SCALE = 2 + TARGET_FRAME_RATE = 3 + CAPTURE_FRAME_RATE = 4 + def __init__(self) -> None: super().__init__(uuid.UUID("e951342c-4f7e-11ea-b238-784f4387d1f7")) @@ -45,32 +58,67 @@ def on_message_received(self, msg: IncomingMessage) -> None: def set_configuration_parameters( self, - width: int = 80, - height: int = 80, - quality_level: int = 1, - time_scale: float = 20.0, - target_frame_rate: int = -1, + width: Optional[int] = None, + height: Optional[int] = None, + quality_level: Optional[int] = None, + time_scale: Optional[float] = None, + target_frame_rate: Optional[int] = None, + capture_frame_rate: Optional[int] = None, ) -> None: """ Sets the engine configuration. Takes as input the configurations of the engine. - :param width: Defines the width of the display. Default 80. - :param height: Defines the height of the display. Default 80. + :param width: Defines the width of the display. (Must be set alongside height) + :param height: Defines the height of the display. (Must be set alongside width) :param quality_level: Defines the quality level of the simulation. - Default 1. :param time_scale: Defines the multiplier for the deltatime in the simulation. If set to a higher value, time will pass faster in the - simulation but the physics might break. Default 20. + simulation but the physics might break. :param target_frame_rate: Instructs simulation to try to render at a - specified frame rate. Default -1. + specified frame rate. + :param capture_frame_rate: Instructs the simulation to consider time between + updates to always be constant, regardless of the actual frame rate. """ - msg = OutgoingMessage() - msg.write_int32(width) - msg.write_int32(height) - msg.write_int32(quality_level) - msg.write_float32(time_scale) - msg.write_int32(target_frame_rate) - super().queue_message_to_send(msg) + + if (width is None and height is not None) or ( + width is not None and height is None + ): + raise UnitySideChannelException( + "You cannot set the width/height of the screen resolution without also setting the height/width" + ) + + if width is not None and height is not None: + screen_msg = OutgoingMessage() + screen_msg.write_int32(self.ConfigurationType.SCREEN_RESOLUTION) + screen_msg.write_int32(width) + screen_msg.write_int32(height) + super().queue_message_to_send(screen_msg) + + if quality_level is not None: + quality_level_msg = OutgoingMessage() + quality_level_msg.write_int32(self.ConfigurationType.QUALITY_LEVEL) + quality_level_msg.write_int32(quality_level) + super().queue_message_to_send(quality_level_msg) + + if time_scale is not None: + time_scale_msg = OutgoingMessage() + time_scale_msg.write_int32(self.ConfigurationType.TIME_SCALE) + time_scale_msg.write_float32(time_scale) + super().queue_message_to_send(time_scale_msg) + + if target_frame_rate is not None: + target_frame_rate_msg = OutgoingMessage() + target_frame_rate_msg.write_int32(self.ConfigurationType.TARGET_FRAME_RATE) + target_frame_rate_msg.write_int32(target_frame_rate) + super().queue_message_to_send(target_frame_rate_msg) + + if capture_frame_rate is not None: + capture_frame_rate_msg = OutgoingMessage() + capture_frame_rate_msg.write_int32( + self.ConfigurationType.CAPTURE_FRAME_RATE + ) + capture_frame_rate_msg.write_int32(capture_frame_rate) + super().queue_message_to_send(capture_frame_rate_msg) def set_configuration(self, config: EngineConfig) -> None: """ diff --git a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py new file mode 100644 index 0000000000..da43ce4e32 --- /dev/null +++ b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py @@ -0,0 +1,37 @@ +from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage +from mlagents_envs.exception import UnityCommunicationException +import uuid +from enum import IntEnum + + +class EnvironmentParametersChannel(SideChannel): + """ + This is the SideChannel for sending environment parameters to Unity. + You can send parameters to an environment with the command + set_float_property. + """ + + class EnvironmentDataTypes(IntEnum): + FLOAT = 0 + + def __init__(self) -> None: + channel_id = uuid.UUID(("534c891e-810f-11ea-a9d0-822485860400")) + super().__init__(channel_id) + + def on_message_received(self, msg: IncomingMessage) -> None: + raise UnityCommunicationException( + "The EnvironmentParametersChannel received a message from Unity, " + + "this should not have happend." + ) + + def set_float_property(self, key: str, value: float) -> None: + """ + Sets a float environment parameter in the Unity Environment. + :param key: The string identifier of the parameter. + :param value: The float value of the parameter. + """ + msg = OutgoingMessage() + msg.write_string(key) + msg.write_int32(self.EnvironmentDataTypes.FLOAT) + msg.write_float32(value) + super().queue_message_to_send(msg) diff --git a/ml-agents/mlagents/trainers/env_manager.py b/ml-agents/mlagents/trainers/env_manager.py index b8f6771e29..844cb7ef77 100644 --- a/ml-agents/mlagents/trainers/env_manager.py +++ b/ml-agents/mlagents/trainers/env_manager.py @@ -72,11 +72,6 @@ def reset(self, config: Dict = None) -> int: def external_brains(self) -> Dict[BehaviorName, BrainParameters]: pass - @property - @abstractmethod - def get_properties(self) -> Dict[BehaviorName, float]: - pass - @abstractmethod def close(self): pass diff --git a/ml-agents/mlagents/trainers/learn.py b/ml-agents/mlagents/trainers/learn.py index a5cb4677af..93c90490f1 100644 --- a/ml-agents/mlagents/trainers/learn.py +++ b/ml-agents/mlagents/trainers/learn.py @@ -234,6 +234,13 @@ def _create_parser(): help="The target frame rate of the Unity environment(s). Equivalent to setting " "Application.targetFrameRate in Unity.", ) + eng_conf.add_argument( + "--capture-frame-rate", + default=60, + type=int, + help="The capture frame rate of the Unity environment(s). Equivalent to setting " + "Time.captureFramerate in Unity.", + ) return argparser @@ -268,6 +275,7 @@ class RunOptions(NamedTuple): quality_level: int = parser.get_default("quality_level") time_scale: float = parser.get_default("time_scale") target_frame_rate: int = parser.get_default("target_frame_rate") + capture_frame_rate: int = parser.get_default("capture_frame_rate") @staticmethod def from_argparse(args: argparse.Namespace) -> "RunOptions": @@ -353,11 +361,12 @@ def run_training(run_seed: int, options: RunOptions) -> None: options.env_path, options.no_graphics, run_seed, port, options.env_args ) engine_config = EngineConfig( - options.width, - options.height, - options.quality_level, - options.time_scale, - options.target_frame_rate, + width=options.width, + height=options.height, + quality_level=options.quality_level, + time_scale=options.time_scale, + target_frame_rate=options.target_frame_rate, + capture_frame_rate=options.capture_frame_rate, ) env_manager = SubprocessEnvManager(env_factory, engine_config, options.num_envs) maybe_meta_curriculum = try_create_meta_curriculum( diff --git a/ml-agents/mlagents/trainers/simple_env_manager.py b/ml-agents/mlagents/trainers/simple_env_manager.py index e3ea815553..fce80ce30e 100644 --- a/ml-agents/mlagents/trainers/simple_env_manager.py +++ b/ml-agents/mlagents/trainers/simple_env_manager.py @@ -5,7 +5,9 @@ from mlagents_envs.timers import timed from mlagents.trainers.action_info import ActionInfo from mlagents.trainers.brain import BrainParameters -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel +from mlagents_envs.side_channel.environment_parameters_channel import ( + EnvironmentParametersChannel, +) from mlagents.trainers.brain_conversion_utils import behavior_spec_to_brain_parameters @@ -15,9 +17,9 @@ class SimpleEnvManager(EnvManager): This is generally only useful for testing; see SubprocessEnvManager for a production-quality implementation. """ - def __init__(self, env: BaseEnv, float_prop_channel: FloatPropertiesChannel): + def __init__(self, env: BaseEnv, env_params: EnvironmentParametersChannel): super().__init__() - self.shared_float_properties = float_prop_channel + self.env_params = env_params self.env = env self.previous_step: EnvironmentStep = EnvironmentStep.empty(0) self.previous_all_action_info: Dict[str, ActionInfo] = {} @@ -42,7 +44,7 @@ def _reset_env( ) -> List[EnvironmentStep]: # type: ignore if config is not None: for k, v in config.items(): - self.shared_float_properties.set_property(k, v) + self.env_params.set_float_property(k, v) self.env.reset() all_step_result = self._generate_all_results() self.previous_step = EnvironmentStep(all_step_result, 0, {}, {}) @@ -57,10 +59,6 @@ def external_brains(self) -> Dict[BehaviorName, BrainParameters]: ) return result - @property - def get_properties(self) -> Dict[BehaviorName, float]: - return self.shared_float_properties.get_property_dict_copy() - def close(self): self.env.close() diff --git a/ml-agents/mlagents/trainers/subprocess_env_manager.py b/ml-agents/mlagents/trainers/subprocess_env_manager.py index dbb042ae36..3b4133ef78 100644 --- a/ml-agents/mlagents/trainers/subprocess_env_manager.py +++ b/ml-agents/mlagents/trainers/subprocess_env_manager.py @@ -23,7 +23,9 @@ ) from mlagents.trainers.brain import BrainParameters from mlagents.trainers.action_info import ActionInfo -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel +from mlagents_envs.side_channel.environment_parameters_channel import ( + EnvironmentParametersChannel, +) from mlagents_envs.side_channel.engine_configuration_channel import ( EngineConfigurationChannel, EngineConfig, @@ -113,7 +115,7 @@ def worker( env_factory: Callable[ [int, List[SideChannel]], UnityEnvironment ] = cloudpickle.loads(pickled_env_factory) - shared_float_properties = FloatPropertiesChannel() + env_parameters = EnvironmentParametersChannel() engine_configuration_channel = EngineConfigurationChannel() engine_configuration_channel.set_configuration(engine_configuration) stats_channel = StatsSideChannel() @@ -138,8 +140,7 @@ def external_brains(): try: env = env_factory( - worker_id, - [shared_float_properties, engine_configuration_channel, stats_channel], + worker_id, [env_parameters, engine_configuration_channel, stats_channel] ) while True: req: EnvironmentRequest = parent_conn.recv() @@ -167,12 +168,9 @@ def external_brains(): reset_timers() elif req.cmd == EnvironmentCommand.EXTERNAL_BRAINS: _send_response(EnvironmentCommand.EXTERNAL_BRAINS, external_brains()) - elif req.cmd == EnvironmentCommand.GET_PROPERTIES: - reset_params = shared_float_properties.get_property_dict_copy() - _send_response(EnvironmentCommand.GET_PROPERTIES, reset_params) elif req.cmd == EnvironmentCommand.RESET: for k, v in req.payload.items(): - shared_float_properties.set_property(k, v) + env_parameters.set_float_property(k, v) env.reset() all_step_result = _generate_all_results() _send_response(EnvironmentCommand.RESET, all_step_result) @@ -295,11 +293,6 @@ def external_brains(self) -> Dict[BehaviorName, BrainParameters]: self.env_workers[0].send(EnvironmentCommand.EXTERNAL_BRAINS) return self.env_workers[0].recv().payload - @property - def get_properties(self) -> Dict[BehaviorName, float]: - self.env_workers[0].send(EnvironmentCommand.GET_PROPERTIES) - return self.env_workers[0].recv().payload - def close(self) -> None: logger.debug(f"SubprocessEnvManager closing.") self.step_queue.close() diff --git a/ml-agents/mlagents/trainers/tests/test_simple_rl.py b/ml-agents/mlagents/trainers/tests/test_simple_rl.py index 9b73be1196..0f783aa43a 100644 --- a/ml-agents/mlagents/trainers/tests/test_simple_rl.py +++ b/ml-agents/mlagents/trainers/tests/test_simple_rl.py @@ -16,7 +16,9 @@ from mlagents.trainers.sampler_class import SamplerManager from mlagents.trainers.demo_loader import write_demo from mlagents.trainers.stats import StatsReporter, StatsWriter, StatsSummary -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel +from mlagents_envs.side_channel.environment_parameters_channel import ( + EnvironmentParametersChannel, +) from mlagents_envs.communicator_objects.demonstration_meta_pb2 import ( DemonstrationMetaProto, ) @@ -139,7 +141,7 @@ def _check_environment_trains( debug_writer = DebugWriter() StatsReporter.add_writer(debug_writer) if env_manager is None: - env_manager = SimpleEnvManager(env, FloatPropertiesChannel()) + env_manager = SimpleEnvManager(env, EnvironmentParametersChannel()) trainer_factory = TrainerFactory( trainer_config=trainer_config, summaries_dir=dir, From be42950b0451939b69ba89b8522d6b6909c357de Mon Sep 17 00:00:00 2001 From: Vincent-Pierre BERGES Date: Thu, 23 Apr 2020 14:33:17 -0700 Subject: [PATCH 21/23] [Side Channels] Edited the documenation and renamed a few things (#3833) * Edited the documetation and renamed a few things * addressing comments * Update docs/Python-API.md Co-Authored-By: Chris Elion * Update com.unity.ml-agents/CHANGELOG.md Co-Authored-By: Chris Elion * Removing unecessary migrating line Co-authored-by: Chris Elion --- com.unity.ml-agents/CHANGELOG.md | 26 ++++++++++-------- com.unity.ml-agents/Runtime/Academy.cs | 2 +- .../Runtime/EnvironmentParameters.cs | 2 +- .../EnvironmentParametersChannel.cs | 5 ++-- .../SideChannels/FloatPropertiesChannel.cs | 6 ++--- .../Tests/Editor/SideChannelTests.cs | 14 +++++----- docs/Custom-SideChannels.md | 10 +++---- docs/Migrating.md | 27 ++++++++++++------- docs/Python-API.md | 25 +++++++---------- docs/Training-Curriculum-Learning.md | 4 +-- docs/Using-Tensorboard.md | 4 +-- ml-agents-envs/mlagents_envs/environment.py | 2 +- .../environment_parameters_channel.py | 4 +-- .../mlagents/trainers/simple_env_manager.py | 2 +- .../trainers/subprocess_env_manager.py | 2 +- 15 files changed, 71 insertions(+), 64 deletions(-) diff --git a/com.unity.ml-agents/CHANGELOG.md b/com.unity.ml-agents/CHANGELOG.md index 2bdbdb98e5..333936c6ae 100755 --- a/com.unity.ml-agents/CHANGELOG.md +++ b/com.unity.ml-agents/CHANGELOG.md @@ -13,10 +13,6 @@ and this project adheres to - The `--load` and `--train` command-line flags have been deprecated. Training now happens by default, and use `--resume` to resume training instead. (#3705) - The Jupyter notebooks have been removed from the repository. -- Introduced the `SideChannelUtils` to register, unregister and access side - channels. -- `Academy.FloatProperties` was removed, please use - `SideChannelUtils.GetSideChannel()` instead. - Removed the multi-agent gym option from the gym wrapper. For multi-agent scenarios, use the [Low Level Python API](../docs/Python-API.md). - The low level Python API has changed. You can look at the document @@ -36,21 +32,29 @@ and this project adheres to communication between Unity and the Python process. - The obsolete `Agent` methods `GiveModel`, `Done`, `InitializeAgent`, `AgentAction` and `AgentReset` have been removed. -- The GhostTrainer has been extended to support asymmetric games and the asymmetric example environment Strikers Vs. Goalie has been added. +- The GhostTrainer has been extended to support asymmetric games and the + asymmetric example environment Strikers Vs. Goalie has been added. +- The SideChannel API has changed (#3833, #3660) : + - Introduced the `SideChannelManager` to register, unregister and access side + channels. + - `EnvironmentParameters` replaces the default `FloatProperties`. + You can access the `EnvironmentParameters` with + `Academy.Instance.EnvironmentParameters` on C# and create an + `EnvironmentParametersChannel` on Python + - `SideChannel.OnMessageReceived` is now a protected method (was public) + - SideChannel IncomingMessages methods now take an optional default argument, + which is used when trying to read more data than the message contains. + - Added a feature to allow sending stats from C# environments to TensorBoard + (and other python StatsWriters). To do this from your code, use + `Academy.Instance.StatsRecorder.Add(key, value)`(#3660) ### Minor Changes - Format of console output has changed slightly and now matches the name of the model/summary directory. (#3630, #3616) -- Added a feature to allow sending stats from C# environments to TensorBoard - (and other python StatsWriters). To do this from your code, use - `SideChannelUtils.GetSideChannel().AddStat(key, value)` - (#3660) - Renamed 'Generalization' feature to 'Environment Parameter Randomization'. - Timer files now contain a dictionary of metadata, including things like the package version numbers. -- SideChannel IncomingMessages methods now take an optional default argument, - which is used when trying to read more data than the message contains. - The way that UnityEnvironment decides the port was changed. If no port is specified, the behavior will depend on the `file_name` parameter. If it is `None`, 5004 (the editor port) will be used; otherwise 5005 (the base diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index 045c87b445..ad1adab06e 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -58,7 +58,7 @@ public class Academy : IDisposable /// on each side, although we may allow some flexibility in the future. /// This should be incremented whenever a change is made to the communication protocol. /// - const string k_ApiVersion = "0.16.0"; + const string k_ApiVersion = "0.17.0"; /// /// Unity package version of com.unity.ml-agents. diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index a86642cedc..9784a5b13b 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -38,7 +38,7 @@ internal EnvironmentParameters() /// public float GetParameterWithDefault(string key, float defaultValue) { - return m_Channel.GetParameterWithDefault(key, defaultValue); + return m_Channel.GetWithDefault(key, defaultValue); } /// diff --git a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs index 23710f68c4..79751e1789 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/EnvironmentParametersChannel.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System; +using UnityEngine; namespace MLAgents.SideChannels { @@ -49,7 +50,7 @@ protected override void OnMessageReceived(IncomingMessage msg) } else { - throw new UnityAgentsException("EnvironmentParametersChannel only supports floats."); + Debug.LogWarning("EnvironmentParametersChannel received an unknown data type.") } } @@ -60,7 +61,7 @@ protected override void OnMessageReceived(IncomingMessage msg) /// Parameter key. /// Default value to return. /// - public float GetParameterWithDefault(string key, float defaultValue) + public float GetWithDefault(string key, float defaultValue) { float valueOut; bool hasKey = m_Parameters.TryGetValue(key, out valueOut); diff --git a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs index f9c402fb39..06753b69a9 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs @@ -43,7 +43,7 @@ protected override void OnMessageReceived(IncomingMessage msg) } /// - public void SetProperty(string key, float value) + public void Set(string key, float value) { m_FloatProperties[key] = value; using (var msgOut = new OutgoingMessage()) @@ -59,7 +59,7 @@ public void SetProperty(string key, float value) } /// - public float GetPropertyWithDefault(string key, float defaultValue) + public float GetWithDefault(string key, float defaultValue) { float valueOut; bool hasKey = m_FloatProperties.TryGetValue(key, out valueOut); @@ -73,7 +73,7 @@ public void RegisterCallback(string key, Action action) } /// - public IList ListProperties() + public IList List() { return new List(m_FloatProperties.Keys); } diff --git a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs index 5f7f7a2fb7..a1ea5ebbab 100644 --- a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs +++ b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs @@ -90,31 +90,31 @@ public void TestFloatPropertiesSideChannel() var dictSender = new Dictionary { { propB.ChannelId, propB } }; propA.RegisterCallback(k1, f => { wasCalled++; }); - var tmp = propB.GetPropertyWithDefault(k2, 3.0f); + var tmp = propB.GetWithDefault(k2, 3.0f); Assert.AreEqual(tmp, 3.0f); - propB.SetProperty(k2, 1.0f); - tmp = propB.GetPropertyWithDefault(k2, 3.0f); + propB.Set(k2, 1.0f); + tmp = propB.GetWithDefault(k2, 3.0f); Assert.AreEqual(tmp, 1.0f); byte[] fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); - tmp = propA.GetPropertyWithDefault(k2, 3.0f); + tmp = propA.GetWithDefault(k2, 3.0f); Assert.AreEqual(tmp, 1.0f); Assert.AreEqual(wasCalled, 0); - propB.SetProperty(k1, 1.0f); + propB.Set(k1, 1.0f); Assert.AreEqual(wasCalled, 0); fakeData = SideChannelsManager.GetSideChannelMessage(dictSender); SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); Assert.AreEqual(wasCalled, 1); - var keysA = propA.ListProperties(); + var keysA = propA.List(); Assert.AreEqual(2, keysA.Count); Assert.IsTrue(keysA.Contains(k1)); Assert.IsTrue(keysA.Contains(k2)); - var keysB = propA.ListProperties(); + var keysB = propA.List(); Assert.AreEqual(2, keysB.Count); Assert.IsTrue(keysB.Contains(k1)); Assert.IsTrue(keysB.Contains(k2)); diff --git a/docs/Custom-SideChannels.md b/docs/Custom-SideChannels.md index e0a6568f2c..b93e4fe30e 100644 --- a/docs/Custom-SideChannels.md +++ b/docs/Custom-SideChannels.md @@ -3,7 +3,7 @@ You can create your own side channel in C# and Python and use it to communicate custom data structures between the two. This can be useful for situations in which the data to be sent is too complex or structured for the built-in -`FloatPropertiesChannel`, or is not related to any specific agent, and therefore +`EnvironmentParameters`, or is not related to any specific agent, and therefore inappropriate as an agent observation. ## Overview @@ -24,7 +24,7 @@ To send data from C# to Python, create an `OutgoingMessage` instance, add data t `base.QueueMessageToSend(msg)` method inside the side channel, and call the `OutgoingMessage.Dispose()` method. -To register a side channel on the Unity side, call `SideChannelUtils.RegisterSideChannel` with the side channel +To register a side channel on the Unity side, call `SideChannelManager.RegisterSideChannel` with the side channel as only argument. ### Python side @@ -122,8 +122,8 @@ public class RegisterStringLogSideChannel : MonoBehaviour // When a Debug.Log message is created, we send it to the stringChannel Application.logMessageReceived += stringChannel.SendDebugStatementToPython; - // The channel must be registered with the SideChannelUtils class - SideChannelUtils.RegisterSideChannel(stringChannel); + // The channel must be registered with the SideChannelManager class + SideChannelManager.RegisterSideChannel(stringChannel); } public void OnDestroy() @@ -131,7 +131,7 @@ public class RegisterStringLogSideChannel : MonoBehaviour // De-register the Debug.Log callback Application.logMessageReceived -= stringChannel.SendDebugStatementToPython; if (Academy.IsInitialized){ - SideChannelUtils.UnregisterSideChannel(stringChannel); + SideChannelManager.UnregisterSideChannel(stringChannel); } } diff --git a/docs/Migrating.md b/docs/Migrating.md index e2cdba355c..b8c6b357ae 100644 --- a/docs/Migrating.md +++ b/docs/Migrating.md @@ -33,6 +33,19 @@ double-check that the versions are in the same. The versions can be found in - The signature of `Agent.Heuristic()` was changed to take a `float[]` as a parameter, instead of returning the array. This was done to prevent a common source of error where users would return arrays of the wrong size. +- The SideChannel API has changed (#3833, #3660) : + - Introduced the `SideChannelManager` to register, unregister and access side + channels. + - `EnvironmentParameters` replaces the default `FloatProperties`. + You can access the `EnvironmentParameters` with + `Academy.Instance.EnvironmentParameters` on C# and create an + `EnvironmentParametersChannel` on Python + - `SideChannel.OnMessageReceived` is now a protected method (was public) + - SideChannel IncomingMessages methods now take an optional default argument, + which is used when trying to read more data than the message contains. + - Added a feature to allow sending stats from C# environments to TensorBoard + (and other python StatsWriters). To do this from your code, use + `Academy.Instance.StatsRecorder.Add(key, value)`(#3660) ### Steps to Migrate @@ -42,18 +55,14 @@ double-check that the versions are in the same. The versions can be found in - To force-overwrite files from a pre-existing run, add the `--force` command-line flag. - The Jupyter notebooks have been removed from the repository. -- `Academy.FloatProperties` was removed. -- `Academy.RegisterSideChannel` and `Academy.UnregisterSideChannel` were - removed. -- Replace `Academy.FloatProperties` with - `SideChannelUtils.GetSideChannel()`. -- Replace `Academy.RegisterSideChannel` with - `SideChannelUtils.RegisterSideChannel()`. -- Replace `Academy.UnregisterSideChannel` with - `SideChannelUtils.UnregisterSideChannel`. - If your Agent class overrides `Heuristic()`, change the signature to `public override void Heuristic(float[] actionsOut)` and assign values to `actionsOut` instead of returning an array. +- If you used `SideChannels` you must: + - Replace `Academy.FloatProperties` with `Academy.Instance.EnvironmentParameters`. + - `Academy.RegisterSideChannel` and `Academy.UnregisterSideChannel` were + removed. Use `SideChannelManager.RegisterSideChannel` and + `SideChannelManager.UnregisterSideChannel` instead. ## Migrating from 0.14 to 0.15 diff --git a/docs/Python-API.md b/docs/Python-API.md index 4cbee7f06f..86da5c6dde 100644 --- a/docs/Python-API.md +++ b/docs/Python-API.md @@ -306,41 +306,34 @@ i = env.reset() ... ``` -#### FloatPropertiesChannel -The `FloatPropertiesChannel` will allow you to get and set pre-defined numerical values in the environment. This can be useful for adjusting environment-specific settings, or for reading non-agent related information from the environment. You can call `get_property` and `set_property` on the side channel to read and write properties. +#### EnvironmentParameters +The `EnvironmentParameters` will allow you to get and set pre-defined numerical values in the environment. This can be useful for adjusting environment-specific settings, or for reading non-agent related information from the environment. You can call `get_property` and `set_property` on the side channel to read and write properties. -`FloatPropertiesChannel` has three methods: +`EnvironmentParametersChannel` has one methods: - * `set_property` Sets a property in the Unity Environment. + * `set_float_parameter` Sets a float parameter in the Unity Environment. * key: The string identifier of the property. * value: The float value of the property. - * `get_property` Gets a property in the Unity Environment. If the property was not found, will return None. - * key: The string identifier of the property. - - * `list_properties` Returns a list of all the string identifiers of the properties - ```python from mlagents_envs.environment import UnityEnvironment -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel +from mlagents_envs.side_channel.environment_parameters_channel import EnvironmentParametersChannel -channel = FloatPropertiesChannel() +channel = EnvironmentParametersChannel() env = UnityEnvironment(side_channels=[channel]) -channel.set_property("parameter_1", 2.0) +channel.set_float_parameter("parameter_1", 2.0) i = env.reset() - -readout_value = channel.get_property("parameter_2") ... ``` Once a property has been modified in Python, you can access it in C# after the next call to `step` as follows: ```csharp -var sharedProperties = SideChannelUtils.GetSideChannel(); -float property1 = sharedProperties.GetPropertyWithDefault("parameter_1", 0.0f); +var envParameters = Academy.Instance.EnvironmentParameters; +float property1 = envParameters.GetWithDefault("parameter_1", 0.0f); ``` #### Custom side channels diff --git a/docs/Training-Curriculum-Learning.md b/docs/Training-Curriculum-Learning.md index 38885287ea..cb0203c8d2 100644 --- a/docs/Training-Curriculum-Learning.md +++ b/docs/Training-Curriculum-Learning.md @@ -40,8 +40,8 @@ the same environment. In order to define the curricula, the first step is to decide which parameters of the environment will vary. In the case of the Wall Jump environment, -the height of the wall is what varies. We define this as a `Shared Float Property` -that can be accessed in `SideChannelUtils.GetSideChannel()`, and by doing +the height of the wall is what varies. We define this as a `Environment Parameters` +that can be accessed in `Academy.Instance.EnvironmentParameters`, and by doing so it becomes adjustable via the Python API. Rather than adjusting it by hand, we will create a YAML file which describes the structure of the curricula. Within it, we can specify which diff --git a/docs/Using-Tensorboard.md b/docs/Using-Tensorboard.md index 6e818fc87d..d4b2c262cb 100644 --- a/docs/Using-Tensorboard.md +++ b/docs/Using-Tensorboard.md @@ -95,6 +95,6 @@ To get custom metrics from a C# environment into Tensorboard, you can use the StatsSideChannel: ```csharp -var statsSideChannel = SideChannelUtils.GetSideChannel(); -statsSideChannel.AddStat("MyMetric", 1.0); +var statsRecorder = Academy.Instance.StatsRecorder; +statsSideChannel.Add("MyMetric", 1.0); ``` diff --git a/ml-agents-envs/mlagents_envs/environment.py b/ml-agents-envs/mlagents_envs/environment.py index 178ebe1eb6..b0f05aa113 100644 --- a/ml-agents-envs/mlagents_envs/environment.py +++ b/ml-agents-envs/mlagents_envs/environment.py @@ -58,7 +58,7 @@ class UnityEnvironment(BaseEnv): # Currently we require strict equality between the communication protocol # on each side, although we may allow some flexibility in the future. # This should be incremented whenever a change is made to the communication protocol. - API_VERSION = "0.16.0" + API_VERSION = "0.17.0" # Default port that the editor listens on. If an environment executable # isn't specified, this port will be used. diff --git a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py index da43ce4e32..958364b675 100644 --- a/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py +++ b/ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py @@ -8,7 +8,7 @@ class EnvironmentParametersChannel(SideChannel): """ This is the SideChannel for sending environment parameters to Unity. You can send parameters to an environment with the command - set_float_property. + set_float_parameter. """ class EnvironmentDataTypes(IntEnum): @@ -24,7 +24,7 @@ def on_message_received(self, msg: IncomingMessage) -> None: + "this should not have happend." ) - def set_float_property(self, key: str, value: float) -> None: + def set_float_parameter(self, key: str, value: float) -> None: """ Sets a float environment parameter in the Unity Environment. :param key: The string identifier of the parameter. diff --git a/ml-agents/mlagents/trainers/simple_env_manager.py b/ml-agents/mlagents/trainers/simple_env_manager.py index fce80ce30e..eca037783e 100644 --- a/ml-agents/mlagents/trainers/simple_env_manager.py +++ b/ml-agents/mlagents/trainers/simple_env_manager.py @@ -44,7 +44,7 @@ def _reset_env( ) -> List[EnvironmentStep]: # type: ignore if config is not None: for k, v in config.items(): - self.env_params.set_float_property(k, v) + self.env_params.set_float_parameter(k, v) self.env.reset() all_step_result = self._generate_all_results() self.previous_step = EnvironmentStep(all_step_result, 0, {}, {}) diff --git a/ml-agents/mlagents/trainers/subprocess_env_manager.py b/ml-agents/mlagents/trainers/subprocess_env_manager.py index 3b4133ef78..35817b150a 100644 --- a/ml-agents/mlagents/trainers/subprocess_env_manager.py +++ b/ml-agents/mlagents/trainers/subprocess_env_manager.py @@ -170,7 +170,7 @@ def external_brains(): _send_response(EnvironmentCommand.EXTERNAL_BRAINS, external_brains()) elif req.cmd == EnvironmentCommand.RESET: for k, v in req.payload.items(): - env_parameters.set_float_property(k, v) + env_parameters.set_float_parameter(k, v) env.reset() all_step_result = _generate_all_results() _send_response(EnvironmentCommand.RESET, all_step_result) From 7bb1cf18292cf5db918b9b2fc376ea37795c9716 Mon Sep 17 00:00:00 2001 From: vincentpierre Date: Thu, 23 Apr 2020 15:59:05 -0700 Subject: [PATCH 22/23] Addressing renaming comments --- .../ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs | 4 ++-- .../Examples/3DBall/Scripts/Ball3DHardAgent.cs | 4 ++-- .../ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs | 2 +- .../FoodCollector/Scripts/FoodCollectorAgent.cs | 4 ++-- .../ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs | 2 +- .../ML-Agents/Examples/GridWorld/Scripts/GridArea.cs | 10 +++++----- .../Examples/PushBlock/Scripts/PushAgentBasic.cs | 8 ++++---- .../ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs | 8 ++++---- .../ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs | 2 +- .../Examples/Soccer/Scripts/SoccerFieldArea.cs | 2 +- .../ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs | 4 ++-- .../ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs | 6 +++--- .../Examples/WallJump/Scripts/WallJumpAgent.cs | 8 ++++---- com.unity.ml-agents/Runtime/EnvironmentParameters.cs | 4 ++-- .../Runtime/SideChannels/FloatPropertiesChannel.cs | 2 +- com.unity.ml-agents/Tests/Editor/SideChannelTests.cs | 4 ++-- 16 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs index f5f603b165..f6049ba529 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs @@ -75,8 +75,8 @@ public override void Heuristic(float[] actionsOut) public void SetBall() { //Set the attributes of the ball by fetching the information from the academy - m_BallRb.mass = m_ResetParams.GetParameterWithDefault("mass", 1.0f); - var scale = m_ResetParams.GetParameterWithDefault("scale", 1.0f); + m_BallRb.mass = m_ResetParams.GetWithDefault("mass", 1.0f); + var scale = m_ResetParams.GetWithDefault("scale", 1.0f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs index dbc7e1b027..674d9498d5 100644 --- a/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs +++ b/Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs @@ -66,8 +66,8 @@ public override void OnEpisodeBegin() public void SetBall() { //Set the attributes of the ball by fetching the information from the academy - m_BallRb.mass = m_ResetParams.GetParameterWithDefault("mass", 1.0f); - var scale = m_ResetParams.GetParameterWithDefault("scale", 1.0f); + m_BallRb.mass = m_ResetParams.GetWithDefault("mass", 1.0f); + var scale = m_ResetParams.GetWithDefault("scale", 1.0f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs index 157eba8ab6..6036a08299 100644 --- a/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs @@ -121,7 +121,7 @@ void Update() public void SetTargetScale() { - var targetScale = m_ResetParams.GetParameterWithDefault("target_scale", 1.0f); + var targetScale = m_ResetParams.GetWithDefault("target_scale", 1.0f); target.transform.localScale = new Vector3(targetScale, targetScale, targetScale); } diff --git a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs index 04d68fcc53..de718fab82 100644 --- a/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs +++ b/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs @@ -272,12 +272,12 @@ void OnCollisionEnter(Collision collision) public void SetLaserLengths() { - m_LaserLength = m_ResetParams.GetParameterWithDefault("laser_length", 1.0f); + m_LaserLength = m_ResetParams.GetWithDefault("laser_length", 1.0f); } public void SetAgentScale() { - float agentScale = m_ResetParams.GetParameterWithDefault("agent_scale", 1.0f); + float agentScale = m_ResetParams.GetWithDefault("agent_scale", 1.0f); gameObject.transform.localScale = new Vector3(agentScale, agentScale, agentScale); } diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs index 2343dbd678..52fbf9fde1 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs @@ -44,7 +44,7 @@ public override void CollectDiscreteActionMasks(DiscreteActionMasker actionMaske // Prevents the agent from picking an action that would make it collide with a wall var positionX = (int)transform.position.x; var positionZ = (int)transform.position.z; - var maxPosition = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f) - 1; + var maxPosition = (int)m_ResetParams.GetWithDefault("gridSize", 5f) - 1; if (positionX == 0) { diff --git a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs index adb3e3338b..22669bea37 100644 --- a/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs +++ b/Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs @@ -52,21 +52,21 @@ public void Start() private void SetEnvironment() { - transform.position = m_InitialPosition * (m_ResetParams.GetParameterWithDefault("gridSize", 5f) + 1); + transform.position = m_InitialPosition * (m_ResetParams.GetWithDefault("gridSize", 5f) + 1); var playersList = new List(); - for (var i = 0; i < (int)m_ResetParams.GetParameterWithDefault("numObstacles", 1); i++) + for (var i = 0; i < (int)m_ResetParams.GetWithDefault("numObstacles", 1); i++) { playersList.Add(1); } - for (var i = 0; i < (int)m_ResetParams.GetParameterWithDefault("numGoals", 1f); i++) + for (var i = 0; i < (int)m_ResetParams.GetWithDefault("numGoals", 1f); i++) { playersList.Add(0); } players = playersList.ToArray(); - var gridSize = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f); + var gridSize = (int)m_ResetParams.GetWithDefault("gridSize", 5f); m_Plane.transform.localScale = new Vector3(gridSize / 10.0f, 1f, gridSize / 10.0f); m_Plane.transform.localPosition = new Vector3((gridSize - 1) / 2f, -0.5f, (gridSize - 1) / 2f); m_Sn.transform.localScale = new Vector3(1, 1, gridSize + 2); @@ -84,7 +84,7 @@ private void SetEnvironment() public void AreaReset() { - var gridSize = (int)m_ResetParams.GetParameterWithDefault("gridSize", 5f); + var gridSize = (int)m_ResetParams.GetWithDefault("gridSize", 5f); foreach (var actor in actorObjs) { DestroyImmediate(actor); diff --git a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs index f7da0a1bb7..53d06e4a50 100644 --- a/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs +++ b/Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs @@ -232,18 +232,18 @@ public void SetGroundMaterialFriction() { var groundCollider = ground.GetComponent(); - groundCollider.material.dynamicFriction = m_ResetParams.GetParameterWithDefault("dynamic_friction", 0); - groundCollider.material.staticFriction = m_ResetParams.GetParameterWithDefault("static_friction", 0); + groundCollider.material.dynamicFriction = m_ResetParams.GetWithDefault("dynamic_friction", 0); + groundCollider.material.staticFriction = m_ResetParams.GetWithDefault("static_friction", 0); } public void SetBlockProperties() { - var scale = m_ResetParams.GetParameterWithDefault("block_scale", 2); + var scale = m_ResetParams.GetWithDefault("block_scale", 2); //Set the scale of the block m_BlockRb.transform.localScale = new Vector3(scale, 0.75f, scale); // Set the drag of the block - m_BlockRb.drag = m_ResetParams.GetParameterWithDefault("block_drag", 0.5f); + m_BlockRb.drag = m_ResetParams.GetWithDefault("block_drag", 0.5f); } private void SetResetParameters() diff --git a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs index 6a8e001070..da369334a6 100644 --- a/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs @@ -114,9 +114,9 @@ public override void OnEpisodeBegin() public void SetResetParameters() { - m_GoalSize = m_ResetParams.GetParameterWithDefault("goal_size", 5); - m_GoalSpeed = Random.Range(-1f, 1f) * m_ResetParams.GetParameterWithDefault("goal_speed", 1); - m_Deviation = m_ResetParams.GetParameterWithDefault("deviation", 0); - m_DeviationFreq = m_ResetParams.GetParameterWithDefault("deviation_freq", 0); + m_GoalSize = m_ResetParams.GetWithDefault("goal_size", 5); + m_GoalSpeed = Random.Range(-1f, 1f) * m_ResetParams.GetWithDefault("goal_speed", 1); + m_Deviation = m_ResetParams.GetWithDefault("deviation", 0); + m_DeviationFreq = m_ResetParams.GetWithDefault("deviation_freq", 0); } } diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs index e18d0dea81..8ec3202a5f 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs @@ -218,7 +218,7 @@ public override void OnEpisodeBegin() { timePenalty = 0; - m_BallTouch = m_ResetParams.GetParameterWithDefault("ball_touch", 0); + m_BallTouch = m_ResetParams.GetWithDefault("ball_touch", 0); if (team == Team.Purple) { transform.rotation = Quaternion.Euler(0f, -90f, 0f); diff --git a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs index c6261ce8e0..fcafa5f50b 100644 --- a/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs +++ b/Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs @@ -80,7 +80,7 @@ public void ResetBall() ballRb.velocity = Vector3.zero; ballRb.angularVelocity = Vector3.zero; - var ballScale = m_ResetParams.GetParameterWithDefault("ball_scale", 0.015f); + var ballScale = m_ResetParams.GetWithDefault("ball_scale", 0.015f); ballRb.transform.localScale = new Vector3(ballScale, ballScale, ballScale); } } diff --git a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs index 9202cb72f3..49d1c4c84c 100644 --- a/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs @@ -105,7 +105,7 @@ public override void OnEpisodeBegin() public void SetRacket() { - angle = m_ResetParams.GetParameterWithDefault("angle", 55); + angle = m_ResetParams.GetWithDefault("angle", 55); gameObject.transform.eulerAngles = new Vector3( gameObject.transform.eulerAngles.x, gameObject.transform.eulerAngles.y, @@ -115,7 +115,7 @@ public void SetRacket() public void SetBall() { - scale = m_ResetParams.GetParameterWithDefault("scale", .5f); + scale = m_ResetParams.GetWithDefault("scale", .5f); ball.transform.localScale = new Vector3(scale, scale, scale); } diff --git a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs index dd32576d78..2d481028cc 100644 --- a/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs +++ b/Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs @@ -179,9 +179,9 @@ public override void OnEpisodeBegin() public void SetTorsoMass() { - m_ChestRb.mass = m_ResetParams.GetParameterWithDefault("chest_mass", 8); - m_SpineRb.mass = m_ResetParams.GetParameterWithDefault("spine_mass", 10); - m_HipsRb.mass = m_ResetParams.GetParameterWithDefault("hip_mass", 15); + m_ChestRb.mass = m_ResetParams.GetWithDefault("chest_mass", 8); + m_SpineRb.mass = m_ResetParams.GetWithDefault("spine_mass", 10); + m_HipsRb.mass = m_ResetParams.GetWithDefault("hip_mass", 15); } public void SetResetParameters() diff --git a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs index dde2547838..69a099a322 100644 --- a/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs +++ b/Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs @@ -316,7 +316,7 @@ void ConfigureAgent(int config) { localScale = new Vector3( localScale.x, - m_ResetParams.GetParameterWithDefault("no_wall_height", 0), + m_ResetParams.GetWithDefault("no_wall_height", 0), localScale.z); wall.transform.localScale = localScale; SetModel("SmallWallJump", noWallBrain); @@ -325,15 +325,15 @@ void ConfigureAgent(int config) { localScale = new Vector3( localScale.x, - m_ResetParams.GetParameterWithDefault("small_wall_height", 4), + m_ResetParams.GetWithDefault("small_wall_height", 4), localScale.z); wall.transform.localScale = localScale; SetModel("SmallWallJump", smallWallBrain); } else { - var min = m_ResetParams.GetParameterWithDefault("big_wall_min_height", 8); - var max = m_ResetParams.GetParameterWithDefault("big_wall_max_height", 8); + var min = m_ResetParams.GetWithDefault("big_wall_min_height", 8); + var max = m_ResetParams.GetWithDefault("big_wall_max_height", 8); var height = min + Random.value * (max - min); localScale = new Vector3( localScale.x, diff --git a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs index 9784a5b13b..55cac9176d 100644 --- a/com.unity.ml-agents/Runtime/EnvironmentParameters.cs +++ b/com.unity.ml-agents/Runtime/EnvironmentParameters.cs @@ -36,7 +36,7 @@ internal EnvironmentParameters() /// The parameter key /// Default value for this parameter. /// - public float GetParameterWithDefault(string key, float defaultValue) + public float GetWithDefault(string key, float defaultValue) { return m_Channel.GetWithDefault(key, defaultValue); } @@ -57,7 +57,7 @@ public void RegisterCallback(string key, Action action) /// Returns a list of all the parameter keys that have received values. /// /// List of parameter keys. - public IList ListParameters() + public IList Keys() { return m_Channel.ListParameters(); } diff --git a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs index 2c2ebd9a14..2bcaf3c919 100644 --- a/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs +++ b/com.unity.ml-agents/Runtime/SideChannels/FloatPropertiesChannel.cs @@ -89,7 +89,7 @@ public void RegisterCallback(string key, Action action) /// Returns a list of all the string identifiers of the properties currently present. /// /// The list of string identifiers - public IList List() + public IList Keys() { return new List(m_FloatProperties.Keys); } diff --git a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs index a1ea5ebbab..0cfdd0794f 100644 --- a/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs +++ b/com.unity.ml-agents/Tests/Editor/SideChannelTests.cs @@ -109,12 +109,12 @@ public void TestFloatPropertiesSideChannel() SideChannelsManager.ProcessSideChannelData(dictReceiver, fakeData); Assert.AreEqual(wasCalled, 1); - var keysA = propA.List(); + var keysA = propA.Keys(); Assert.AreEqual(2, keysA.Count); Assert.IsTrue(keysA.Contains(k1)); Assert.IsTrue(keysA.Contains(k2)); - var keysB = propA.List(); + var keysB = propA.Keys(); Assert.AreEqual(2, keysB.Count); Assert.IsTrue(keysB.Contains(k1)); Assert.IsTrue(keysB.Contains(k2)); From f326961ed86a0694c60d446c75756bd08041b085 Mon Sep 17 00:00:00 2001 From: vincentpierre Date: Thu, 23 Apr 2020 16:09:39 -0700 Subject: [PATCH 23/23] Removing the EngineParameters class --- com.unity.ml-agents/Runtime/Academy.cs | 6 ++-- .../Runtime/EngineParameters.cs | 35 ------------------- .../Runtime/EngineParameters.cs.meta | 11 ------ 3 files changed, 2 insertions(+), 50 deletions(-) delete mode 100644 com.unity.ml-agents/Runtime/EngineParameters.cs delete mode 100644 com.unity.ml-agents/Runtime/EngineParameters.cs.meta diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs index 5d3f7c1648..73dbeec163 100644 --- a/com.unity.ml-agents/Runtime/Academy.cs +++ b/com.unity.ml-agents/Runtime/Academy.cs @@ -42,7 +42,7 @@ void FixedUpdate() /// Access the Academy singleton through the /// property. The Academy instance is initialized the first time it is accessed (which will /// typically be by the first initialized in a scene). - /// + /// /// At initialization, the Academy attempts to connect to the Python training process through /// the external communicator. If successful, the training process can train /// instances. When you set an agent's setting @@ -311,7 +311,6 @@ static int ReadPortFromArgs() } } - private EngineParameters m_EngineParameters; private EnvironmentParameters m_EnvironmentParameters; private StatsRecorder m_StatsRecorder; @@ -347,7 +346,7 @@ void InitializeEnvironment() EnableAutomaticStepping(); - m_EngineParameters = new EngineParameters(); + SideChannelsManager.RegisterSideChannel(new EngineConfigurationChannel()); m_EnvironmentParameters = new EnvironmentParameters(); m_StatsRecorder = new StatsRecorder(); @@ -558,7 +557,6 @@ public void Dispose() Communicator?.Dispose(); Communicator = null; - m_EngineParameters.Dispose(); m_EnvironmentParameters.Dispose(); m_StatsRecorder.Dispose(); SideChannelsManager.UnregisterAllSideChannels(); // unregister custom side channels diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs b/com.unity.ml-agents/Runtime/EngineParameters.cs deleted file mode 100644 index d7c0eec167..0000000000 --- a/com.unity.ml-agents/Runtime/EngineParameters.cs +++ /dev/null @@ -1,35 +0,0 @@ -using MLAgents.SideChannels; -using UnityEngine; - -namespace MLAgents -{ - /// - /// A container for the Engine Settings that can be specified at the start of - /// training. These Engine settings are set once at the start of training based on the - /// training configuration. The actual Engine settings applied may be slightly different - /// (e.g. TimeScale is clamped). This class enables the retrieval of the final settings. Note - /// that if the Engine settings are directly changed anywhere in your Project, then the values - /// returned here may not be reflective of the actual Engine settings. - /// - internal sealed class EngineParameters - { - /// - /// The side channel that is used to receive the engine configurations. - /// - readonly EngineConfigurationChannel m_Channel; - - /// - /// Constructor. - /// - public EngineParameters() - { - m_Channel = new EngineConfigurationChannel(); - SideChannelsManager.RegisterSideChannel(m_Channel); - } - - internal void Dispose() - { - SideChannelsManager.UnregisterSideChannel(m_Channel); - } - } -} diff --git a/com.unity.ml-agents/Runtime/EngineParameters.cs.meta b/com.unity.ml-agents/Runtime/EngineParameters.cs.meta deleted file mode 100644 index 3d5cf01220..0000000000 --- a/com.unity.ml-agents/Runtime/EngineParameters.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: de156bd22d1b24f7aa2419409c82dacd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: