Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Single agent environment act as MultiAgent env?

Discussion in 'ML-Agents' started by BenceDD, Mar 19, 2020.

  1. BenceDD

    BenceDD

    Joined:
    Mar 18, 2019
    Posts:
    3
    Hi All,

    I made an environment in Unity 2019.3.4f1 with unity-ml 0.14.1 and gym-unity by following insrtructions at the official documentation:

    https://github.com/Unity-Technologi...lease/docs/Learning-Environment-Create-New.md

    For the first few try it was working, but than something broken and now when I try to create the UnityGym wrapper object, I get the wolloeing exception:

    UnityGymException: The environment was launched as a single-agent environment, however there is more than one agent in the scene.


    Here is the agent script, and the componensts attached to the gameobject...

    Code (CSharp):
    1. public class CubeScript : Agent {
    2.     public override void AgentAction(float[] vectorAction) {
    3.         transform.position = new Vector3(
    4.             transform.position.x + vectorAction[0],
    5.             transform.position.y + vectorAction[1],
    6.             transform.position.z
    7.         );
    8.     }
    9.  
    10.     public override float[] Heuristic() {
    11.         return new[] { Input.GetAxis("Horizontal"), Input.GetAxis("Vertical") };
    12.     }
    13. }
    unity_img.png

    (CameraSensor is not used yet, but I will want to use it later.)

    Thanks for any suggestions!
     
  2. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,816
    We'll flag this for the team to have a look!
     
    BenceDD likes this.
  3. celion_unity

    celion_unity

    Joined:
    Jun 12, 2019
    Posts:
    289
    Hi,
    I've tried to reproduce this error using the provided gym notebook and the 3DBall scene (with all but one Agent disabled) and can't get it to happen. Can you confirm that you only ever have one Agent in the scene?
     
  4. BenceDD

    BenceDD

    Joined:
    Mar 18, 2019
    Posts:
    3
    Hi,

    I tried the 3DBall and the Basic scene too, but both raised the mentioned exception with the notebook you said.
    I built the scenes in development mode and I didn't change anything in neither (havent added any agents) so I think they supposed to work.

    If I can provide more information, please tell.
     
  5. celion_unity

    celion_unity

    Joined:
    Jun 12, 2019
    Posts:
    289
    Can you post the code that you're using to create the UnityEnv? Note that if you have more than one Agent in the scene, you'll need to pass
    multiagent=True
    to the initializer.
     
  6. BenceDD

    BenceDD

    Joined:
    Mar 18, 2019
    Posts:
    3
    I'm sure that the environment has single agent.

    Finally tried with a fresh installion of Unity, MLAgents, Python and VS in a virtual environment. For the first time, it was not worked, but after many tries (making agent code simpler), I was able to train with unity-gym in Python. Then, to find the issue why was my code wrong, I reverted all the changes, but then it was worked too.

    So, I really have no idea why I got this exception before.


    Here is the code which was not worked because of unity-gym raising the mentioned multiagent exception.
    (I used the lock because I thought I have concurrency issues.)

    Code (CSharp):
    1. using UnityEngine;
    2. using MLAgents;
    3. using System;
    4.  
    5. public class BAgentCube : Agent {
    6.     public int _state;
    7.     public bool _explored = false;
    8.  
    9.     public Vector3[] statePlaces = {
    10.         new Vector3(0f, 1f, -12.5f),
    11.         new Vector3(0f, 1f, -7.5f),
    12.         new Vector3(0f, 1f, -2.5f),
    13.         new Vector3(0f, 1f, 2.5f),
    14.         new Vector3(0f, 1f, 7.5f),
    15.         new Vector3(0f, 1f, 12.5f),
    16.     };
    17.  
    18.     // debug
    19.     public long _episodes = 0;
    20.     public float _cum_reward = 0f;
    21.  
    22.     public readonly object readLock = new object();
    23.     public readonly System.Random myRand = new System.Random(48);
    24.  
    25.     void Start() {
    26.         // AgentReset();
    27.     }
    28.  
    29.     public override void AgentReset() {
    30.         lock (readLock) {
    31.             _state = 1;
    32.             transform.position = statePlaces[_state];
    33.             _explored = false;
    34.         }
    35.     }
    36.  
    37.     public override void AgentAction(float[] vectorAction) {
    38.         lock (readLock) {
    39.             var floatAction = vectorAction[0];
    40.  
    41.             if (floatAction < -0.1)
    42.                 return;
    43.  
    44.             int move;
    45.  
    46.             var tst = myRand.NextDouble() < 0.5;
    47.  
    48.             if (Mathf.RoundToInt(floatAction) == 0 || _state == 5 || tst)
    49.                 move = -1;
    50.             else
    51.                 move = 1;
    52.             _state += move;
    53.  
    54.             transform.position = statePlaces[_state];
    55.  
    56.             if (_state == 5)
    57.                 _explored = true;
    58.  
    59.             if (_state == 0) {
    60.                 if (_explored) {
    61.                     SetReward(1f);
    62.                     _cum_reward += 1f;
    63.                 } else {
    64.                     SetReward(0.01f);
    65.                     _cum_reward += 0.01f;
    66.                 }
    67.                 _episodes++;
    68.  
    69.                 if (_episodes % 10 == 0) {
    70.                     var crpe = _cum_reward / _episodes;
    71.                     if (crpe > 0.25)
    72.                         Debug.Log($"Wrong!! {_cum_reward / _episodes}");
    73.                     else
    74.                         Debug.Log($"Avg: {_cum_reward / _episodes}");
    75.                 }
    76.  
    77.                 Done();
    78.             }
    79.         }
    80.  
    81.     }
    82.  
    83.     public override float[] Heuristic() {
    84.         switch (Input.GetAxis("Horizontal")) {
    85.             case 1:
    86.                 return new[] { 1f };
    87.             case -1:
    88.                 return new[] { 0f };
    89.             default:
    90.                 return new[] { -1f };
    91.         };
    92.     }
    93.  
    94. }
    95.  
    And here is an other, which is equivalent in theory. This was worked for the first time.

    Code (CSharp):
    1. using UnityEngine;
    2. using MLAgents;
    3.  
    4. public class CubeScript : Agent {
    5.  
    6.     public int state;
    7.     public bool explored = false;
    8.  
    9.     public Vector3[] statePlaces = {
    10.         new Vector3(0f, 1f, -12.5f),
    11.         new Vector3(0f, 1f, -7.5f),
    12.         new Vector3(0f, 1f, -2.5f),
    13.         new Vector3(0f, 1f, 2.5f),
    14.         new Vector3(0f, 1f, 7.5f),
    15.         new Vector3(0f, 1f, 12.5f),
    16.     };
    17.  
    18.     public override void AgentReset() {
    19.         state = 1;
    20.         transform.position = statePlaces[state];
    21.         explored = false;
    22.     }
    23.  
    24.     public override void AgentAction(float[] vectorAction) {
    25.         var action = Mathf.RoundToInt(vectorAction[0]);
    26.  
    27.         if (Random.value < 0.5 || action == 1 || state == 5)
    28.             state -= 1;
    29.         else
    30.             state += 1;
    31.  
    32.         transform.position = statePlaces[state];
    33.  
    34.         if (state == 5)
    35.             explored = true;
    36.  
    37.         if (state == 0) {
    38.             if (explored)
    39.                 SetReward(1f);
    40.             else
    41.                 SetReward(0.01f);
    42.             Done();
    43.         }
    44.     }
    45.  
    46.     public override float[] Heuristic() {
    47.         switch (Input.GetAxis("Horizontal")) {
    48.             case 1:
    49.                 return new[] { 2f };
    50.             case -1:
    51.                 return new[] { 1f };
    52.             default:
    53.                 return new[] { 0f };
    54.         };
    55.     }
    56. }

    Thank you for your assistance!