Locate Keihin tables + render real fuel maps in the viewer
Reversed the inner map format from l.java (Nc/Lb) and validated it against the stock reference maps: - reconstruct_rom.py: decoded map -> unpack directory -> 384KB flat ROM. In the flat ROM, production (20187) vs aftermarket (20188) differ only 1.4% (vs 96% packed), i.e. real fuel enrichment. - table_map.py + TABLES.md: fe = c.a[Qd*48]; base = (fe[0]&0x2F0)<<12 = 0x50000; table = base + fe[k]. Located 9 tables (main/low-throttle fuel per cylinder, base/idle fuel, ignition by gear x4), 32 RPM rows x 20 throttle cols, with real axes (RPM fe[8], throttle fe[27]) and the AFR curve (fe[2], 128=lambda 1.00). Validated: main-fuel delta is uniformly richer in the aftermarket map. Viewer now has a "Triumph tables" tab: drop a real .hex (or pick two) and it decodes, unpacks, and renders the fuel/ignition tables as heatmaps with real axes, plus an A->B difference view. build_viewer.py embeds the c.a/s.a directory so any map resolves in-browser. Catalogue dropdown: download_maps.py fetches map .hex files into maps_cache/; serve.py serves the viewer over http so the dropdown can fetch them (drag-and-drop still works on file://). Proprietary map binaries (*.hex, *.dec.bin, maps_cache/) are gitignored — code and docs only.
This commit is contained in:
44
tunie/viewer/serve.py
Normal file
44
tunie/viewer/serve.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""Serve the tunie viewer locally so the catalogue dropdown can fetch cached maps.
|
||||
|
||||
python3 serve.py # serves this folder at http://localhost:8000
|
||||
python3 serve.py 9000 # custom port
|
||||
|
||||
Browsers block fetch() on file:// URLs, so the Triumph-tables catalogue dropdown
|
||||
only works when the viewer is served over HTTP. Drag-and-drop works either way.
|
||||
Run download_maps.py first to populate maps_cache/.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import http.server
|
||||
import socketserver
|
||||
import sys
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
|
||||
|
||||
def main() -> int:
|
||||
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
|
||||
if not (HERE / "maps_cache" / "index.json").exists():
|
||||
print("note: maps_cache/index.json not found — run download_maps.py first "
|
||||
"for the catalogue dropdown (drag-and-drop still works).")
|
||||
|
||||
handler = lambda *a, **k: http.server.SimpleHTTPRequestHandler(*a, directory=str(HERE), **k)
|
||||
with socketserver.TCPServer(("127.0.0.1", port), handler) as httpd:
|
||||
url = f"http://localhost:{port}/tunie-viewer.html"
|
||||
print(f"serving {HERE} at {url}\nCtrl-C to stop.")
|
||||
try:
|
||||
webbrowser.open(url)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
print("\nstopped.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user