using System; using System.Collections.Generic; using System.Linq; using Unity.MLAgents.Policies; namespace Unity.MLAgents.Actuators { /// /// Defines the structure of an Action Space to be used by the Actuator system. /// public readonly struct ActionSpec { /// /// An array of branch sizes for our action space. /// /// For an IActuator that uses a Discrete , the number of /// branches is the Length of the Array and each index contains the branch size. /// The cumulative sum of the total number of discrete actions can be retrieved /// by the property. /// /// For an IActuator with a Continuous it will be null. /// public readonly int[] BranchSizes; /// /// The number of actions for a Continuous . /// public int NumContinuousActions { get; } /// /// The number of branches for a Discrete . /// public int NumDiscreteActions { get; } /// /// Get the total number of Discrete Actions that can be taken by calculating the Sum /// of all of the Discrete Action branch sizes. /// public int SumOfDiscreteBranchSizes { get; } /// /// Creates a Continuous with the number of actions available. /// /// The number of actions available. /// An Continuous ActionSpec initialized with the number of actions available. public static ActionSpec MakeContinuous(int numActions) { var actuatorSpace = new ActionSpec(numActions, 0); return actuatorSpace; } /// /// Creates a Discrete with the array of branch sizes that /// represents the action space. /// /// The array of branch sizes for the discrete action space. Each index /// contains the number of actions available for that branch. /// An Discrete ActionSpec initialized with the array of branch sizes. public static ActionSpec MakeDiscrete(params int[] branchSizes) { var numActions = branchSizes.Length; var actuatorSpace = new ActionSpec(0, numActions, branchSizes); return actuatorSpace; } internal ActionSpec(int numContinuousActions, int numDiscreteActions, int[] branchSizes = null) { NumContinuousActions = numContinuousActions; NumDiscreteActions = numDiscreteActions; BranchSizes = branchSizes; SumOfDiscreteBranchSizes = branchSizes?.Sum() ?? 0; } /// /// Temporary check that the ActionSpec uses either all continuous or all discrete actions. /// This should be removed once the trainer supports them. /// /// internal void CheckNotHybrid() { if (NumContinuousActions > 0 && NumDiscreteActions > 0) { throw new UnityAgentsException("Hybrid action spaces not supported by the trainer. " + "ActionSpecs must be all continuous or all discrete."); } } } }