Metadata-Version: 2.4
Name: mskit-simu
Version: 0.6.2
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-Simu — Mini Simulation Kit

[![PyPI](https://img.shields.io/pypi/v/mskit-simu?color=blue&label=PyPI)](https://pypi.org/project/mskit-simu/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mskit-simu)](https://pypi.org/project/mskit-simu/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![HuggingFace Dataset](https://img.shields.io/badge/🤗%20Dataset-AW3D30--DEM--Tiles-yellow)](https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles)
[![HuggingFace Model](https://img.shields.io/badge/🤗%20Model-SmolLM2--360M-orange)](https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct)

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)
```bash
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)
```bash
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
```bash
pip install mskit-simu[gguf]
```
Lets you load any `.gguf` model file locally (e.g. from LM Studio or Ollama exports).

### Option 4 — Everything
```bash
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:

```bash
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
```bash
mskit --brain untrained --mode custom
mskit --brain huggingface --mode everything
mskit --brain custom --model ./my-model.gguf --mode random
```

### Start at a specific location
```bash
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
```bash
mskit simu
```

### `mskit run` — One-shot simulation from the terminal
```bash
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
```bash
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
```bash
mskit traffic --city london
mskit traffic --lat 35.6762 --lon 139.6503      # Tokyo
```

### `mskit info` — Version, sources, and all sim types
```bash
mskit info
```

### `mskit demo` — Full feature walkthrough (no input needed)
```bash
mskit demo
```

---

## 🐍 Python API

### 1. Talk to Simu (plain English)
```python
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
```python
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
```python
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
```python
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
```python
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:
```bash
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 |

```python
# 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:

**[MegaBites-AI/AW3D30-DEM-Tiles](https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles)**

- 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.24`
- `requests >= 2.28`
- `huggingface_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:**
- PyPI: https://pypi.org/project/mskit-simu/
- GitHub: https://github.com/OnyxNeol/MSKit
- Dataset: https://huggingface.co/datasets/MegaBites-AI/AW3D30-DEM-Tiles
- AI Model: https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct
