Link Status
rosbridge over the SSH tunnel opened by scripts/start-husky. Not set up on the robot yet -- see docs/technical.tex.
Battery
Vehicle
Safety (from /status)
Mirrors the physical status panel LEDs on the back of the chassis.
Sensor Diagnostics
Status dots are placeholders (grey = unknown). A browser can't query USB devices on a remote robot directly -- this needs a small diagnostics-publishing node on the robot side to become live.
Notes
This cockpit is scaffolding: the 3D view, camera feed and telemetry panels are wired to real ROS topic
names (see js/config.js) but nothing is live until rosbridge_server and
web_video_server are installed and running on the robot, and scripts/start-husky
has an active tunnel open. Teleop publishes on the confirmed real topic,
/husky_velocity_controller/cmd_vel -- not the generic /cmd_vel, which does not
exist on this unit.
3D View — base_link frame
Loading the real Husky A200 CAD model… (a one-time ~13 MB fetch + in-browser parse; the placeholder box below is shown until this finishes)
X = red, Y = green, Z = blue. Drag to orbit, scroll to zoom.
Camera Feed
Set
CONFIG.cameraTopic in js/config.js once
web_video_server is running on the robot.
Teleoperation
No controller detected -- connect it and press any button to activate.
Publishes geometry_msgs/Twist on /husky_velocity_controller/cmd_vel at
10 Hz whenever connected. Base cap ±0.5 m/s / ±0.5 rad/s (js/config.js),
further scaled by the speed limit slider above -- this cap and the E-STOP below apply no matter
which control mode is active. E-STOP immediately publishes zero velocity and latches: input is
ignored until you press it again to release. This is in addition to the physical joystick and
the robot's own hardware e-stop, not a replacement for either.
PS4 Controller mode reads a controller connected to this computer (USB or Bluetooth pairing done in the OS, not on the robot) via the browser's Gamepad API -- left stick drives, same as the on-screen joystick. Press any button on it once connected for the browser to notice it.
Control Barrier Functions
A control barrier function (CBF) defines a safe set — every state x where a scalar function
h(x) stays non-negative — and a corresponding filter that intervenes on a commanded input
only when the state is about to leave that set. It enforces that h can never decrease faster
than a bound tied to its own current margin, typically by solving a small quadratic program that finds
the control input closest to what was actually requested (teleop, or a future planner)
while still satisfying that constraint. The point is minimal intervention: unlike the hard velocity clamp
already in Camera & Teleop (maxLinearSpeed/maxAngularSpeed in
js/config.js, which caps every command unconditionally), a CBF filter would leave commands
untouched until the robot is genuinely approaching a constraint boundary.
Candidate constraints on this robot
/scan (RPLidar A3M1)
not wired
RTK GPS position hardware not installed
/husky_velocity_controller/cmd_vel
hard clamp exists, not CBF-filtered
None of these are connected to anything yet. The lidar is fused into MINS as of 2026-09-25
(see the Navigation tab), but it is not wired into any safety layer; the RTK GPS receiver has not been
purchased (see docs/technical.tex, GNSS RTK positioning); and the existing speed limiter is a
simple clamp, not a state-dependent barrier. Listed here as the constraints most relevant to this
platform once each becomes available, so the filter can be wired in incrementally, one constraint at a
time — the same one-sensor-at-a-time discipline already used for MINS.
Planned layout (once implemented)
These three rows are reserved (their element ids are already wired into nothing) for when a real CBF node publishes something to subscribe to: the current barrier margin, whether the filter is active per constraint, and whether the last command sent to the robot was actually the one requested or one the QP had to modify to stay safe. Deliberately not populated with placeholder numbers — a fake-looking live value here would be worse than an empty one.
Robot agent not running
This panel is driven by scripts/cockpit_agent.py, a small companion node on the robot.
Nothing here is live until it is started — the rest of the cockpit works without it.
scp scripts/cockpit_agent.py cerveaux@ubuntu:~/ ssh cerveaux@ubuntu source /opt/ros/noetic/setup.bash source ~/catkin_ws/devel/setup.bash python3 ~/cockpit_agent.py
It publishes /cockpit/diagnostics once a second and listens on /cockpit/command.
If it is running and this message persists, the rosbridge connection is the thing to check — see
the Link Status card on the Overview tab.
Pre-flight
Rates are measured on the robot, not in the browser. Readiness is judged only on the streams MINS
actually consumes — camera, IMU, wheels, and the lidar (as /scan/points,
started from the Navigation tab). The lidar stage existed from 2026-09-10 but only began
contributing on 2026-09-25; before that its updates were all silently rejected. The raw /scan and
/mins/imu/odom (MINS's own output) are diagnostic only and do not block a run. An
expected rate is shown only where it has been confirmed on this unit; where it has not, the measured
value is reported without a verdict.
Run Recorder
The topic sets are defined on the robot (RECORD_PRESETS in cockpit_agent.py),
not here, so the two cannot drift apart. Every MINS set includes /tf and
/tf_static: a bag without them cannot be replayed through MINS or Kalibr at all, and that
mistake should not be one click away. Stopping sends SIGINT, which is the only signal
that makes rosbag close and rename the file cleanly — a killed recording leaves a
.bag.active that needs rosbag reindex.
Recorded runs
Newest first, 25 most recent. Recording refuses to start below 5 GB free: a MINS bag with two gray image streams runs to roughly 1 GB per minute, and a full disk turns a ten-minute experiment into a truncated bag discovered afterwards.
Research log
Technical doc
Rendered from docs/research.tex and docs/technical.tex by
scripts/build_docs.sh. If scripts/watch_docs.sh is running (started
automatically by start-husky), each panel refreshes on its own within ~15s of the
source file changing -- no manual rebuild or page reload needed.