Unity/인공지능

[5.17] ML-Agent 환경 구성하기

ljw4104 2021. 5. 17. 18:06

환경 씬 및 Agent 인스펙터

using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;

public class RollerAgent : Agent
{
    private Rigidbody rBody;

    public Transform target;
    void Start()
    {
        this.rBody = GetComponent<Rigidbody>();
    }

    //새로운 환경을 설정.
    //Agent가 다양한 조건에서 작업을 해결하는 방법을 배울 수 있도록 무작위로 초기화.
    public override void OnEpisodeBegin()
    {
        if (this.transform.localPosition.y < 0)
        {
            this.rBody.angularVelocity = Vector3.zero;
            this.rBody.velocity = Vector3.zero;
            this.transform.localPosition = new Vector3(0, 0.5f, 0);
        }

        this.target.localPosition = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4);
    }

    //Agent가 정보를 수집하도록 함.
    public override void CollectObservations(VectorSensor sensor)
    {
        //각각의 성분을 float으로 분해해서 보내기때문에
        //여기서는 8개(localPosition 3개 * 2 + 2)의 성분이 Brain으로 보내진다.
        sensor.AddObservation(this.target.localPosition);
        sensor.AddObservation(this.transform.localPosition);

        sensor.AddObservation(this.rBody.velocity.x);
        sensor.AddObservation(this.rBody.velocity.z);
    }

    public float forceMultiplier = 10;
    //Python Trainer로부터 데이터를 받아옴.
    //ActionBuffers에 담긴 데이터를 가지고 행동을 취함.
    public override void OnActionReceived(ActionBuffers actionBuffers)
    {
        //Data를 받아와서 Action을 취한다.
        //Agent가 x방향 혹은 z방향으로 이동할 수 있도록 힘을 줌.
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = actionBuffers.ContinuousActions[0];
        controlSignal.z = actionBuffers.ContinuousActions[1];
        //ContinuoousAction : 연속적인 값을 판단함.
        rBody.AddForce(controlSignal * forceMultiplier);

        float distanceToTarget = Vector3.Distance(this.transform.localPosition, this.target.localPosition);
        //일정수준 이하로 거리가 좁혀졌으면 보상을 주고 새로운 에피소드 시작.
        if (distanceToTarget < 1.42f)
        {
            SetReward(1.0f);
            EndEpisode();
        }
        //범위를 벗어났으면 종료 후 새로운 에피소드 시작.
        else if (this.transform.localPosition.y < 0)
        {
            EndEpisode();
        }
    }

    public override void Heuristic(in ActionBuffers actionsOut)
    {
        //임시로 키보드로 테스트하게함.
        var continuousActionsOut = actionsOut.ContinuousActions;
        continuousActionsOut[0] = Input.GetAxis("Horizontal");
        continuousActionsOut[1] = Input.GetAxis("Vertical");
    }
}

 

아직까지는 자동으로 움직이지 않는다. Trainer가 없기 때문에...

키보드로 조종할 수 있다. 

아무래도 Heuristic 함수의 continuousActionOut 구조체에 값을 파이썬에서 받아와서 넣는것같다.

 

Agent를 상속받는다. 아래의 함수들을 오버라이드 해야한다.

  1. public override void OnEpisodeBegin() : 환경을 초기화한다.
  2. public override void CollectObservations(VectorSensor sensor) : Agent가 Brain에게 정보를 전달한다. 환경관찰
  3. public override void OnActionReceived(ActionBuffers actionBuffers) : 결과값을 바탕으로 이동한다. 목표에 도달하였을 경우 보상을 받음.
  4. public override void Heuristic(in ActionBuffers actionsOut) : 사람이 직접 Agent를 제어하는 함수이다.