Skip to main content

mmwcore

mmwcore decodes captured and live mmWave data for offline training and real-time inference. Its boundary starts at caller-owned bytes plus explicit physical contracts, then produces range-Doppler cubes, detections, calibrated point clouds, clusters, tracks, and vital-sign products.

PyPI crates.io docs.rs CI License

Install

CPython 3.12–3.14:

pip install mmwcore

Rust 1.85 or newer:

cargo add mmwcore

Input boundary

Maintained inputs are:

  • archived DCA1000 datagrams;
  • headerless int16 ADC files with an explicit frame contract;
  • completed versioned capture directories opened with open_capture;
  • finite mmwcli.capture_stream.v1 data supplied through a caller-owned BinaryIO;
  • published radar-plus-camera sessions opened with open_multisensor_capture;
  • finite mmwcli.multisensor_stream.v1 data opened with open_multisensor_stream.
mmwcli output mmwcore entry point Typical use
radar capture-session directory open_capture reproducible offline radar processing
radar --stream stdout open_capture_stream pull-driven real-time radar inference
radar-plus-camera session directory open_multisensor_capture training data, indexed source access, and causal joins
aggregate --stream stdout open_multisensor_stream provisional multi-sensor inference followed by COMMIT/EOF validation

The matching acquisition commands and camera-producer workflow are documented by mmwcli and its multi-sensor guide.

The library does not configure devices, render firmware commands, or manage live acquisition. Callers must supply ADC layout, frame geometry, timing, antenna geometry, and trusted packet/frame origins when the stored format does not prove them.

TI capture contracts

  • group2_i_then_q: complex16 two-lane layout documented by the TI mmWave Studio reader for xWR16xx, xWR18xx, and xWR68xx captures.
  • group4_i_then_q: complex16 four-lane, channel-interleaved layout documented by the TI mmWave Studio reader for xWR12xx and xWR14xx captures.
  • Source-backed antenna geometries: XWR1642, standard XWR1843 EVM, IWR6843ISK, IWR6843 AOP, and AWR1843 AOP.

These explicit decoders and geometry presets are usable only when the caller proves the actual layout and board. Versioned mmwcli directory and stream v1 readers accept the three closed family tuples family=xwr16xx, family=xwr18xx, and family=xwr68xx; each also requires vendor=ti, empty model/revision, identity_source=route_declaration, config_format=ti_mmwave_legacy_cli.v1, dtype=int16, byte_order=little, lane_count=2, and layout=group2_i_then_q.

The embedded legacy CFG must match the declared family: xWR16xx uses the 76–81 GHz range and up to two TX identifiers, xWR18xx uses 76–81 GHz and up to three, and xWR68xx uses 57–64 GHz and up to three. Chirp order determines the explicit tx_order; no family selects antenna geometry or a preset. The standalone TI CLI parser likewise requires an explicit family keyword and has no default. ADCFileCapture.raw_capture and CaptureStreamContract.raw_capture expose the declared tuple, but decoder acceptance does not claim that an mmwcli acquisition route has been validated. route_declaration is not an observed device identity. See the mmwcli hardware-support matrix.

Python examples

The repository includes complete command-line examples that consume files or binary stdin and never start hardware:

Workflow Example
capture directory or explicit raw frames capture_or_raw.py
explicit xWR18xx/XWR1843 EVM geometry and recipe xwr18_range_doppler.py
finite radar live stream radar_live_stream.py
multi-sensor offline training pairs multisensor_offline_training.py
multi-sensor provisional live inference multisensor_live_inference.py

See the example index for copyable commands and finalization semantics.

Open a versioned capture directory

open_capture validates the manifest schema, required regular files, hashes, byte count, and finite physical contract. The directory must remain unchanged while it is open.

from mmwcore import open_capture

capture = open_capture("capture-session")
raw = capture.frame(0)
print(capture.raw_capture.family, raw.samples.shape)

The hash proves internal consistency, not provenance. A supplied preset is the caller's explicit declaration of a processing contract; the route-declared manifest does not identify or guess a board. Pass an exact RangeDopplerRecipe or callable preset to open_capture(..., range_doppler=...) when Range-Doppler processing is wanted. Built-in board presets are conveniences, not family defaults.

Process a finite capture stream

import mmwcore

stream = mmwcore.open_capture_stream(source)  # caller-owned BinaryIO
for item in stream.frames():
    infer(item.frame, stream.contract.radar_capture)
commit = stream.require_commit()

Frames remain provisional until require_commit validates COMMIT and terminal EOF. mmwcore neither closes the source nor opens a process, socket, or device. The source must make read honor any required deadline or cancellation. Processing is synchronous and pull-driven, without prefetch or worker threads.

Train from synchronized radar and camera data

from mmwcore import open_multisensor_capture

