Reinforcement Learning
ml-agents
TensorBoard
ONNX
Pyramids
deep-reinforcement-learning
ML-Agents-Pyramids
Instructions to use AnnaMats/ppo-Pyramids-Training with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- ml-agents
How to use AnnaMats/ppo-Pyramids-Training with ml-agents:
mlagents-load-from-hf --repo-id="AnnaMats/ppo-Pyramids-Training" --local-dir="./download: string[]s"
- Notebooks
- Google Colab
- Kaggle
| //Put this script on your blue cube. | |
| using System.Collections; | |
| using UnityEngine; | |
| using Unity.MLAgents; | |
| using Unity.MLAgents.Actuators; | |
| public class PushAgentBasic : Agent | |
| { | |
| /// <summary> | |
| /// The ground. The bounds are used to spawn the elements. | |
| /// </summary> | |
| public GameObject ground; | |
| public GameObject area; | |
| /// <summary> | |
| /// The area bounds. | |
| /// </summary> | |
| [] | |
| public Bounds areaBounds; | |
| PushBlockSettings m_PushBlockSettings; | |
| /// <summary> | |
| /// The goal to push the block to. | |
| /// </summary> | |
| public GameObject goal; | |
| /// <summary> | |
| /// The block to be pushed to the goal. | |
| /// </summary> | |
| public GameObject block; | |
| /// <summary> | |
| /// Detects when the block touches the goal. | |
| /// </summary> | |
| [] | |
| public GoalDetect goalDetect; | |
| public bool useVectorObs; | |
| Rigidbody m_BlockRb; //cached on initialization | |
| Rigidbody m_AgentRb; //cached on initialization | |
| Material m_GroundMaterial; //cached on Awake() | |
| /// <summary> | |
| /// We will be changing the ground material based on success/failue | |
| /// </summary> | |
| Renderer m_GroundRenderer; | |
| EnvironmentParameters m_ResetParams; | |
| protected override void Awake() | |
| { | |
| base.Awake(); | |
| m_PushBlockSettings = FindObjectOfType<PushBlockSettings>(); | |
| } | |
| public override void Initialize() | |
| { | |
| goalDetect = block.GetComponent<GoalDetect>(); | |
| goalDetect.agent = this; | |
| // Cache the agent rigidbody | |
| m_AgentRb = GetComponent<Rigidbody>(); | |
| // Cache the block rigidbody | |
| m_BlockRb = block.GetComponent<Rigidbody>(); | |
| // Get the ground's bounds | |
| areaBounds = ground.GetComponent<Collider>().bounds; | |
| // Get the ground renderer so we can change the material when a goal is scored | |
| m_GroundRenderer = ground.GetComponent<Renderer>(); | |
| // Starting material | |
| m_GroundMaterial = m_GroundRenderer.material; | |
| m_ResetParams = Academy.Instance.EnvironmentParameters; | |
| SetResetParameters(); | |
| } | |
| /// <summary> | |
| /// Use the ground's bounds to pick a random spawn position. | |
| /// </summary> | |
| public Vector3 GetRandomSpawnPos() | |
| { | |
| var foundNewSpawnLocation = false; | |
| var randomSpawnPos = Vector3.zero; | |
| while (foundNewSpawnLocation == false) | |
| { | |
| var randomPosX = Random.Range(-areaBounds.extents.x * m_PushBlockSettings.spawnAreaMarginMultiplier, | |
| areaBounds.extents.x * m_PushBlockSettings.spawnAreaMarginMultiplier); | |
| var randomPosZ = Random.Range(-areaBounds.extents.z * m_PushBlockSettings.spawnAreaMarginMultiplier, | |
| areaBounds.extents.z * m_PushBlockSettings.spawnAreaMarginMultiplier); | |
| randomSpawnPos = ground.transform.position + new Vector3(randomPosX, 1f, randomPosZ); | |
| if (Physics.CheckBox(randomSpawnPos, new Vector3(2.5f, 0.01f, 2.5f)) == false) | |
| { | |
| foundNewSpawnLocation = true; | |
| } | |
| } | |
| return randomSpawnPos; | |
| } | |
| /// <summary> | |
| /// Called when the agent moves the block into the goal. | |
| /// </summary> | |
| public void ScoredAGoal() | |
| { | |
| // We use a reward of 5. | |
| AddReward(5f); | |
| // By marking an agent as done AgentReset() will be called automatically. | |
| EndEpisode(); | |
| // Swap ground material for a bit to indicate we scored. | |
| StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.goalScoredMaterial, 0.5f)); | |
| } | |
| /// <summary> | |
| /// Swap ground material, wait time seconds, then swap back to the regular material. | |
| /// </summary> | |
| IEnumerator GoalScoredSwapGroundMaterial(Material mat, float time) | |
| { | |
| m_GroundRenderer.material = mat; | |
| yield return new WaitForSeconds(time); // Wait for 2 sec | |
| m_GroundRenderer.material = m_GroundMaterial; | |
| } | |
| /// <summary> | |
| /// Moves the agent according to the selected action. | |
| /// </summary> | |
| public void MoveAgent(ActionSegment<int> act) | |
| { | |
| var dirToGo = Vector3.zero; | |
| var rotateDir = Vector3.zero; | |
| var action = act[0]; | |
| switch (action) | |
| { | |
| case 1: | |
| dirToGo = transform.forward * 1f; | |
| break; | |
| case 2: | |
| dirToGo = transform.forward * -1f; | |
| break; | |
| case 3: | |
| rotateDir = transform.up * 1f; | |
| break; | |
| case 4: | |
| rotateDir = transform.up * -1f; | |
| break; | |
| case 5: | |
| dirToGo = transform.right * -0.75f; | |
| break; | |
| case 6: | |
| dirToGo = transform.right * 0.75f; | |
| break; | |
| } | |
| transform.Rotate(rotateDir, Time.fixedDeltaTime * 200f); | |
| m_AgentRb.AddForce(dirToGo * m_PushBlockSettings.agentRunSpeed, | |
| ForceMode.VelocityChange); | |
| } | |
| /// <summary> | |
| /// Called every step of the engine. Here the agent takes an action. | |
| /// </summary> | |
| public override void OnActionReceived(ActionBuffers actionBuffers) | |
| { | |
| // Move the agent using the action. | |
| MoveAgent(actionBuffers.DiscreteActions); | |
| // Penalty given each step to encourage agent to finish task quickly. | |
| AddReward(-1f / MaxStep); | |
| } | |
| public override void Heuristic(in ActionBuffers actionsOut) | |
| { | |
| var discreteActionsOut = actionsOut.DiscreteActions; | |
| if (Input.GetKey(KeyCode.D)) | |
| { | |
| discreteActionsOut[0] = 3; | |
| } | |
| else if (Input.GetKey(KeyCode.W)) | |
| { | |
| discreteActionsOut[0] = 1; | |
| } | |
| else if (Input.GetKey(KeyCode.A)) | |
| { | |
| discreteActionsOut[0] = 4; | |
| } | |
| else if (Input.GetKey(KeyCode.S)) | |
| { | |
| discreteActionsOut[0] = 2; | |
| } | |
| } | |
| /// <summary> | |
| /// Resets the block position and velocities. | |
| /// </summary> | |
| void ResetBlock() | |
| { | |
| // Get a random position for the block. | |
| block.transform.position = GetRandomSpawnPos(); | |
| // Reset block velocity back to zero. | |
| m_BlockRb.velocity = Vector3.zero; | |
| // Reset block angularVelocity back to zero. | |
| m_BlockRb.angularVelocity = Vector3.zero; | |
| } | |
| /// <summary> | |
| /// In the editor, if "Reset On Done" is checked then AgentReset() will be | |
| /// called automatically anytime we mark done = true in an agent script. | |
| /// </summary> | |
| public override void OnEpisodeBegin() | |
| { | |
| var rotation = Random.Range(0, 4); | |
| var rotationAngle = rotation * 90f; | |
| area.transform.Rotate(new Vector3(0f, rotationAngle, 0f)); | |
| ResetBlock(); | |
| transform.position = GetRandomSpawnPos(); | |
| m_AgentRb.velocity = Vector3.zero; | |
| m_AgentRb.angularVelocity = Vector3.zero; | |
| SetResetParameters(); | |
| } | |
| public void SetGroundMaterialFriction() | |
| { | |
| var groundCollider = ground.GetComponent<Collider>(); | |
| 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.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.GetWithDefault("block_drag", 0.5f); | |
| } | |
| void SetResetParameters() | |
| { | |
| SetGroundMaterialFriction(); | |
| SetBlockProperties(); | |
| } | |
| } | |