Interface contract:
carbon-interfacev1.5.6 — unchanged from v0.17.1.
Firmware compatibility: install FPGA v1.5.6 / MCU v4.1.0 with the v7.1.X
bringup script / updater. Not compatible with FPGA v1.3.3 / MCU v2.6.0 or older.
The first stable release. Recordings move to a new native .vynt format, installation
no longer builds Cap'n Proto from source, the shipped command-line tools drop their
carbon qualifier, and the Python and C++ surfaces are tidied for 1.0. Recordings made
before v1.0.0 need a one-time conversion, and the whole toolchain has to be updated
together — pre-v1.0.0 tools cannot read the new files.
Breaking Changes
Recordings
- New
.vyntrecording format. It replaces the Cap'n Proto-based format used
through v0.17.1. Recordings made before v1.0.0 are rejected when opened rather than
misparsed — convert them once: the visualizer offers the conversion when you open an
old recording, or script it with the newvoyant_recording_migratetool. - Pre-v1.0.0 tools open v1.0.0 recordings as empty — no frames, and no error
explaining why. Update the visualizer, CLI tools, and bindings together. - Old raw-peak CSV captures are unsupported. There is no converter; re-capture, or
reach out to Voyant support about updating existing captures.
Installation
- Cap'n Proto is no longer a build dependency. The
voyant-api-devpackage, the
Python wheel, and the ROS driver all install without building it from source.
Command-line tools
- Shipped tools lose their
carbonqualifier:voyant_carbon_client_check→
voyant_client_check,voyant_carbon_simulator→voyant_simulator, and likewise
for the rest. The old names are gone, so scripts that call them need updating. - The recorder's buffer-size knob is removed — the buffer now sizes itself. This
dropsvoyant_logger_binary --buffer-size-mb, the Pythonbuffer_size_mbargument,
and the C++bufferSizeMbfield. The dead--send-buffer-sizeflag is also gone
from the client tools. - The CSV converters (
voyant_bin_to_csv/voyant_csv_to_bin) are now
internal-only and no longer publicly documented. For analysis exports, use the
Python bindings'points()matrix or the ROS driver. voyant_hello_worldprints the interface-contract version rather than a proto
version.
Python
points()returns a different column set.- The per-field accessor families and the
voyant_api.utilscompatibility shim are
removed. describe()returns a string instead of printing.- The fourth column of
xyzv()is renamed fromradial_veltodoppler_mps. valid_mask()returns a NumPy boolean array.- Playback's
filter_pointsbecomeskeep_invalid_points; the PCD helper's
valid_onlylikewise. - The client config's
set_keep_invalid_pointsbecomesset_diagnostic_mode
(capture-side only — the playback-sidekeep_invalid_pointsflags keep their name). VoyantClientis removed.- The public peak-dump API (the
start_peak_dumpfamily) is replaced by diagnostic
capture. - The elevation-interpolation options are removed from the client config
(set_missing_elevations,set_interp_range_threshold,
set_interp_doppler_threshold) along with the pipeline stage behind them. The
feature was off by default.
C++
- Frames are the native
VoyantFrameclass rather than the Cap'n Proto
VoyantFrameWrapper:tryReceiveFrame()returnsstd::optional<VoyantFrame>
directly and the separatelatestFrame()accessor is gone; point data is read
throughpoints()/xyz(), and state throughsensorState()/hostState(). VoyantClientandPointsClientare removed.- Playback's
filter_pointsbecomeskeep_invalid_points, and its default is no
longer inverted. CarbonConfig::setKeepInvalidPointsbecomessetDiagnosticMode(capture-side only —
the playback-sidekeepInvalidPointsflag keeps its name).- The peak-dump API is replaced by diagnostic capture.
- The elevation-interpolation setters are removed from
CarbonConfig
(setMissingElevations,setInterpRangeThreshold,setInterpDopplerThreshold),
along with the pipeline stage behind them. The feature was off by default. voyant_playback_is_file_openis removed from the C FFI with no C++ replacement.
Python keepsis_open.- C FFI only, no C++ change:
voyant_recorder_creategained error output parameters,
matchingvoyant_playback_open_file.
New Features
voyant_recording_migrateconverts pre-v1.0.0 recordings to.vynt.- Diagnostic capture records a support bundle for Voyant support: a recording that
keeps invalid points, paired with a raw-peaks sidecar file. It replaces the old
peak-dump tooling in the visualizer and both bindings. - Edit a recording and save it back. Read frames, change their points, and write a
new recording — including a per-pointuser_datacolumn that native recordings
preserve verbatim. - Build frames from your own points. Both bindings can now create synthetic frames
(identified by a simulator device id) and stateless frames, for points that arrive
without a sensor heartbeat behind them — a simulator scene, a ROS cloud, a CSV. - Sensor and host state are readable from a frame —
sensor_state()/
host_state()in Python,sensorState()/hostState()in C++. - The API and interface-contract versions are readable from both bindings,
mirroring whatvoyant_hello_worldprints. - The recorder reports the file it is writing — the
current_file_pathproperty
in Python,getCurrentFilePath()in C++ — with timestamped and split naming
resolved, so a file that has to pair with a recording can be named from it. - Visualizer: new color-by-field modes with in-panel legends, a marker highlighting
picked points, combine-method and user-data rows in the point inspector, and a
recording can be opened straight from the command line with--input. The
pre-release banner is gone. - C++ additions:
setPointsXyz(), the supported inverse ofVoyantFrame::xyz()
for points that arrive as x/y/z, andVoyantRecorder::getLastError(), so an invalid
recorder can say why it is invalid rather than only that it is.
Behavior Changes
- An existing recording is no longer overwritten unless you opt in. Recording to a
path that already exists fails instead of clobbering it. - Unusable playback rates play unpaced. A playback rate of zero, or one that is
negative, non-finite, or below 0.001×, plays as fast as possible and logs a warning.
Bug Fixes
- Returns between the mirror center and the lidar datum are no longer recorded as
valid points at a negative range. The range sanity check ran before the datum
shift, so a near-field return that was valid at the mirror could land behind the
datum and still be reported as valid. It is now checked on both sides of the shift
and dropped. Point counts fall very slightly as a result — measured at roughly
0.008–0.016% of otherwise-valid points on a Carbon 30 — and reflections from inside
the sensor housing no longer appear in point clouds. - Fixed a use-after-free in the C++ recorder, where finalizing and then destroying
a recorder freed the same resources twice.