-
Notifications
You must be signed in to change notification settings - Fork 4.3k
API for sending custom protobuf messages to and from Unity. #1595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API for sending custom protobuf messages to and from Unity. #1595
Conversation
…tfix-0.6.0a Hotfix 0.6.0a to master
@@ -541,6 +548,7 @@ void ResetData() | |||
* param.numStackedVectorObservations]); | |||
|
|||
info.visualObservations = new List<Texture2D>(); | |||
info.customOutput = new CustomOutput(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear to me how the user is supposed to pass a customOutput
to the agentInfo. Here you create a new one and the GetCustomOutput()
gives you the customOutput in the AgentInfo. I would rather have at this line info.customOutput = this.customOutput
and have getter and setter on Agent.customOuptut
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My idea was the user does something like
void AgentAction(...) {
var myOutput = GetCustomOutput();
myOutput.x = 5;
}
This was to get around the user having to create their own instance of CustomOutput
, since then the example becomes
void AgentAction(...) {
var myOutput = new CommunicatorObjects.CustomOutput();
myOutput.x = 5;
customOutput = myOutput;
That seems rather ugly, although it become betters if CustomOutput
is imported into MLAgents
namespace.
Are you proposing simply
void AgentAction(...) {
customOutput.x = 5;
}
with customOutput
a getter on an internal attribute that is still created automatically by Agent
instead of by the user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to avoid creating a new instance of CustomOutput at every step when it is not needed. I am not sure what the API should look like here. To be consistent with AddObservation, we could have a AddCustomOutput method.
Now that I think about it, having an Agent.customOutput might be confusing. The user might try to modify this value from another script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about SetCustomOutput
to mirror SetReward
? AddObservation
seems to imply that there can be multiple instances of a CustomOutput
outputted by an agent on each step, which isn't true at the moment.
@@ -3,6 +3,9 @@ syntax = "proto3"; | |||
option csharp_namespace = "MLAgents.CommunicatorObjects"; | |||
package communicator_objects; | |||
|
|||
message CustomOutput { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both CustomOutput and CustomParameters should live in separate files. Since these are supposed to be modified by the user, they should be separated from the rest of the proto definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved them into their own files. I could also move them into a separate folder and a separate C#/proto namespace if you think that's useful.
/// User-customizable object for sending structured output from Unity to Python in response | ||
/// to an action in addition to a scalar reward. | ||
/// </summary> | ||
public CustomOutput customOutput; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would need to investigate but I am not sure this is ever used.
/// Creates a new instance of a custom output object. | ||
/// </summary> | ||
/// <returns>A reference to a new CustomOutput object.</returns> | ||
static public CustomOutput CreateCustomOutput() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is fine to let the developer instantiate his own CustomOutput. This method feels redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that could be problematic since the user has to then know about the CommunicatorObjects
namespace, where the CustomOutput
class lives. If the C# namespace of the custom_output.proto file ever changes due to some kind of internal refactoring, users would have to adopt their code.
But sure, I'll make this change.
Hi @malmaud
Do you have an example use case ? This would help us define better what the API should look like. |
I've very grateful for the team's support. Thank you! I'll make all those requests changes in the next few days. I do have a use case since this was motivated by one of my PhD projects. I can boil that down to the minimum to show off the API and post a link for discussion. |
WRT to renaming
I was thinking of adding a new custom message to |
Unfortunately, there is no way to send data from Unity to Python at the AgentAction level. The second scenario you are proposing would require information to be sent from Unity to Python twice per step (If I understood correctly). I do not think the second scenario you mentioned would fit in the ML-Agents toolkit. |
I am unclear regarding what |
Here was my thinking. I'm totally happy to just get rid of The basic flow I imagined was:
In principle, the Unity agent could just store whatever information it was going to put in the custom action result during |
I see what you mean, |
Alright. How about I add a getter for the |
I think the PR looks good. I think we would need to make sure pytest still work, maybe even make new unit tests. The API looks good, I think you can start making documentation update for it. Let us know if you need help. |
Ok, great. It will be a week or so until I can get back to this. |
…lease-v0.7 Release v0.7 into master
@malmaud Did you have time to revisit this PR ? |
I can work on it later this week.
…On Tue, Mar 12, 2019 at 1:21 PM Vincent-Pierre BERGES < ***@***.***> wrote:
@malmaud <https://github.com/malmaud> Did you have time to revisit this
PR ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1595 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA8SveML4T6HGkmP7ZEve0mUT9cFPvM6ks5vV-IKgaJpZM4Z8dWU>
.
|
OK, ready to work on this again. So it sounds like what's still needed is docs and tests. Looks like for docs, I'd add sections to the Can you guide me a bit on how to get started with adding tests? It looks like |
Yes, all the documentation is present in the |
OK, I added some documentation. It's primarily in a new I implemented all the examples I mention in that file to double-check that they work. Still have to work on tests. |
* Rename CustomParameters -> CustomResetParameters * Rename CustomOutput -> CUstomObservation * Add CustomAction * Add CustomActionResult
Also eliminate GetCustomObservation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved!
Thanks everyone! |
…chnologies#1595) * API for sending custom protobuf messages to and from Unity. * Rename custom_output to custom_outputs. * Move custom protos to their own files. * Add SetCustomOutput method. * Add docstrings. * Various adjustments. * Rename CustomParameters -> CustomResetParameters * Rename CustomOutput -> CUstomObservation * Add CustomAction * Add CustomActionResult * Remove custom action result. * Remove custom action result from Python API * Start new documentation. * Add some docstrings * Expand documentation. * Typos * Tweak doc. Also eliminate GetCustomObservation. * Fix typo. * Clarify docs. * Remove trailing whitspace
Implements #1549.
This allows users to customize two protobuffer messages:
They can add fields to
CustomParameters
and pass an instance of their custom parameters toUnityEnvironment.reset
with the newcustom_config
keyword argument. This is useful if the scene configuration is complex and hard to encode as a few scalar parameters, as the academy is currently set up to support.They can also add fields to
CustomOutput
message and set the value of those fields inAgentAction
, which will in turn be available in Python as part of the agent info returned fromUnityEnvironment.step
. They callGetCustomOutput
inAgentAction
orCollectObservations
to get an instance of theCustomOutput
object and set the value of its fields.This enables Unity to return more than a single scalar reward to Python, which is useful for eg sending back the complex effects of an action and having the reward calculation logic happen in Python, or for debugging or computing diagnostics in Python.
I'm happy to write up documentation once (if) an API is agreed upon.