v1.0.0 (New Recording Format & Stable API)
View this release on GitHub → Release Date: August 26, 2026
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.
A step-by-step migration guide covers converting recordings and moving scripts and code to the new tools and Python/C++ APIs.
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.
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 drops
voyant_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 are now internal-only and no longer publicly documented. For analysis exports, use the Python bindings’
points()matrix or the voyant-ros repository; see Retired Tools. 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’svalid_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 ProtoVoyantFrameWrapper: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-point
user_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 what
voyant_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.
Documentation
For comprehensive documentation, examples, and installation instructions, visit our documentation site.
Feedback
We value your feedback! If you encounter issues or have suggestions for improvements, please see our troubleshooting guide for the best options for getting in touch with us.