# Sentry An autonomous sentry gun subapp that uses the device camera and on-device machine learning to detect people and automatically send a tag from a KTag blaster connected via USB when a person is detected in the crosshair. ## How It Works 1. The back camera streams frames continuously through CameraX. 2. Each frame is analyzed by **MediaPipe Tasks Vision** running the **EfficientDet-Lite0** object detection model entirely on-device — no network connection required. 3. When a person is detected with ≥ 50 % confidence, a red bounding box is drawn over them and a continuous 880 Hz tone plays (if enabled). 4. If the bounding box overlaps the crosshair at the centre of the screen, the sentry fires: it sends a trigger-press command followed by a trigger-release command over USB serial to the connected KTag device. 5. A cooldown period prevents the sentry from firing again until the timer expires. ## Setup ### 1. Download the detection model The EfficientDet-Lite0 model is not bundled with the APK and must be placed manually: ``` subapp-sentry/src/main/assets/efficientdet_lite0.tflite ``` Download the **TFLite (efficientdet/lite0/detection/metadata/1)** file from: > https://tfhub.dev/tensorflow/lite-model/efficientdet/lite0/detection/metadata/1 ### 2. Connect a KTag device via USB Plug a KTag device into the Android device using a USB OTG cable. The app will detect it automatically and show it in the device selector. ### 3. Grant camera permission The app requests `CAMERA` permission on first launch. Deny it and the camera preview will not start. ## UI | Element | Description | |----------------------|-----------------------------------------------------------------------------------------------------| | Camera preview | Full-screen live view from the back camera | | Red bounding box | Drawn around any detected person | | White crosshair | Fixed plus symbol at the centre of the screen; firing only occurs when it overlaps the bounding box | | **DETECTED** badge | Appears in the top-right corner whenever a person is visible | | Device selector | Drop-down listing connected USB serial devices | | Connect / Disconnect | Connects to the selected USB device or drops the connection | | Status bar | Shows connection state, configured team, and time since last trigger | ## Settings Open the settings screen via the gear icon in the top-right corner. | Setting | Options | Default | Description | |---------------------|----------------------|---------|----------------------------------------------------------| | Tag Team | Blue, Red, Purple | Blue | Team argument sent in the trigger command | | Trigger Cooldown | 3 s, 5 s, 10 s, 30 s | 5 s | Minimum time between consecutive trigger firings | | Play Detection Tone | On / Off | On | Plays a continuous 880 Hz tone while a person is visible | ## USB Serial Protocol When the sentry fires, it simulates a trigger press by sending two commands in sequence: ``` KEvent 7 0\n ← trigger press KEvent 8 0\n ← trigger release ``` The device selector lists all recognised USB serial devices. The app requests USB permission automatically on first connect. ## Audio | Sound | Condition | Details | |------------------------|-------------------------|----------------------------------------------------------------------------------------------| | Continuous 880 Hz tone | Person visible in frame | `AudioTrack` sine wave; plays until person leaves frame or "Play Detection Tone" is disabled | | Short beep | Sentry fires | 200 ms `ToneGenerator` beep | Both sounds play on the media audio stream and respect the device's media volume. ## Dependencies | Library | Version | Purpose | |------------------------|---------|----------------------------------------------------------| | CameraX | 1.4.0 | Camera preview and frame capture | | MediaPipe Tasks Vision | 0.10.32 | On-device object detection | | EfficientDet-Lite0 | 1 | Person detection model (Apache-2.0, download separately) | | usb-serial-for-android | 3.10.0 | USB serial communication with KTag hardware | > **Note:** MediaPipe transitively includes Firebase. The `AndroidManifest.xml` explicitly removes `FirebaseInitProvider` via `tools:node="remove"` to prevent any Firebase initialisation.