/// <summary> /// Create an <see cref="ActionBuffers"/> instance with ActionSpec and all actions stored as a float array. /// </summary> /// <param name="actionSpec"><see cref="ActionSpec"/> of the <see cref="ActionBuffers"/></param> /// <param name="actions">The float array of all actions, including discrete and continuous actions.</param> /// <returns>An <see cref="ActionBuffers"/> instance initialized with a <see cref="ActionSpec"/> and a float array. internal static ActionBuffers FromActionSpec(ActionSpec actionSpec, float[] actions) { if (actions == null) { return(ActionBuffers.Empty); } Debug.Assert(actions.Length == actionSpec.NumContinuousActions + actionSpec.NumDiscreteActions, $"The length of '{nameof(actions)}' does not match the total size of ActionSpec.\n" + $"{nameof(actions)}.Length: {actions.Length}\n" + $"{nameof(actionSpec)}: {actionSpec.NumContinuousActions + actionSpec.NumDiscreteActions}"); ActionSegment <float> continuousActionSegment = ActionSegment <float> .Empty; ActionSegment <int> discreteActionSegment = ActionSegment <int> .Empty; int offset = 0; if (actionSpec.NumContinuousActions > 0) { continuousActionSegment = new ActionSegment <float>(actions, 0, actionSpec.NumContinuousActions); offset += actionSpec.NumContinuousActions; } if (actionSpec.NumDiscreteActions > 0) { int[] discreteActions = new int[actionSpec.NumDiscreteActions]; for (var i = 0; i < actionSpec.NumDiscreteActions; i++) { discreteActions[i] = (int)actions[i + offset]; } discreteActionSegment = new ActionSegment <int>(discreteActions); } return(new ActionBuffers(continuousActionSegment, discreteActionSegment)); }
/// <summary> /// Creates a Discrete <see cref="ActionSpec"/> with the array of branch sizes that /// represents the action space. /// </summary> /// <param name="branchSizes">The array of branch sizes for the discrete action space. Each index /// contains the number of actions available for that branch.</param> /// <returns>An Discrete ActionSpec initialized with the array of branch sizes.</returns> public static ActionSpec MakeDiscrete(params int[] branchSizes) { var numActions = branchSizes.Length; var actuatorSpace = new ActionSpec(0, numActions, branchSizes); return(actuatorSpace); }
/// <summary> /// This method validates that all <see cref="IActuator"/>s have unique names /// if the `DEBUG` preprocessor macro is defined, and allocates the appropriate buffers to manage the actions for /// all of the <see cref="IActuator"/>s that may live on a particular object. /// </summary> /// <param name="actuators">The list of actuators to validate and allocate buffers for.</param> /// <param name="numContinuousActions">The total number of continuous actions for all of the actuators.</param> /// <param name="sumOfDiscreteBranches">The total sum of the discrete branches for all of the actuators in order /// to be able to allocate an <see cref="IDiscreteActionMask"/>.</param> /// <param name="numDiscreteBranches">The number of discrete branches for all of the actuators.</param> internal void ReadyActuatorsForExecution(IList <IActuator> actuators, int numContinuousActions, int sumOfDiscreteBranches, int numDiscreteBranches) { if (m_ReadyForExecution) { return; } #if DEBUG // Make sure the names are actually unique ValidateActuators(); #endif // Sort the Actuators by name to ensure determinism SortActuators(); var continuousActions = numContinuousActions == 0 ? ActionSegment <float> .Empty : new ActionSegment <float>(new float[numContinuousActions]); var discreteActions = numDiscreteBranches == 0 ? ActionSegment <int> .Empty : new ActionSegment <int>(new int[numDiscreteBranches]); StoredActions = new ActionBuffers(continuousActions, discreteActions); m_CombinedActionSpec = CombineActionSpecs(actuators); m_DiscreteActionMask = new ActuatorDiscreteActionMask(actuators, sumOfDiscreteBranches, numDiscreteBranches, m_CombinedActionSpec.BranchSizes); m_ReadyForExecution = true; }
/// <summary> /// Construct an <see cref="ActionBuffers"/> instance with <see cref="ActionSpec"/>. All values are initialized to zeros. /// /// </summary> /// <param name="actionSpec">The <see cref="ActionSpec"/> to send to an <see cref="IActionReceiver"/>.</param> public ActionBuffers(ActionSpec actionSpec) : this(new ActionSegment <float>(new float[actionSpec.NumContinuousActions]), new ActionSegment <int>(new int[actionSpec.NumDiscreteActions])) { }
/// <summary> /// Creates a Discrete <see cref="ActionSpec"/> with the array of branch sizes that /// represents the action space. /// </summary> /// <param name="branchSizes">The array of branch sizes for the discrete actions. Each index /// contains the number of actions available for that branch.</param> /// <returns>An Discrete ActionSpec initialized with the array of branch sizes.</returns> public static ActionSpec MakeDiscrete(params int[] branchSizes) { var actuatorSpace = new ActionSpec(0, branchSizes); return(actuatorSpace); }
/// <summary> /// Creates a Continuous <see cref="ActionSpec"/> with the number of actions available. /// </summary> /// <param name="numActions">The number of continuous actions available.</param> /// <returns>An Continuous ActionSpec initialized with the number of actions available.</returns> public static ActionSpec MakeContinuous(int numActions) { var actuatorSpace = new ActionSpec(numActions, null); return(actuatorSpace); }