mirror of
https://github.com/bbenchoff/OrthoRoute.git
synced 2025-12-28 03:16:47 +00:00
381 lines
8.9 KiB
Markdown
381 lines
8.9 KiB
Markdown
# 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
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```json
|
|
{
|
|
"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 copper
|
|
- `B.Cu` - Back copper
|
|
- `In1.Cu` through `In30.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:
|
|
|
|
```python
|
|
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:
|
|
|
|
```python
|
|
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:
|
|
|
|
1. **Export** .ORP file locally
|
|
2. **Upload** to cloud instance via SCP:
|
|
```bash
|
|
scp board.ORP user@gpu-instance:/workspace/
|
|
```
|
|
3. **Route** on cloud:
|
|
```bash
|
|
ssh user@gpu-instance
|
|
cd /workspace
|
|
python main.py headless board.ORP
|
|
```
|
|
4. **Download** .ORS file:
|
|
```bash
|
|
scp user@gpu-instance:/workspace/board.ORS ./
|
|
```
|
|
5. **Import** in KiCad with Ctrl+I
|
|
|
|
**Recommended Providers:**
|
|
- [Vast.ai](https://vast.ai) - ~$0.37/hr for RTX 5090
|
|
- [RunPod](https://runpod.io) - ~$0.40/hr for RTX 4090
|
|
- [Lambda Labs](https://lambdalabs.com) - ~$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:**
|
|
|
|
1. **Existing traces not exported** - .ORP assumes a clean board
|
|
2. **Keepout zones not serialized** - Must manually avoid keepouts
|
|
3. **No parameter override** - Uses default routing parameters
|
|
4. **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
|