Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,15 @@ jobs:
shell: bash
run: |
nix develop -c make bindgen-packets-test
- name: Test Proto Plugin
shell: bash
run: |
nix develop -c make proto-plugin-test
- name: Test Proto C++ Conversion Plugin
shell: bash
run: |
nix develop -c make proto-cpp-plugin-test
- name: Test SSL League Proto Compatibility
shell: bash
run: |
nix develop -c make ssl-proto-test
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# nix aritfacts
# nix artifacts
result
result/

# Python
__pycache__/
*.pyc
*.pyo
.pytest_cache/
43 changes: 43 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,46 @@ bindgen-packets-test: bindgen-packets-clean
cd ateam-common-packets/rust-lib && \
cargo test
test:: bindgen-packets-test

proto-plugin-test:
cd ateam-common-packets && \
python3 -m pytest cmake/tests/test_plugin.py -v
test:: proto-plugin-test

proto-cpp-plugin-test:
cd ateam-common-packets && \
python3 -m pytest cmake/tests/test_cpp_plugin.py -v
test:: proto-cpp-plugin-test

ssl-proto-test:
python3 -m pytest ssl-league-protobufs/tests/test_ssl_protos.py -v
test:: ssl-proto-test

# Detect Wireshark personal plugins directory (Linux/macOS).
_WS_PLUGIN_DIR ?= $(shell \
wireshark -G folders 2>/dev/null \
| awk -F'\t' '$$1 == "Personal Lua Plugins" {print $$2}' \
)

.PHONY: install-wireshark-plugin
install-wireshark-plugin:
@if [ -z "$(_WS_PLUGIN_DIR)" ]; then \
echo "Could not detect Wireshark plugin directory."; \
echo "Copy wireshark/ateam_radio.lua manually to your personal Lua plugins folder."; \
echo "(Help → About Wireshark → Folders → Personal Lua Plugins)"; \
exit 1; \
fi
mkdir -p "$(_WS_PLUGIN_DIR)"
cp wireshark/ateam_radio.lua "$(_WS_PLUGIN_DIR)/"
@echo "Installed to $(_WS_PLUGIN_DIR)/ateam_radio.lua"
@echo "Reload in Wireshark with Ctrl+Shift+L or restart."

.PHONY: uninstall-wireshark-plugin
uninstall-wireshark-plugin:
@if [ -z "$(_WS_PLUGIN_DIR)" ]; then \
echo "Could not detect Wireshark plugin directory."; \
echo "Remove wireshark/ateam_radio.lua from your personal Lua plugins folder manually."; \
exit 1; \
fi
rm -f "$(_WS_PLUGIN_DIR)/ateam_radio.lua"
@echo "Removed $(_WS_PLUGIN_DIR)/ateam_radio.lua"
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
# Software Common Respository ![Build Status Badge](https://github.com/SSL-A-Team/common/actions/workflows/CI.yml/badge.svg)
# Software Common Repository ![Build Status Badge](https://github.com/SSL-A-Team/common/actions/workflows/CI.yml/badge.svg)

Contains software artifacts shared across the firmware/software boundary.
Shared artifacts across the firmware/software boundary: packet definitions, proto schemas, and generated bindings.

Sub folders contain relevant sub README files.
- `ateam-common-packets/` - all packet definitions used in Robot\<-\>AI communications.
- `radio-protocol/` - the top level radio communication spec (bot discovery, coms, etc)
## Repository Structure

# Development Setup
```
ateam-common-packets/ Robot↔AI communication packet definitions (C headers, protos, Rust bindings)
ssl-league-protobufs/ SSL league proto definitions (game controller, vision, simulation)
wireshark/ Wireshark Lua dissector for the radio link
flake.nix Nix dev environment (protoc, Python, arm-none-eabi-gcc for bindgen)
Makefile Top-level build/test targets
```

These artifacts are generally included in other projects that produce actual
build artifacts. As such, there is no default setup. A nix flake is included
to independently support bindgen if desired. Nix setup is described in
the [firmware repository readme](https://github.com/SSL-A-Team/firmware/blob/main/README.md).
## Development Setup

A Nix flake provides all required tools. See the [firmware repository README](https://github.com/SSL-A-Team/firmware/blob/main/README.md) for Nix setup instructions.

```sh
nix develop # enter dev shell (protoc, Python 3, arm-none-eabi-gcc, cargo)
make test # run all test suites
make # build Rust bindings
```

## Wireshark Dissector

[`wireshark/`](wireshark/README.md) — Lua dissector for the radio link. Decodes `CRC32 | varint(len) | RadioPacket` frames; delegates field decoding to Wireshark's built-in protobuf dissector using the `.proto` files in this repo.

```sh
make install-wireshark-plugin # install to Wireshark personal plugins directory
make uninstall-wireshark-plugin # remove it
```

## Sub-package READMEs

- [`ateam-common-packets/README.md`](ateam-common-packets/README.md) — C headers, proto schemas, ROS2 msg generation, Rust bindings
119 changes: 110 additions & 9 deletions ateam-common-packets/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,121 @@
# Radio Packets
# ateam-common-packets

This folder includes all common packets sent via radio, which requires a C/Rust interface.
Packet definitions for Robot↔AI radio communication: C headers, Protocol Buffer schemas, ROS2 `.msg` generation, and Rust bindings.

The headers are defined in C and generated for Rust using bind gen.
## Directory Structure

## Including C Code
```
include/
common.h Shared primitive types (fixed-width ints, assert_size macro)
robot_metadata.h Robot identity metadata
radio/ Packets exchanged over the radio link
radio.h Top-level packet union (RadioData)
basic_control.h AI→Robot motion command
basic_telemetry.h Robot→AI status packet
extended_telemetry.h Robot→AI full debug telemetry
body_control.h Body controller extended telemetry
discovery.h Hello request/response
error_telemetry.h Robot→AI error report
robot_parameters.h Runtime-tunable parameter read/write
robot_maneuvers/ Per-mode command and telemetry structs
wire/ Packets on the robot-internal SPI/UART buses (not sent over radio)
stspin.h Motor controller velocity command
stspin_current.h Motor controller current/telemetry packets
kicker.h Kicker board command and telemetry
power.h Power board telemetry

You can include the C headers into any C/C++ program as you would normally.
proto/ Protocol Buffer schemas (proto3)
radio.proto Top-level RadioPacket oneof (replaces C CommandCode + RadioData union)
control.proto BasicControl message
telemetry.proto BasicTelemetry and ExtendedTelemetry messages
maneuvers.proto Per-mode command messages and body controller telemetry stubs
body_control.proto BodyControlExtendedTelemetry message
discovery.proto HelloRequest / HelloResponse messages
diagnostics.proto ErrorTelemetry message
robot_parameters.proto ParameterCommand message (runtime tuning)
motor.proto CcmTelemetry messages
power.proto PowerTelemetry messages
kicker.proto KickerTelemetry messages
ateam_options.proto Custom proto options (bitmask annotation)

cmake/
Ros2MsgGen.cmake CMake function: generate ROS2 .msg files from protos at configure time
Ros2CppConvertGen.cmake CMake function: generate C++ fromProto() headers from protos
protoc_gen_ros2msg.py protoc plugin — .proto → ROS2 .msg
protoc_gen_ros2cpp.py protoc plugin — .proto → C++ fromProto() headers
ateam_proto_shared.py Shared helpers used by both plugins
tests/ pytest suites for both plugins

## Building
rust-lib/
build.rs Runs bindgen (C→Rust) and micropb-gen (proto→Rust) at build time
src/
lib.rs Public API + basic control safety checks
radio.rs Rust types mirroring C radio packet structs
translation.rs From<&c::T> for proto::T conversion impls
bindings.rs bindgen-generated C bindings (from include/radio/)
metadata_bindings.rs bindgen-generated bindings (from include/robot_metadata.h)
proto_packets_gen.rs micropb-generated Rust proto types (from proto/)
```

Enter the development environment shell using the direction in the top level readme.
## Wire Framing

Run `cargo build` to generate the bindings, and verify they compile.
Radio packets use the format: `CRC32 || varint(len) || RadioPacket bytes`

Run `cargo test` to run bindgen packing tests.
The `RadioPacket` proto `oneof` wire tag replaces the legacy C `CommandCode` byte. Field numbers in `radio.proto` intentionally match the old `CC_*` enum values for cross-reference. CRC32 and length are transport-layer concerns external to the proto encoding.

## C Headers

Include the top-level radio header for all radio-facing types:

```c
#include "ateam-common-packets/include/radio/radio.h"
```

Wire-internal headers (motor controller, kicker, power board) are under `include/wire/` and are not needed by AI software.

## Proto / ROS2 Integration

Generate ROS2 `.msg` files from the proto schemas using the provided CMake function:

```cmake
include(Ros2MsgGen)
generate_ros2_msgs(
PROTO_FILES ${PROTO_FILES}
PROTO_PATHS ${PROTO_DIR}
OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/msg
)
rosidl_generate_interfaces(${PROJECT_NAME} ${GENERATED_ROS2_MSGS})
```

Generate C++ `fromProto()` conversion headers:

```cmake
include(Ros2CppConvertGen)
generate_ros2_cpp_conversions(
PROTO_FILES ${PROTO_FILES}
PROTO_PATHS ${PROTO_DIR}
PROTO_INCLUDE_PREFIX ateam_common_packets
ROS2_PACKAGE ateam_radio_msgs
OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/include/conversions
)
```

## Rust Bindings

```sh
nix develop
cargo build # generates bindings.rs and proto_packets_gen.rs
cargo test # runs packing/size tests
```

Requires `arm-none-eabi-gcc` on the path (provided by the Nix shell) for bindgen's cross-compilation target headers. Set `$ARM_NONE_EABI_ROOT` to override the sysroot search.

## Testing

```sh
nix develop
make test # all suites
python3 -m pytest cmake/tests/test_plugin.py -v # ROS2 .msg plugin tests
python3 -m pytest cmake/tests/test_cpp_plugin.py -v # C++ conversion plugin tests
cargo test # Rust binding tests
```
Loading
Loading