rec · bench 04t+00:00.0

Accelerate your hardware development by 10x

Go from test to root cause in hours, not weeks

Test faster Debug faster Learn faster Iterate faster
00 / Platform

Connect any hardware, run any test, understand everything that happens

01Connect & configure

Plug it in. It is already talking to Phloem.

Phloem automatically discovers DAQ units, SCPI instruments and other bench hardware. No configuration files. No driver hunting.

  • Automatic device detection
  • Any hardware, any protocol
discovery · bench 04scanning
nidaqmxNI cDAQ-9178 · 16 ch analog indetected
scpiRigol DP832 · programmable psudetected
labjackLabJack T7 · 14 ch mixed iodetected
ethernetipAllen-Bradley PLC · valve bankdetected
cancan0 · powertrain.dbc · 42 signalsdecoding
video/cam/pad · 1080p60 h.264streaming
74 channels live · named, typed, with units — zero config files
02Monitor

Watch the run as it happens.

See telemetry, video, point clouds, and more on a single timeline—live, while the test is running. No manual clock alignment.

live · wall 04 · one timeline1 MS/s
/motor/thrust_clean128.4 kN
/cam/pad60 fps
/lidar/points10 Hz
/mav/attitude/roll+2.1°
/motor/chamber_pressure_bar70.9 bar
/case/vib_spectrum · fft312 Hz
  • Real-time visualization across every modality
  • Automatic time synchronization, with no manual alignment
  • Watch any machine on the network, from anywhere
03Control and command

Phloem runs the test, not just the data.

Automate deterministic test sequences with local safety loops and abort conditions—even offline. The same sequence produces the same result, every time.

  • Deterministic test execution
  • Distributed benches, local or across sites
  • Full traceability for every run
sequence · static_fire_r7armed
01purge.hold(duration=30s)pass
02psu.limit(current=2.0A)pass
03interlock.require("/pad/deluge_ok")healthy
04chamber.redline(hi=78bar, abort=vent)amber 70.8
05igniter.arm() → fire()held
06record.context(build, operator, config)captured
local safety loop 250 ms · abort conditions armed · runs offline
04Analysis

Understand what happened during the test.

Replay any run with telemetry, video, and events synced to the same timeline. Compare against historical runs to pinpoint changes in configuration, signals, and outcomes.

  • Synchronized replay across all data, video and events
  • Compare any test run against history
  • Automated reporting
replay · run 118 vs historyt+41.8s
run 118 · unit 3today · 214 s
run 117 · unit 2aug 28 · 212 s
run 116 · unit 1aug 21 · 209 s
run 112 · cold flowaug 14 · 96 s
run 110 · qual blockaug 9 · 204 s
/motor/thrust_clean
/motor/chamber_pressure_bar
/cam/pad
events · cmd + verdicts
ignition transientchug 41 Hztail-off long
05Artificial intelligence

Ask why. Get answers backed by your test history.

Ask questions in plain language and get answers based on your actual test history. Every answer traces back to the underlying evidence, not a generic hypothesis.

  • Root cause analysis across every run
  • Context across systems, software, and hardware
agent · run 118 post-test3 citations
Why did unit 3's tail-off run 1.9 s long?
phloem

Pressure and thrust decay together after t+96 s at 2.3× the historical mean — residual impulse after burnout, not a sensor artifact. Run 96 showed the same signature; borescope confirmed throat erosion.

/motor/thrust_clean · t+90 → t+112 s · run 118 vs history
evidencerun 118run 117 · config diffrun 96 · tag + fix
01 / Trellis

Write the test stand — or let AI write it. Deploy. The engine keeps it safe.

A few lines describe the stand: what you read, what you command, where it must stop. Deploy, and a sealed engine on the machine takes it from there.

hotfire · Codecompiles · 0 problems
setup("hotfire")
ch = channels()
pc = ch.read("/stand/chamber_bar", unit="bar",
             limits=limits(hi=70, hihi=78), checks=True)
ch.write("/stand/main_valve", dtype="bool", safe=False)

interlock(name="overpressure",
    when=lambda: pc > 78,
    then=[set(ch["/stand/main_valve"], False)])

step("fire",
    step("purge",  set(ch["/stand/purge"], True),      hold("30s")),
    step("ignite", set(ch["/stand/main_valve"], True), hold("8s")),
    safe=safe())

page("Hotfire", layout=col(
    row(gauge(pc), toggle(ch["/stand/main_valve"])),
    row(alerts(), log())))
one parser · verdict on every tick · deploy is a compare-and-set
Hotfire · Paneldeployed · armed
/stand/chamber_bargauge64.2bar
/stand/main_valvetoggleopensafe = False
procedure · firerunning
purge · hold 30sdone
ignite · hold 8s00:05
alerts0 trippedoverpressure · watching
log
12:04:31ignite · started12:04:01purge · held 30s12:03:58deployed hotfire@3f1c
Stop or Shift+Esc drives every output safe · latched until Reset
Safety loopOn the machine

No window, link or cloud in the loop.

Trip to safeIn milliseconds

Interlocks act, then latch until Reset.

DeterministicOne engine, one verdict

Same channels in, same verdict out.

02 / Deployment

Run where your hardware is

Phloem runs entirely within your infrastructure, even without an internet connection. Your systems and data stay on site, with syncing enabled only when you choose.

infrastructureDeploy on premise or in your private cloud
connectivityNo internet connection required
dataYour test data stays within your infrastructure
aiRun AI on premise alongside your systems
your site boundary
Bench 01DAQ · PLC
Bench 02SCPI · autopilot
Vehiclecameras · CAN
Phloem Edgerecords + runs tests · offline-first
Phloem Cloud · on air gap, on cloud, anywhereevery run · SQL · replay · AI
external syncoff by default — you choose
03 / Integrations

Speak your stack

Phloem works with the hardware, protocols, and data formats you already use. No need to change your stack.

ROS bagMCAPMAVLinkCAN / candumpCSVSCPINI DAQEthernet DAQ / DACVideoPoint clouds
open architecture · extensions NI DAQmx LabVIEW FlexLogger LabJack OPC UA MATLAB Python ArduPilot Gazebo Isaac Sim
Get started

Build your hardware at software speed

Book a demo