8.9 KiB
OrthoRoute File Formats
This document describes the file formats used by OrthoRoute for cloud routing workflows.
Overview
OrthoRoute uses two specialized file formats to enable routing PCBs without KiCad:
.ORP(OrthoRoute PCB) - Contains board geometry and design rules.ORS(OrthoRoute Solution) - Contains routing results (traces and vias)
Both formats use JSON with gzip compression for efficient storage and transfer.
.ORP Format (OrthoRoute PCB)
Purpose: Export board data from KiCad for routing on remote machines
Creation: File → Export PCB (Ctrl+E) in OrthoRoute GUI
Contents:
- Board metadata (filename, dimensions, layer count)
- Pad locations and net assignments
- Net definitions (terminal positions)
- Design rules (clearances, track widths, via sizes)
- Grid parameters
File Structure
{
"format_version": "1.0",
"board_metadata": {
"filename": "MyBoard.kicad_pcb",
"bounds": {
"x_min": 100.0,
"y_min": 50.0,
"x_max": 200.0,
"y_max": 150.0
},
"layer_count": 6
},
"pads": [
{
"position": [150.5, 100.2],
"net": "VCC",
"drill": 0.8,
"layer_mask": 4227858432
}
],
"nets": {
"VCC": [[150.5, 100.2], [175.3, 120.5]],
"GND": [[160.0, 110.0], [180.0, 130.0]]
},
"drc_rules": {
"clearance": 0.15,
"track_width": 0.25,
"via_diameter": 0.6,
"via_drill": 0.3,
"min_drill": 0.2
},
"grid_parameters": {
"pitch": 0.4
}
}
Coordinate System
- Units: Millimeters (mm)
- Origin: Board lower-left corner (x_min, y_min)
- Axes: X increases right, Y increases up
- Layer IDs: KiCad layer numbering (0=F.Cu, 31=B.Cu, 1-30=Internal)
Typical File Sizes
- Small board (50 nets): ~15 KB compressed
- Medium board (200 nets): ~40 KB compressed
- Large board (500 nets): ~80 KB compressed
.ORS Format (OrthoRoute Solution)
Purpose: Store routing results for import back into KiCad
Creation: Automatically generated by python main.py headless <board>.ORP
Contents:
- Routed traces (per net, per layer)
- Via locations and layer spans
- Iteration metrics (convergence history)
- Final routing statistics
File Structure
{
"format_version": "1.0",
"geometry": {
"by_net": {
"VCC": {
"net_id": "VCC",
"tracks": [
{
"layer": "In1.Cu",
"start": {"x": 150.5, "y": 100.2},
"end": {"x": 151.5, "y": 100.2},
"width": 0.25
}
],
"vias": [
{
"position": {"x": 150.5, "y": 100.2},
"from_layer": "F.Cu",
"to_layer": "In1.Cu",
"diameter": 0.6,
"drill": 0.3
}
]
}
},
"all_tracks": [...],
"all_vias": [...],
"layer_usage": {
"In1.Cu": 250,
"In2.Cu": 180
}
},
"iteration_metrics": [
{
"iteration": 1,
"overuse_count": 42000,
"nets_routed": 512,
"overflow_cost": 85000.0,
"wirelength": 15000.5,
"via_count": 1250,
"iteration_time_seconds": 45.2
}
],
"metadata": {
"export_timestamp": "2025-11-13T18:19:50Z",
"orthoroute_version": "0.1.0",
"board_name": "MyBoard.kicad_pcb",
"total_iterations": 71,
"converged": true,
"total_time_seconds": 1680.5,
"notes": ""
},
"statistics": {
"total_tracks": 4128,
"total_vias": 2593,
"total_wirelength_mm": 12500.8,
"nets_routed": 512,
"final_overuse_count": 0,
"final_overflow_cost": 0.0,
"converged": true,
"iterations_completed": 71
}
}
Coordinate System
Same as .ORP format - all coordinates in millimeters relative to board origin.
Layer Naming
Layers use KiCad naming convention:
F.Cu- Front copperB.Cu- Back copperIn1.CuthroughIn30.Cu- Internal layers
Typical File Sizes
- Small board (50 nets, 500 tracks): ~80 KB compressed
- Medium board (200 nets, 2000 tracks): ~250 KB compressed
- Large board (500 nets, 4000 tracks): ~450 KB compressed
Workflow
┌─────────────┐
│ KiCad │
│ Design │
└──────┬──────┘
│
│ Export (Ctrl+E)
▼
┌─────────────┐
│ .ORP File │ ◄── Upload to cloud GPU
└──────┬──────┘
│
│ python main.py headless board.ORP
▼
┌─────────────┐
│ .ORS File │ ◄── Download from cloud
└──────┬──────┘
│
│ Import (Ctrl+I)
▼
┌─────────────┐
│ KiCad │
│ (Routed) │
└─────────────┘
File Format Versioning
Current Version: 1.0
Both .ORP and .ORS files include a "format_version" field. Future versions of OrthoRoute will maintain backward compatibility by checking this version and handling older formats appropriately.
Version History
- 1.0 (2025-11-13) - Initial format specification
- Basic board geometry export
- Net-organized routing results
- Iteration metrics and statistics
Working with Files
Reading Files Manually
Both formats are gzip-compressed JSON, so you can inspect them with:
import gzip
import json
# Read ORP file
with gzip.open('board.ORP', 'rt', encoding='utf-8') as f:
orp_data = json.load(f)
print(f"Board: {orp_data['board_metadata']['filename']}")
print(f"Nets: {len(orp_data['nets'])}")
# Read ORS file
with gzip.open('board.ORS', 'rt', encoding='utf-8') as f:
ors_data = json.load(f)
print(f"Tracks: {ors_data['statistics']['total_tracks']}")
print(f"Vias: {ors_data['statistics']['total_vias']}")
print(f"Converged: {ors_data['metadata']['converged']}")
Programmatic Access
Use the OrthoRoute serialization module:
from orthoroute.infrastructure.serialization import (
import_board_from_orp,
export_board_to_orp,
import_solution_from_ors,
export_solution_to_ors
)
# Import board
board_data = import_board_from_orp('board.ORP')
# Import solution
geometry_data, metadata = import_solution_from_ors('board.ORS')
# Access data
print(f"Total nets: {len(geometry_data['by_net'])}")
print(f"Convergence: {metadata['metadata']['converged']}")
print(f"Total time: {metadata['metadata']['total_time_seconds']:.1f}s")
Cloud Provider Setup
The .ORP/.ORS workflow is designed for cloud GPU routing. Typical setup:
- Export .ORP file locally
- Upload to cloud instance via SCP:
scp board.ORP user@gpu-instance:/workspace/ - Route on cloud:
ssh user@gpu-instance cd /workspace python main.py headless board.ORP - Download .ORS file:
scp user@gpu-instance:/workspace/board.ORS ./ - Import in KiCad with Ctrl+I
Recommended Providers:
- Vast.ai - ~$0.37/hr for RTX 5090
- RunPod - ~$0.40/hr for RTX 4090
- Lambda Labs - ~$1.10/hr for A100
File Validation
OrthoRoute validates files on import:
ORP Validation:
- ✓ Format version is supported
- ✓ Required fields present (board_metadata, pads, nets, drc_rules)
- ✓ Coordinate ranges are reasonable
- ✓ Net references are consistent
ORS Validation:
- ✓ Format version is supported
- ✓ Required sections present (geometry, metadata, statistics)
- ✓ Track coordinates are valid
- ✓ Layer names are recognized
Invalid files will show a clear error message indicating what's wrong.
Limitations and Future Work
Current Limitations:
- Existing traces not exported - .ORP assumes a clean board
- Keepout zones not serialized - Must manually avoid keepouts
- No parameter override - Uses default routing parameters
- No component information - Only pads and nets exported
Planned Enhancements:
- Export existing traces for partial routing
- Include keepout zone definitions
- Support custom parameter JSON files
- Component placement data for reference
- Differential pair information
- Impedance control specifications
Technical Notes
Why gzip compression?
Plain JSON files can be 1-2 MB for large boards. Gzip compression reduces this to ~50-100 KB (95%+ reduction), making uploads/downloads much faster.
Why JSON instead of binary?
JSON is:
- Human-readable and debuggable
- Easy to parse in any language
- Self-documenting
- Extensible for future versions
- Well-supported by all platforms
The gzip compression eliminates most of the size overhead of JSON.
Thread safety
Both import and export functions are thread-safe and can be called concurrently from multiple threads if needed.
Last Updated: November 13, 2025 Format Version: 1.0 OrthoRoute Version: 0.1.0