Skip to main content

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, and MLEngine.
  • 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_PATH on 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) via pyproj.
  • Extracts cyclic time features: day_sin/cos, hour_sin/cos, and minute_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, recomputing next_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 for MERAH_BIASA, MERAH_PAGI, BIRU_BIASA, and BIRU_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 from main branch)
  • Staging Tag: latest (deployed from staging branch)
  • Region: ap-southeast-1 (Singapore)

Environment Variables​

KeyDescriptionDefault (Dev)Sensitive?
WS_URLWebSocket URL to BikunTracker V2 backendhttps://api-damri.istsolutions.co.idNo
PORTFastAPI server port8000No
MODEL_PATHPath to CatBoost model filemodels/catboost_v1.cbmNo
WS_URLExternal GPS WebSocket URLws://localhost:8000/statusNo
RM_APIRM lane-detection service URLhttps://eta-bikun-tracker-production.up.railway.appNo
PRINT_CSV_LOGSEnable CSV log POST to port 4040FALSENo
PORTPort the server listens on8080No
DB_HOSTPostgreSQL host addresslocalhostNo
DB_NAMEDatabase namebikun_trackerNo
DB_USERDatabase usernamepostgresNo
DB_PASSWORDDatabase passwordβ€”Yes
DB_PORTDatabase port5043No
WS_UPGRADE_WHITELISTAllowed WebSocket origins (comma-separated)localhost:5173No
JWT_EXPIRY_IN_DAYSAccess token validity in days1No
JWT_REFRESH_EXPIRY_IN_DAYSRefresh token validity in days30No
JWT_SECRET_KEYHMAC secret for JWT signingβ€”Yes
ADMIN_API_KEYAPI 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 ..