Synapse v0.4.0
GitHub Get started
New — bulk reads on the hardware thread

Robot code that thinks in signals

Synapse is a tiny, annotation-driven pub/sub bus for FIRST Tech Challenge robots. Nodes talk over named, typed topics while one dedicated thread keeps every hardware touch safe.

MIT licensed · 40 KB JAR · zero runtime dependencies

orchestrator — live simulation60 Hzmessages 0
CONTROLSSUBSCRIBERSg1/right_bumper/risingg1/left_bumper/risingg1/left_stick_yimu/headingmotors/powerset/powerleds/colorORCHESTRATORgamepad1RBLBLSIMUimu/heading42.0°DRIVEmotors/power0.00INTAKEset/power0.0LEDsleds/colorOFF

topic log — newest first

waiting for messages…

The bus never sleeps — click any control to publish your own message.

In the field Synapse runs the robot code of FTC Team 23684 · Tech Titans

40 KB

JAR, minified

0

runtime dependencies

4

threaded architecture

60 Hz

gamepad-to-topic input

Why Synapse

Safest and smallest, by design

Purpose-built for FTC: fast enough for a 50 Hz drivetrain, strict enough to protect your I²C bus.

One hardware thread, no exceptions
Every motor write, servo command, and sensor read funnels through a single dedicated thread. A runtime assertion fails fast if you touch hardware from anywhere else.
Three-layer API
Annotations, a HardwareActions facade, and SafeDevice<T> wrappers. Pick the style that fits your team — they all serialize onto the same safe path.
Backpressure that respects deadlines
Separate pools for periodic and callback work with bounded queues. A slow subscriber slows its publisher — it never starves your control loop.
Gamepad to topics in one line
GamepadAdaptor.attach() publishes buttons, edges, and axes at 60 Hz. Bind an intake to a rising edge in two lines of annotation.
R8-minify-safe, verified
The entire test suite runs through minification, so the release JAR survives the FTC robot controller build without surprises.
40 KB, zero dependencies
One Gradle line drops it into build.dependencies.gradle. No transitive jars, no version conflicts with the SDK.
Developer experience

Declare intent. Let the bus do the wiring.

Annotate a method and Synapse wires it to the topic, the thread pool, and the hardware thread — no manual tick counting, no references between subsystems.

  • @SubscribedTo callbacks fire the instant a value publishes.
  • @RunPeriodically(hz = 50) loops never drift with the main OpMode loop.
  • @OnHardwareThread hops any callback onto the only thread allowed to touch hardware.
SynapseDemo.java
Observability

Watch every topic from one panel

Named, typed topics mean your telemetry is a live map of the robot, not a pile of print statements.

orchestrator · live
4 pools50 Hz
Every topic, typed and named — watched from one place.
g1/left_stick_yFloat60 Hz
g1/right_bumper/risingBooleanon edge
drive/motors/ampsDouble50 Hz
imu/headingDouble100 Hz
Backpressurequeue 41/256
scheduler 8 threads · callbacks 12 · actions 2 · hw 1
Threading model

Four pools, each with a job

Slow callbacks cannot starve periodic loops. Slow periodic loops cannot starve hardware writes.

Pool Threads Bounded Used for
Scheduler 8 — @RunPeriodically loops
Callback 4–16 256 @SubscribedTo handlers
Action unbounded no @RunnableAction invocations
Hardware 1 (dedicated) — All hardware reads/writes
Feedback

Share your experience

Running Synapse in an OpMode? Tell us what's working and what's grinding your gears — it directly shapes the roadmap.

Opens a public issue on GitHub — read by the maintainers, no email needed.

FAQ

Questions teams ask first

Ship safer robot code this season

One dependency line. One hardware thread. No surprises at the competition table.

$implementation "com.aaravlabs:synapse:0.4.0"
Read the docs