Example #1
0
    public override void CollectObservations()
    {
        // Robot position in each environment
        AddVectorObs(this.transform.position - environment.transform.position);

        // Robot position
        Vector3 currentPosition = transform.position - environment.transform.position;

        AddVectorObs(currentPosition.x, "robot_position_x");
        AddVectorObs(currentPosition.z, "robot_position_z");

        // Robot rotation
        AddVectorObs(transform.rotation.eulerAngles.y, "robot_rotation");

        // Robot velocity
        Vector3 localVelocity = rb.transform.InverseTransformDirection(rb.velocity);

        AddVectorObs(localVelocity.x, "robot_velocity_x");
        AddVectorObs(localVelocity.z, "robot_velocity_z");

        // Shovel position
        AddVectorObs(shovel.GetShovelPos(), "shovel_position");

        // Comment out these observations if using PPO
        AddVectorObs(timesWon, "times_won");
        AddVectorObs(timeElapsed, "time_elapsed");

        // DropZone position and radius
        dropZonePosition = transform.InverseTransformPoint(dropZone.transform.position);
        AddVectorObs(dropZonePosition.x, "dropzone_position_x");
        AddVectorObs(dropZonePosition.z, "dropzone_position_z");
        AddVectorObs(dropZone.GetRadius(), "dropzone_radius");

        // Distance sensor measurements
        float[] distances = sensors.GetMeasuredDistances();
        for (int dist = 0; dist < distances.Length; dist++)
        {
            AddVectorObs(distances[dist], "sensor_measurement_" + (dist + 1));
        }

        // Debris positions
        debrisInfos = vision.UpdateVision();

        if (limitedObservations)
        {
            // Debris Position
            debrisPosition = Vector3.zero;
            if (debrisInfos != null && debrisInfos.Count > 0 && debrisInfos[0].transform != null)
            {
                debrisPosition = transform.InverseTransformPoint(debrisInfos[0].transform.position);
            }

            AddVectorObs(debrisPosition.x, "debris_position_x");
            AddVectorObs(debrisPosition.z, "debris_position_z");
        }
        else
        {
            for (int debris = 0; debris < debrisInfos.Count; debris++)
            {
                AddVectorObs(debrisInfos[debris].lastKnownPosition.x, "debris_" + (debris + 1) + "_position_x");
                AddVectorObs(debrisInfos[debris].lastKnownPosition.z, "debris_" + (debris + 1) + "_position_z");
            }

            for (int i = 0; i < DebrisCount - debrisInfos.Count; i++)
            {
                AddVectorObs(0f, "debris_" + (i + debrisInfos.Count + 1) + "_position_x");
                AddVectorObs(0f, "debris_" + (i + debrisInfos.Count + 1) + "_position_z");
            }

            // Simulation time
            AddVectorObs(timeElapsed, "simulation_time");

            // Features:

            //Check if robot is within dropZone, Returns boolean
            bool isInDropZone = dropZone.IsInZone(transform.position);
            AddVectorObs(isInDropZone, "robot_in_dropzone");

            ObsDistanceToDebris();
            ObsDebrisIsInShovel();
            ObsAngleToDebris();
            ObsDebrisInFront();
            ObsFacingDebris();
            ObsGettingCloserToDebris();

            // Angle to dropzone
            float angleToDropZone = Vector3.Angle(dropZonePosition, transform.forward);
            if (transform.rotation.eulerAngles.y > 180)
            {
                angleToDropZone = -angleToDropZone;
            }
            AddVectorObs(angleToDropZone, "angle_to_dropzone");

            ObsDebrisToDropZone();
            ObsNextAngleToDebris();
        }

#if UNITY_EDITOR
        // AUTO GENERATE RobotObservations.py
        if (!observationsLogged && !limitedObservations)
        {
            DirectoryInfo mlAgentsRootDir = new DirectoryInfo(Application.dataPath).Parent.Parent;

            string filePath = Path.Combine(mlAgentsRootDir.ToString(), "project/RobotObservations.py");

            using (StreamWriter sw = new StreamWriter(filePath))
            {
                StringBuilder stringBuilder = new StringBuilder();

                stringBuilder.AppendLine("# This file was generated by RobotAgent.cs");
                stringBuilder.AppendLine("from enum import IntEnum");
                stringBuilder.AppendLine("");
                stringBuilder.AppendLine("");
                stringBuilder.AppendLine("class RobotObservations(IntEnum):");
                stringBuilder.AppendLine("    # Accessible by self.obs.'field_name'");

                for (int i = 0; i < observationNames.Count; i++)
                {
                    stringBuilder.AppendLine("    " + observationNames[i] + " = " + i);
                }

                sw.Write(stringBuilder.ToString());
            }
        }
        observationsLogged = true;
#endif
    }