Unity 机器学习代理工具包 (ML-Agents) 是一个开源项目,它使游戏和模拟能够作为训练智能代理的环境。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

330 行
9.0 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/**
* Welcome to Unity Machine Learning Agents documentation.
*/
[System.Serializable]
public class ScreenConfiguration
{
[Tooltip("Width of the environment window in pixels.")]
public int width;
[Tooltip("Height of the environment window in pixels")]
public int height;
[Tooltip("Rendering quality of environment. (Higher is better quality)")]
[Range(0, 5)]
public int qualityLevel;
[Tooltip("Speed at which environment is run. (Higher is faster)")]
[Range(1f, 100f)]
public float timeScale;
[Tooltip("FPS engine attempts to maintain.")]
public int targetFrameRate;
public ScreenConfiguration(int w, int h, int q, float ts, int tf)
{
width = w;
height = h;
qualityLevel = q;
timeScale = ts;
targetFrameRate = tf;
}
}
[HelpURL("https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Agents-Editor-Interface.md#academy")]
/** Create a child class to implement InitializeAcademy(), AcademyStep()
* and AcademyReset(). The child class script must be attached to an empty game
* object in your scene, and there can only be one such object within the scene.
*/
public abstract class Academy : MonoBehaviour
{
[SerializeField]
[Tooltip("Total number of steps per episode. \n" +
"0 corresponds to episodes without a maximum number of steps. \n" +
"Once the step counter reaches maximum, " +
"the environment will reset.")]
private int maxSteps;
[SerializeField]
[HideInInspector]
public bool isInference = true;
/**< \brief Do not modify : If true, the Academy will use inference
* settings. */
private bool _isCurrentlyInference;
[SerializeField]
[Tooltip("The engine-level settings which correspond to rendering quality" +
" and engine speed during Training.")]
private ScreenConfiguration trainingConfiguration =
new ScreenConfiguration(80, 80, 1, 100.0f, -1);
[SerializeField]
[Tooltip("The engine-level settings which correspond to rendering quality" +
" and engine speed during Inference.")]
private ScreenConfiguration inferenceConfiguration =
new ScreenConfiguration(1280, 720, 5, 1.0f, 60);
/**< \brief Contains a mapping from parameter names to float values. */
/**< You can specify the Default Reset Parameters in the Inspector of the
* Academy. You can modify these parameters when training with an External
* brain by passing a config dictionary at reset. Reference resetParameters
* in your AcademyReset() or AcademyStep() to modify elements in your
* environment at reset time. */
[SerializeField]
[Tooltip("List of custom parameters that can be changed in the " +
"environment on reset.")]
public ResetParameters resetParameters;
public event System.Action BrainDecideAction;
public event System.Action<bool, bool, int> AgentSetStatus;
public event System.Action AgentResetIfDone;
public event System.Action AgentSendState;
public event System.Action AgentAct;
public event System.Action AgentForceReset;
/**< \brief The done flag of the Academy. */
/**< When set to true, the Academy will call AcademyReset() instead of
* AcademyStep() at step time.
* If true, all agents done flags will be set to true.*/
private bool done;
/// <summary>
/// The max step reached.
/// </summary>
private bool maxStepReached;
/**< \brief Increments each time the environment is reset. */
[HideInInspector]
public int episodeCount;
[HideInInspector]
public int stepsSinceReset;
/**< \brief Do not modify : pointer to the communicator currently in
* use by the Academy. */
public Communicator communicator;
private bool firstAcademyReset;
void Awake()
{
_InitializeAcademy();
}
void _InitializeAcademy()
{
List<Brain> brains = GetBrains(gameObject);
InitializeAcademy();
communicator = new ExternalCommunicator(this);
if (!communicator.CommunicatorHandShake())
{
communicator = null;
}
foreach (Brain brain in brains)
{
brain.InitializeBrain(this, communicator);
}
if (communicator != null)
{
communicator.InitializeCommunicator();
communicator.UpdateCommand();
}
isInference = (communicator == null);
_isCurrentlyInference = !isInference;
BrainDecideAction += () => { };
AgentSetStatus += (m, d, i) => { };
AgentResetIfDone += () => { };
AgentSendState += () => { };
AgentAct += () => { };
AgentForceReset += () => { };
}
/// Environment specific initialization.
/**
* Implemented in environment-specific child class.
* This method is called once when the environment is loaded.
*/
public virtual void InitializeAcademy()
{
}
private void ConfigureEngine()
{
if ((!isInference))
{
Screen.SetResolution(
trainingConfiguration.width,
trainingConfiguration.height,
false);
QualitySettings.SetQualityLevel(
trainingConfiguration.qualityLevel, true);
Time.timeScale = trainingConfiguration.timeScale;
Application.targetFrameRate =
trainingConfiguration.targetFrameRate;
QualitySettings.vSyncCount = 0;
Time.captureFramerate = 60;
Monitor.SetActive(false);
}
else
{
Screen.SetResolution(
inferenceConfiguration.width,
inferenceConfiguration.height,
false);
QualitySettings.SetQualityLevel(
inferenceConfiguration.qualityLevel, true);
Time.timeScale = inferenceConfiguration.timeScale;
Application.targetFrameRate =
inferenceConfiguration.targetFrameRate;
Time.captureFramerate = 60;
Monitor.SetActive(true);
}
}
/// Environment specific step logic.
/**
* Implemented in environment-specific child class.
* This method is called at every step.
*/
public virtual void AcademyStep()
{
}
/// Environment specific reset logic.
/**
* Implemented in environment-specific child class.
* This method is called everytime the Academy resets (when the global done
* flag is set to true).
*/
public virtual void AcademyReset()
{
}
public void Done()
{
done = true;
}
public bool IsDone()
{
return done;
}
/// <summary>
/// Forceds the full reset. The done flags are not affected. Is either
/// called the first reset at inference and every external reset
/// at training.
/// </summary>
private void ForcedFullReset()
{
_AcademyReset();
AgentForceReset();
firstAcademyReset = true;
}
internal void _AcademyStep()
{
if (isInference != _isCurrentlyInference)
{
ConfigureEngine();
_isCurrentlyInference = isInference;
}
if (communicator != null)
{
if (communicator.GetCommand() == ExternalCommand.RESET)
{
Dictionary<string, float> NewResetParameters =
communicator.GetResetParameters();
foreach (KeyValuePair<string, float> kv in NewResetParameters)
{
resetParameters[kv.Key] = kv.Value;
}
ForcedFullReset();
communicator.SetCommand(ExternalCommand.STEP);
}
if (communicator.GetCommand() == ExternalCommand.QUIT)
{
Application.Quit();
}
}
else if (!firstAcademyReset)
{
ForcedFullReset();
}
if ((stepsSinceReset >= maxSteps) && maxSteps > 0)
{
maxStepReached = true;
Done();
}
AgentSetStatus(maxStepReached, done, stepsSinceReset);
if (done)
_AcademyReset();
AgentResetIfDone();
AgentSendState();
BrainDecideAction();
AcademyStep();
AgentAct();
stepsSinceReset += 1;
}
internal void _AcademyReset()
{
stepsSinceReset = 0;
episodeCount++;
done = false;
maxStepReached = false;
AcademyReset();
}
void FixedUpdate()
{
_AcademyStep();
}
private static List<Brain> GetBrains(GameObject gameObject)
{
List<Brain> brains = new List<Brain>();
var transform = gameObject.transform;
for (var i = 0; i < transform.childCount; i++)
{
var child = transform.GetChild(i);
var brain = child.GetComponent<Brain>();
if (brain != null && child.gameObject.activeSelf)
brains.Add(brain);
}
return brains;
}
}