A backup wireless telemetry protocol that converts vehicle sensor data (JSON) into Protocol Buffer packets, transmits them via the selected communication method, and decodes the data for visualization on the Race Engineer Dashboard.
- Minimodem (encodes data into audio tones using Frequency-Shift Keying modulation)
- UDP over Starlink (see below)
UDP support remains in this repository for local testing and development only.
For competition, ROS is the primary telemetry method.
WINDOWS USERS: Minimodem does not run natively on Windows. Install WSL2 with Ubuntu and run this project in the WSL terminal if you plan to use modem mode.
Clone repo with submodules:
git clone --recurse-submodules https://github.com/cornellev/redundant-telemetry.git
cd redundant-telemetryIf you already cloned without submodules:
git submodule update --init --recursiveInstall Python dependencies:
pip install -r requirements.txtIf you plan to use modem mode, install Minimodem:
# macOS
brew install minimodem
# Windows/Linux (Ubuntu/WSL)
sudo apt-get update && sudo apt-get install -y minimodemNote: sender.py requires the SHM reader class from the UC26 Sensor Reader repo, included as a git submodule (configured in .gitmodules). Clone with submodules as shown above before running the project.
Create your local environment file from the template and set corresponding values in .env:
DATA_TRANSFER_BAUDDATA_TRANSFER_UDP_HOSTDATA_TRANSFER_UDP_PORTDATA_TRANSFER_SENDER_NUMBERDATA_TRANSFER_RECEIVER_NUMBERDATA_TRANSFER_MODEM_PORTDATA_TRANSFER_MODEM_POWER_KEYDATA_TRANSFER_MODEM_BAUD
This repo uses a src layout, so set PYTHONPATH=src before running modules.
$env:PYTHONPATH="src"
python -m receiver.receiver --mode udp
python -m sender.sender --mode udpexport PYTHONPATH=src
python -m receiver.receiver --mode udp
python -m sender.sender --mode udpUse --mode modem instead of --mode udp to transfer data via minimodem.
Sender behavior:
- Continuously streams protobuf packets using the data from
SensorShmReader.
Receiver behavior:
- Modem mode: powers on the SIM7600, answers an incoming call, receives/decodes packets in a loop, then hangs up.
- UDP mode (current implementation): uses a
2.0second idle timeout to exit if no packets are received (this timeout is customizable inreceiver.py).
redundant-telemetry/
|-- src/
| |-- config.py # Runtime configuration for transmission mode
| |-- hardware/
| | |-- cellular_modem.py # SIM7600 GPIO + serial control helper
| | `-- __init__.py
| |-- modes/
| | |-- interface.py
| | |-- modem_mode.py # minimodem transfer implementation
| | |-- udp_mode.py # UDP transfer implementation
| | `-- __init__.py
| |-- receiver/
| | |-- receiver.py # Receives packets and decodes protobuf frames
| | `-- __init__.py
| |-- sender/
| | |-- sender.py # Reads SHM, serializes, and sends
| | `-- __init__.py
| |-- schema/ # Generated protobuf Python runtime files
| | |-- data_pb2.py
| | `-- __init__.py
| `-- __init__.py
|-- .gitmodules
|-- schema/ # Protobuf source schema directory
| `-- data.proto
|-- .env.example
|-- requirements.txt
`-- README.md
Sensors message fields:
seqglobal_tspower { ts, current, voltage }steering { ts, brake_pressure, turn_angle }rpm_front { ts, rpm_left, rpm_right }rpm_back { ts, rpm_left, rpm_right }gps { ts, gps_lat, gps_long }motor { ts, rpm, throttle }
This system uses Google Protocol Buffers to define structured messages.
- Edit
schema/data.proto. - Regenerate Python bindings:
protoc --python_out=src schema/data.proto- Add a new
.protofile underschema/(example:schema/new_data.proto). - Generate Python bindings for the new file:
protoc --python_out=src schema/new_data.proto- Commit both:
- the
.protosource file inschema/ - the generated
*_pb2.pyfile insrc/schema/
