Class DashboardBridge

java.lang.Object
com.marswars.dashboard.DashboardBridge

public class DashboardBridge extends Object
Bridges a browser-based interactive dashboard (served off the RoboRIO, driven by NT4 from the browser) to robot code over two NetworkTables tables: one the dashboard writes and the robot reads ("ToRobot"), one the robot writes and the dashboard reads ("ToDashboard").

This class only knows about wire-level int/boolean channels and the edge-detection/dirty-check plumbing around them -- it has no idea what any channel *means*. Bitfield packing, game rules, and 3D pose visualization are all the consumer's job, layered on top of this class in a per-year robot repo.

Not a singleton -- a robot may host zero or one of these; there's no reason to force a single shared instance.

  • Constructor Details

  • Method Details

    • startWebServer

      public void startWebServer()
      Starts serving the static dashboard web app. Call once from production robot code (e.g. during subsystem construction); skip in tests, which don't need the HTTP server.
    • readInputs

      public void readInputs()
      Call once per loop, before any getIntIfChanged/getBoolIfChanged calls. Drains every bidirectional channel's inbound queue and records which channels received a new value this tick.
    • getIntIfChanged

      public OptionalInt getIntIfChanged(DashboardChannel channel)
      Did the dashboard send a new value for this bidirectional int channel this tick?
    • getBoolIfChanged

      public Optional<Boolean> getBoolIfChanged(DashboardChannel channel)
      Did the dashboard send a new value for this bidirectional boolean channel this tick?
    • getInt

      public int getInt(DashboardChannel channel)
      Last known value for this channel, whether or not it changed this tick.
    • getBool

      public boolean getBool(DashboardChannel channel)
      Last known value for this channel, whether or not it changed this tick.
    • set

      public void set(DashboardChannel channel, int value)
      Sets the authoritative value the robot reports to the dashboard for this channel. Safe to call unconditionally every loop -- only writes to NetworkTables when the value actually differs from what was last published, so redundant calls cost nothing on the wire.

      The dirty-check here compares against last_published_int_, not current_int_values_. Those two must stay separate: if the dashboard just sent 2 for this channel, readInputs() already set current_int_values_ to 2 before consumer code calls set(channel, 2) to echo it back. Comparing against current_int_values_ would see "2 == 2" and skip the publish -- but the dashboard was never actually told the robot accepted that value; nothing has gone out over the wire yet. Comparing against last_published_int_ instead means the first set() call after any inbound change always publishes (no prior "last published" entry), and only genuinely repeated calls get suppressed.

    • set

      public void set(DashboardChannel channel, boolean value)
      See set(DashboardChannel, int) -- same dirty-check reasoning applies here.
    • publishIfChanged

      public static <T> Set<T> publishIfChanged(StructArrayPublisher<T> publisher, Set<T> previousValues, Set<T> newValues, IntFunction<T[]> arrayGenerator)
      Publishes newValues via publisher only if it differs from previousValues. Returns the value to remember as "previous" for the next call.

      For the "recompute a derived Set<T> every tick, only call StructArrayPublisher.set() if it actually changed" idiom -- e.g. broadcasting scored game-piece poses to AdvantageScope without spamming NT on every unchanged tick. The pose math itself is inherently game-specific and stays in consumer code; only this dirty-check shape is generic.