session = open_multisensor_capture("training-session")
radar = session.source("radar-0")
radar_capture = radar.open_radar_capture()
for camera_item, radar_item in session.causal_pairs(
    "camera-0", "radar-0", lag_min_ns=0, lag_max_ns=50_000_000
):
    train(
        camera_item.payload,
        radar_capture.frame(radar_item.item_index),
    )

The join uses conservative mapped time intervals, not equal frame numbers or nearest arrival time. If training needs Range-Doppler cubes instead of raw frames, bind the exact recipe or preset through open_radar_capture(range_doppler=...) and call range_doppler. Choose processing geometry from the actual board, never from the family string alone.

Consume a live aggregate stream

from mmwcore import open_multisensor_stream

stream = open_multisensor_stream(source)  # caller-owned BinaryIO
provisional = list(stream.items())
commit = stream.require_commit()
accepted = [item for item in provisional if commit.accepts(item)]

Radar and delivery_observed camera items expose mapped_time on the same host-relative axis. A camera exposure_midpoint remains unmapped in the live stream unless the producer supplies a live mapping; mmwcore never substitutes delivery time for exposure time. Items and derived results remain provisional until global COMMIT and EOF.

Read a headerless ADC file

from mmwcore.core import ADCComplexLayout, ADCFrameSpec
from mmwcore.io import ADCFileFrameReader

spec = ADCFrameSpec(
    num_chirps=2,
    num_rx=4,
    num_samples=128,
    layout=ADCComplexLayout.GROUP2_I_THEN_Q,
)
reader = ADCFileFrameReader("adc.bin", spec, frame_periodicity_s=0.01)
raw = reader.read_frame(0)
print(raw.samples.shape)

ADCFileFrameReader rejects incomplete files by default and reads frames without loading the full capture.

Assemble archived datagrams

from mmwcore.core import ADCFrameSpec
from mmwcore.io import assemble_dca1000_frame_bytes

spec = ADCFrameSpec(num_chirps=1, num_rx=1, num_samples=2)
raw, stats = assemble_dca1000_frame_bytes(
    [datagram_0, datagram_1],
    spec,
    frame_start_byte_count=trusted_frame_origin,
    payload_values_per_packet=2,
)

Stateless assembly requires exactly one complete frame: fixed payload lengths, contiguous u48 byte slots, and contiguous wrapping u32 packet numbers. frame_start_byte_count must come from the capture lifecycle; it is never inferred from the first packet or a modulo guess.

Continue to point clouds and tracks

Use an explicit PointCloudRecipe with process_adc_to_calibrated_point_cloud, then cluster_point_cloud and ClusterTracker2D. Source-backed geometry helpers cover XWR1642, standard XWR1843 EVM, IWR6843ISK, IWR6843 AOP, and AWR1843 AOP; the IWR6843 processing recipes are one optional preset family, not the mmwcore input boundary. Thresholds, calibration, Tx order, and tracker timing remain explicit. Keep one tracker instance for a sequence; recreating it discards temporal state.

Rust example

use mmwcore::{AdcComplexLayout, AdcFrameSpec, decode_adc_i16};

let spec = AdcFrameSpec::new(1, 1, 2, AdcComplexLayout::Group2IThenQ).expect("valid spec");
let cube = decode_adc_i16(&[1, 2, 3, 4], spec, false).expect("valid captured payload");
assert_eq!(cube.shape(), [1, 1, 1, 2]);

Package map

  • mmwcore.core: axes, units, ADC, cube, detection, point-cloud, and tracking contracts.
  • mmwcore.config: finite radar profiles, capture contracts, antenna geometries, and recipes.
  • mmwcore.io: packet, ADC-file, radar/multi-sensor directory, and finite live-stream readers.
  • mmwcore.dsp: FFT, clutter removal, CFAR, calibration, AoA, projection, and clustering.
  • mmwcore.tracking: assignment, stateful trackers, runners, metrics, and validation artifacts.
  • mmwcore.plot: optional research visualizations outside the Rust compute core.

Validation boundaries

The retained laboratory capture used for the figures below has 5000 frames, 2 chirps, 4 receivers, 128 complex samples, group2_i_then_q, and a 10 ms period. It lacks slope and sample-rate metadata, so range remains in bins. The source capture is not distributed; the figures are evidence, not a runnable fixture.

Range-Time magnitude before and after temporal-background suppression

Raw ADC I/Q and four-receiver range spectra

Synthetic tests verify shapes, axes, finite values, wrap behavior, and deterministic transforms. They do not prove a board configuration, capture provenance, universal thresholds, or performance superiority. Device documentation and redistributable reference vectors remain authoritative.

Benchmarks and development

The reproducible synthetic pipeline, workload contract, and comparison rules are documented in docs/benchmarking.md.

