Metadata-Version: 2.4
Name: mskit-simu
Version: 0.6.1
Summary: Mini Simulation Kit — terrain + traffic simulations powered by Simu AI, OpenCTV, JAXA AW3D30
Author: MegaBites AI Team
License: MIT
Project-URL: Homepage, https://github.com/OnyxNeol/MSKit
Project-URL: Repository, https://github.com/OnyxNeol/MSKit
Project-URL: Dataset, https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles
Project-URL: Bug Tracker, https://github.com/OnyxNeol/MSKit/issues
Project-URL: Simu Model, https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct
Keywords: simulation,terrain,dem,elevation,ai,gis,jaxa,aw3d30,traffic,opentraffic,utd19,openctv,cameras,smollm2,llm,natural language
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: requests>=2.28
Requires-Dist: huggingface_hub>=0.20
Provides-Extra: llm
Requires-Dist: transformers>=4.40; extra == "llm"
Requires-Dist: torch>=2.0; extra == "llm"
Requires-Dist: accelerate>=0.27; extra == "llm"
Requires-Dist: sentencepiece>=0.1.99; extra == "llm"
Provides-Extra: gguf
Requires-Dist: llama-cpp-python>=0.2; extra == "gguf"
Provides-Extra: viz
Requires-Dist: matplotlib>=3.7; extra == "viz"
Provides-Extra: tiff
Requires-Dist: tifffile>=2023.1; extra == "tiff"
Provides-Extra: all
Requires-Dist: mskit-simu[gguf,llm,tiff,viz]; extra == "all"
Dynamic: license-file

# MSKit — Mini Simulation Kit

