ASU · RAS 598 · Mobile Robotics · Spring 2026

Milestone 2: Mid-Point Technical Proof

Autonomous Frontier Exploration with Semantic Hazard Mapping — TurtleBot4 Lite

Due: Apr 15, 2026 Weight: 10% 2500–3000 words Team: PriColon · rmane2 · Mkondamu

Overview

Milestone 2 documents our transition from system design (M1) to working implementation. This milestone presents concrete evidence of three custom ROS2 nodes running on the TurtleBot4 Lite hardware platform, a complete single-command launch system, and a recorded ROS bag demonstrating live frontier exploration with semantic hazard classification.

Our system enables a TurtleBot4 Lite to autonomously explore unknown indoor environments, detect and classify environmental hazards using camera, depth, LiDAR, and onboard sensors, and navigate safely by avoiding dangerous frontier zones — all without human intervention.

What we built

  • frontier_explorer_node.py
  • semantic_hazard_classifier_node.py
  • behavior_coordinator_node.py
  • exploration.launch.py
  • DeepHAZMAT YOLOv3-tiny integration

Evidence provided

  • Demo video — frontier exploration
  • RQT node graph — live system
  • ROS bag — full sensor recording
  • GitHub — all code pushed
  • Math PDFs — derivations

System Architecture

The full exploration stack connects four primary subsystems: SLAM Toolbox builds the occupancy map, the frontier explorer identifies exploration targets, the semantic hazard classifier labels dangerous zones, and the behavior coordinator orchestrates safe navigation through Nav2.

System architecture Mermaid diagram showing node connections
Figure 1 — Full system node graph generated from the running ROS2 stack
RQT graph showing active nodes and topic connections
Figure 2 — RQT graph captured during live frontier exploration run on TurtleBot4 Lite

Frontier Explorer Node

The frontier explorer node (frontier_explorer_node.py), developed by Princess Colon, implements the core exploration strategy. It continuously processes the SLAM occupancy map to identify unexplored regions and publishes ranked navigation targets to the behavior coordinator.

Algorithm

The node subscribes to /map (OccupancyGrid from slam_toolbox) and /odometry/filtered (EKF-filtered pose). Every time a new map arrives, the following pipeline executes:

Frontier Detection Pipeline

  1. Cell scanning — iterate all free cells (value=0) in the OccupancyGrid
  2. Frontier test — a free cell is a frontier if its 3×3 kernel contains at least one unknown cell (value=−1) and no occupied cells (value=100)
  3. Clustering — connected frontier cells are grouped using scipy.ndimage.label() with a 3×3 structure element; clusters smaller than min_cluster_size=10 are discarded as noise
  4. Scoring — each cluster is ranked by: score = (α × size + β × unknown_near) / (dist + ε)
  5. Publishing — sorted PoseArray published to /frontier_goals; MarkerArray to /frontier_markers for RViz2 visualization

The scoring formula balances three competing objectives: size rewards larger unknown regions, unknown_near rewards frontiers surrounded by more undiscovered space (maximizing information gain), and dist penalizes faraway frontiers to minimize unnecessary travel. The parameters α=1.0 and β=2.0 weight unknown area discovery twice as heavily as cluster size, reflecting the goal of maximizing map coverage.

Evidence

Video 1 — Frontier Explorer Node running on TurtleBot4 Lite. The robot autonomously selects and navigates to frontier goals while building the SLAM map in real time.

ROS Topics active during recording: /map · /frontier_goals · /frontier_markers · /odometry/filtered · /scan

Semantic Hazard Classifier Node

The semantic hazard classifier (semantic_hazard_classifier_node.py) is the core contribution of this milestone from Manjunath Kondamu. It runs at 10 Hz and processes data from five independent sensor layers simultaneously, fusing their outputs into a single hazard classification that is published to the robot's semantic map.

The term "semantic" refers to attaching meaningful labels to spatial regions rather than simply marking them as occupied or free. Where a standard occupancy grid treats a wall and a fire identically, our semantic map distinguishes between CLEAR, DEBRIS, SMOKE, WATER, DARK, NARROW, POTHOLE, GLASS, HAZMAT, FIRE, and CLIFF zones — enabling the behavior coordinator to make informed navigation decisions.

5-Layer Detection Architecture

Layer Sensor Topic Detects
L1 Hardware Create3 sensors /hazard_detection
/slip_status
CLIFF (type=2), BUMP (type=1), wheel slip → WATER
L2 RGB Camera OAK-D RGB /oakd/rgb/preview/image_raw FIRE (orange/red HSV), WATER (blue/shiny), SMOKE (low saturation), HAZMAT (yellow diamond cue), DEBRIS (high Canny edge density), DARK (brightness <45)
L3 Depth OAK-D stereo /oakd/rgb/preview/depth POTHOLE (floor depth >1.5 m), GLASS (NaN ratio >50%), unstable terrain (depth variance >0.35)
L4 LiDAR RPLIDAR A1M8 /scan NARROW (both sides <0.35 m), DEAD_END (front + sides blocked), front obstacle <0.25 m
L5 HAZMAT YOLO OAK-D RGB /oakd/rgb/preview/image_raw 13 HAZMAT sign classes via DeepHAZMAT YOLOv3-tiny (confidence >0.5)

Hazard Priority Fusion

All five layers run in parallel every 100 ms. Their detections are collected into a list and passed to fuse_hazards(), which selects the single highest-priority hazard using a predefined severity scale:

HAZARD_PRIORITY = {
    'CLIFF':    100,   # immediate physical danger
    'FIRE':     100,   # immediate physical danger
    'POTHOLE':  90,    # structural floor hazard
    'GLASS':    85,    # invisible obstacle
    'HAZMAT':   85,    # chemical/biological risk
    'WATER':    80,    # slippery surface / flooding
    'DEAD_END': 80,    # navigation trap
    'NARROW':   70,    # passage risk
    'SMOKE':    60,    # visibility / air quality
    'DARK':     60,    # unknown danger
    'DEBRIS':   40,    # passable but cautious
    'CLEAR':    0,
}

Critical hazards (CLIFF, FIRE, POTHOLE, HAZMAT) trigger an immediate E-stop by publishing True to /exploration/stop, halting the behavior coordinator and zeroing the velocity command.

DeepHAZMAT Integration

Layer 5 integrates the DeepHAZMAT framework (Najafi et al., 2021), which uses a YOLOv3-tiny architecture trained on the HAZMAT-13 dataset containing 52,845 images across 13 hazardous material sign categories. The model was selected specifically for its design under restricted computational resources — matching the constraints of the Raspberry Pi 4 (2 GB RAM) aboard the TurtleBot4 Lite.

13 HAZMAT Classes Detected

Poison · Flammable · Flammable Solid · Oxidizer · Explosive · Corrosive · Radioactive · Dangerous · Non-Flammable Gas · Infectious · Organic Peroxide · Inhalation Hazard · Spontaneously Combustible

Implementation Status

Library installed
Weights integrated
Sample image test
Robot camera test
M3

DeepHAZMAT Detection — Evidence

The following screenshots demonstrate DeepHAZMAT YOLOv3-tiny running on sample HAZMAT images, confirming successful detection and bounding box generation prior to robot camera integration.

DeepHAZMAT detection screenshot 1
HAZMAT sign detected — bounding box with class label
DeepHAZMAT detection screenshot 2
Multi-class HAZMAT detection output
DeepHAZMAT detection screenshot 3
GrabCut segmentation on detected HAZMAT region

Outputs

The classifier publishes to three topics simultaneously:

  • /semantic_map — OccupancyGrid where cell values encode hazard severity (0=CLEAR, 30=DEBRIS, 85=HAZMAT, 100=FIRE/CLIFF)
  • /hazard_alert — String with current highest-priority hazard name
  • /hazard_markers — MarkerArray of colored 3D cubes for RViz2 visualization

Behavior Coordinator Node

The behavior coordinator (behavior_coordinator_node.py) is the decision-making brain of the exploration system. It integrates the outputs of both the frontier explorer and the semantic hazard classifier to select safe navigation goals and drive the robot to full map coverage.

5-State Machine

IDLE
SELECTING
NAVIGATING
ARRIVED
DONE

IDLE

Waits for first /frontier_goals message. Transitions to SELECTING immediately on receipt.

SELECTING

Iterates the ranked frontier list. Skips frontiers within 0.3 m of previously visited points, and skips any frontier whose map cell has a semantic value ≥70 (WATER or above). Sends the first valid goal to Nav2.

NAVIGATING

Monitors the active Nav2 NavigateToPose action. On success → ARRIVED. On failure → increments counter; after 3 consecutive failures marks the frontier unreachable and returns to SELECTING.

ARRIVED

Records the reached position in the visited list, resets the failure counter, and immediately transitions back to SELECTING to pick the next frontier.

When no valid frontiers remain (all visited or all hazardous), the node transitions to DONE, publishes a zero velocity command, and emits EXPLORATION_COMPLETE on /exploration/status.

Safety Systems

Safety TriggerConditionResponse
Battery E-stop Battery percentage < 15% Cancel Nav2 goal · zero velocity · transition to DONE
Cliff E-stop /hazard_detection type=2 while NAVIGATING Cancel goal · zero velocity · return to SELECTING
Operator kill /exploration/stop = True Immediate stop · transition to DONE
Deadman switch /frontier_goals stale >5 s Zero velocity · return to IDLE
Nav2 failure limit 3 consecutive goal failures Mark frontier unreachable · try next frontier

Launch System

The entire exploration stack launches with a single command via exploration.launch.py. The launch file starts all subsystems in the correct order with appropriate delays:

ros2 launch frontier_exploration_mapping exploration.launch.py

Launch sequence

  1. slam_toolbox — async SLAM in mapping mode (resolution 0.05 m)
  2. robot_localization EKF — fuses wheel odometry + IMU → /odometry/filtered
  3. Nav2 — costmap, path planner (NavFn), DWA local controller
  4. frontier_explorer_node — starts immediately after Nav2
  5. semantic_hazard_classifier_node — starts immediately
  6. behavior_coordinator_node — delayed 5 s to allow SLAM and Nav2 to initialize

The use_sim_time:=true argument switches all nodes to Gazebo simulation time for testing, while the default false uses hardware time for deployment on the physical TurtleBot4 Lite.

ROS Bag Recording

A complete ROS bag was recorded during the frontier exploration demo run. The bag captures all sensor and algorithmic topics required for post-analysis and replay.

Bag file: rosbag_full_frontier_functional
Format: MCAP · Location: ros2_ws/rosbags/
Topics recorded: /map · /scan · /odom · /odometry/filtered · /frontier_goals · /frontier_markers · /oakd/rgb/preview/image_raw · /oakd/rgb/preview/depth · /tf · /tf_static

To replay the bag:

ros2 bag play ros2_ws/rosbags/rosbag_full_frontier_functional

Mathematical Foundations

The mathematical derivations supporting all algorithmic decisions in this system were compiled by Rohit Mane and are provided in full as LaTeX-formatted documents. Key derivations include the frontier scoring function, EKF state estimation equations, differential drive kinematics, occupancy grid Bayesian update rules, and the HSV threshold derivations for the semantic classifier.

PDF
Milestone 2 — Mathematical Documentation Part 1
PDF
Milestone 2 — Mathematical Documentation Part 2

Team Contributions

The following table documents the specific technical contributions of each team member for Milestone 2.

Team MemberRoleM2 Contributions
Princess Colon
PriColon
Frontier Exploration Lead frontier_explorer_node.py — full implementation · SLAM on TurtleBot4 Lite hardware · ROS bag recording · Demo video · RViz2 config · RQT node graph · System architecture diagram
Rohit Mane
rmane2
Mathematical Foundations Frontier scoring formula derivation · EKF prediction and update equations · Differential drive kinematics proof · Occupancy grid Bayesian update · HSV threshold derivations · DWA planner velocity constraints · LaTeX documentation Parts 1 & 2
Manjunath Kondamu
Mkondamu
Hazard Mapping & Integration semantic_hazard_classifier_node.py — 5-layer detection · DeepHAZMAT YOLOv3-tiny integration · behavior_coordinator_node.py — 5-state machine · exploration.launch.py — single-command launch · YOLO weights packaged into ROS2 workspace · Milestone 2 website

Next Steps — Milestone 3

Hardware validation

Run the full autonomous exploration stack on the physical TurtleBot4 Lite in a disaster-scenario test environment with placed HAZMAT signs, debris, and simulated water hazards.

HAZMAT on robot camera

Complete end-to-end testing of DeepHAZMAT YOLOv3-tiny running on the OAK-D RGB feed from the TurtleBot4 Lite at real-time inference speeds.

Semantic map persistence

Merge the semantic hazard OccupancyGrid with the SLAM map so that hazard labels persist across the full explored area rather than just the camera's current field of view.

idsia-robotics dataset evaluation

Evaluate our HSV classifier against the Hazards&Robots dataset (324k frames, 20 anomaly classes) to quantify detection accuracy and tune thresholds for M3.

← Milestone 1 Milestone 3 →