Unity-Technologies / ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.
https://unity.com/products/machine-learning-agents
Other
17.18k stars 4.16k forks source link

RayPercieve2D.Perceive does not ignore self collider #2402

Closed AidinD closed 5 years ago

AidinD commented 5 years ago

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. Create a RayPerceive2D and shoot a ray.

Expected behaviour: The float distance should show the distance to the tagged objects included in detectable objects if in range

Actual behaviour: The distance is always 0 since it hits its own collider

It works if changing the layer to "Ignore "Raycast" layer.

ervteng commented 5 years ago

Hi @AidinD, is your RayPercieve inside the object? You might be able to increase the startOffset when calling Perceive to get out of the object.

AidinD commented 5 years ago

Hi @ervteng Thank you for the response.

  1. There is no argument for the offset in the 2D RayPercieve. Only in the 3D.
  2. The 3D version seems to work without using an offset, why should the 2D behave differently?
  3. Since we use detectable objects, wouldn't it be more intuitive if ONLY objects with these tags were considered? Meaning, the objects itself (unless assigned one of the detectable tags) should not be considered.
ervteng commented 5 years ago

@awjuliani are you familiar with the collider for 2D RayPercieve?

As for 3. I believe that is the case for the 3D case. But not sure why this would be different for 2D.

awjuliani commented 5 years ago

There should be no difference between the two in terms of how they do or don't ignore objects. Are you sure that the ray begins within the object that needs to be ignored?

AidinD commented 5 years ago

@awjuliani I did a quick setup and took a few screenshots to show my setup and highlight the issue. Here is the agent code and this is the only script used in the project except for an empty Academy script:

using System.Collections; using System.Collections.Generic; using MLAgents; using UnityEngine;

public class Circle : Agent {

    private RayPerception2D rayPerception;

    public override void InitializeAgent () {
        rayPerception = GetComponent<RayPerception2D> ();
    }

    public override void AgentReset () {

    }

    public override void CollectObservations () {
        float rayDistance = 5f;
        float[] rayAngles = { 0f };
        string[] detectableObjects = { "wall" };

        var rayValues = rayPerception.Perceive (rayDistance, rayAngles, detectableObjects);

        Debug.Log (rayValues[0]);
        Debug.Log (rayValues[1]);
        Debug.Log (rayValues[2]);

        AddVectorObs (rayValues);
    }

    public override void AgentAction (float[] vectorAction, string textAction) {

    }
}

The first screenshot shows a non working scenario. You can see in the console output that all the values that are returned from the rayPerception2D are zeroes. Note that the agent is untagged while the Wall is tagged as "wall" and both are inside the "Default" layer.

NotWorking

In this second screenshot you can see that we actually get non zero values back from the rayPerception2D. The only difference now is that the agent is put inside the "Ignore Raycast" layer.

Working

Corquasso commented 5 years ago

I am having the same issue, I've been trying to figure out why my machine learning samples do not work until I found out the same problem and wanted to report.

chriselion commented 5 years ago

It appears that the different physics systems handle raycasts which start inside a collider differently:

For 2D: https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html

Additionally, this will also detect Collider(s) at the start of the ray. In this case, the ray starts inside the Collider and doesn't intersect the Collider surface. This means that the collision normal cannot be calculated, in which case the returned collision normal is set to the inverse of the ray vector being tested. This can easily be detected because such results are always at a RaycastHit2D fraction of zero.

For 3D: https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Note: Raycasts will not detect Colliders for which the Raycast origin is inside the Collider.

This is a property of the physics systems, so there's not much that the RayPerception code can do about it right now.

surfnerd commented 5 years ago

Screen Shot 2019-10-23 at 4 05 21 PM If you got into Edit -> Project Settings -> Physics2D, uncheck the Queries start in colliders checkbox and see if that helps.

AidinD commented 5 years ago

Thank you very much. I have totally missed this setting! I will close this now.

github-actions[bot] commented 3 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.