File size: 10,932 Bytes
05c9ac2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
using Unity.Barracuda;
using System;
using UnityEngine;
using UnityEngine.Serialization;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors.Reflection;
namespace Unity.MLAgents.Policies
{
/// <summary>
/// Defines what type of behavior the Agent will be using
/// </summary>
[Serializable]
public enum BehaviorType
{
/// <summary>
/// The Agent will use the remote process for decision making.
/// if unavailable, will use inference and if no model is provided, will use
/// the heuristic.
/// </summary>
Default,
/// <summary>
/// The Agent will always use its heuristic
/// </summary>
HeuristicOnly,
/// <summary>
/// The Agent will always use inference with the provided
/// neural network model.
/// </summary>
InferenceOnly
}
/// <summary>
/// Options for controlling how the Agent class is searched for <see cref="ObservableAttribute"/>s.
/// </summary>
public enum ObservableAttributeOptions
{
/// <summary>
/// All ObservableAttributes on the Agent will be ignored. This is the
/// default behavior. If there are no ObservableAttributes on the
/// Agent, this will result in the fastest initialization time.
/// </summary>
Ignore,
/// <summary>
/// Only members on the declared class will be examined; members that are
/// inherited are ignored. This is a reasonable tradeoff between
/// performance and flexibility.
/// </summary>
/// <remarks>This corresponds to setting the
/// [BindingFlags.DeclaredOnly](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.bindingflags?view=netcore-3.1)
/// when examining the fields and properties of the Agent class instance.
/// </remarks>
ExcludeInherited,
/// <summary>
/// All members on the class will be examined. This can lead to slower
/// startup times.
/// </summary>
ExamineAll
}
/// <summary>
/// A component for setting an <seealso cref="Agent"/> instance's behavior and
/// brain properties.
/// </summary>
/// <remarks>At runtime, this component generates the agent's policy objects
/// according to the settings you specified in the Editor.</remarks>
[AddComponentMenu("ML Agents/Behavior Parameters", (int)MenuGroup.Default)]
public class BehaviorParameters : MonoBehaviour
{
[HideInInspector, SerializeField]
BrainParameters m_BrainParameters = new BrainParameters();
/// <summary>
/// Delegate for receiving events about Policy Updates.
/// </summary>
/// <param name="isInHeuristicMode">Whether or not the current policy is running in heuristic mode.</param>
public delegate void PolicyUpdated(bool isInHeuristicMode);
/// <summary>
/// Event that fires when an Agent's policy is updated.
/// </summary>
internal event PolicyUpdated OnPolicyUpdated;
/// <summary>
/// The associated <see cref="Policies.BrainParameters"/> for this behavior.
/// </summary>
public BrainParameters BrainParameters
{
get { return m_BrainParameters; }
internal set { m_BrainParameters = value; }
}
[HideInInspector, SerializeField]
NNModel m_Model;
/// <summary>
/// The neural network model used when in inference mode.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
/// to set it instead.
/// </summary>
public NNModel Model
{
get { return m_Model; }
set { m_Model = value; UpdateAgentPolicy(); }
}
[HideInInspector, SerializeField]
InferenceDevice m_InferenceDevice = InferenceDevice.Default;
/// <summary>
/// How inference is performed for this Agent's model.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
/// to set it instead.
/// </summary>
public InferenceDevice InferenceDevice
{
get { return m_InferenceDevice; }
set { m_InferenceDevice = value; UpdateAgentPolicy(); }
}
[HideInInspector, SerializeField]
BehaviorType m_BehaviorType;
/// <summary>
/// The BehaviorType for the Agent.
/// </summary>
public BehaviorType BehaviorType
{
get { return m_BehaviorType; }
set { m_BehaviorType = value; UpdateAgentPolicy(); }
}
[HideInInspector, SerializeField]
string m_BehaviorName = "My Behavior";
/// <summary>
/// The name of this behavior, which is used as a base name. See
/// <see cref="FullyQualifiedBehaviorName"/> for the full name.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
/// to set it instead.
/// </summary>
public string BehaviorName
{
get { return m_BehaviorName; }
set { m_BehaviorName = value; UpdateAgentPolicy(); }
}
/// <summary>
/// The team ID for this behavior.
/// </summary>
[HideInInspector, SerializeField, FormerlySerializedAs("m_TeamID")]
public int TeamId;
// TODO properties here instead of Agent
[FormerlySerializedAs("m_useChildSensors")]
[HideInInspector]
[SerializeField]
[Tooltip("Use all Sensor components attached to child GameObjects of this Agent.")]
bool m_UseChildSensors = true;
[HideInInspector]
[SerializeField]
[Tooltip("Use all Actuator components attached to child GameObjects of this Agent.")]
bool m_UseChildActuators = true;
/// <summary>
/// Whether or not to use all the sensor components attached to child GameObjects of the agent.
/// Note that changing this after the Agent has been initialized will not have any effect.
/// </summary>
public bool UseChildSensors
{
get { return m_UseChildSensors; }
set { m_UseChildSensors = value; }
}
[HideInInspector]
[SerializeField]
[Tooltip("Set action selection to deterministic, Only applies to inference from within unity.")]
private bool m_DeterministicInference = false;
/// <summary>
/// Whether to select actions deterministically during inference from the provided neural network.
/// </summary>
public bool DeterministicInference
{
get { return m_DeterministicInference; }
set { m_DeterministicInference = value; }
}
/// <summary>
/// Whether or not to use all the actuator components attached to child GameObjects of the agent.
/// Note that changing this after the Agent has been initialized will not have any effect.
/// </summary>
public bool UseChildActuators
{
get { return m_UseChildActuators; }
set { m_UseChildActuators = value; }
}
[HideInInspector, SerializeField]
ObservableAttributeOptions m_ObservableAttributeHandling = ObservableAttributeOptions.Ignore;
/// <summary>
/// Determines how the Agent class is searched for <see cref="ObservableAttribute"/>s.
/// </summary>
public ObservableAttributeOptions ObservableAttributeHandling
{
get { return m_ObservableAttributeHandling; }
set { m_ObservableAttributeHandling = value; }
}
/// <summary>
/// Returns the behavior name, concatenated with any other metadata (i.e. team id).
/// </summary>
public string FullyQualifiedBehaviorName
{
get { return m_BehaviorName + "?team=" + TeamId; }
}
void Awake()
{
OnPolicyUpdated += mode => { };
}
internal IPolicy GeneratePolicy(ActionSpec actionSpec, ActuatorManager actuatorManager)
{
switch (m_BehaviorType)
{
case BehaviorType.HeuristicOnly:
return new HeuristicPolicy(actuatorManager, actionSpec);
case BehaviorType.InferenceOnly:
{
if (m_Model == null)
{
var behaviorType = BehaviorType.InferenceOnly.ToString();
throw new UnityAgentsException(
$"Can't use Behavior Type {behaviorType} without a model. " +
"Either assign a model, or change to a different Behavior Type."
);
}
return new BarracudaPolicy(actionSpec, actuatorManager, m_Model, m_InferenceDevice, m_BehaviorName, m_DeterministicInference);
}
case BehaviorType.Default:
if (Academy.Instance.IsCommunicatorOn)
{
return new RemotePolicy(actionSpec, actuatorManager, FullyQualifiedBehaviorName);
}
if (m_Model != null)
{
return new BarracudaPolicy(actionSpec, actuatorManager, m_Model, m_InferenceDevice, m_BehaviorName, m_DeterministicInference);
}
else
{
return new HeuristicPolicy(actuatorManager, actionSpec);
}
default:
return new HeuristicPolicy(actuatorManager, actionSpec);
}
}
/// <summary>
/// Query the behavior parameters in order to see if the Agent is running in Heuristic Mode.
/// </summary>
/// <returns>true if the Agent is running in Heuristic mode.</returns>
public bool IsInHeuristicMode()
{
if (BehaviorType == BehaviorType.HeuristicOnly)
{
return true;
}
return BehaviorType == BehaviorType.Default &&
ReferenceEquals(Model, null) &&
(!Academy.IsInitialized ||
Academy.IsInitialized &&
!Academy.Instance.IsCommunicatorOn);
}
internal void UpdateAgentPolicy()
{
var agent = GetComponent<Agent>();
if (agent == null)
{
return;
}
agent.ReloadPolicy();
OnPolicyUpdated?.Invoke(IsInHeuristicMode());
}
}
}
|