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(); } } }