using System;
using UnityEngine;
using UnityEngine.Serialization;
using Unity.MLAgents.Actuators;
namespace Unity.MLAgents.Policies
{
///
/// This is deprecated. Agents can now use both continuous and discrete actions together.
///
[Obsolete("Continuous and discrete actions on the same Agent are now supported; see ActionSpec.")]
public enum SpaceType
{
///
/// Discrete action space: a fixed number of options are available.
///
Discrete,
///
/// Continuous action space: each action can take on a float value.
///
Continuous
}
///
/// Holds information about the brain. It defines what are the inputs and outputs of the
/// decision process.
///
///
/// Set brain parameters for an instance using the
/// component attached to the agent's [GameObject].
///
/// [GameObject]: https://docs.unity3d.com/Manual/GameObjects.html
///
[Serializable]
public class BrainParameters : ISerializationCallbackReceiver
{
///
/// The number of the observations that are added in
///
///
///
/// The length of the vector containing observation values.
///
[FormerlySerializedAs("vectorObservationSize")]
public int VectorObservationSize = 1;
///
/// Stacking refers to concatenating the observations across multiple frames. This field
/// indicates the number of frames to concatenate across.
///
[FormerlySerializedAs("numStackedVectorObservations")]
[Range(1, 50)] public int NumStackedVectorObservations = 1;
[SerializeField]
internal ActionSpec m_ActionSpec = new ActionSpec(0, null);
///
/// The specification of the Actions for the BrainParameters.
///
public ActionSpec ActionSpec
{
get { return m_ActionSpec; }
set
{
m_ActionSpec.NumContinuousActions = value.NumContinuousActions;
m_ActionSpec.BranchSizes = value.BranchSizes;
SyncDeprecatedActionFields();
}
}
///
/// (Deprecated) The number of possible actions.
///
/// The size specified is interpreted differently depending on whether
/// the agent uses the continuous or the discrete actions.
///
/// For the continuous actions: the length of the float vector that represents
/// the action.
/// For the discrete actions: the number of branches.
///
[Obsolete("VectorActionSize has been deprecated, please use ActionSpec instead.")]
[FormerlySerializedAs("vectorActionSize")]
public int[] VectorActionSize = new[] { 1 };
///
/// The list of strings describing what the actions correspond to.
///
[FormerlySerializedAs("vectorActionDescriptions")]
public string[] VectorActionDescriptions;
///
/// (Deprecated) Defines if the action is discrete or continuous.
///
[Obsolete("VectorActionSpaceType has been deprecated, please use ActionSpec instead.")]
[FormerlySerializedAs("vectorActionSpaceType")]
public SpaceType VectorActionSpaceType = SpaceType.Discrete;
[SerializeField]
[HideInInspector]
internal bool hasUpgradedBrainParametersWithActionSpec;
///
/// (Deprecated) The number of actions specified by this Brain.
///
[Obsolete("NumActions has been deprecated, please use ActionSpec instead.")]
public int NumActions
{
get
{
return ActionSpec.NumContinuousActions > 0 ? ActionSpec.NumContinuousActions : ActionSpec.NumDiscreteActions;
}
}
///
/// Deep clones the BrainParameter object.
///
/// A new BrainParameter object with the same values as the original.
public BrainParameters Clone()
{
// Disable deprecation warnings so we can read/write the old fields.
#pragma warning disable CS0618
return new BrainParameters
{
VectorObservationSize = VectorObservationSize,
NumStackedVectorObservations = NumStackedVectorObservations,
VectorActionDescriptions = (string[])VectorActionDescriptions.Clone(),
ActionSpec = new ActionSpec(ActionSpec.NumContinuousActions, ActionSpec.BranchSizes),
VectorActionSize = (int[])VectorActionSize.Clone(),
VectorActionSpaceType = VectorActionSpaceType,
};
#pragma warning restore CS0618
}
///
/// Propogate ActionSpec fields from deprecated fields
///
private void UpdateToActionSpec()
{
// Disable deprecation warnings so we can read the old fields.
#pragma warning disable CS0618
if (!hasUpgradedBrainParametersWithActionSpec
&& m_ActionSpec.NumContinuousActions == 0
&& m_ActionSpec.BranchSizes == null)
{
if (VectorActionSpaceType == SpaceType.Continuous)
{
m_ActionSpec.NumContinuousActions = VectorActionSize[0];
m_ActionSpec.BranchSizes = null;
}
if (VectorActionSpaceType == SpaceType.Discrete)
{
m_ActionSpec.NumContinuousActions = 0;
m_ActionSpec.BranchSizes = (int[])VectorActionSize.Clone();
}
}
hasUpgradedBrainParametersWithActionSpec = true;
#pragma warning restore CS0618
}
///
/// Sync values in ActionSpec fields to deprecated fields
///
private void SyncDeprecatedActionFields()
{
// Disable deprecation warnings so we can read the old fields.
#pragma warning disable CS0618
if (m_ActionSpec.NumContinuousActions == 0)
{
VectorActionSize = (int[])ActionSpec.BranchSizes.Clone();
VectorActionSpaceType = SpaceType.Discrete;
}
else if (m_ActionSpec.NumDiscreteActions == 0)
{
VectorActionSize = new[] { m_ActionSpec.NumContinuousActions };
VectorActionSpaceType = SpaceType.Continuous;
}
else
{
VectorActionSize = null;
}
#pragma warning restore CS0618
}
///
/// Called by Unity immediately before serializing this object.
///
public void OnBeforeSerialize()
{
UpdateToActionSpec();
SyncDeprecatedActionFields();
}
///
/// Called by Unity immediately after deserializing this object.
///
public void OnAfterDeserialize()
{
UpdateToActionSpec();
SyncDeprecatedActionFields();
}
}
}