Mini Simulation Kit — terrain + traffic simulations powered by Simu AI, OpenCTV, JAXA AW3D30
Project description
MSKit-Simu — Mini Simulation Kit
A lightweight Python library for terrain-based simulations powered by real-world elevation data, live traffic feeds, open camera streams, and Simu — an embedded AI assistant you talk to in plain English.
✨ What's Inside
| Module | Description |
|---|---|
| DEMLoader | Streams JAXA AW3D30 30 m elevation tiles lazily from HuggingFace — no manual download needed |
| TrafficRouter | Auto-selects OpenTraffic → UTD19 → synthetic fallback, globally |
| OpenCTVLayer | Aggregates free public traffic camera feeds (Singapore, London, NYC) |
| Simu | Embedded AI assistant — understands plain English, picks and runs the right simulation |
CLI (mskit) |
Interactive terminal interface covering all features in one place |
🚀 Installation
Option 1 — Core only (no AI brain, rule-based Simu)
pip install mskit-simu
Includes: terrain sims, traffic router, OpenCTV cameras. Simu works with rule-based NLU (no model download).
Option 2 — With AI brain (recommended)
pip install mskit-simu[llm]
Downloads SmolLM2-360M-Instruct (~700 MB, once). Simu understands natural language much better.
Option 3 — With your own GGUF model
pip install mskit-simu[gguf]
Lets you load any .gguf model file locally (e.g. from LM Studio or Ollama exports).
Option 4 — Everything
pip install mskit-simu[all]
Includes LLM, GGUF, matplotlib visualisation, and TIFF tile support.
🖥️ Quickstart — CLI
The fastest way to get started is the interactive CLI:
mskit
You'll be guided through two prompts:
┌─────────────────────────────────────────────┐
│ MSKit — Choose your AI brain │
│ │
│ [1] untrained Rule-based NLU (instant) │
│ [2] huggingface SmolLM2-360M (recommended) │
│ [3] custom Your own model / GGUF │
└─────────────────────────────────────────────┘
Enter choice (1/2/3): 1
┌─────────────────────────────────────────────┐
│ MSKit — Simulation mode │
│ │
│ [1] random One random sim per message │
│ [2] custom Pick from plain English │
│ [3] everything Run all 6 sims at once │
└─────────────────────────────────────────────┘
Enter choice (1/2/3): 2
Simu> random walk in Tokyo for 500 steps
Skip the prompts
mskit --brain untrained --mode custom
mskit --brain huggingface --mode everything
mskit --brain custom --model ./my-model.gguf --mode random
Start at a specific location
mskit --city tokyo
mskit --lat 51.5074 --lon -0.1278 # London
🖥️ CLI Subcommands
Beyond the interactive mode, the mskit command has dedicated subcommands:
mskit simu — Full interactive AI session
mskit simu
mskit run — One-shot simulation from the terminal
mskit run "water flow simulation in Zurich"
mskit run "projectile launched from Mount Fuji at 45 degrees"
mskit run "random walk in Singapore 300 steps"
mskit cameras — Traffic cameras near a location
mskit cameras --city singapore
mskit cameras --city london --radius 3
mskit cameras --lat 40.7128 --lon -74.0060 # New York City
Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📷 OpenCTV — Cameras near Singapore
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Source : Singapore LTA (data.gov.sg) — 87 cameras, 20 s refresh, no key
Fetching... 12 cameras found.
📍 Nearest : SG-1001 (0.43 km)
Image URL: https://images.data.gov.sg/api/traffic-images/...
mskit traffic — Live traffic speed & congestion
mskit traffic --city london
mskit traffic --lat 35.6762 --lon 139.6503 # Tokyo
mskit info — Version, sources, and all sim types
mskit info
mskit demo — Full feature walkthrough (no input needed)
mskit demo
🐍 Python API
1. Talk to Simu (plain English)
from mskit import Simu
simu = Simu() # interactive brain + mode selection
# or skip the prompts:
simu = Simu(auto_select="untrained", auto_simmode="custom")
result = simu.chat("random walk in Tokyo for 300 steps")
print(result["output"]) # dict with sim results
print(result["intent"]) # what Simu understood
2. Load elevation data
from mskit import DEMLoader
dem = DEMLoader() # lazy — no download yet
# Single point
elev = dem.elevation_at(35.6762, 139.6503) # Tokyo, metres
print(f"Elevation: {elev} m")
# 2D patch (returns numpy array)
patch = dem.patch(lat=51.5074, lon=-0.1278, radius_km=5)
print(patch.shape) # (H, W) int16 array
# Elevation profile between two points
distances, elevations = dem.elevation_profile(
lat1=35.36, lon1=138.73, # Mount Fuji base
lat2=35.36, lon2=138.80,
steps=200,
)
3. Run simulations directly
from mskit import DEMLoader, RandomWalk, Projectile, WaterFlow, TerrainAgent
dem = DEMLoader()
# Slope-biased random walk
rw = RandomWalk(dem, lat=35.6762, lon=139.6503, slope_bias=0.6)
path = rw.run(steps=500)
print(f"Distance: {path['total_distance_km']:.2f} km")
print(f"Elev gain: {path['elevation_gain_m']:.0f} m")
# Ballistic trajectory over real terrain
proj = Projectile(dem, lat=35.3606, lon=138.7274, # Mount Fuji
elevation_deg=45, azimuth_deg=90, speed_ms=80)
traj = proj.run()
print(f"Range: {traj['range_km']:.2f} km | Max alt: {traj['max_altitude_m']:.0f} m")
# D8 water runoff routing
wf = WaterFlow(dem, patch_km=10)
flow = wf.run(lat=47.3769, lon=8.5417) # Zurich
# RL terrain agent
agent = TerrainAgent(dem, 35.6762, 139.6503, 35.7300, 139.7400)
episode = agent.generate_episode(max_steps=300)
print(f"Steps taken: {episode['steps']}")
4. Query live traffic
from mskit import DEMLoader, TrafficRouter
router = TrafficRouter(DEMLoader())
info = router.traffic_at(51.5074, -0.1278) # London
print(f"Speed : {info.speed_kmh:.1f} km/h")
print(f"Congestion : {info.congestion_level}")
print(f"Source : {info.source}") # opentraffic / utd19 / synthetic
5. OpenCTV traffic cameras
from mskit import OpenCTVLayer
ctv = OpenCTVLayer()
# Cameras near a location
cameras = ctv.cameras_near(lat=1.3521, lon=103.8198, radius_km=3)
for cam in cameras:
print(f"{cam.name} — {cam.distance_km(1.3521, 103.8198):.2f} km")
print(f" Image: {cam.image_url}")
# Full report (camera count + nearest)
report = ctv.traffic_report(lat=51.5074, lon=-0.1278, radius_km=5)
print(f"{report.camera_count} cameras found near London")
print(f"Nearest: {report.nearest.name}")
# Check if an area is covered by a live feed
source = ctv.covered_at(1.35, 103.82) # 'lta_sg'
source = ctv.covered_at(0, 0) # None → synthetic fallback
# Refresh a camera snapshot URL (LTA refreshes every 20s)
fresh_url = ctv.snapshot(cameras[0])
📷 OpenCTV Camera Sources
| Source key | Region | Cameras | Refresh | API Key |
|---|---|---|---|---|
lta_sg |
Singapore | 87 | 20 s | ❌ None |
tfl |
London, UK | 900+ | ~30 s | ❌ None (optional for rate limits) |
nyc |
New York City | ~900 | ~60 s | ❌ None |
synthetic |
Everywhere else | ∞ | — | ❌ None |
Optional: set TFL_APP_KEY env var for higher TfL rate limits:
export TFL_APP_KEY=your_free_key_here # get one free at api.tfl.gov.uk
🚦 Traffic Source Priority
| Priority | Source | Coverage |
|---|---|---|
| 1st | OpenTraffic / OSRM | Global road network, live speeds |
| 2nd | UTD19 (ETH Zurich) | 40 cities, 23,541 loop detectors |
| 3rd | Synthetic | Everywhere — slope + time-of-day model |
🤖 Simu AI Brain Options
| Option | How to activate | Download | Best for |
|---|---|---|---|
untrained |
auto_select="untrained" |
None | Quick tests, offline use |
huggingface |
auto_select="huggingface" |
~700 MB (once) | Best accuracy |
custom HF |
auto_select="custom" → HF repo ID |
~varies | Your fine-tuned model |
custom local |
auto_select="custom" → folder path |
None | Local models |
custom GGUF |
auto_select="custom" → .gguf file |
None | Quantized models |
# Use a HuggingFace model by repo ID
simu = Simu(auto_select="custom",
custom_model="microsoft/phi-2",
auto_simmode="custom")
# Use a local folder
simu = Simu(auto_select="custom",
custom_model="/models/my-llm",
auto_simmode="everything")
# Use a GGUF file (requires mskit-simu[gguf])
simu = Simu(auto_select="custom",
custom_model="/models/phi-2-q4.gguf",
auto_simmode="random")
🗂 Project Structure
mskit-simu/
├── mskit/
│ ├── __init__.py ← top-level exports
│ ├── cli.py ← unified CLI (mskit / simu commands)
│ ├── dem.py ← DEMTile + DEMLoader (JAXA AW3D30)
│ ├── sims/
│ │ ├── random_walk.py ← slope-biased terrain walk
│ │ ├── projectile.py ← ballistic trajectory
│ │ ├── flow.py ← D8 water runoff routing
│ │ └── agent.py ← RL terrain navigator
│ ├── traffic/
│ │ ├── opentraffic.py ← OpenTraffic / OSRM layer
│ │ ├── utd19.py ← ETH Zurich loop detector data
│ │ ├── router.py ← unified TrafficRouter (auto-fallback)
│ │ └── openctv.py ← OpenCTV camera aggregator
│ └── simu/
│ ├── intent.py ← rule-based NLU intent parser
│ └── simu.py ← Simu AI assistant core
├── pyproject.toml
├── LICENSE
└── README.md
🤗 Elevation Dataset
Tiles are streamed lazily (no bulk download) from:
- JAXA AW3D30 — global 30 m Digital Surface Model
- Tiles cached locally after first use
- No HuggingFace account required for public access
🔧 Requirements
- Python ≥ 3.9
numpy >= 1.24requests >= 2.28huggingface_hub >= 0.20
Optional (installed with extras):
[llm]→transformers,torch,accelerate,sentencepiece[gguf]→llama-cpp-python[viz]→matplotlib[tiff]→tifffile
📄 License
MIT © MegaBites AI Team
Links:
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mskit_simu-0.6.4.tar.gz.
File metadata
- Download URL: mskit_simu-0.6.4.tar.gz
- Upload date:
- Size: 60.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b6e18f2742dacfd0497162e890e1795d198153b07ccee9d0663a7cf5315d5dc
|
|
| MD5 |
1dd347683a9b2e5e3e411a97170be2e2
|
|
| BLAKE2b-256 |
7f6c7ca1d8f34358350f5dc6ccab86a6e63bed5bb6ffd222e5aa9dbaa8c69321
|
File details
Details for the file mskit_simu-0.6.4-py3-none-any.whl.
File metadata
- Download URL: mskit_simu-0.6.4-py3-none-any.whl
- Upload date:
- Size: 64.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff29b243f659adee02659883d12423aa8c02541fadce6aca5f4407ab5d1749b3
|
|
| MD5 |
8c41a4f48ece5b1eae1e791c5dad760b
|
|
| BLAKE2b-256 |
10b76de776acec45ad530dceaa7daa471d3ed9342556e02da12f8637bc1df50c
|