[![PyPI](https://img.shields.io/badge/PyPI-mskit-blue)](https://pypi.org/project/mskit/)
[![HuggingFace](https://img.shields.io/badge/🤗-AW3D30--DEM--Tiles-yellow)](https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.9%2B-blue)](https://python.org)

A lightweight Python library for **terrain-based simulations** powered by real-world elevation, live traffic, open camera feeds, and an embedded AI assistant named **Simu**.

---

## ✨ Features

| Module | What it does |
|---|---|
| **DEMLoader** | Streams JAXA AW3D30 30m elevation tiles lazily from HuggingFace |
| **TrafficRouter** | Auto-selects OpenTraffic → UTD19 → synthetic fallback |
| **OpenCTV** | Aggregates free public traffic camera feeds (Singapore, London, Sydney, Oregon) |
| **Simu** | Embedded AI assistant — understands plain English, runs the right sim |
| **CLI** (`mskit`) | Full interactive terminal with all features in one place |

---

## 🚀 Install

```bash
# Core (terrain + traffic + cameras + rule-based Simu)
pip install mskit

# With AI brain (SmolLM2-360M, ~700 MB downloaded once)
pip install mskit[llm]

# With GGUF support (your own .gguf model)
pip install mskit[gguf]

# Everything
pip install mskit[all]
```

---

## 🖥️ CLI — One command to rule them all

```bash
mskit                                        # full interactive mode
mskit --brain untrained --mode custom        # skip both prompts
mskit --brain huggingface --mode everything  # SmolLM2 + run all 6 sims
mskit --lat 51.5074 --lon -0.1278           # start in London
```

### Startup flow

When you run `mskit`, Simu guides you through two steps:

**Step 1 — Choose AI Brain:**
```
╔══════════════════════════════════════════════════════════════╗
║          🤖  Simu — Step 1: Choose Your AI Brain            ║
╠══════════════════════════════════════════════════════════════╣
║  1. untrained   — Rule-based parser. Instant, no download.  ║
║  2. huggingface — SmolLM2-360M-Instruct  ★ recommended ★   ║
║  3. custom      — HF repo ID / local folder / .gguf file    ║
╚══════════════════════════════════════════════════════════════╝
```

**Step 2 — Choose Simulation Mode:**
```
╔══════════════════════════════════════════════════════════════╗
║        🎮  Simu — Step 2: Choose Simulation Mode            ║
╠══════════════════════════════════════════════════════════════╣
║  1. random      — Simu surprises you with a random sim      ║
║  2. custom      — You describe exactly what you want        ║
║  3. everything  — Run all 6 simulations at once             ║
╚══════════════════════════════════════════════════════════════╝
```

### CLI commands

```
<natural language>          Run a simulation (Simu handles it)
cameras                     List cameras near current location
cameras <city/lat,lon>      Cameras near a specific place
cameras sources             Show all camera sources
camera snap <id>            Refresh snapshot URL for a camera
location <city/lat,lon>     Change default location
location                    Show current location
switch brain                Re-pick AI brain
switch sim                  Re-pick simulation mode
history                     Show session sim history
help                        Full command reference
quit                        Exit
```

---

## 🐍 Python API

### Simu — AI Assistant

```python
from mskit import Simu, DEMLoader, TrafficRouter

loader = DEMLoader()
router = TrafficRouter(loader)

# Interactive startup (brain + sim mode prompts)
simu = Simu(dem_loader=loader, traffic_router=router)

# Skip prompts programmatically
simu = Simu(
    dem_loader=loader,
    traffic_router=router,
    auto_select="huggingface",   # or "untrained" / "custom"
    auto_simmode="custom",       # or "random" / "everything"
)

# Chat in plain English
result = simu.chat("Run a random walk in Tokyo for 1000 steps")
result = simu.chat("Shoot a projectile from Mount Fuji east at 45° 80 m/s")
result = simu.chat("What's the traffic like in London?")
result = simu.chat("Simulate water flow in Zurich")
result = simu.chat("Navigate an agent from 35.6,139.7 to 35.65,139.75")

# Run all 6 simulations at once
results = simu.run_all("Tokyo")

# Switch brain/mode mid-session
simu.switch_brain()
simu.switch_sim_mode()
```

### Custom brain (your own model)

```python
# HuggingFace repo
simu = Simu(auto_select="custom",
            custom_model="mistralai/Mistral-7B-Instruct-v0.3")

# Local transformers folder
simu = Simu(auto_select="custom",
            custom_model="/home/user/my-finetuned-model/")

# GGUF file via llama.cpp  (pip install mskit[gguf])
simu = Simu(auto_select="custom",
            custom_model="/home/user/mistral-7b-q4.gguf")
```

### OpenCTV — Traffic Cameras

```python
from mskit import OpenCTV

ctv = OpenCTV()

# Sources available — all free, no API key needed
print(ctv.sources)
# ['singapore', 'london_tfl', 'sydney_rms', 'portland_or']

# Find cameras near a location
cams = ctv.cameras_near(1.3521, 103.8198, radius_km=2)   # Singapore
cams = ctv.cameras_near(51.5074, -0.1278, radius_km=1)    # London

# Get snapshot URL
cam = cams[0]
print(cam.image_url)   # live JPEG URL
fresh = ctv.snapshot(cam)  # refresh URL

# Structured reading near a point
reading = ctv.reading_at(1.3521, 103.8198)
print(reading.cameras_used)    # 4
print(reading.image_url)       # nearest camera snapshot
```

### Traffic (flow data)

```python
from mskit import DEMLoader, TrafficRouter

router = TrafficRouter(DEMLoader())
info = router.traffic_at(51.5074, -0.1278)   # London
print(info.speed_kmh)           # 42.3
print(info.congestion_level)    # "moderate"
print(info.source)              # "utd19" or "osrm" or "synthetic"
```

### Simulations (direct API)

```python
from mskit import DEMLoader, RandomWalk, Projectile, WaterFlow, TerrainAgent

loader = DEMLoader()

# Slope-biased random walk
rw = RandomWalk(loader, lat=35.68, lon=139.69, slope_bias=0.6)
path = rw.run(steps=500)

# Ballistic trajectory over real terrain
proj = Projectile(loader, lat=35.36, lon=138.73,
                  elevation_deg=45, azimuth_deg=90, speed_ms=80)
traj = proj.run()

# D8 water runoff routing
wf = WaterFlow(loader, patch_km=10)
flow = wf.run(lat=47.38, lon=8.54)

# RL agent navigation episode
agent = TerrainAgent(loader, 35.68, 139.69, 35.73, 139.74)
episode = agent.generate_episode(max_steps=300)
```

---

## 📡 Traffic Sources — Priority Order

| Priority | Source | Coverage | Data |
|---|---|---|---|
| 1st | **OpenTraffic / OSRM** | Global road network | Live speeds, routing |
| 2nd | **UTD19 (ETH Zurich)** | 40 cities, 23,541 detectors | Flow, occupancy, speed |
| 3rd | **Synthetic** | Everywhere | Slope + time-of-day estimate |

## 📷 Camera Sources (OpenCTV)

| Source | Region | Cameras | Refresh | Key needed |
|---|---|---|---|---|
| `singapore` | Singapore | 87 | 20 s | ❌ None |
| `london_tfl` | London, UK | 900+ | ~30 s | ❌ None (optional for rate limits) |
| `sydney_rms` | Sydney, AU | 100+ | 1 min | ❌ None |
| `portland_or` | Oregon, US | 200+ | 2 min | ❌ None |

---

## 🗂 Project Structure

```
mskit/
├── mskit/
│   ├── __init__.py          # top-level exports
│   ├── cli.py               # unified CLI (mskit command)
│   ├── dem.py               # DEMTile + DEMLoader (AW3D30)
│   ├── sims/
│   │   ├── random_walk.py   # slope-biased walk
│   │   ├── projectile.py    # ballistic trajectory
│   │   ├── flow.py          # D8 water runoff
│   │   └── agent.py         # RL terrain agent
│   ├── traffic/
│   │   ├── opentraffic.py   # OSRM routing layer
│   │   ├── utd19.py         # ETH Zurich loop detectors
│   │   ├── router.py        # unified TrafficRouter
│   │   └── openctv.py       # OpenCTV camera feeds
│   └── simu/
│       ├── intent.py        # rule-based NLU intent parser
│       └── simu.py          # Simu AI assistant
├── pyproject.toml
└── README.md
```

---

## 🤗 Dataset

Elevation tiles are streamed lazily from:
**[MegaBites-AI/AW3D30-DEM-Tiles](https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles)**

- JAXA AW3D30 global 30m DSM/DEM
- HiRISE tiles for select regions
- MSKit wheel + source files

---

## 📄 License

MIT © MegaBites AI Team
