# udp-telemetry A lightweight UDP telemetry system for FTC robots and other embedded targets. The Java library sends structured JSON packets from the robot (or any JVM process); a Python logger receives them and stores every reading in a SQLite triplestore for later query and analysis. Built and maintained by [Nexus Workshops LLC](https://nexusworkshops.com). --- ## How it works ``` Robot / JVM process Laptop / driver station +---------------------------+ +---------------------------+ | UdpTelemetry.java | UDP/JSON | telelog.py | | put("left_motor","power",|---------->| SQLite triplestore | | 0.8) | port 3000| packets + triples tables | | send() | +---------------------------+ +---------------------------+ ``` Each call to `send()` serializes the current buffer into a JSON packet: ```json { "left_motor": {"power": 0.8, "temp": 42.1}, "right_motor": {"power": 0.75, "temp": 38.5}, "imu": {"yaw": 45.0, "steering": 0.05}, "loop_time_ms": 50 } ``` `telelog.py` unpacks every packet into `(subject, predicate, object)` triples and writes them to SQLite. Nested values are flattened with dot notation (`pid.p`, `pid.i`). Flat scalars use the sender's IP as the subject. --- ## Prerequisites ### Java (sender) - Java 11 or newer - Apache Maven 3.6 or newer ### Python (logger) - Python 3.8 or newer - No third-party packages required -- only the standard library --- ## Installation ### Windows **1. Install Java 11+** Download and run the OpenJDK installer from https://adoptium.net. Accept the default options. Verify in a new terminal: ``` java -version ``` **2. Install Maven** Download the binary zip from https://maven.apache.org/download.cgi. Extract it (e.g. `C:\tools\maven`), then add `C:\tools\maven\bin` to your system `PATH` via System Properties -> Environment Variables. Verify: ``` mvn -version ``` **3. Install Python 3** Download from https://www.python.org/downloads/windows/. Check "Add python.exe to PATH" during setup. Verify: ``` python --version ``` **4. Clone and build** ``` git clone https://github.com/nexusworkshops/udp-telemetry.git cd udp-telemetry mvn package ``` The shaded (self-contained) JAR lands at: ``` target\udp-telemetry-1.0.0-shaded.jar ``` --- ### Linux **1. Install Java 11+** ```bash sudo apt update sudo apt install openjdk-11-jdk java -version ``` **2. Install Maven** ```bash sudo apt install maven mvn -version ``` **3. Python 3 is usually pre-installed -- verify** ```bash python3 --version ``` If not present: ```bash sudo apt install python3 ``` **4. Clone and build** ```bash git clone https://github.com/nexusworkshops/udp-telemetry.git cd udp-telemetry mvn package ``` The shaded JAR lands at: ``` target/udp-telemetry-1.0.0-shaded.jar ``` --- ## Running Open two terminals in the project directory. **Terminal 1 -- start the logger** Windows: ``` python telelog.py ``` Linux: ``` python3 telelog.py ``` Output: ``` [telelog] Schema initialized: telemetry.db [telelog] Listening on 0.0.0.0:3000 db=telemetry.db tag=(untagged) [telelog] Ctrl-C to stop ``` **Terminal 2 -- run the demo sender** Windows: ``` java -jar target\udp-telemetry-1.0.0-shaded.jar ``` Linux: ``` java -jar target/udp-telemetry-1.0.0-shaded.jar ``` The demo sender transmits 20 packets at 20 Hz simulating two drive motors, a chute hood servo, and an IMU. You will see each packet acknowledged in Terminal 1 and written to `telemetry.db`. --- ## Logger options ``` python3 telelog.py [options] --port PORT UDP listen port (default: 3000) --host HOST Bind address (default: 0.0.0.0) --db FILE SQLite database file (default: telemetry.db) --tag LABEL Session label stored with every packet (e.g. auto_match_3) --init-db Create/reset the schema and exit --quiet Suppress per-packet console output ``` Example -- tag a match session: ``` python3 telelog.py --tag "semifinal_1" --port 3000 ``` --- ## Sending from a real robot Point `UdpTelemetry` at the driver station IP and add it to your op mode: ```java UdpTelemetry t = new UdpTelemetry("192.168.43.100", 3000); // In your loop: t.put("left_motor", "power", leftDrive.getPower()) .put("right_motor", "power", rightDrive.getPower()) .put("imu", "yaw", imu.getRobotYawPitchRollAngles().getYaw(AngleUnit.DEGREES)) .send(); ``` Call `t.close()` in your op mode's `stop()` method. --- ## Querying the database ```sql -- All readings from the left motor SELECT p.ts, t.predicate, t.object FROM triples t JOIN packets p ON p.id = t.packet_id WHERE t.subject = 'left_motor' ORDER BY p.ts; -- Peak yaw value in a session SELECT MAX(CAST(t.object AS REAL)) FROM triples t JOIN packets p ON p.id = t.packet_id WHERE t.subject = 'imu' AND t.predicate = 'yaw' AND p.tag = 'semifinal_1'; ``` --- ## Project structure ``` udp-telemetry/ src/main/java/com/nexusworkshops/telemetry/ UdpTelemetry.java -- UDP sender library Main.java -- demo sender telelog.py -- UDP logger / SQLite triplestore pom.xml -- Maven build site/ -- Nexus Workshops learning site assets ``` --- ## License The source code in this repository is released under the MIT License. See [LICENSE](LICENSE) for the full text. The field guide (`Robot_Telemetry_Complete_Field_Guide.pdf/.docx`) is separately licensed under the Nexus Workshops Content License Agreement and is **not** covered by the MIT License. Personal and educational use is permitted; commercial use requires a separate written license from Nexus Workshops LLC. See [LICENSES.md](LICENSES.md) for a full breakdown of what each license covers.