Skip to content

Commit b405630

Browse files
committed
[API] Make the DecisionRequester public and add a delegate to its API to allow users to customize it's behavior.
- Rename Academy.AgentSetStatus to Academy.AgentPreStep and make it public. - Fix Unity library cache issues for backwards compatibility tests. - Collect standalone build and logs to artifacts for standalone build jobs. - cat standalone build log if the build fails. - Default verbose to False for standalone build test.
1 parent d78c10c commit b405630

18 files changed

+253
-574
lines changed

.yamato/gym-interface-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ test_gym_interface_{{ editor.version }}:
1313
commands:
1414
- pip install pyyaml
1515
- python -u -m ml-agents.tests.yamato.setup_venv
16-
- ./venv/bin/python ml-agents/tests/yamato/scripts/run_gym.py --env=Project/testPlayer-Basic
16+
- ./venv/bin/python ml-agents/tests/yamato/scripts/run_gym.py --env=artifacts/testPlayer-Basic
1717
dependencies:
1818
- .yamato/standalone-build-test.yml#test_mac_standalone_{{ editor.version }}
1919
triggers:

.yamato/protobuf-generation-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ test_mac_protobuf_generation:
3636
- "protobuf-definitions/*.md"
3737
- "protobuf-definitions/**/*.md"
3838
artifacts:
39-
dist:
39+
patch:
4040
paths:
41-
- "artifacts/*"
41+
- "artifacts/*.*"

.yamato/python-ll-api-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ test_mac_ll_api_{{ editor.version }}:
1515
- python -u -m ml-agents.tests.yamato.setup_venv
1616
- ./venv/bin/python ml-agents/tests/yamato/scripts/run_llapi.py
1717
dependencies:
18-
- .yamato/standalone-build-test.yml#test_mac_standalone_{{ editor.version }} --env=Project/testPlayer
18+
- .yamato/standalone-build-test.yml#test_mac_standalone_{{ editor.version }}
1919
triggers:
2020
cancel_old_ci: true
2121
changes:

.yamato/standalone-build-test.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ test_mac_standalone_{{ editor.version }}:
2727
- "com.unity.ml-agents/*.md"
2828
- "com.unity.ml-agents/**/*.md"
2929
artifacts:
30+
logs:
31+
paths:
32+
- "artifacts/standalone_build.txt"
3033
standalonebuild:
3134
paths:
32-
- "Project/testPlayer*/**"
35+
- "artifacts/testPlayer*/**"
3336
{% endfor %}

.yamato/training-int-tests.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ test_mac_training_int_{{ editor.version }}:
3535
- "com.unity.ml-agents/*.md"
3636
- "com.unity.ml-agents/**/*.md"
3737
artifacts:
38-
unit:
38+
logs:
3939
paths:
40-
- "artifacts/**"
40+
- "artifacts/standalone_build.txt"
41+
standalonebuild:
42+
paths:
43+
- "artifacts/testplayer*/**"
4144
{% endfor %}

