Bikun Tracker ETA Service V2 - Documentation
π Background
Overviewβ
BikunTracker ETA Service is a FastAPI-based machine learning microservice that provides real-time Estimated Time of Arrival (ETA) predictions for UI campus shuttle buses. It connects to the BikunTracker V2 backend via WebSocket to receive live GPS telemetry, processes the data through a CatBoost regression model, and exposes REST API endpoints for frontend clients to query ETA by stop and line. The service uses a chain prediction approach β iteratively predicting travel time for each segment of a bus's remaining trajectory β to produce ETAs for every stop on the route, not just the next one.
Stakeholdersβ
- Users: UI students and staff (consume ETA via frontend), BikunTracker V2 backend (upstream GPS data source), Product Engineering RistekCSUI (service owner)
- Upstream Dependencies: BikunTracker V2 Backend β WebSocket /ws (live GPS coordinates and operational status)
- Downstream Consumers: Frontend web dashboard β REST API endpoints /api/eta/*
Scope & Boundariesβ
In Scope
- Real-time ETA prediction via CatBoost ML model
- WebSocket listener consuming BikunTracker V2 broadcast
- Chain (trajectory) prediction for all remaining stops per bus
- REST API endpoints for single stop, full (up to 3 buses), and all-stops ETA
- Model training pipeline with 5-fold cross-validation
- RTA (Remaining Time to Arrival) label construction from historical WebSocket data
- Route variant detection (morning vs regular)
- Idle bus filtering (5-minute threshold)
Out of Scope
- Frontend rendering or UI components
- BikunTracker V2 backend implementation
- Persistent database storage (currently in-memory only)
- Redis caching (listed as future TODO)
- Deployment to Azure Container Apps (listed as future TODO)
βοΈ Architecture & Design
System Diagramβ
Architecture Decisions (ADRs)β
- Language/Framework: Python 3.10 β FastAPI with uvicorn
- ML Model: CatBoost Regressor β handles categorical features natively
- Model Target: RTA (Remaining Time to Arrival) in seconds
- Inbound Data: WebSocket consumer β connects to BikunTracker V2
- Outbound: REST API β JSON responses to frontend clients
- Coordinate System: WGS84 (lat/lon) projected to Web Mercator (EPSG:3857) for distance calculation
- Time Reference: GPS timestamp from batch (not VM clock) to avoid time sync issues
- Prediction Strategy: Chain prediction β iterative segment-by-segment trajectory forecast
- Container: Docker (python:3.10-slim base)
π»Technical Specifications
API Documentationβ
Data Model/Schemaβ
Project Structureβ
bikun-eta-service/
βββ app/
β βββ core/
β β βββ config.py # Environment configuration
β β βββ static_data.py # Stop coordinates and route definitions
β βββ schemas/
β β βββ prediction.py # Pydantic request/response models
β βββ services/
β βββ ws_listener.py # WebSocket listener and prediction cache
β βββ feature_engineering.py # Feature extraction and preprocessing
β βββ rta_constructor.py # RTA label construction
β βββ ml_engine.py # CatBoost model and training
βββ models/ # Trained models (.cbm)
βββ Dockerfile
βββ requirements.txt
βββ README.md
Key Componentsβ
app/main.py β Application Bootstrap
- Initializes the FastAPI app with CORS middleware.
- Starts the WebSocket listener as a background async task on startup via lifespan.
- Wires all service instances:
WSListener,FeatureEngineering,RTAConstructor, andMLEngine. - Registers all REST API routes under
/api/. - Uses a custom HTTP exception handler so CORS headers are included in error responses.
app/services/ws_listener.py β WebSocket Listener
- Maintains a persistent WebSocket connection to BikunTracker V2 with auto-reconnect.
- Processes GPS batches every 5 seconds minimum.
- Filters grey-line and idle buses when GPS timestamps are older than 5 minutes.
- Uses the latest GPS timestamp from each batch as the reference time to avoid VM clock sync issues.
- Determines route variant, runs
MLEngine.predict_trajectory(), and stores predictions in an in-memory cache. - Optionally logs raw telemetry to CSV for training data collection via
LOG_WS_DATA=true.
app/services/ml_engine.py β ML Engine
- Loads the CatBoost model from
MODEL_PATHon startup. - Runs async chain prediction through each remaining stop.
- Accumulates total travel time and advances simulation state.
- Supports 5-fold cross-validation with early stopping via
train_continual(). - Excludes RTA values above 600 seconds from training.
app/services/feature_engineering.py β Feature Engineering
- Projects GPS coordinates to Web Mercator (
EPSG:3857) viapyproj. - Extracts cyclic time features:
day_sin/cos,hour_sin/cos, andminute_sin/cos. - Calculates Euclidean distance from bus to next stop.
- Looks up next stop coordinates from
static_data.py. - Cleans training data by removing duplicates, stabilizing
current_halte, recomputingnext_halte, and filtering non-operational buses.
app/services/rta_constructor.py β RTA Constructor
- Finds the first valid "Arriving" event per segment.
- Computes RTA by working backwards using timestamp differences.
- Treats RTA values above 600 seconds as
NaN. - Groups rows into segments by reverse cumulative sum of first-arriving events.
app/core/static_data.py β Static Route Data
LOCATION_COORDS: GPS coordinates for every stop by route and internal stop key.LOCATION_MAPPING: display stop names mapped to internal coordinate keys per route.ROUTES: ordered stop sequences forMERAH_BIASA,MERAH_PAGI,BIRU_BIASA, andBIRU_PAGI.
βοΈ Operational Playbook
Infrastructureβ
- Cloud Provider: AWS ECR + Pusilkom instance
- Link: Pusilkom deployment
- Container Registry:
638207107223.dkr.ecr.ap-southeast-1.amazonaws.com - Image Name:
bikun-tracker-v2-backend - Production Tag:
stable(deployed frommainbranch) - Staging Tag:
latest(deployed fromstagingbranch) - Region:
ap-southeast-1(Singapore)
Environment Variablesβ
| Key | Description | Default (Dev) | Sensitive? |
|---|---|---|---|
| WS_URL | WebSocket URL to BikunTracker V2 backend | https://api-damri.istsolutions.co.id | No |
| PORT | FastAPI server port | 8000 | No |
| MODEL_PATH | Path to CatBoost model file | models/catboost_v1.cbm | No |
| WS_URL | External GPS WebSocket URL | ws://localhost:8000/status | No |
| RM_API | RM lane-detection service URL | https://eta-bikun-tracker-production.up.railway.app | No |
| PRINT_CSV_LOGS | Enable CSV log POST to port 4040 | FALSE | No |
| PORT | Port the server listens on | 8080 | No |
| DB_HOST | PostgreSQL host address | localhost | No |
| DB_NAME | Database name | bikun_tracker | No |
| DB_USER | Database username | postgres | No |
| DB_PASSWORD | Database password | β | Yes |
| DB_PORT | Database port | 5043 | No |
| WS_UPGRADE_WHITELIST | Allowed WebSocket origins (comma-separated) | localhost:5173 | No |
| JWT_EXPIRY_IN_DAYS | Access token validity in days | 1 | No |
| JWT_REFRESH_EXPIRY_IN_DAYS | Refresh token validity in days | 30 | No |
| JWT_SECRET_KEY | HMAC secret for JWT signing | β | Yes |
| ADMIN_API_KEY | API key for admin-protected endpoints | β | Yes |
πQuestions
π List of frequently asked questions or question that need to be answered that is related to this initiative ..