0

I am working on a simulation game where you need to place a medical station somewhere on the map. Thenthe simulation run and compute the effectiveness of the position (it can't be too far or too close some other building). I want to train a MLAgent to find the optimal spot. So I manually call the RequestDecision() method because it needs to wait the end of the simulation to get the reward (then the simulation reset and the agent try again). But it doesn't invoke OnActionReceived() as it is supposed to. Here my code :

public class AIController : Agent
{
    public LayerMask ground;
    public float[] mapSize = new float[2];

    private void Update()
    {
        SimulationMaster.SimulationState state = SimulationMaster.Instance.State;
        if (state == SimulationMaster.SimulationState.End)
        {
            SetReward(-SimulationMaster.Instance.GetTotalScore());
            EndEpisode();
        }
        else if (state == SimulationMaster.SimulationState.EditMode)
        {
            RequestDecision();
        }
    }
    
    public override void OnEpisodeBegin()
    {
        SimulationMaster.Instance.ResetToEditMode();
    }

    private void SpawnMedicalStation(float x, float y)
    {
        Ray ray = new Ray(new Vector3(x * mapSize[0], 10, y * mapSize[1]), Vector3.down);
        if (!Physics.Raycast(ray, out RaycastHit hitInfo, Mathf.Infinity, ground))
        {
            Debug.LogError("AIController - Out of bound");
            return;
        }
        SpawnManager.Instance.SpawnMedicalStation(hitInfo.point, 2, 2);
    }
    
    public override void CollectObservations(VectorSensor sensor)
    {
        Vector3 pos = TacticEventManager.Instance.TacticEvents[0].Barycentre;
        sensor.AddObservation(new Vector2(pos.x, pos.z));
    }

    public override void OnActionReceived(ActionBuffers actions)
    {
        if (SimulationMaster.Instance.State != SimulationMaster.SimulationState.EditMode) return;
        float x = actions.ContinuousActions[0];
        float y = actions.ContinuousActions[1];
    
        Debug.Log($"Action received: ({x}, {y})");
        SpawnMedicalStation(x, y);
        SimulationMaster.Instance.StartSimulation();
    }
}
Eloi
  • 101
  • 10
  • Where is the code for RequestDecision? – John Glenn Jan 21 '22 at 19:28
  • It is a inherited method from Agent supposed to invoke OnActionReceived(). See documentation here : https://docs.unity3d.com/Packages/com.unity.ml-agents@2.1/api/Unity.MLAgents.Agent.html#Unity_MLAgents_Agent_RequestDecision – Eloi Jan 22 '22 at 11:30
  • Is your if ... return statement at the top of OnActionReceived firing? Could you set a breakpoint on that line an rerun just to confirm that the OnActionReceived method isn't called at all? – John Glenn Jan 22 '22 at 14:16
  • I've already checked that, the breakpoint is not triggered, I even tried without the if statement. I am confused, I really do not know why the method is not triggered. Also I don't want to use the DecisionRequestor script because I want to trigger the decision manually (It needs to wait the end of the simulation before making a new decision). – Eloi Jan 22 '22 at 17:00

0 Answers0