com.unity.ml-agents/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1515
- Removed the multi-agent gym option from the gym wrapper. For multi-agent scenarios, use the [Low Level Python API](Python-API.md).
1616
- The low level Python API has changed. You can look at the document [Low Level Python API documentation](Python-API.md) for more information. If you use `mlagents-learn` for training, this should be a transparent change.
1717
- Added ability to start training (initialize model weights) from a previous run ID. (#3710)
18+
- The internal event `Academy.AgentSetStatus` was renamed to `Academy.AgentPreStep` and made public.
19+
- The offset logic was removed from DecisionRequester.
1820

1921
### Minor Changes
2022
- Format of console output has changed slightly and now matches the name of the model/summary directory. (#3630, #3616)

com.unity.ml-agents/Runtime/Academy.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,14 @@ public bool IsCommunicatorOn
138138
// This will mark the Agent as Done if it has reached its maxSteps.
139139
internal event Action AgentIncrementStep;
140140

141-
// Signals to all the agents at each environment step along with the
142-
// Academy's maxStepReached, done and stepCount values. The agents rely
143-
// on this event to update their own values of max step reached and done
144-
// in addition to aligning on the step count of the global episode.
145-
internal event Action<int> AgentSetStatus;
141+
142+
/// <summary>
143+
/// Signals to all of the <see cref="Agent"/>s that their step is about to begin.
144+
/// This is a good time for an <see cref="Agent"/> to decide if it would like to
145+
/// call <see cref="Agent.RequestDecision"/> or <see cref="Agent.RequestAction"/>
146+
/// for this step. Any other pre-step setup could be done during this even as well.
147+
/// </summary>
148+
public event Action<int> AgentPreStep;
146149

147150
// Signals to all the agents at each environment step so they can send
148151
// their state to their Policy if they have requested a decision.
@@ -347,7 +350,7 @@ void ResetActions()
347350
{
348351
DecideAction = () => {};
349352
DestroyAction = () => {};
350-
AgentSetStatus = i => {};
353+
AgentPreStep = i => {};
351354
AgentSendState = () => {};
352355
AgentAct = () => {};
353356
AgentForceReset = () => {};
@@ -423,7 +426,7 @@ public void EnvironmentStep()
423426
ForcedFullReset();
424427
}
425428

426-
AgentSetStatus?.Invoke(m_StepCount);
429+
AgentPreStep?.Invoke(m_StepCount);
427430

428431
m_StepCount += 1;
429432
m_TotalStepCount += 1;

com.unity.ml-agents/Runtime/DecisionRequester.cs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using UnityEngine;
23
using UnityEngine.Serialization;
34

@@ -8,12 +9,12 @@ namespace MLAgents
89
/// at regular intervals.
910
/// </summary>
1011
[AddComponentMenu("ML Agents/Decision Requester", (int)MenuGroup.Default)]
11-
internal class DecisionRequester : MonoBehaviour
12+
[RequireComponent(typeof(Agent))]
13+
public class DecisionRequester : MonoBehaviour
1214
{
1315
/// <summary>
1416
/// The frequency with which the agent requests a decision. A DecisionPeriod of 5 means
15-
/// that the Agent will request a decision every 5 Academy steps.
16-
/// </summary>
17+
/// that the Agent will request a decision every 5 Academy steps. /// </summary>
1718
[Range(1, 20)]
1819
[Tooltip("The frequency with which the agent requests a decision. A DecisionPeriod " +
1920
"of 5 means that the Agent will request a decision every 5 Academy steps.")]
@@ -29,37 +30,32 @@ internal class DecisionRequester : MonoBehaviour
2930
[FormerlySerializedAs("RepeatAction")]
3031
public bool TakeActionsBetweenDecisions = true;
3132

32-
/// <summary>
33-
/// Whether or not the Agent decisions should start at an offset (different for each agent).
34-
/// This does not affect <see cref="DecisionPeriod"/>. Turning this on will distribute
35-
/// the decision-making computations for all the agents across multiple Academy steps.
36-
/// This can be valuable in scenarios where you have many agents in the scene, particularly
37-
/// during the inference phase.
38-
/// </summary>
39-
[Tooltip("Whether or not Agent decisions should start at an offset.")]
40-
public bool offsetStep;
41-
33+
[NonSerialized]
4234
Agent m_Agent;
43-
int m_Offset;
4435

4536
internal void Awake()
4637
{
47-
m_Offset = offsetStep ? gameObject.GetInstanceID() : 0;
4838
m_Agent = gameObject.GetComponent<Agent>();
49-
Academy.Instance.AgentSetStatus += MakeRequests;
39+
Debug.Assert(m_Agent != null, "Agent component was not found on this gameObject and is required.");
40+
Academy.Instance.AgentPreStep += MakeRequests;
5041
}
5142

5243
void OnDestroy()
5344
{
5445
if (Academy.IsInitialized)
5546
{
56-
Academy.Instance.AgentSetStatus -= MakeRequests;
47+
Academy.Instance.AgentPreStep -= MakeRequests;
5748
}
5849
}
5950

60-
void MakeRequests(int count)
51+
/// <summary>
52+
/// Method that hooks into the Academy in order inform the Agent on whether or not it should request a
53+
/// decision, and whether or not it should take actions between decisions.
54+
/// </summary>
55+
/// <param name="academyStepCount">The current step count of the academy.</param>
56+
void MakeRequests(int academyStepCount)
6157
{
62-
if ((count + m_Offset) % DecisionPeriod == 0)
58+
if (academyStepCount % DecisionPeriod == 0)
6359
{
6460
m_Agent?.RequestDecision();
6561
}

com.unity.ml-agents/Tests/Editor/PublicAPI/PublicApiValidation.cs

Lines changed: 1 addition & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using MLAgents.Sensors;
55
using NUnit.Framework;
66
using UnityEngine;
7+
using UnityEngine.TestTools;
78

89
namespace MLAgentsExamples
910
{
@@ -71,106 +72,5 @@ public void CheckSetupRayPerceptionSensorComponent()
7172

7273
sensorComponent.CreateSensor();
7374
}
74-
75-
class PublicApiAgent : Agent
76-
{
77-
public int numHeuristicCalls;
78-
79-
public override float[] Heuristic()
80-
{
81-
numHeuristicCalls++;
82-
return base.Heuristic();
83-
}
84-
}
85-
86-
// Simple SensorComponent that sets up a StackingSensor
87-
class StackingComponent : SensorComponent
88-
{
89-
public SensorComponent wrappedComponent;
90-
public int numStacks;
91-
92-
public override ISensor CreateSensor()
93-
{
94-
var wrappedSensor = wrappedComponent.CreateSensor();
95-
return new StackingSensor(wrappedSensor, numStacks);
96-
}
97-
98-
public override int[] GetObservationShape()
99-
{
100-
int[] shape = (int[]) wrappedComponent.GetObservationShape().Clone();
101-
for (var i = 0; i < shape.Length; i++)
102-
{
103-
shape[i] *= numStacks;
104-
}
105-
106-
return shape;
107-
}
108-
}
109-
110-
111-
[Test]
112-
public void CheckSetupAgent()
113-
{
114-
var gameObject = new GameObject();
115-
116-
var behaviorParams = gameObject.AddComponent<BehaviorParameters>();
117-
behaviorParams.brainParameters.vectorObservationSize = 3;
118-
behaviorParams.brainParameters.numStackedVectorObservations = 2;
119-
behaviorParams.brainParameters.vectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
120-
behaviorParams.brainParameters.vectorActionSize = new[] { 2, 2 };
121-
behaviorParams.brainParameters.vectorActionSpaceType = SpaceType.Discrete;
122-
behaviorParams.behaviorName = "TestBehavior";
123-
behaviorParams.TeamId = 42;
124-
behaviorParams.useChildSensors = true;
125-
126-
var agent = gameObject.AddComponent<PublicApiAgent>();
127-
// Make sure we can set the behavior type correctly after the agent is added
128-
behaviorParams.behaviorType = BehaviorType.InferenceOnly;
129-
// Can't actually create an Agent with InferenceOnly and no model, so change back
130-
behaviorParams.behaviorType = BehaviorType.Default;
131-
132-
// TODO - not internal yet
133-
// var decisionRequester = gameObject.AddComponent<DecisionRequester>();
134-
// decisionRequester.DecisionPeriod = 2;
135-
136-
var sensorComponent = gameObject.AddComponent<RayPerceptionSensorComponent3D>();
137-
sensorComponent.sensorName = "ray3d";
138-
sensorComponent.detectableTags = new List<string> { "Player", "Respawn" };
139-
sensorComponent.raysPerDirection = 3;
140-
141-
// Make a StackingSensor that wraps the RayPerceptionSensorComponent3D
142-
// This isn't necessarily practical, just to ensure that it can be done
143-
var wrappingSensorComponent = gameObject.AddComponent<StackingComponent>();
144-
wrappingSensorComponent.wrappedComponent = sensorComponent;
145-
wrappingSensorComponent.numStacks = 3;
146-
147-
// ISensor isn't set up yet.
148-
Assert.IsNull(sensorComponent.raySensor);
149-
150-
agent.LazyInitialize();
151-
// Make sure we can set the behavior type correctly after the agent is initialized
152-
// (this creates a new policy).
153-
behaviorParams.behaviorType = BehaviorType.HeuristicOnly;
154-
155-
// Initialization should set up the sensors
156-
Assert.IsNotNull(sensorComponent.raySensor);
157-
158-
// Let's change the inference device
159-
var otherDevice = behaviorParams.inferenceDevice == InferenceDevice.CPU ? InferenceDevice.GPU : InferenceDevice.CPU;
160-
agent.SetModel(behaviorParams.behaviorName, behaviorParams.model, otherDevice);
161-
162-
agent.AddReward(1.0f);
163-
164-
agent.RequestAction();
165-
agent.RequestDecision();
166-
167-
Academy.Instance.AutomaticSteppingEnabled = false;
168-
Academy.Instance.EnvironmentStep();
169-
170-
var actions = agent.GetAction();
171-
// default Heuristic implementation should return zero actions.
172-
Assert.AreEqual(new[] {0.0f, 0.0f}, actions);
173-
Assert.AreEqual(1, agent.numHeuristicCalls);
174-
}
17575
}
17676
}

0 commit comments

Comments
 (0)