Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
token: ${{ secrets.GHE_ACCESS_TOKEN }}
submodules: recursive
- uses: actions/setup-python@v2
- uses: actions/setup-node@v2
with:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using TMPro;
using Unity.Barracuda;
using Unity.MLAgents;
using Unity.MLAgents.Policies;
using UnityEditor;
#if UNITY_EDITOR
using UnityEditor.Recorder;
#endif
using UnityEngine;

/**
* Usage Notes:
*
* Add onnx models to the list and they will be played sequentially.
* Create a recorder and a video of the sequence will be captured automatically if "Auto Record" is selected.
* Recording only works in the Editor (not in standalone build)
* Create a TextMeshPro Text GameObject and attach it to have the number of training steps of the current model shown.
* To manually control transition between models choose a very large time, or "Pause" the system,
* then use "Force Next" to advance.
* "Reset" will start the sequence from the beginning again, use "Start" to proceed after resetting.
* "Time Scale Override" can be set, "Seconds Between Switches" will decrease proportionally if you increase this
* (i.e it represents simulated seconds between switches, not real time)
*/


public class ModelCarousel : MonoBehaviour
{
public bool m_Start = true;
public bool m_Reset = false;
public bool m_Pause = true;
public bool m_ForceNext = false;
public bool m_Loop = false;
public bool m_AutoRecord = true;
public bool m_ResetAgentOnModelChange = false;
public int m_SecondsBetweenSwitches = 10;
public float m_TimeScaleOverride = 0.0f;
public List<NNModel> m_Models = new List<NNModel>();
public bool m_ShowStepNumber = true;
public int m_StepNumberRounding = 10000;

private int m_StepsSinceLastSwitch = 0;
private int m_CurrentModelIndex = 0;
private int m_CurrentlySetModelIndex = -1;

private NNModel m_OriginalModel = null;

private int k_FixedUpdatePerSecond;

// The attached Agent
Agent m_Agent;

public TextMeshProUGUI textMeshComponent;

#if UNITY_EDITOR
private RecorderWindow GetRecorderWindow()
{
return (RecorderWindow)EditorWindow.GetWindow(typeof(RecorderWindow));
}
#endif

private void Reset()
{
m_Reset = false;
m_StepsSinceLastSwitch = 0;
m_CurrentModelIndex = 0;
m_Agent.SetModel(m_OriginalModel.name, m_OriginalModel);
textMeshComponent?.SetText("Ready to Start");
}

private void OnEnable()
{
m_Agent = GetComponent<Agent>();
m_OriginalModel = m_Agent.GetComponent<BehaviorParameters>().Model;

Reset();

k_FixedUpdatePerSecond = (int)(1.0f / Time.fixedDeltaTime);

if (m_TimeScaleOverride > 0.0f)
{
Time.timeScale = m_TimeScaleOverride;
}
}

void StartRecording()
{
#if UNITY_EDITOR
if (!m_AutoRecord)
return;

Debug.Log("Starting Recording");
RecorderWindow recorderWindow = GetRecorderWindow();
if (!recorderWindow.IsRecording())
recorderWindow.StartRecording();
#endif
}

void StopRecording()
{
#if UNITY_EDITOR
if (!m_AutoRecord)
return;

Debug.Log("Stopping Recording");
RecorderWindow recorderWindow = GetRecorderWindow();
if (recorderWindow.IsRecording())
recorderWindow.StopRecording();
#endif
}

void UpdateStepNumberText()
{
if (!m_ShowStepNumber)
return;

var result = Regex.Match(m_Models[m_CurrentModelIndex].name, @".*-(\d+)$");

string newText = "";
if (result.Success && result.Groups.Count > 0)
{
var steps = Int32.Parse(result.Groups[1].Captures[0].Value);

int round = m_StepNumberRounding;
steps += round / 2;
steps /= round;
steps *= round;

newText = $"After {steps:n0} steps";
}

textMeshComponent?.SetText(newText);
}

void SetModel()
{
if (m_CurrentModelIndex < 0 || m_CurrentModelIndex >= m_Models.Count)
return;

m_Agent.SetModel(m_Models[m_CurrentModelIndex].name, m_Models[m_CurrentModelIndex]);
m_CurrentlySetModelIndex = m_CurrentModelIndex;

UpdateStepNumberText();

if (m_ResetAgentOnModelChange)
m_Agent.EndEpisode();
}

void FixedUpdate()
{
if (m_Start)
{
m_Start = false;
m_Pause = false;
StartRecording();
}

if (m_Reset)
{
StopRecording();
Reset();
m_Pause = true;
m_Start = false;
}

if (m_Pause && !m_ForceNext)
return;

if (m_CurrentlySetModelIndex != m_CurrentModelIndex)
{
SetModel();
}

m_StepsSinceLastSwitch++;

if (m_StepsSinceLastSwitch >= m_SecondsBetweenSwitches * k_FixedUpdatePerSecond || m_ForceNext)

@taozhuo taozhuo Dec 14, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_ForceNext has not been set to true anywhere in the code. If it's related to then use "Force Next" to advance., is there a place we need to set it to true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is. It's in the editor inspector window when you click on an object this has this script attached to it. This is a monobehaviour script, so any public property shows up in the inspector window for any object that has this script attached to it.

{
m_ForceNext = false;
m_StepsSinceLastSwitch = 0;
m_CurrentModelIndex++;

if (m_CurrentModelIndex == m_Models.Count)
{
if (m_Loop)
{
m_CurrentModelIndex = 0;
}
else
{
Application.Quit(0);
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#endif
return;
}
}

SetModel();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Project/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"com.unity.ml-agents": "file:../../com.unity.ml-agents",
"com.unity.ml-agents.extensions": "file:../../com.unity.ml-agents.extensions",
"com.unity.nuget.newtonsoft-json": "2.0.0",
"com.unity.recorder": "3.0.3",
"com.unity.test-framework": "1.1.29",
"com.unity.textmeshpro": "3.0.6",
"com.unity.toolchain.macos-x86_64-linux-x86_64": "2.0.3",
"com.unity.ugui": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
Expand Down
57 changes: 57 additions & 0 deletions Project/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.recorder": {
"version": "3.0.3",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.timeline": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.sysroot": {
"version": "2.0.4",
"depth": 1,
Expand Down Expand Up @@ -103,6 +112,27 @@
},
"url": "https://packages.unity.com"
},
"com.unity.textmeshpro": {
"version": "3.0.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.6.4",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.toolchain.macos-x86_64-linux-x86_64": {
"version": "2.0.3",
"depth": 0,
Expand All @@ -122,6 +152,27 @@
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 2,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 2,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 2,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
Expand All @@ -140,6 +191,12 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 2,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
Expand Down
2 changes: 2 additions & 0 deletions com.unity.ml-agents/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ and this project adheres to
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)

#### ml-agents / ml-agents-envs
- Added training config feature to evenly distribute checkpoints throughout training. (#5842)
- Updated training area replicator to add a condition to only replicate training areas when running a build. (#5842)

### Bug Fixes
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)
Expand Down
26 changes: 19 additions & 7 deletions com.unity.ml-agents/Runtime/Areas/TrainingAreaReplicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ public class TrainingAreaReplicator : MonoBehaviour
/// </summary>
public float separation = 10f;

int3 m_GridSize = new int3(1, 1, 1);
int m_areaCount = 0;
/// <summary>
/// Whether to replicate in the editor or in a build only. Default = true
/// </summary>
public bool buildOnly = true;

int3 m_GridSize = new(1, 1, 1);
int m_AreaCount;
string m_TrainingAreaName;

/// <summary>
Expand Down Expand Up @@ -57,7 +62,14 @@ public void Awake()
/// </summary>
public void OnEnable()
{
// Adds the training are replicas during OnEnable to ensure they are added before the Academy begins its work.
// Adds the training as replicas during OnEnable to ensure they are added before the Academy begins its work.
if (buildOnly)
{
#if UNITY_STANDALONE && !UNITY_EDITOR
AddEnvironments();
#endif
return;
}
AddEnvironments();
}

Expand Down Expand Up @@ -95,14 +107,14 @@ void AddEnvironments()
{
for (int x = 0; x < m_GridSize.x; x++)
{
if (m_areaCount == 0)
if (m_AreaCount == 0)
{
// Skip this first area since it already exists.
m_areaCount = 1;
m_AreaCount = 1;
}
else if (m_areaCount < numAreas)
else if (m_AreaCount < numAreas)
{
m_areaCount++;
m_AreaCount++;
var area = Instantiate(baseArea, new Vector3(x * separation, y * separation, z * separation), Quaternion.identity);
area.name = m_TrainingAreaName;
}
Expand Down
2 changes: 1 addition & 1 deletion com.unity.ml-agents/Runtime/Sensors/GridSensorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void OnDrawGizmos()
var cellColors = m_DebugSensor.PerceptionBuffer;
var rotation = m_GridPerception.GetGridRotation();

var scale = new Vector3(m_CellScale.x, 1, m_CellScale.z);
var scale = new Vector3(m_CellScale.x, m_CellScale.y, m_CellScale.z);
var gizmoYOffset = new Vector3(0, m_GizmoYOffset, 0);
var oldGizmoMatrix = Gizmos.matrix;
for (var i = 0; i < m_DebugSensor.PerceptionBuffer.Length; i++)
Expand Down
Loading