Day 01 The Hidden Void
Module 1 • Environment Design

Building the Terrestrial Abyss

Creating a signal-denied, light-restricted simulation for autonomous drone training.

Subsurface Realities

As seen in the Team Umbrella mission proposal (ISU MSS 2026), lava tubes are the "holy grail" of Martian exploration. They offer protection from radiation and meteorites, but they present a navigation nightmare.

Inside a lava tube, an agent is effectively isolated from the rest of the solar system. The thick basaltic ceilings act as a Faraday cage, creating a zone of near-total radio silence. Traditional positioning systems (like GPS on Earth or orbital relay tracking on Mars) are non-existent. Without line-of-sight to satellites, drones cannot rely on external corrections for their position.

This same challenge applies to Earth. Search and Rescue (SAR) drones inside collapsed buildings or deep cave systems cannot rely on GPS. They must navigate using pure Ego-Motion and tactile/range-based sensors like Lidar.


Protocol 1: Project Initialization

Step 1.1: Create Unity Project

  1. Open Unity Hub.
  2. Click New Project.
  3. Select 3D (Core) template.
  4. Name it: Terrestrial_Abyss_Agent.
  5. Location: Choose a folder on your local drive (avoid cloud-synced folders for performance).
  6. Click Create Project. Wait for the Editor to open (~2-5 mins).

Step 1.2: Install ML-Agents Package

  1. In Unity, go to Window > Package Manager.
  2. Click the + icon (top left) > Add package from disk...
  3. Navigate to where you installed the ml-agents repository (setup Day 0).
  4. Select the package.json file inside com.unity.ml-agents folder.
  5. Wait for installation to complete. You should see "ML Agents" in your packages list.

Protocol 2: The Environment (Cave Design)

We need a tunnel, not just a plane. We will use ProBuilder to model it quickly.

Step 2.1: Initial Cave Segment

  1. Go to Tools > ProBuilder > ProBuilder Window.
  2. Click New Shape.
  3. Select Pipe shape.
  4. Set Radius: 5m, Thickness: 0.5m, Height: 10m.
  5. In the Hierarchy, rename it to Cave_Segment_01.
  6. Rotate it 90 degrees on X-axis so it lays flat as a tunnel.

Step 2.2: Physics & Materials

Go to your Project window (bottom).

  1. Right-click > Create > Physic Material. Name it RoughRock.
  2. Set Dynamic Friction: 0.8, Static Friction: 0.8.
  3. Drag this material onto your cave segment in the Scene view.
  4. Why? If the drone crashes, we want it to snag and tumble, not slide infinitely like ice.

Protocol 3: The Agent (Drone)

Step 3.1: Drone Body

  1. Create an Empty GameObject named DroneAgent.
  2. Inside it, create a Sphere (Scale: 0.5, 0.2, 0.5) to represent the chassis.
  3. On the parent DroneAgent, add component Rigidbody.
    • Mass: 1.5 (kg)
    • Drag: 0.5
    • Angular Drag: 0.5
    • Use Gravity: Checked
  4. Add component Decision Requester.
    • Decision Period: 5
  5. Add component Behavior Parameters.
    • Behavior Name: CaveExplorer
    • Vector Observation Space Size: 0 (we use sensors)
    • Vector Action Space: Continuous, Size: 2 (Forward thrust, Yaw rotation)

Step 3.2: The "Eyes" (Ray Perception)

This is the critical sensor for dark environments.

  1. On DroneAgent, add component Ray Perception Sensor 3D.
  2. Rays Per Direction: 12 (Total rays = 25).
  3. Max Ray Degrees: 60 (Wide field of view).
  4. Sphere Cast Radius: 0.1 (Thick rays).
  5. Detectable Tags: Add a tag "Wall" and apply it to your Cave Segment object.
  6. Stacked Raycasts: 1 (No history needed yet).

Protocol 4: The Brain (Scripting)

Create a new C# script named CaveExplorerAgent.cs and paste this code.

using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;

public class CaveExplorerAgent : Agent
{
    Rigidbody rBody;
    public float flySpeed = 10f;

    public override void Initialize()
    {
        rBody = GetComponent();
    }

    public override void OnEpisodeBegin()
    {
        // Reset velocity
        rBody.velocity = Vector3.zero;
        rBody.angularVelocity = Vector3.zero;
        
        // Reset position to start of tube
        transform.localPosition = new Vector3(0, 0.5f, 0); 
        transform.localRotation = Quaternion.identity;
    }

    public override void OnActionReceived(ActionBuffers actions)
    {
        // Inputs from Neural Network
        float moveForward = actions.ContinuousActions[0];
        float yaw = actions.ContinuousActions[1];

        // Apply Forces
        Vector3 force = transform.forward * moveForward * flySpeed;
        rBody.AddForce(force);
        
        Vector3 rotation = transform.up * yaw * 100f;
        rBody.AddTorque(rotation);

        // Energy Penalty (existential cost)
        AddReward(-0.001f);
    }

    // Manual Control for Testing
    public override void Heuristic(in ActionBuffers actionsOut)
    {
        var continuousActionsOut = actionsOut.ContinuousActions;
        continuousActionsOut[0] = Input.GetAxis("Vertical"); // W/S
        continuousActionsOut[1] = Input.GetAxis("Horizontal"); // A/D
    }
    
    // Collision Logic
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Wall"))
        {
            SetReward(-1.0f); // Big Penalty for crashing
            EndEpisode();
            Debug.Log("Crashed into Wall!");
        }
    }
}

Check your work

1. Attach this script to your DroneAgent game object.

2. Press Play in Unity.

3. Use W/A/S/D keys. Does the drone move? Do you see red lines (rays) shooting out?

If YES: You have successfully built a sensor-equipped agent.

Proceed to Day 2: The Training Loop →