Ejemplo n.º 1
0
    private IEnumerator TakeGradualAIActionRoutine(float[] vectorAction)
    {
        // Interprets the actions as absolute positions
        // Moves the Lamp's servo positions from their initial positions to their final positions over a duration of 2 seconds

        int count = Lamp.NumberOfServos;

        int[] endServoPositions = new int[count];

        for (int i = 0; i < count; ++i)
        {
            endServoPositions[i] = lamp.GetServo(i).OffsetFromNormalized(Mathf.Clamp(vectorAction[i], -1f, 1f));
        }

        float duration = 2f;
        float time     = 0f;
        int   offset;

        // Interpolate servo positions from their initial positions to their final (end) positions
        while (time < duration)
        {
            time = Mathf.Min(time + Time.deltaTime, duration);

            for (int i = 0; i < count; ++i)
            {
                offset = (int)Mathf.SmoothStep(initialServoPositions[i], endServoPositions[i], time / duration);
                lamp.GetServo(i).SetOffset(offset);
            }

            yield return(null);
        }

        // Servos are now at their final positions, evaluate the action
        ActionResultFlags resultFlags;
        float             reward = EvaluateAction(vectorAction, out resultFlags);
        bool success             = (resultFlags & ActionResultFlags.Success) != 0;

        print(success ? "Success" : "Fail");
        print("Reward: " + reward);
        print("-----------\n");

        AddReward(reward);

        if (success)
        {
            ++SuccessFulActions;
        }

        ++ActionsTaken;
        ResetAgentIfNotDone();         // agent is automatically reset if its done... so we only reset if not done to avoid double reset

        ActionWasTaken?.Invoke();

        if (requestOnStart)
        {
            // requestOnStart should probably be renamed, but basically we just assume movement automation
            RequestDecision();
        }
    }
Ejemplo n.º 2
0
    public override void AgentAction(float[] vectorAction, string textAction)
    {
        // The vectorAction parameter is our "output vector"
        // Here the Agent decides how to take an action based on its actionType
        // Instant: Snap the Lamp's servos into the final positions (primarily used during reinforcement learning training sessions)
        // Gradual: Starts a coroutine that move the Lamp's servos into the final positions over a duration (primarily for viewing trained models and during imitation learning sessions)
        // Player: Moves the Lamp's servos based on key presses (used to test lamp movement in the editor)

        ActionResultFlags resultFlags;

        switch (actionType)
        {
        case EActionType.Instant:
            TakeInstantAIAction(vectorAction);
            AddReward(EvaluateAction(vectorAction, out resultFlags));

            if ((resultFlags & ActionResultFlags.Terminal) != 0)
            {
                Done();
            }
            else
            {
                ResetAgentIfNotDone();
            }

            ActionWasTaken?.Invoke();

            break;

        case EActionType.Gradual:
            // Print actions
            print("Action: " + vectorAction.AsString());
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(logFilePath, true))
            {
                file.WriteLine("Action: " + vectorAction.AsString());
            }
            TakeGradualAIAction(vectorAction);
            break;

        case EActionType.Player:
            TakePlayerAction(vectorAction);
            EvaluateAction(vectorAction, out resultFlags);

            if ((resultFlags & ActionResultFlags.Success) != 0)
            {
                ResetAgentIfNotDone();
            }

            ActionWasTaken?.Invoke();

            break;
        }
    }