Andrew Cohen
5 年前
当前提交
59b88be6
共有 62 个文件被更改,包括 441 次插入 和 427 次删除
-
2.pylintrc
-
2Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs
-
2Project/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs
-
2Project/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs
-
5Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorAgent.cs
-
2Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs
-
18Project/Assets/ML-Agents/Examples/GridWorld/Scenes/GridWorld.unity
-
3Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs
-
2Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridArea.cs
-
3Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridSettings.cs
-
5Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs
-
3Project/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherAgent.cs
-
3Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ProjectSettingsOverrides.cs
-
3Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerFieldArea.cs
-
2Project/Assets/ML-Agents/Examples/Tennis/Scripts/TennisAgent.cs
-
2Project/Assets/ML-Agents/Examples/Walker/Scripts/WalkerAgent.cs
-
13Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs
-
6com.unity.ml-agents/CHANGELOG.md
-
71com.unity.ml-agents/Runtime/Academy.cs
-
29com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs
-
195com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
-
2com.unity.ml-agents/Runtime/SideChannels/SideChannel.cs
-
8com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs
-
16com.unity.ml-agents/Tests/Editor/SideChannelTests.cs
-
8docs/Custom-SideChannels.md
-
3docs/Installation.md
-
5docs/Learning-Environment-Create-New.md
-
6docs/Migrating.md
-
5docs/Python-API.md
-
1docs/Readme.md
-
2docs/Training-Curriculum-Learning.md
-
4docs/Training-Environment-Parameter-Randomization.md
-
2docs/Using-Tensorboard.md
-
2gym-unity/README.md
-
7gym-unity/gym_unity/envs/__init__.py
-
5ml-agents-envs/mlagents_envs/environment.py
-
4ml-agents-envs/mlagents_envs/side_channel/outgoing_message.py
-
4ml-agents-envs/mlagents_envs/side_channel/side_channel.py
-
5ml-agents/mlagents/model_serialization.py
-
5ml-agents/mlagents/trainers/components/reward_signals/__init__.py
-
4ml-agents/mlagents/trainers/curriculum.py
-
5ml-agents/mlagents/trainers/env_manager.py
-
5ml-agents/mlagents/trainers/ghost/trainer.py
-
17ml-agents/mlagents/trainers/learn.py
-
4ml-agents/mlagents/trainers/meta_curriculum.py
-
4ml-agents/mlagents/trainers/policy/tf_policy.py
-
4ml-agents/mlagents/trainers/ppo/trainer.py
-
4ml-agents/mlagents/trainers/sac/optimizer.py
-
5ml-agents/mlagents/trainers/sac/trainer.py
-
7ml-agents/mlagents/trainers/stats.py
-
5ml-agents/mlagents/trainers/subprocess_env_manager.py
-
5ml-agents/mlagents/trainers/trainer/trainer.py
-
4ml-agents/mlagents/trainers/trainer_controller.py
-
5ml-agents/mlagents/trainers/trainer_util.py
-
2ml-agents/setup.py
-
1setup.cfg
-
234com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs
-
11com.unity.ml-agents/Runtime/SideChannels/SideChannelUtils.cs.meta
-
46ml-agents-envs/mlagents_envs/logging_util.py
-
19docs/Background-Jupyter.md
-
10ml-agents/mlagents/logging_util.py
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using System.IO; |
|||
|
|||
namespace MLAgents.SideChannels |
|||
{ |
|||
public static class SideChannelUtils |
|||
{ |
|||
|
|||
private static Dictionary<Guid, SideChannel> RegisteredChannels = new Dictionary<Guid, SideChannel>(); |
|||
|
|||
private struct CachedSideChannelMessage |
|||
{ |
|||
public Guid ChannelId; |
|||
public byte[] Message; |
|||
} |
|||
|
|||
private static Queue<CachedSideChannelMessage> m_CachedMessages = new Queue<CachedSideChannelMessage>(); |
|||
|
|||
/// <summary>
|
|||
/// Registers a side channel to the communicator. The side channel will exchange
|
|||
/// messages with its Python equivalent.
|
|||
/// </summary>
|
|||
/// <param name="sideChannel"> The side channel to be registered.</param>
|
|||
public static void RegisterSideChannel(SideChannel sideChannel) |
|||
{ |
|||
var channelId = sideChannel.ChannelId; |
|||
if (RegisteredChannels.ContainsKey(channelId)) |
|||
{ |
|||
throw new UnityAgentsException(string.Format( |
|||
"A side channel with type index {0} is already registered. You cannot register multiple " + |
|||
"side channels of the same id.", channelId)); |
|||
} |
|||
|
|||
// Process any messages that we've already received for this channel ID.
|
|||
var numMessages = m_CachedMessages.Count; |
|||
for (int i = 0; i < numMessages; i++) |
|||
{ |
|||
var cachedMessage = m_CachedMessages.Dequeue(); |
|||
if (channelId == cachedMessage.ChannelId) |
|||
{ |
|||
using (var incomingMsg = new IncomingMessage(cachedMessage.Message)) |
|||
{ |
|||
sideChannel.OnMessageReceived(incomingMsg); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
m_CachedMessages.Enqueue(cachedMessage); |
|||
} |
|||
} |
|||
RegisteredChannels.Add(channelId, sideChannel); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Unregisters a side channel from the communicator.
|
|||
/// </summary>
|
|||
/// <param name="sideChannel"> The side channel to be unregistered.</param>
|
|||
public static void UnregisterSideChannel(SideChannel sideChannel) |
|||
{ |
|||
if (RegisteredChannels.ContainsKey(sideChannel.ChannelId)) |
|||
{ |
|||
RegisteredChannels.Remove(sideChannel.ChannelId); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Unregisters all the side channels from the communicator.
|
|||
/// </summary>
|
|||
public static void UnregisterAllSideChannels() |
|||
{ |
|||
RegisteredChannels = new Dictionary<Guid, SideChannel>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the SideChannel of Type T if there is one registered, or null if it doesn't.
|
|||
/// If there are multiple SideChannels of the same type registered, the returned instance is arbitrary.
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <returns></returns>
|
|||
public static T GetSideChannel<T>() where T: SideChannel |
|||
{ |
|||
foreach (var sc in RegisteredChannels.Values) |
|||
{ |
|||
if (sc.GetType() == typeof(T)) |
|||
{ |
|||
return (T) sc; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns all SideChannels of Type T that are registered. Use <see cref="GetSideChannel{T}()"/> if possible,
|
|||
/// as that does not make any memory allocations.
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <returns></returns>
|
|||
public static List<T> GetSideChannels<T>() where T: SideChannel |
|||
{ |
|||
var output = new List<T>(); |
|||
|
|||
foreach (var sc in RegisteredChannels.Values) |
|||
{ |
|||
if (sc.GetType() == typeof(T)) |
|||
{ |
|||
output.Add((T) sc); |
|||
} |
|||
} |
|||
return output; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Grabs the messages that the registered side channels will send to Python at the current step
|
|||
/// into a singe byte array.
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
internal static byte[] GetSideChannelMessage() |
|||
{ |
|||
return GetSideChannelMessage(RegisteredChannels); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Grabs the messages that the registered side channels will send to Python at the current step
|
|||
/// into a singe byte array.
|
|||
/// </summary>
|
|||
/// <param name="sideChannels"> A dictionary of channel type to channel.</param>
|
|||
/// <returns></returns>
|
|||
internal static byte[] GetSideChannelMessage(Dictionary<Guid, SideChannel> sideChannels) |
|||
{ |
|||
using (var memStream = new MemoryStream()) |
|||
{ |
|||
using (var binaryWriter = new BinaryWriter(memStream)) |
|||
{ |
|||
foreach (var sideChannel in sideChannels.Values) |
|||
{ |
|||
var messageList = sideChannel.MessageQueue; |
|||
foreach (var message in messageList) |
|||
{ |
|||
binaryWriter.Write(sideChannel.ChannelId.ToByteArray()); |
|||
binaryWriter.Write(message.Length); |
|||
binaryWriter.Write(message); |
|||
} |
|||
sideChannel.MessageQueue.Clear(); |
|||
} |
|||
return memStream.ToArray(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Separates the data received from Python into individual messages for each registered side channel.
|
|||
/// </summary>
|
|||
/// <param name="dataReceived">The byte array of data received from Python.</param>
|
|||
internal static void ProcessSideChannelData(byte[] dataReceived) |
|||
{ |
|||
ProcessSideChannelData(RegisteredChannels, dataReceived); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Separates the data received from Python into individual messages for each registered side channel.
|
|||
/// </summary>
|
|||
/// <param name="sideChannels">A dictionary of channel type to channel.</param>
|
|||
/// <param name="dataReceived">The byte array of data received from Python.</param>
|
|||
internal static void ProcessSideChannelData(Dictionary<Guid, SideChannel> sideChannels, byte[] dataReceived) |
|||
{ |
|||
while (m_CachedMessages.Count != 0) |
|||
{ |
|||
var cachedMessage = m_CachedMessages.Dequeue(); |
|||
if (sideChannels.ContainsKey(cachedMessage.ChannelId)) |
|||
{ |
|||
using (var incomingMsg = new IncomingMessage(cachedMessage.Message)) |
|||
{ |
|||
sideChannels[cachedMessage.ChannelId].OnMessageReceived(incomingMsg); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
Debug.Log(string.Format( |
|||
"Unknown side channel data received. Channel Id is " |
|||
+ ": {0}", cachedMessage.ChannelId)); |
|||
} |
|||
} |
|||
|
|||
if (dataReceived.Length == 0) |
|||
{ |
|||
return; |
|||
} |
|||
using (var memStream = new MemoryStream(dataReceived)) |
|||
{ |
|||
using (var binaryReader = new BinaryReader(memStream)) |
|||
{ |
|||
while (memStream.Position < memStream.Length) |
|||
{ |
|||
Guid channelId = Guid.Empty; |
|||
byte[] message = null; |
|||
try |
|||
{ |
|||
channelId = new Guid(binaryReader.ReadBytes(16)); |
|||
var messageLength = binaryReader.ReadInt32(); |
|||
message = binaryReader.ReadBytes(messageLength); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new UnityAgentsException( |
|||
"There was a problem reading a message in a SideChannel. Please make sure the " + |
|||
"version of MLAgents in Unity is compatible with the Python version. Original error : " |
|||
+ ex.Message); |
|||
} |
|||
if (sideChannels.ContainsKey(channelId)) |
|||
{ |
|||
using (var incomingMsg = new IncomingMessage(message)) |
|||
{ |
|||
sideChannels[channelId].OnMessageReceived(incomingMsg); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// Don't recognize this ID, but cache it in case the SideChannel that can handle
|
|||
// it is registered before the next call to ProcessSideChannelData.
|
|||
m_CachedMessages.Enqueue(new CachedSideChannelMessage |
|||
{ |
|||
ChannelId = channelId, |
|||
Message = message |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2506dff31271f49298fbff21e13fa8b6 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
import logging # noqa I251 |
|||
|
|||
CRITICAL = logging.CRITICAL |
|||
FATAL = logging.FATAL |
|||
ERROR = logging.ERROR |
|||
WARNING = logging.WARNING |
|||
INFO = logging.INFO |
|||
DEBUG = logging.DEBUG |
|||
NOTSET = logging.NOTSET |
|||
|
|||
_loggers = set() |
|||
_log_level = NOTSET |
|||
DATE_FORMAT = "%Y-%m-%d %H:%M:%S" |
|||
LOG_FORMAT = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s" |
|||
|
|||
|
|||
def get_logger(name: str) -> logging.Logger: |
|||
""" |
|||
Create a logger with the specified name. The logger will use the log level |
|||
specified by set_log_level() |
|||
""" |
|||
logger = logging.getLogger(name=name) |
|||
|
|||
# If we've already set the log level, make sure new loggers use it |
|||
if _log_level != NOTSET: |
|||
logger.setLevel(_log_level) |
|||
|
|||
# Keep track of this logger so that we can change the log level later |
|||
_loggers.add(logger) |
|||
return logger |
|||
|
|||
|
|||
def set_log_level(log_level: int) -> None: |
|||
""" |
|||
Set the ML-Agents logging level. This will also configure the logging format (if it hasn't already been set). |
|||
""" |
|||
global _log_level |
|||
_log_level = log_level |
|||
|
|||
# Configure the log format. |
|||
# In theory, this would be sufficient, but if another library calls logging.basicConfig |
|||
# first, it doesn't have any effect. |
|||
logging.basicConfig(level=_log_level, format=LOG_FORMAT, datefmt=DATE_FORMAT) |
|||
|
|||
for logger in _loggers: |
|||
logger.setLevel(log_level) |
|
|||
# Background: Jupyter |
|||
|
|||
[Jupyter](https://jupyter.org) is a fantastic tool for writing code with |
|||
embedded visualizations. We provide one such notebook, |
|||
`notebooks/getting-started.ipynb`, for testing the Python control interface to a |
|||
Unity build. This notebook is introduced in the |
|||
[Getting Started Guide](Getting-Started.md) |
|||
tutorial, but can be used for testing the connection to any Unity build. |
|||
|
|||
For a walkthrough of how to use Jupyter, see |
|||
[Running the Jupyter Notebook](http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/execute.html) |
|||
in the _Jupyter/IPython Quick Start Guide_. To launch Jupyter, run in the |
|||
command line: |
|||
|
|||
```sh |
|||
jupyter notebook |
|||
``` |
|||
|
|||
Then navigate to `localhost:8888` to access your notebooks. |
|
|||
import logging |
|||
|
|||
|
|||
def create_logger(name, log_level): |
|||
date_format = "%Y-%m-%d %H:%M:%S" |
|||
log_format = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s" |
|||
|
|||
logging.basicConfig(level=log_level, format=log_format, datefmt=date_format) |
|||
logger = logging.getLogger(name=name) |
|||
return logger |
撰写
预览
正在加载...
取消
保存
Reference in new issue