refactor(bench): remove the Hawkeye viewer tee

The --viewer path (tee MAVLink frames to UDP and enable the
HIL_STATE_QUATERNION/HIL_ACTUATOR_CONTROLS streams so Hawkeye could
render an SIH flight live) was never validated end to end: Hawkeye
never actually rendered from it. Rather than ship an unproven feature,
drop it.

Removes px4bench.attach_viewer_tee (and its function-local socket use),
the flight_mission --viewer/--viewer-port args, the viewer tee call and
the stream-enable block, and the now-unused --board-dev arg that only
fed those stream commands. The SIH flight logic, firmware gate,
storage/serial tests, and the arming gate are unchanged. README and the
bench testing docs page drop the Hawkeye section and all --viewer
mentions.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
This commit is contained in:
Ramon Roche
2026-07-07 20:29:01 -07:00
parent bf7dcb7229
commit ca47db5faa
4 changed files with 7 additions and 68 deletions

View File

@@ -38,7 +38,7 @@ Tools/bench_test/
run_bench_suite.py # orchestrator for the non-interactive bench tests run_bench_suite.py # orchestrator for the non-interactive bench tests
px4bench/ # shared library package px4bench/ # shared library package
__init__.py # Reporter, connect, MavlinkShell, reboot/replug, __init__.py # Reporter, connect, MavlinkShell, reboot/replug,
# viewer tee, mavlink-status parsers, # mavlink-status parsers,
# pymavlink add_message workaround # pymavlink add_message workaround
params.py # param read/set/drain/echo, int32 union encoding params.py # param read/set/drain/echo, int32 union encoding
missions.py # mission items, upload/download/compare/clear missions.py # mission items, upload/download/compare/clear
@@ -178,8 +178,7 @@ over SERIAL_CONTROL. MAVSDK abstracts exactly those layers away, and adds an
asyncio runtime plus the mavsdk_server gRPC binary as dependencies. The one asyncio runtime plus the mavsdk_server gRPC binary as dependencies. The one
plausible candidate was flight orchestration in `sih/flight_mission.py`, but plausible candidate was flight orchestration in `sih/flight_mission.py`, but
that test also depends on the nsh shell (arming via `commander`, explicit that test also depends on the nsh shell (arming via `commander`, explicit
`param save`, enabling viewer streams) and on teeing raw frames to a viewer, `param save`), which MAVSDK does not expose. Verdict: pymavlink everywhere.
neither of which MAVSDK exposes. Verdict: pymavlink everywhere.
## Risk map ## Risk map
@@ -334,9 +333,8 @@ Skips with a warning when the firmware lacks `serial_test`
``` ```
./sih/flight_mission.py CONNECTION [-b BAUD] [--airframe N] [--alt M] ./sih/flight_mission.py CONNECTION [-b BAUD] [--airframe N] [--alt M]
[--viewer] [--viewer-port PORT] [--keep-config] [--keep-config] [--allow-arming]
[--allow-arming] [--expect-hash PREFIX] [--expect-hash PREFIX] [--report-dir DIR]
[--board-dev DEV] [--report-dir DIR]
``` ```
Switches the board to a SIH airframe (`SYS_AUTOSTART=1100`, `SYS_HITL=2`, Switches the board to a SIH airframe (`SYS_AUTOSTART=1100`, `SYS_HITL=2`,
@@ -344,9 +342,7 @@ physics simulated on the FMU, `pwm_out_sim` in place of real outputs), flies
takeoff, a 3-waypoint square, and RTL as an auto mission with per-phase takeoff, a 3-waypoint square, and RTL as an auto mission with per-phase
timeouts (arming, airborne, waypoint progression, touchdown, auto-disarm), timeouts (arming, airborne, waypoint progression, touchdown, auto-disarm),
downloads the flight ULog, and restores the original configuration even on downloads the flight ULog, and restores the original configuration even on
failure. `--viewer` tees every MAVLink frame to UDP so Hawkeye failure.
(`hawkeye -udp 19410 -mc`) renders the flight live from the serial-connected
board.
Runs last in the default suite and works standalone. Before doing anything Runs last in the default suite and works standalone. Before doing anything
it probes the live firmware for the SIH module (`simulator_sih status`); if it probes the live firmware for the SIH module (`simulator_sih status`); if

View File

@@ -2,8 +2,8 @@
Core primitives every test builds on: MAVLink connection setup, PASS/FAIL Core primitives every test builds on: MAVLink connection setup, PASS/FAIL
reporting, a non-interactive nsh shell over SERIAL_CONTROL (pattern from reporting, a non-interactive nsh shell over SERIAL_CONTROL (pattern from
Tools/mavlink_shell.py), reboot and USB re-detection helpers, a live viewer Tools/mavlink_shell.py), reboot and USB re-detection helpers, and small
tee, and small parsers for `mavlink status` output. parsers for `mavlink status` output.
Protocol-area helpers live in submodules: Protocol-area helpers live in submodules:
px4bench.params parameter read/set/echo with PX4's int32 union encoding px4bench.params parameter read/set/echo with PX4's int32 union encoding
@@ -407,32 +407,6 @@ def arming_gate(allow_arming, action='run the SIH flight test'):
return False return False
def attach_viewer_tee(conn, host='127.0.0.1', port=19410):
"""Forward every received MAVLink frame to a UDP endpoint, one frame per
datagram (same framing the SITL viewer channel uses), so Hawkeye can
watch a serial-connected board live: hawkeye -udp <port>.
Wraps conn.recv_msg rather than logfile_raw because logfile_raw gets raw
read() chunks, which would split frames across datagrams.
"""
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = (host, port)
orig_recv_msg = conn.recv_msg
def recv_msg_tee():
msg = orig_recv_msg()
if msg is not None:
try:
sock.sendto(msg.get_msgbuf(), addr)
except OSError:
pass
return msg
conn.recv_msg = recv_msg_tee
return conn
def send_reboot(mav): def send_reboot(mav):
"""Request an autopilot reboot (MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, param1=1).""" """Request an autopilot reboot (MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, param1=1)."""
mav.mav.command_long_send( mav.mav.command_long_send(

View File

@@ -10,10 +10,6 @@ auto-disarm, all on real NuttX scheduling. The physics is simulated; real
sensor drivers and real outputs are not exercised (pwm_out_sim replaces them, sensor drivers and real outputs are not exercised (pwm_out_sim replaces them,
so nothing on the output rails is ever driven). so nothing on the output rails is ever driven).
With --viewer, every received MAVLink frame is teed to UDP (default 19410)
and the SIH viewer streams are enabled on the board, so a locally running
Hawkeye (`hawkeye -udp 19410 -mc`) renders the flight live.
Requires firmware built with CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y. Requires firmware built with CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y.
""" """
@@ -350,16 +346,9 @@ def main():
add_connection_args(parser) add_connection_args(parser)
parser.add_argument('--airframe', type=int, default=SIH_QUAD_AIRFRAME, parser.add_argument('--airframe', type=int, default=SIH_QUAD_AIRFRAME,
help='SIH airframe SYS_AUTOSTART (default: %(default)s)') help='SIH airframe SYS_AUTOSTART (default: %(default)s)')
parser.add_argument('--board-dev', default='/dev/ttyACM0',
help='mavlink device name ON the board for stream '
'commands (default: %(default)s)')
parser.add_argument('--alt', type=float, default=20.0, parser.add_argument('--alt', type=float, default=20.0,
help='takeoff/waypoint altitude AMSL-relative m ' help='takeoff/waypoint altitude AMSL-relative m '
'(default: %(default)s)') '(default: %(default)s)')
parser.add_argument('--viewer', action='store_true',
help='tee MAVLink to UDP and enable SIH viewer streams '
'(watch with: hawkeye -udp 19410 -mc)')
parser.add_argument('--viewer-port', type=int, default=19410)
parser.add_argument('--keep-config', action='store_true', parser.add_argument('--keep-config', action='store_true',
help='stay on the SIH airframe when done') help='stay on the SIH airframe when done')
parser.add_argument('--expect-hash', metavar='PREFIX', default=None, parser.add_argument('--expect-hash', metavar='PREFIX', default=None,
@@ -437,10 +426,6 @@ def main():
if original_autostart is None or report.num_failed > 0: if original_autostart is None or report.num_failed > 0:
return report.finish() return report.finish()
if args.viewer:
px4bench.attach_viewer_tee(mav, port=args.viewer_port)
report.info('viewer tee on udp:127.0.0.1:{}'.format(args.viewer_port))
# One shell session for the whole flight, torn down in finally so an # One shell session for the whole flight, torn down in finally so an
# error path never leaks the firmware nsh task. # error path never leaks the firmware nsh task.
shell = MavlinkShell(mav) shell = MavlinkShell(mav)
@@ -448,15 +433,6 @@ def main():
report.fail('shell', 'could not open nsh shell') report.fail('shell', 'could not open nsh shell')
return report.finish() return report.finish()
try: try:
if args.viewer:
for cmd in ('mavlink stream -d {} -s HIL_STATE_QUATERNION -r 25'
.format(args.board_dev),
'mavlink stream -d {} -s HIL_ACTUATOR_CONTROLS -r 200'
.format(args.board_dev)):
shell_cmd(report, shell, cmd, 'viewer_stream')
report.info('viewer streams on; watch with: hawkeye -udp {} -mc'
.format(args.viewer_port))
ok = fly(report, mav, shell, args.alt, report_dir) ok = fly(report, mav, shell, args.alt, report_dir)
if not ok: if not ok:
# Best effort: never leave a (simulated) vehicle armed. # Best effort: never leave a (simulated) vehicle armed.

View File

@@ -88,13 +88,6 @@ The flight log is downloaded into the report directory automatically for post-fl
Real outputs are replaced by `pwm_out_sim` in this mode, so nothing is driven on the output rails; still, run it only on a bare bench board with nothing connected to the outputs. Real outputs are replaced by `pwm_out_sim` in this mode, so nothing is driven on the output rails; still, run it only on a bare bench board with nothing connected to the outputs.
The firmware must be built with `CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y` (boards may provide a bench variant that adds it, such as `px4_fmu-v6xrt_bench`). The firmware must be built with `CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y` (boards may provide a bench variant that adds it, such as `px4_fmu-v6xrt_bench`).
To watch the flight live in 3D, install [Hawkeye](https://github.com/PX4/Hawkeye) and run the test with `--viewer`:
```sh
hawkeye -udp 19410 -mc &
./sih/flight_mission.py /dev/ttyACM0 --viewer
```
## Baseline Comparison ## Baseline Comparison
`boot_health` can diff two report directories, comparing uORB publication rates, work queues, and topics between runs: `boot_health` can diff two report directories, comparing uORB publication rates, work queues, and topics between runs: