Skip to main content
🤝

이 가이드는 인류와 AI가 함께 만드는 지식입니다.

이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.

ROS 2 Logistics & Warehouse Robotics Guide 2026

Warehouse automation is the biggest commercial market in robotics. This guide covers the ROS 2 stack for autonomous mobile robots (AMRs): Nav2 in dynamic aisles, Open-RMF fleet orchestration, the VDA5050 standard, and warehouse management system integration.

1. The Warehouse Robotics Stack

A production AMR fleet layers navigation, fleet management, and enterprise integration:

sudo apt-get install -y   ros-humble-nav2-bringup   ros-humble-rmf-fleet-adapter   ros-humble-rmf-traffic   ros-humble-rmf-task

# Stack (bottom -> top):
#   1. Per-robot Nav2      (localization + local planning)
#   2. Fleet adapter       (VDA5050 / Open-RMF bridge)
#   3. Traffic management   (reservations, deadlock avoidance)
#   4. Task allocation      (which robot does which order)
#   5. WMS / WES integration (SAP EWM, Manhattan, etc.)

2. Nav2 Tuning for Warehouses

Warehouses are dynamic and narrow. Tune Nav2 for tight aisles and moving forklifts:

# nav2_warehouse.yaml (key overrides)
controller_server:
  ros__parameters:
    controller_frequency: 20.0
    FollowPath:
      plugin: "nav2_mppi_controller::MPPIController"  # smooth in tight aisles
      max_vel_x: 1.2
      max_vel_theta: 1.0

local_costmap:
  ros__parameters:
    inflation_layer:
      inflation_radius: 0.35        # tight — aisles are narrow
      cost_scaling_factor: 3.0
    obstacle_layer:
      observation_sources: scan pointcloud
      # detect low pallets AND overhanging shelves

global_costmap:
  ros__parameters:
    # keepout filter marks no-go zones (charging lanes, human areas)
    filters: ["keepout_filter"]

3. Open-RMF: Multi-Fleet Orchestration

Open-RMF coordinates heterogeneous fleets (different vendors) over a shared map:

# fleet_config.yaml for an RMF fleet adapter
rmf_fleet:
  name: "warehouse_amrs"
  limits:
    linear: [1.2, 0.6]     # [max velocity, max acceleration]
    angular: [1.0, 0.8]
  profile:
    footprint: 0.4
    vicinity: 0.6
  reversible: false
  battery_system:
    voltage: 24.0
    capacity: 40.0
    charging_current: 20.0
  recharge_threshold: 0.15   # auto-return to dock at 15%
  task_capabilities:
    delivery: true
    patrol: false

4. VDA5050: The Interoperability Standard

VDA5050 is the MQTT-based standard letting any master control any vendor's AMR. An order message:

{
  "headerId": 42,
  "orderId": "order-2026-0714",
  "orderUpdateId": 0,
  "nodes": [
    { "nodeId": "pick_A12", "sequenceId": 0, "released": true,
      "nodePosition": { "x": 12.4, "y": 3.1, "mapId": "wh1" } },
    { "nodeId": "drop_dock3", "sequenceId": 2, "released": true,
      "nodePosition": { "x": 45.0, "y": 8.2, "mapId": "wh1" } }
  ],
  "edges": [
    { "edgeId": "e0", "sequenceId": 1, "released": true,
      "startNodeId": "pick_A12", "endNodeId": "drop_dock3" }
  ]
}
# A ROS 2 fleet adapter translates this into Nav2 goals and
# streams AGV state back on the vda5050/state topic.

5. Traffic Management & Deadlock Avoidance

With dozens of robots in shared aisles, you need space-time reservations:

# rmf_traffic reserves corridor segments in time
schedule = TrafficSchedule()

# Robot A requests a route; the negotiator checks conflicts
itinerary = planner.plan(start=A12, goal=dock3, robot="amr_07")
conflicts = schedule.check_conflicts(itinerary)

if conflicts:
    # Negotiate: one robot yields at a passing bay
    resolved = negotiator.resolve(conflicts, priority="amr_07")
    schedule.commit(resolved)
else:
    schedule.commit(itinerary)

# Single-lane aisles use mutex groups so only one robot
# enters at a time — prevents head-on deadlock.

6. Order Picking & Task Allocation

Allocate incoming orders to the best-positioned, best-charged robot:

def allocate_order(order, fleet):
    best, best_cost = None, float('inf')
    for robot in fleet:
        if robot.battery < 0.2 or robot.state != 'idle':
            continue
        travel = estimate_travel_time(robot.pose, order.pick_location)
        queue  = robot.pending_tasks * AVG_TASK_TIME
        cost = travel + queue
        if cost < best_cost:
            best, best_cost = robot, cost
    return best   # lowest combined travel + queue cost wins

7. WMS / WES Integration

The fleet must talk to the warehouse management system. Bridge ROS 2 to the enterprise layer:

class WmsBridge(Node):
    """Receives pick orders from WMS, reports completion back."""
    def __init__(self):
        super().__init__('wms_bridge')
        self.task_pub = self.create_publisher(RmfTask, '/rmf/dispatch', 10)
        self.create_subscription(TaskSummary, '/rmf/task_summary',
                                 self.on_task_done, 10)
        # Poll WMS REST/MQTT for new orders (keep enterprise creds
        # server-side — never in the robot)

    def on_task_done(self, msg):
        if msg.state == msg.STATE_COMPLETED:
            self.report_to_wms(msg.task_id, status="picked")

8. Charging & Uptime

9. Safety & Human Coexistence

10. Deployment Metrics That Matter

Key Takeaways

Warehouse automation is where robotics pays. Tune Nav2 with MPPI and tight inflation for narrow aisles, orchestrate multi-vendor fleets with Open-RMF, and speak VDA5050 for interoperability. Space-time traffic reservations prevent deadlock, cost-based allocation assigns orders efficiently, and a WMS bridge ties it into the enterprise. Design for charging, safety-rated sensing, and the uptime metrics that decide whether the deployment actually returns on its investment.