Unity强化学习工具MLAgents

文章目录

  • 参考资料
  • 一、环境准备
    • 1、下载ml-agents
    • 2、安装Unity Hub
    • 3、安装Unity 3D
  • 二、新建项目
    • 2.1 新建工程
    • 2.2 搭建场景
    • 2.3 设置材质
  • 三、程序
    • 3.1 游戏过程
    • 3.2 代码
  • 三、查看日志

参考资料

B站视频: 年轻人的第一个游戏AI:Unity强化学习工具MLAgents全流程实例教程.

一、环境准备

1、下载ml-agents

ml-agents,选择版本0.14.0。
Unity强化学习工具MLAgents_第1张图片
Unity强化学习工具MLAgents_第2张图片
下载完后,进入ml-agents-envs目录,例如我的路径为:D:\simws\lib\ml-agents-0.14.0\ml-agents-envs>。
cmd后,运行pip install -e .(-e后有一个点)。
再进入ml-agents目录,再执行pip install -e .
执行mlagents-learn --help测试是否安装成功。
如图所示,即安装成功!
Unity强化学习工具MLAgents_第3张图片

2、安装Unity Hub

https://www.jianshu.com/p/e21a32e67b70.

3、安装Unity 3D

选择的版本是2019.4.16https://unity.cn/releases/lts.

二、新建项目

2.1 新建工程

打开Unity Hub: 选择项目——>新建:
Unity强化学习工具MLAgents_第4张图片
选择3D,输入名称,选择路径。
Unity强化学习工具MLAgents_第5张图片
在项目中,选择Window——>package manager——>左上角+号——>add package from disk。
Unity强化学习工具MLAgents_第6张图片
选择下载的ML-agents包里com.unity.ml-agents里的package.json文件。
Unity强化学习工具MLAgents_第7张图片

2.2 搭建场景

2.2.1 新建空的游戏对象
在Hierarchy空白区域右键鼠标,选择Create Empty。在右侧改名字为JuggleArea
Unity强化学习工具MLAgents_第8张图片
2.2.2 在空对象里新建一个平面
在JuggleArea上右键,选择3D Object——>Plane.改名字为Ground,x轴和y轴都设置为2倍。
Unity强化学习工具MLAgents_第9张图片
2.2.3 新建一个球,3D Object——>Sphere,改名字为Ball。给它Y轴坐标一个5。

Unity强化学习工具MLAgents_第10张图片
2.2.4 新建一个Capsule,3D Object——>Capsule,表示球员,改名字为Player。给它Y轴坐标一个1。
Unity强化学习工具MLAgents_第11张图片

2.3 设置材质

2.3.1 在Assets下新建文件夹Materials存放材质文件。
Unity强化学习工具MLAgents_第12张图片
2.3.2 在Materials目录下右键——>Create,新建一个Material,修改名字为Ball,修改颜色为红色。
Unity强化学习工具MLAgents_第13张图片
将材质拖动到球上,即可给球添加上材质。
2.3.3
Ctrl+D复制材质。改名字为Player,选一个颜色,再复制一个材质,改名字为Ground选择一个颜色。
2.3.4 给Ball和Player分别设置刚体(Rigibody).
选择Ball,选择Add Component,
Unity强化学习工具MLAgents_第14张图片
选择RigidBody.
Unity强化学习工具MLAgents_第15张图片
此时点击Play按钮,发现弹性不是很好。需要添加物理材质。
Unity强化学习工具MLAgents_第16张图片
2.3.5 添加物理材质。
再Materials区域,右键——>Create——>Physic Materials,修改名字为BallPhy,弹性修改为0.9。
Unity强化学习工具MLAgents_第17张图片
Ctrl+D复制一个物理材质,修改名字为PlayPhy,弹性设置为0.5.将材质给物体都添加上即可。
为了防止Player出现奇怪的姿势,将它的X轴和Y轴的角度冻结。
Unity强化学习工具MLAgents_第18张图片

三、程序

3.1 游戏过程

Unity强化学习工具MLAgents_第19张图片
第一步:CollectObservations()收集游戏的各种环境。例如球的位置,球的速度,球员的位置,球员的速度等,将这些信息给到MLAgents。
第二步:MLAgents根据环境信息计算一个操作数组。
第三步:将操作数组发送给AgentAction()。它实现整个游戏的一个操作。在本例中主要实现移动球员,判断颠球,以及判断游戏是否结束。如果结束了,就调用AgentRest()重置环境。没有结束就从第一步循环下去。

3.2 代码

在Assets下新建Scripts文件夹,在文件夹下新建一个C#脚本JuggleAgent,并将JuggleAgent拖到Player上。在Assets下新建Prefabs文件夹。将JuggleArea拖进去。这样就成了一个预设。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
using TMPro;

public class JuggleAgent : Agent
{
    public Rigidbody ball;
    Rigidbody player;
    public float speed = 30.0f;
    
    float diff = 0.0f; // 球员当前的y轴与上一步的的差异
    float previousDiff = 0.0f; // 保留了上一个diff
    float previousY = 5.0f; // 球员上一步的y轴的值
    bool collied = false;

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.rigidbody == ball)
        {
            collied = true;
        }
    }

    public override void InitializeAgent()
    {
        player = this.GetComponent<Rigidbody>();
    }
// 观察到的场景信息
    public override void CollectObservations()
    {
        AddVectorObs(ball.transform.localPosition); // 球的位置  3维 
        AddVectorObs(ball.velocity); // 球的速度, 3维
        AddVectorObs(ball.rotation); // 球的角度, 4维
        AddVectorObs(ball.angularVelocity); // 球的角速度,3维 
        // 球的信息 3+3+4+3 = 13

        AddVectorObs(player.transform.localPosition);
        AddVectorObs(player.velocity);
        AddVectorObs(player.rotation);
        AddVectorObs(player.angularVelocity);
        // 球+球员信息:13 * 2 =26 维数据
    }

    public override void AgentAction(float[] vectorAction)
    {
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = vectorAction[0];
        controlSignal.z = vectorAction[1];
        // 先判断Y轴是不是等于1(在地面,因为设置的地面高度为1),只有在地面的时候才能起跳,不在地面不能跳。
        if(player.transform.localPosition.y == 1.0f)
        {
            controlSignal.y = vectorAction[2] * 10.0f;
        }

        player.AddForce(controlSignal * speed);
        // 下面是判断球员是否颠球成功。球从上往下掉,Y轴减小,颠球成功,则Y轴变大,所以在Y先变小,后变大的时候,表示颠球成功,及previousDiff<0,diff>0的时候。
        diff = ball.transform.localPosition.y - previousY;
        // 为了防止球员拿着球上下移动,所以加了一个碰撞检测collied由OnCollisionEnter()方法得出。
        if(diff > 0.0f && previousDiff < 0.0f && collied)
        {
            AddReward(0.1f);
        }
        collied = false;
        previousDiff = diff;
        previousY = ball.transform.localPosition.y;
        // 如果球低于1.5,即接不到球,或者球员跑出了边界(场地为20*20,以中心点为(0,0),则位置绝对值大于10表示出街),判定游戏结束。
        if(ball.transform.localPosition.y < 1.5f || Mathf.Abs(player.transform.localPosition.x) > 10.0f || Mathf.Abs(player.transform.localPosition.z) > 10.0f)
        {
            Done();
        }
        
    }
   // 重置方法,重置时,让球在球员头顶Y=5处,以(0,0)为圆心,5-10处随机掉落。
    public override void AgentReset()
    {
        ball.transform.localPosition = new Vector3(Random.value * 10 - 5, 5.0f, Random.value * 10 - 5);
        ball.velocity = Vector3.zero;
        ball.rotation = Quaternion.Euler(Vector3.zero);
        ball.angularVelocity = Vector3.zero;

        player.transform.localPosition = Vector3.up;
        player.velocity = Vector3.zero;
        player.rotation = Quaternion.Euler(Vector3.zero);
        player.angularVelocity = Vector3.zero;

        diff = 0.0f; 
        previousDiff = 0.0f;
        previousY = 5.0f;
        collied = false;
    }

    public override float[] Heuristic()
    {
        float[] vectorAction = new float[3];
        vectorAction[0] = Input.GetAxis("Horizontal");
        vectorAction[1] = Input.GetAxis("Vertical");
        vectorAction[2] = Input.GetAxis("Jump");
        return vectorAction;
    }
}

在CollectObservations()方法中,环境信息是26维的。在Prefabs中双击JuggleArea。选择Player——>Behavior Parameters——>Vector Observation-——>Space Size设置为26。将名字改为JuggleBrain,将动作改为连续Continuous,动作空间改为3。AgentAction()方法即配置的3维操作数据。
Unity强化学习工具MLAgents_第20张图片
在Assets目录下新建config文件夹,新建文件trainer_config.yaml

default:
    trainer: ppo
    batch_size: 16
    beta: 5.0e-3
    buffer_size: 256
    epsilon: 0.2
    hidden_units: 128
    lambd: 0.95
    learning_rate: 3.0e-4
    learning_rate_schedule: linear
    max_steps: 100.0e5
    memory_size: 256
    normalize: false
    num_epoch: 3
    num_layers: 4
    time_horizon: 64
    sequence_length: 64
    summary_freq: 10000
    use_recurrent: false
    vis_encode_type: simple
    reward_signals:
        extrinsic:
            strength: 1.0
            gamma: 0.99

在Assets下cmd运行mlagents-learn config\trainer_config.yaml --run-id=playball --train
在unity中点击开始按钮。

三、查看日志

日志文件在Assets/summaries文件夹。
cd 到Assets

tensorboard --logdir=summaries

输出

Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.0.2 at http://localhost:6006/ (Press CTRL+C to quit)

可在http://localhost:6006/查看训练数据。

你可能感兴趣的:(机器人,深度学习,unity,mesh,编辑器)