Curso de Inteligencia Artificial con ML-Agents de UNITY. Introducción.
Nuestro primer MLAgent Humanoide
Cualquier duda o comentario de la lección podéis dejarla en el foro del curso.
Creamos una escena nueva donde el Agente es un personaje Humanoide. Aprovechamos para cambiar el Space Type del Vector Action de Continous a Discrete y ver la otra forma de manejar las acciones desde el script que controla nuestro agente.
Al ser el agente de tipo humanoide solo camina hacia adelante, por lo que debemos incorporar más variables en observaciones para que pueda decidir hacia donde debe girar antes de avanzar.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Unity.MLAgents; using Unity.MLAgents.Sensors; public class HumanoidML : Agent { [Header("Velocidad")] [Range(0f, 5f)] public float _speed; [Header("Velocidad de giro")] [Range(50f, 300f)] public float _turnSpeed; public bool _training = true; private Rigidbody _rb; [SerializeField] private Transform _target; private Animator _anim; private Vector3 _previous; public override void Initialize() { _rb = GetComponent<Rigidbody>(); _anim = GetComponent<Animator>(); _previous = transform.position; //MaxStep forma parte de la clase Agent if (!_training) MaxStep = 0; } public override void OnEpisodeBegin() { _rb.velocity = Vector3.zero; _rb.angularVelocity = Vector3.zero; MoverPosicionInicial(); _previous = transform.position; } public override void OnActionReceived(float[] vectorAction) { float lForward = vectorAction[0]; float lTurn = 0; if (vectorAction[1] == 1) { lTurn = -1; } else if (vectorAction[1] == 2) { lTurn = 1; } _rb.MovePosition(transform.position + transform.forward * lForward * _speed * Time.deltaTime); transform.Rotate(transform.up * lTurn * _turnSpeed * Time.deltaTime); } public void Update() { float velocity = ((transform.position - _previous).magnitude) / Time.deltaTime; _previous = transform.position; _anim.SetFloat("multiplicador", velocity); } public override void Heuristic(float[] actionsOut) { float lForward = 0f; float lTurn = 0f; if (Input.GetKey(KeyCode.UpArrow)) { lForward = 1f; } if (Input.GetKey(KeyCode.LeftArrow)) { lTurn = 1f; } else if (Input.GetKey(KeyCode.RightArrow)) { lTurn = 2f; } // Put the actions into an array and return actionsOut[0] = lForward; actionsOut[1] = lTurn; } public override void CollectObservations(VectorSensor sensor) { //Distancia al target. //Float de 1 posicion. sensor.AddObservation( Vector3.Distance(_target.transform.position, transform.position)); //Dirección al target. //Vector 3 posiciones. sensor.AddObservation( (_target.transform.position - transform.position).normalized); //Vector del señor, donde mira. //Vector de 3 posiciones. sensor.AddObservation( transform.forward); } private void OnTriggerStay(Collider other) { if (_training) { if (other.CompareTag("target")) { AddReward(0.5f); } if (other.CompareTag("borders")) { AddReward(-0.05f); } } } private void MoverPosicionInicial() { bool posicionEncontrada = false; int intentos = 100; Vector3 posicionPotencial = Vector3.zero; while (!posicionEncontrada || intentos >= 0) { intentos--; posicionPotencial = new Vector3( transform.parent.position.x + UnityEngine.Random.Range(-3f, 3f), 0.555f, transform.parent.position.z + UnityEngine.Random.Range(-3f, 3f)); //en el caso de que tengamos mas cosas en el escenario checker que no choca Collider[] colliders = Physics.OverlapSphere(posicionPotencial, 0.5f); if (colliders.Length == 0) { transform.position = posicionPotencial; posicionEncontrada = true; } } } }
Ficheros útiles o necesarios para crear la escena.
- Segunda escena completa: scene_humanoid.unitypackage
En caso de que no os queráis bajar la escena completa y prefiráis seguir los pasos del vídeo podéis bajar estos assets:
- Personaje humanoide creado con MagicaVoxel y animado: personaje
- Low Poly environment pack: https://assetstore.unity.com/packages/3d/environments/landscapes/lowpoly-environment-pack-99479
Comandos usados en la creación del segundo entorno de conda para este proyecto:
- Creamos el entorno, en caso de que tengamos otra versión de python indicarla: conda create -n cursoml2 python=3.7
- Activamos el entorno: conda activate cursoml2
- Instalamos los MLAgents: pip instal mlagents
En el caso de que os de problemas la instalación probad estos otros comandos:
- Crear el entorno: conda create -n ml-agents python=3.8
- Activar el entorno: conda activate ml-agents
- instalar numpy: pip install numpy==1.19.0
- instalar ml-agents: pip install ml-agents
- instalar pytorch: conda install -c pytorch pytorch
También podéis crear el personaje por vosotros mismos siguiendo los pasos de este otro vídeo: