Create a Complete Layout

This tutorial builds a small assembly line from a blank Python file. The line receives brackets, cuts them, holds finite WIP, assembles them, and sends completed units to Shipping.

1. Create the plant and footprints

from manufacturing_sim_s import AGV, Buffer, Machine, Plant, Product, Sink, Source

plant = Plant(
    "Custom Assembly Line",
    width=145,
    height=60,
    distance_method="manhattan",
    clearance=6,
)

receiving = Source("Receiving", (5, 25), 10, 10, arrivals=75)
cutting = Machine("Cutting", (30, 25), 12, 10, processing_time=55)
wip = Buffer("WIP Buffer", (58, 23), 10, 14, capacity=8)
assembly = Machine("Assembly", (84, 25), 12, 10, processing_time=80)
shipping = Sink("Shipping", (120, 25), 10, 10)

Every tuple is the component's bottom-left (x, y) coordinate. The next two numbers are width and depth. arrivals=75 means one Part is scheduled every 75 seconds; Machine processing times are also seconds.

2. Define the process and movement

agv = AGV("AGV 1", (5, 5), speed=6)

bracket = Product(
    "Bracket",
    [receiving, cutting, wip, assembly, shipping],
)

plant.add(receiving, cutting, wip, assembly, shipping, agv, bracket)

for origin, destination in zip(bracket.route, bracket.route[1:]):
    plant.connect(origin, destination, transporter=agv)

The Product list defines the process order. It does not assign transportation. The loop creates four directed material-flow connections, all served by the AGV. Sharing one AGV means concurrent moves wait for the same vehicle.

3. Validate and inspect the floor plan

from pathlib import Path

Path("outputs/plots").mkdir(parents=True, exist_ok=True)
print(plant.validate())
figure, axes = plant.visualize(product=bracket)
figure.savefig("outputs/plots/custom_layout.png", dpi=150, bbox_inches="tight")

Validation should report five stationary components, one mobile resource, one Product, and four connections with no layout conflicts. The drawing shows actual footprints and routing arrows. Its legend sits above the axes so it does not cover the layout.

4. Run and inspect results

result = plant.run(duration=3_600, seed=42)
result.report()

print(result.machine_metrics)
print(result.buffer_metrics)
print(result.transporter_metrics)

The 3,600-second duration is the arrival window. Sources stop releasing Parts at that point, then the model drains remaining WIP. A unit counts as produced only when it reaches Shipping.

Run the complete file from the repository root:

uv run python examples/custom_layout.py

Next, learn how to select your own coordinates in Plan Coordinates and Clearance.