uv sync --extra dev --locked
uv run pytest --cov=mmwcore
cargo test --workspace --locked
uv run python benchmarks/pipeline.py --warmups 0 --samples 1 --stream-frames 2

See CONTRIBUTING.md and docs/architecture.md.

License

Apache-2.0. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mmwcore-0.3.0.tar.gz (191.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

mmwcore-0.3.0-cp314-cp314-win_amd64.whl (907.7 kB view details)

Uploaded CPython 3.14Windows x86-64

mmwcore-0.3.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

mmwcore-0.3.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded CPython 3.14macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

mmwcore-0.3.0-cp313-cp313-win_amd64.whl (906.3 kB view details)

Uploaded CPython 3.13Windows x86-64

mmwcore-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

mmwcore-0.3.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded CPython 3.13macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

mmwcore-0.3.0-cp312-cp312-win_amd64.whl (906.7 kB view details)

Uploaded CPython 3.12Windows x86-64

mmwcore-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

mmwcore-0.3.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded CPython 3.12macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file mmwcore-0.3.0.tar.gz.

File metadata

  • Download URL: mmwcore-0.3.0.tar.gz
  • Upload date:
  • Size: 191.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mmwcore-0.3.0.tar.gz
Algorithm Hash digest
SHA256 70f93c9a46351fc1d67a4f4112bd34f56d46099460c18939030ce3b0a07953ca
MD5 e4ea1e2872705f2d55137d17fe399bb8
BLAKE2b-256 d0e13173e22423806f2b4b7cfde7512137e9f2c9bf2177d200b3113593213efb

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0.tar.gz:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: mmwcore-0.3.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 907.7 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mmwcore-0.3.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 c7abffafce4a0a07f25a89d0fceb2dcb3fe150aea0c899ef441ae78b2c9c14f0
MD5 da3baacde42b0bb70796d7be3fdbba3f
BLAKE2b-256 a8af79ae419a6d022406f9b01c35b21beb577a72daafee0b4182f4fcded90e80

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp314-cp314-win_amd64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3db9dbb74e8075f8bce17ace5d3687cf5edd1a61485f9c2743d1100faba00707
MD5 63d441e849e34fc11b23872c1728b2fc
BLAKE2b-256 eb21f6d4d190d071066ddf82f0e160da462c7396566618cce5c1cda7da7d9e4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 f00c587bb1c61a9c496ec5fc330da3fcd283c2b47f4ae748a53766640c5b1950
MD5 2eba947815a0658e34983afb8f006be0
BLAKE2b-256 a3b369bd7f23ab46d1b548ea0a075ec835f48d80dd7cdbdb5faf838e0e572f71

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: mmwcore-0.3.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 906.3 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mmwcore-0.3.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 467ccd2dcada10b020f7ec374887ea58c0d3e2a9d7a82bbe0c1537834994b665
MD5 526f424da06b93088fdaa85bdb8c3f1a
BLAKE2b-256 1ba14142e701ea632556d364341dfb7ed453f2e88347eab3b53c8972bb1fd877

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp313-cp313-win_amd64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2909eab3ddda112a6cfb1ed90c61dfd63d42de677e16512a19b3c0d22c86747f
MD5 aa6f556d5d2dcac09e904e67a2a2e6fb
BLAKE2b-256 e1f63a33064c31ff34425d2b2808c9c09ffcfc0980e0021ef99ae63526cc332d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 e0c3c47093b366b03415af86004aa34c28e99d3b7693cde61bc725e6e8f81d7f
MD5 a6dd828ec0451294fa53bc1e2e6f0444
BLAKE2b-256 baaec04b9e40f488f4bd7afd0a52ff4adb308b9dc881bbcdb55de2907585e6ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: mmwcore-0.3.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 906.7 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mmwcore-0.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 fa5eea1817df014f070a82d20dbf4b377d4ca0dba25813c01d49bb5f0687d7c3
MD5 37c988f3ac5a2df97c8f809e9f39c224
BLAKE2b-256 4aaa3c6aa4c11e6f5e07b4a70b00a851e226011551a3937413a2be69617b809c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp312-cp312-win_amd64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 905de0d568f70c6e11df9817c2896be9766c7b636068d619586b9cef2d6cf74e
MD5 f186cf148a69dff53f9847e00943a331
BLAKE2b-256 7d6db1298ef6e4c80b83cdf57b1307958386402ab393bd022e04d5aa715a2b2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mmwcore-0.3.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for mmwcore-0.3.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 2768608b00f841e41f926f07724be1ed014f01fab0cb01010685bf371e2ad2f6
MD5 1bfbd7f8c2991a15cb91c5b00e2185d6
BLAKE2b-256 066793b4a58c9204e8315c6adaa513ba85e3ce124c865fdc72ebf326fff938c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for mmwcore-0.3.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on AIoT-Laboratory/mmwcore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page