Skip to content

RayPerception sensor #2874

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

Merged
merged 19 commits into from
Nov 14, 2019
Merged

RayPerception sensor #2874

merged 19 commits into from
Nov 14, 2019

Conversation

chriselion
Copy link
Contributor

@chriselion chriselion commented Nov 8, 2019

I also made some adjustments to the raycast logic on how it handles hit perception. Hits against known object tags are the same but:

  • Hitting an unknown object now sets the hit fraction component of the output.
  • Missing sets the hit fraction to 1.0

I think these make sense and are more "continuous", i.e. an object just at the end of the ray will have a hit fraction of .99, and if the object moves out of range, the hit fraction increases to 1.0. The old behavior can be enabled via a flag (RayPerception3D uses it but the sensor doesn't).

Rays are evenly distributed in a "cone" in front of the agent. There's always a ray at 90 degrees, and also "rays per direction" to the left and right, up to "max rays degrees". This is a bit more restrictive than the old system, but also means you only need parameters. Can change to a list of angles (or list of offsets) if that might be better.

Currently only converted WallJump and trained a new model for it. Can update other scenes later once this is merged.

image

https://jira.hq.unity3d.com/browse/MLA-310 and https://jira.hq.unity3d.com/browse/MLA-311 are followup jiras to improve the editor UI and debug drawing respectively.

@@ -1,10 +1,8 @@
using System.Collections.Generic;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleanup suggested by Rider.

}

var subList = new float[detectableObjects.Length + 2];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got rid of this, and just wrote to the buffer with an offset instead.

@@ -10,9 +11,6 @@ namespace MLAgents
/// </summary>
public class RayPerception3D : RayPerception
{
RaycastHit m_Hit;
float[] m_SubList;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same comment as above. Also RayCast hit is a struct so we don't need to keep it around (I think, correct me if I'm wrong)

// TODO reenable checks there are enough Visual Observation Placeholder in the model.
// If there are not enough Visual Observation Input compared to what the
// sensors expect.
var visObsIndex = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There were removed in https://github.com/Unity-Technologies/ml-agents/pull/2731/files#diff-bbd30aae9fbe4211cf7e967224f2864dL242
Add them back here (and also check for not enough visual inputs, which was missing earlier).

Transform transform, float[] perceptionBuffer,
bool legacyHitFractionBehavior = false)
{
Array.Clear(perceptionBuffer, 0, perceptionBuffer.Length);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was migrated (and improved IMHO) from the old code.


bool castHit;
RaycastHit rayHit;
if (castRadius > 0f)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The size of the spherecast is now adjustable. If set to 0 (or smaller) it will use raycasts instead.

[Tooltip("Whether to stack previous observations. Using 1 means no previous observations.")]
public int observationStacks = 1;

// TODO layerMask for raycasts
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See https://jira.hq.unity3d.com/browse/MLA-16 - would be nice but not sure if there's an easy way to make it look good in the editor.

/// Returns the shape of the sensor observations that will be created.
/// </summary>
/// <returns></returns>
public abstract int[] GetObservationShape();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added this to the editor components; they now have to return the size that the sensors will create.

/// <returns></returns>
public abstract int[] GetObservationShape();

public virtual bool IsVisual()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not strictly needed, but I thought it made some of the code cleaner.

Copy link
Contributor

@surfnerd surfnerd left a comment

Choose a reason for hiding this comment

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

👏

@surfnerd
Copy link
Contributor

Will this have a follow up with docs changes?

@@ -150,7 +151,7 @@ public void MoveAgent(float[] act)
{
var myTransform = transform;
myLaser.transform.localScale = new Vector3(1f, 1f, m_LaserLength);
var position = myTransform.TransformDirection(RayPerception3D.PolarToCartesian(25f, 90f));
var position = myTransform.TransformDirection(RayPerceptionSensor.PolarToCartesian(25f, 90f));
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be 3DRayPerceptionSensor to show this is 3D?

Copy link
Contributor

Choose a reason for hiding this comment

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

Should PolarToCartesian live in some Utility class? Should the Debug.DrawRay be part of the sensor instead ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me try to clean some of this up a bit. I'd lean towards not doing any trig functions at runtime, and either save a quaternion "base" and "increment", or storing the local space vectors on the sensor.

Copy link
Contributor Author

@chriselion chriselion Nov 13, 2019

Choose a reason for hiding this comment

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

🤦‍♂ This should just be "25.0 * transform.forwards" since the angle is hardcoded to 90

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleaned this part up. It had no need for any RayPerception* code here. Note this is "game logic" inside MoveAgent(), not actually related to observations.

/// <summary>
/// Converts polar coordinate to cartesian coordinate.
/// </summary>
public static Vector2 PolarToCartesian(float radius, float angle)
{
var x = radius * Mathf.Cos(DegreeToRadian(angle));
var y = radius * Mathf.Sin(DegreeToRadian(angle));
var x = radius * Mathf.Cos(RayPerceptionSensor.DegreeToRadian(angle));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as in PolarToCartesian. Is there a better place to put these ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also made the PolarToCartesian methods private in their respective classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is folded into RayPerceptionSensor now.

}

const float castRadius = 0.5f;
const bool legacyHitFractionBehavior = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel this adds complexity. It is fair to say, you need to retrain when updating. I don't think we should have legacy code in a beta project.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed it adds complexity. Disagree that we shouldn't support it, at least for one more release. The old code is marked as [Obsolete] and we can remove it after the next release ships.

{
if (input.shape.Length == 4)
{
if (input.name.StartsWith(TensorNames.VisualObservationPlaceholderPrefix))
Copy link
Contributor

Choose a reason for hiding this comment

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

Magic strings... But I don't see an alternative without changing the way the trainer code works... @ervteng any refactor of the trainers (related to model inputs) planned?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I don't love it either. There are several other places in the (resurrected) barracuda code that check for this too. Trainer refactor is probably not sufficient, will likely need some tf2bc.py changes too.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wasn't planning on changing how the trainer detects these... but that was because I was assuming it wasn't going to change on the C# side :P would the alternative be having a "type" for the observation that's an enum or similar?

I think the tricky thing about the tf2bc part is that it uses the TensorFlow tensor names to determine what to put as input and output, and those are limited to being strings.

@chriselion
Copy link
Contributor Author

@surfnerd

Will this have a follow up with docs changes?

Definitely will add a migration guide for it. I don't think there are any docs on the old code, but I can find a place to add a writeup on the new stuff.

@chriselion chriselion merged commit a820650 into develop Nov 14, 2019
@delete-merged-branch delete-merged-branch bot deleted the develop-MLA-10-raycast-sensor branch November 14, 2019 23:07
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants