An open API service indexing awesome lists of open source software.

https://github.com/electrified/sheffield-supertram-simulator


https://github.com/electrified/sheffield-supertram-simulator

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# Sheffield Supertram Simulator

A Unity 6.3 LTS driving simulator for the Sheffield Supertram light rail network, using real-world terrain (Ordnance Survey) and route data (OpenStreetMap).

## Prerequisites

- **Unity 6000.3.x** (Unity 6.3 LTS) with Universal Render Pipeline
- **Python 3.10+** with venv
- **GDAL CLI tools**: `gdalbuildvrt`, `gdal_translate`, `gdalwarp`, `gdalinfo`
- **jq** (JSON processor)

Install GDAL and jq on Arch Linux:
```bash
sudo pacman -S gdal jq
```

## Quick Start

### 1. Set up Python environment

```bash
python3 -m venv .venv
.venv/bin/pip install -r tools/requirements.txt
```

### 2. Download and process terrain data

Download **OS Terrain 50** (ASCII Grid format) from:
https://osdatahub.os.uk/downloads/open/Terrain50

Extract the needed tile `.asc` files into `data/terrain_tiles/`. The required tiles are: SK28, SK29, SK38, SK39, SK48, SK49.

If you downloaded the full UK zip:
```bash
mkdir -p data/terrain_tiles
for tile in sk28 sk29 sk38 sk39 sk48 sk49; do
unzip -o -j "data/terrain_tiles/sk/${tile}_OST50GRID_*.zip" "*.asc" -d data/terrain_tiles/
done
```

Then run the terrain pipeline:
```bash
bash tools/terrain_pipeline.sh
```

This produces:
- `data/sheffield_terrain.raw` — 16-bit unsigned RAW heightmap (4097x4097)
- `data/terrain_metadata.json` — dimensions, elevation range, Unity settings

### 3. Fetch and process OSM data

```bash
# Fetch raw data from Overpass API (takes a few minutes, respects rate limits)
.venv/bin/python3 tools/fetch_osm.py

# Process into game-ready formats
.venv/bin/python3 tools/osm_to_json.py
```

This produces:
- `data/tram_routes.json` — route waypoints with Unity coordinates
- `data/stations.json` — all 50+ tram stops with Unity coordinates
- `data/buildings.geojson` — building footprints near tram routes
- `data/roads.geojson` — road centrelines near tram routes
- `data/road_network.json` — road network for detail zones

### 4. Import into Unity

Open the project in Unity, then either:

**GUI method:**
1. `Window > Sheffield Supertram > Import Terrain` — imports the heightmap
2. `Window > Sheffield Supertram > Import Routes` — imports tram routes and stations

**Batch method (command line):**
```bash
# Remove stale lock file if Unity isn't running
rm -f Temp/UnityLockfile

# Full import: terrain + scene setup + routes
Unity -projectPath . -executeMethod FullImport.Run -batchmode -quit -logFile -
```

Or run individual steps:
```bash
# Terrain + scene setup only
Unity -projectPath . -executeMethod BatchSetup.Run -batchmode -quit -logFile -

# Routes only (requires terrain scene to exist already)
Unity -projectPath . -executeMethod RouteImporter.BatchImport -batchmode -quit -logFile -
```

### 5. Open the scene and play

1. Open `Assets/Scenes/DevScene.unity`
2. Press Play — a test cube will follow the first tram route automatically
3. Use the **Dev Camera** (free-fly) to explore:
- **WASD** — move horizontally
- **Q/E** — move down/up
- **Right-click + mouse** — look around
- **Shift** — move faster
- **Scroll wheel** — adjust movement speed

## Tools Reference

| Tool | Purpose |
|------|---------|
| `tools/terrain_pipeline.sh` | Process OS Terrain 50 `.asc` tiles into Unity RAW heightmap |
| `tools/fetch_osm.py` | Download tram routes, stations, buildings, roads from OpenStreetMap |
| `tools/osm_to_json.py` | Convert raw OSM data into game-ready JSON and GeoJSON |
| `tools/coord_utils.py` | Coordinate conversion utility (WGS84 / OSGB36 / Unity) |
| `tools/config.json` | Central configuration for all pipeline parameters |

### Coordinate conversion examples

```bash
# WGS84 lat/lon to Unity coordinates
.venv/bin/python3 tools/coord_utils.py --lat 53.3826 --lon -1.4691 --unity

# OSGB36 easting/northing to Unity coordinates
.venv/bin/python3 tools/coord_utils.py --easting 435850 --northing 387100 --unity

# Run self-test
.venv/bin/python3 tools/coord_utils.py --test
```

## Coordinate System

- **OSGB36 / EPSG:27700** (British National Grid) — metres
- Unity axes: **X** = Easting, **Z** = Northing, **Y** = Up
- Origin: terrain SW corner (E 431000, N 380000) = Unity (0, 0, 0)
- Terrain extent: 15,000m x 15,000m (E 431000–446000, N 380000–395000)
- Elevation range: ~17m (Don Valley) to ~280m (western hills)

## Project Structure

```
README.md This file
PLAN.md Full implementation plan (13 milestones)
CLAUDE.md Project conventions for AI assistants
tools/
config.json Pipeline configuration (bounding box, tiles, zones)
terrain_pipeline.sh GDAL terrain processing pipeline
fetch_osm.py OSM data downloader (Overpass API)
osm_to_json.py OSM data processor
coord_utils.py Coordinate conversion (pyproj)
requirements.txt Python dependencies
data/
terrain_tiles/ OS Terrain 50 .asc source files (not in git)
intermediate/ GDAL intermediate files (not in git)
osm_raw/ Raw Overpass API responses
sheffield_terrain.raw Unity heightmap (generated)
terrain_metadata.json Terrain dimensions and settings (generated)
tram_routes.json Tram route waypoints (generated)
stations.json Tram station positions (generated)
buildings.geojson Building footprints (generated)
roads.geojson Road centrelines (generated)
Assets/
Editor/
BatchSetup.cs Batch terrain import + scene setup
RouteImporter.cs Batch route/station import
FullImport.cs Combined terrain + routes import
TerrainSetup.cs GUI terrain importer
SceneSetup.cs GUI scene setup
URPSetup.cs URP pipeline configuration
Scripts/
Tram/
TrackSegment.cs Spline wrapper with length, gradient, stations
TramRoute.cs Ordered list of track segments
SplineFollower.cs Moves transform along a route
TrackMeshGenerator.cs Generates visible track mesh from spline
Junction.cs Track junction switching
StationMarker.cs Station metadata component
Camera/
FreeFlyCamera.cs Developer fly camera (WASD + mouse)
Scenes/
DevScene.unity Main development scene

.venv/ Python virtual environment (not in git)
```

## Vehicle Profiles

Vehicle physics are configurable via ScriptableObject profiles, editable in the Unity Inspector. Create new profiles via **Create > Sheffield Supertram** in the Project window.

| Profile Type | Used By | Key Parameters |
|---|---|---|
| **Tram Profile** | `TramPhysics`, `TramArticulation` | Mass, power, max speed, braking forces, rolling/aero resistance, bogie geometry |
| **Car Profile** | `CarPhysics` | Torque, max speed, braking forces, steering angle |
| **AI Car Profile** | `AICarController` | Raycast interval/distances, stuck detection thresholds, speed variation |

Assign a profile to the `profile` field on the relevant component. If no profile is assigned, built-in defaults are used (matching the real Siemens-Duewag Supertram specs for trams, and sensible defaults for cars). This means existing scenes work unchanged.

To create a variant (e.g. a heavier loaded tram):
1. **Create > Sheffield Supertram > Tram Profile**
2. Adjust values in the Inspector
3. Assign to the `TramPhysics` and `TramArticulation` components on your tram

## Data Attribution

- Terrain: [OS Terrain 50](https://osdatahub.os.uk/downloads/open/Terrain50) — Open Government Licence v3.0
- Routes, stations, buildings, roads: [OpenStreetMap](https://www.openstreetmap.org/) — ODbL