Feature: nativemodule livox and fastlio2#1235
Conversation
…notations` The future annotations import made Out[PointCloud2] and Out[Imu] lazy strings, preventing the Module metaclass from creating real port descriptors. Move type imports out of TYPE_CHECKING block so ports are properly resolved at class definition time.
Livox-specific module (LivoxLidarModule, LivoxLidarModuleConfig) now lives in dimos/hardware/sensors/lidar/livox/module.py alongside the driver and SDK code. Generic LidarModule stays in the parent.
Greptile OverviewGreptile SummaryThis PR introduces a comprehensive NativeModule framework that enables C++ executables to participate in the dimos blueprint system, plus native drivers for Livox Mid-360 LiDAR and FAST-LIO2 SLAM. Key Changes:
Architecture:
Test Coverage:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Python as Python NativeModule
participant Subprocess as C++ Binary
participant LivoxSDK as Livox SDK2
participant FASTLIO as FAST-LIO2
participant LCM as LCM Bus
Python->>Python: start() - collect port topics
Python->>Subprocess: spawn with --port topic args
Subprocess->>Subprocess: parse CLI args (dimos_native_module.hpp)
Subprocess->>LivoxSDK: init SDK with memfd config
Subprocess->>LCM: initialize publisher
alt Mid360 Driver
LivoxSDK->>Subprocess: on_point_cloud(raw packets)
Subprocess->>Subprocess: accumulate points in buffer
loop Every 1/frequency seconds
Subprocess->>LCM: publish PointCloud2
end
LivoxSDK->>Subprocess: on_imu_data(IMU packets)
Subprocess->>LCM: publish Imu (immediately)
else FAST-LIO2
LivoxSDK->>Subprocess: on_point_cloud(raw packets)
Subprocess->>Subprocess: accumulate CustomMsg points
LivoxSDK->>Subprocess: on_imu_data(IMU)
Subprocess->>FASTLIO: feed_imu(imu_msg)
loop Main processing loop
Subprocess->>FASTLIO: feed_lidar(accumulated points)
FASTLIO->>FASTLIO: EKF-LOAM SLAM
FASTLIO->>Subprocess: return registered cloud + odometry
Subprocess->>Subprocess: voxel filter + outlier removal
Subprocess->>LCM: publish PointCloud2 (world frame)
Subprocess->>LCM: publish Odometry
opt Global Map Enabled
Subprocess->>Subprocess: VoxelMap.insert(cloud)
Subprocess->>Subprocess: VoxelMap.raycast_clear()
Subprocess->>LCM: publish global_map PointCloud2
end
end
end
Python->>Subprocess: SIGTERM (on stop())
Subprocess->>LivoxSDK: shutdown
Subprocess->>Subprocess: exit
Python->>Python: wait for exit + cleanup
Last reviewed commit: af4e732 |
Integrates FAST-LIO-NON-ROS directly with Livox SDK2 as a dimos NativeModule. The C++ binary feeds live LiDAR/IMU data into FAST-LIO's EKF-LOAM SLAM and publishes aggregated world-frame point clouds and odometry over LCM. Includes rate-limited output (pointcloud_freq, odom_freq), Odometry.to_rerun() for visualization, and nix flake deps.
Add standalone nix flakes to build native C++ modules with all dependencies (Livox SDK2, LCM, PCL, etc.) from nix, avoiding glibc version conflicts. CMakeLists.txt now accepts FASTLIO_DIR as an external parameter for hermetic nix builds.
…n flake Move livox flake.nix into cpp/ for consistency with fastlio2. Add cmake install() rules with default prefix=result so both nix and cmake produce binaries at cpp/result/bin/. Remove livox-sdk and lidar deps from main flake since native modules build via their own standalone flakes.
# Conflicts: # dimos/core/__init__.py # dimos/robot/all_blueprints.py # dimos/robot/unitree_webrtc/unitree_go2_blueprints.py
- Add generic type param to NativeModule (Module[NativeModuleConfig]) - Add Any import and type annotations to NativeModule.__init__ - Fix ModuleConfig import in lidar module - Fix FastLio2Module -> FastLio2 import in test - Rename test_spec_compliance.py to test_spec.py across lidar modules - Adjust fastlio2 voxel_size from 0.25 to 0.15
Resolved conflict in Odometry.py: kept dev's refactored class structure and added to_rerun() method from feat/livox.
Resolved conflicts: kept to_rerun() in Odometry.py, took dev's updated doc paths in modules.md.
true, this can host docker very easily.. wrote some docs, and yeah autobuild sounds good, just wanted to keep the PR smaller, pretty big already
|
| class MyConfig(NativeModuleConfig): | ||
| executable: str = "./build/my_module" # relative or absolute path to your executable | ||
| host_ip: str = "192.168.1.5" # becomes --host_ip 192.168.1.5 | ||
| frequency: float = 10.0 # becomes --frequency 10.0 | ||
| enable_imu: bool = True # becomes --enable_imu true | ||
| filters: list[str] = field(default_factory=lambda: ["a", "b"]) # becomes --filters a,b | ||
| ``` | ||
|
|
||
| - `None` values are skipped. | ||
| - Booleans are lowercased (`true`/`false`). | ||
| - Lists are comma-joined. |
There was a problem hiding this comment.
It's probably safer to pass it as JSON.
There was a problem hiding this comment.
Yeah or ENV actually, given this would make it compatible with Docker modules, need to coordinate this a bit, IMO this is a POC, wanted to create an issue and discuss
dimos/core/native_module.py
Outdated
| self._io_threads = [ | ||
| self._start_reader(self._process.stdout, "info"), | ||
| self._start_reader(self._process.stderr, "warning"), | ||
| ] |
There was a problem hiding this comment.
It's a bit wasteful to start two extra threads just to pipe two streams. You can do everything from the watchdog thread.
There was a problem hiding this comment.
I've put management of these threads in the watchdog, but the code gets really ugly if I try to process everything in the same thread, so keeping split for ease of undertanding now
Remove runtime assert_implements_protocol and test_spec files. Instead, add TYPE_CHECKING instantiation at the bottom of each module file so mypy catches missing or misnamed protocol ports statically.
Move reader thread spawning into the watchdog thread so only one thread is externally managed. Use tmp_path pytest fixture instead of manual tempfile. Use communicate() for build subprocess.
Use argparse in native_echo.py instead of env vars for output_file and die_after. Add these as config fields on StubNativeConfig so they flow through the normal to_cli_args() path.
Replace NATIVE_ECHO_OUTPUT/NATIVE_ECHO_DIE_AFTER env vars with output_file/die_after config fields passed as CLI args. Add type annotations to test functions. Remove stale type: ignore on NativeModule.default_config.
# Conflicts: # dimos/robot/all_blueprints.py
Release v0.0.10: Manipulation Stack, MuJoCo Simulation, DDS Transport, Web and Native Visualization via Rerun ## Highlights 88+ commits, 20 contributors, 700+ files changed. The TLDR: **a complete manipulation stack**, **MuJoCo simulation**, **DDS transport**, and **a rewritten visualization pipeline**. Agents are no longer bolted on top — they're refactored as native modules with direct stream access. The entire ROS message dependency has been removed from core DimOS, and we've added VR, phone, and arm teleoperation stacks. You can now vibecode a pick-and-place task from natural language to motor commands. Installation has been significantly streamlined — no more direnv, simpler setup, and the web viewer is now the default. --- ## 🚀 New Features ### Simulation - **MuJoCo simulation module** — Run any DimOS blueprint in simulation with no hardware. Supports xArm and Unitree embodiments, parses MJCF/URDF for robot properties, monotonic clock timing (no `time.sleep`). `dimos --simulation run unitree-go2` ([#1035](#1035)) by @jca0 - **Simulation teleop blueprints** — Added simulation teleop blueprints for Piper, xArm6, and xArm7. ([#1308](#1308)) by @mustafab0 ### Manipulation - **Modular manipulation stack** — Full planning stack with Drake: FK/IK solvers (Jacobian + Drake optimization), RRT path planning, world model with obstacle monitoring, multi-robot management. xArm6/7 and Piper support. ([#1079](#1079)) by @mustafab0 - **Joint servo and cartesian controllers** — Joint position/velocity controllers and cartesian IK task with Pinocchio solver. PoseStamped stream input for real-time control. ([#1116](#1116)) by @mustafab0 - **GraspGen integration** — Grasp generation via Docker-hosted GPU model. Lazy container startup, thread-safe init, RPC `generate_grasps()` returns ranked PoseArray. ([#1119](#1119), [#1234](#1234)) by @JalajShuklaSS - **Gripper control** — Gripper RPC methods on control coordinator, exposed adapter property for custom implementations. ([#1213](#1213)) by @mustafab0 - **Detection3D and Object support** — Object input topics, TF support on manipulation module, pointcloud-to-convex-hull for Drake imports. ([#1236](#1236)) by @mustafab0 - **Agentic pick and place** — Reimplemented manipulation skills for agent-driven pick-and-place workflows. ([#1237](#1237)) by @mustafab0 ### Teleoperation - **Quest VR teleoperation** — Full WebXR + Deno bridge stack. Quest controller data (pose, trigger, grip) streamed to DimOS modules. Monitor-style locking for control loops. ([#1215](#1215)) by @ruthwikdasyam - **Phone teleoperation** — Control Go2 from your phone with a web-based teleop interface. ([#1280](#1280)) by @ruthwikdasyam - **Arm teleop with Pinocchio IK** — Single and dual arm teleoperation using Pinocchio inverse kinematics. Blueprints for xArm, Piper, and dual configurations. ([#1246](#1246)) by @ruthwikdasyam ### Transports & Infrastructure - **DDS transport protocol** — CycloneDDS transport with configurable QoS (high-throughput and reliable profiles). Optional install, benchmark integration. ([#1174](#1174)) by @Kaweees - **Pubsub pattern subscriptions** — Glob and regex pattern matching for topic subscriptions. `subscribe_all()` for bridge-style consumers. Topic type encoding in channel strings (`/topic#module.ClassName`). ([#1114](#1114)) by @leshy - **LCM raw bytes passthrough** — Skip `lcm_encode()` when message is already bytes. ([#1223](#1223)) by @leshy - **Unified TimeSeriesStore** — Pluggable backends (InMemory, SQLite, Pickle, PostgreSQL) with SortedKeyList for O(log n) operations. Replaces the old replay system and TimestampedCollection. Collection API with slice, range, and streaming methods. ([#1080](#1080)) by @leshy - **DimosROS benchmark tests** — Benchmark suite for ROS transport performance. ([#1087](#1087)) by @leshy ### Navigation - **FASTLIO2 support** — Hardware-verified localization with arm64 support. Docker deployment with FAR Planner, terrain analysis, and bagfile playback mode. Builds or-tools from source on arm64. ([#1149](#1149)) by @baishibona - **Native Livox + FASTLIO2 module** — First-class DimOS native module for Livox Mid-360 lidar with FASTLIO2 localization. ([#1235](#1235)) by @leshy ### Visualization - **RerunBridge module and CLI** — New bridge that subscribes to all LCM messages and logs those with `to_rerun()` to Rerun viewer. GlobalConfig singleton, web viewer support. Replaces the old rerun initialization system. ([#1154](#1154)) by @leshy - **Webcam rerun visualization** — Camera module logs to Rerun with pinhole projection for 3D visualization. ([#1117](#1117)) by @ruthwikdasyam - **Default viewer switched to rerun-web** — Browser-based viewer is now the default for broader compatibility. No native viewer install needed. ([#1324](#1324)) by @spomichter ### Agents - **Agent refactor** — Restructured agent module with cleaner imports and global config integration. ([#1211](#1211)) by @paul-nechifor - **Timestamp knowledge** — Agents now have timestamp awareness in prompts for temporal reasoning. ([#1093](#1093)) by @ClaireBookworm - **Observe skill** — Go2 can now observe (capture and describe) its environment via agent skill. ([#1109](#1109)) by @paul-nechifor ### Platform & Hardware - **G1 without ROS** — Unitree G1 blueprints decoupled from ROS dependency. Lazy imports for fast startup. ([#1221](#1221)) by @jeff-hykin - **ARM (aarch64) support** — DimOS runs on ARM hardware. Platform-conditional dependencies, open3d source builds for arm64. ([#1229](#1229)) by @jeff-hykin - **Universal joint/hardware schema** — `HardwareComponent` dataclass with `JointState`, `JointName` type aliases. Backend registry with auto-discovery for SDK adapters. ([#1040](#1040), [#1067](#1067)) by @mustafab0 --- ## 🔧 Improvements - **Optional Dask** — Start without Dask using `--no-dask` flag. Startup time reduced from ~60s to ~45s. ([#1111](#1111), [#1232](#1232)) by @paul-nechifor - **RPC rework** — Renamed `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream`. Added `ModuleRef`, improved type hints throughout. ([#1143](#1143)) by @jeff-hykin - **Image class simplification** — Rewritten as pure NumPy dataclass. Removed CUDA backend, unused methods (solve_pnp, csrt_tracker), and image_impls/ directory. ([#1161](#1161)) by @leshy - **Odometry message cleanup** — Simplified Odometry message type. ([#1256](#1256)) by @leshy - **Remove all ROS message dependencies** — Purged ROS message types from core DimOS. Refactored rosnav to use ROSTransport. Removed dead ROS bridge code. ([#1230](#1230)) by @alexlin2 - **Removed bad function serialization** — Eliminated unnecessary serialization of Python functions. ([#1121](#1121)) by @paul-nechifor - **Benchmark IEC units** — Switched bandwidth benchmarks from SI to IEC units for accuracy. ([#1147](#1147)) by @leshy - **Pubsub typing improvements** — Thread-safety locks on `subscribe_new_topics` and `subscribe_all`. Proper type params across pubsub stack. ([#1153](#1153)) by @leshy - **Autogenerated blueprint list** — Blueprints are now auto-discovered and listed. ([#1100](#1100)) by @paul-nechifor - **Generic Buttons message** — Renamed `QuestButtons` to `Buttons` with generic field names for cross-platform teleop. ([#1261](#1261)) by @ruthwikdasyam - **Dev container uses ros-dev image** — `./bin/dev` now runs the ROS-enabled dev image. ([#1170](#1170)) by @leshy - **LSP support** — Added python-lsp-server and python-lsp-ruff to dev dependencies. ([#1169](#1169)) by @leshy - **Lazy-load pyrealsense2** — RealSense camera module uses lazy imports to avoid errors in simulation environments without the SDK. ([#1309](#1309)) by @spomichter - **Removed unused mmcv and mmengine** — Dead Detic dependencies removed, eliminating slow source builds from install. ([#1319](#1319)) by @spomichter - **Simplified installation** — Removed direnv requirement, streamlined install instructions across all platforms. ([#1315](#1315)) by @spomichter - **DDS extra excluded from --all-extras** — `cyclonedds` requires a source build, so `dds` is now excluded from `uv sync --all-extras` by default. ([#1318](#1318)) by @spomichter - **Nix pre-commit skip** — Skip pre-commit install if hooks already exist. ([#1162](#1162)) by @leshy - **Removed base-requirements** — Consolidated dependency management. ([#1098](#1098)) by @paul-nechifor - **Removed old graspnet** — Cleaned up deprecated graspnet version. ([#1248](#1248)) by @paul-nechifor - **Code cleanup** — Removed `tofix` markers ([#1216](#1216)), fixed ruff issues ([#1112](#1112)), removed old README_installation.md ([#1101](#1101)) by @paul-nechifor --- ## 🐛 Bug Fixes - Fix LFS updating (move from .local to venv) ([#1090](#1090)) by @jeff-hykin - Launch hotfixes: git clone HTTPS, get_data main branch ([#1091](#1091)) by @spomichter - Fix camera demo not showing in Rerun ([#1148](#1148)) by @jeff-hykin - Default to rerun native viewer ([#1099](#1099)) by @Nabla7 - Fix exploration blocking agent loop ([#1258](#1258)) by @paul-nechifor - Fix person-follow blocking agent loop ([#1278](#1278)) by @paul-nechifor - Skip metric3d tests on unsupported xformers GPUs (Blackwell compute capability >9.0) ([#1225](#1225)) by @leshy - Fix manipulation tests ([#1218](#1218), [#1247](#1247)) by @jeff-hykin, @paul-nechifor - Fix control coordinator e2e test ([#1212](#1212)) by @mustafab0 - Fix xarm7-sim broken e2e tests ([#1294](#1294)) by @paul-nechifor - Pin langchain to restore supported providers ([#1241](#1241)) by @spomichter - Fix missing library dependencies in Nix flake ([#1240](#1240)) by @Kaweees - Fix discord invite link ([#1122](#1122)) by @spomichter - macOS edgecase fix ([#1096](#1096)) by @jeff-hykin - Fix second N in logo ([#1250](#1250)) by @jeff-hykin - Fix Unitree Go2 minor issues ([#1307](#1307)) by @paul-nechifor - Fix broken tests ([#1305](#1305)) by @ruthwikdasyam - Fix `uv sync` for some macOS systems ([#1322](#1322)) by @jeff-hykin - Fix mmcv install ([#1313](#1313)) by @paul-nechifor - Fix mypy issues ([#1150](#1150), [#1167](#1167), [#1257](#1257)) by @leshy, @paul-nechifor, @jeff-hykin - Fix Nix install uv pip extras ([#1321](#1321)) by @spomichter --- ## 📚 Documentation - **Major docs overhaul** — New README with feature grid, hardware table, quickstart. Navigation, transports, data streams, and agent docs. ([#1295](#1295)) by @leshy - **Day 1 docs** — Comprehensive getting started guide, development docs, contributing guide, architecture overview. Executable blueprint docs via md-babel-py. ([#1064](#1064)) by @jeff-hykin - **Arm integration guide** — How-to for integrating new robotic arms with DimOS. ([#1238](#1238)) by @mustafab0 - **MCP documentation update** — Updated MCP install and usage instructions. ([#1251](#1251)) by @Kaweees - **Docker docs** — First pass on Docker deployment documentation. ([#1151](#1151)) by @leshy - **Transports documentation** — Encode/decode mixins, SHM examples, ROS/DDS transport docs. ([#1107](#1107)) by @leshy - **Rerun API examples** — Updated examples for the new RerunBridge API. ([#1262](#1262)) by @jeff-hykin - **PR template** added ([#1172](#1172)) by @christiefhyang - **Simplified install instructions** — Removed direnv, streamlined across all platforms. ([#1315](#1315)) by @spomichter - **Python example restored** — Added back the Python usage example. ([#1317](#1317)) by @jeff-hykin - **Nix install updated** — Replaced uv with pip for Nix compatibility. ([#1326](#1326)) by @ruthwikdasyam - **README improvements** ([#1311](#1311)) by @paul-nechifor - **Simplified writing docs** — Consolidated writing_docs to a single markdown file. ([#1254](#1254)) by @jeff-hykin --- ## 🏗️ CI & Build - **ci-complete gate** — Dynamic branch protection via single aggregated status check. MD-only PRs no longer blocked. ([#1279](#1279)) by @spomichter - **Path-based test filtering** — Test jobs fully skip (no container spin-up) when no relevant code changed. ([#1284](#1284), [#1286](#1286)) by @spomichter - **Navigation docker build workflow** — CI builds for the ROS navigation stack. ([#1259](#1259)) by @spomichter - **CUDA test marker** — `@pytest.mark.cuda` for GPU-dependent tests. ([#1220](#1220)) by @jeff-hykin - **e2e test marker** — Marked end-to-end tests for selective CI runs. ([#1110](#1110)) by @paul-nechifor - **pytest stdin fix** — Added `-s` to default addopts for LCM autoconf compatibility. ([#1320](#1320)) by @spomichter --- ##⚠️ Breaking Changes - **RPC renames**: `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream` ([#1143](#1143)) - **Image class rewrite**: `CudaImage` and `NumpyImage` removed. Image is now a pure NumPy dataclass. Methods like `solve_pnp`, `csrt_tracker`, `from_depth`, `to_depth_meters` removed. ([#1161](#1161)) - **ROS messages removed from core**: All `to_ros`/`from_ros` conversion methods removed. Use `ROSTransport` instead. ([#1230](#1230)) - **QuestButtons → Buttons**: Renamed with generic field names. ([#1261](#1261)) - **RerunBridge replaces old rerun init**: `dimos.dashboard.rerun_init` removed. Use `RerunBridgeModule` or the `rerun-bridge` CLI. ([#1154](#1154)) - **Unitree directory restructuring**: `unitree_go2` → `unitree/go2`, `unitree_g1` → `unitree/g1`. Blueprint names updated. ([#1221](#1221)) - **Default viewer is now rerun-web**: Use `--viewer-backend rerun` to restore native viewer. ([#1324](#1324)) --- ## Quickstart ```bash # Install uv pip install dimos[base,unitree] # Try it (no hardware needed) # NOTE: First run downloads ~2.4 GB from LFS dimos --replay run unitree-go2 # Simulate uv pip install dimos[base,unitree,sim] dimos --simulation run unitree-go2 ``` --- ## New Contributors 🎉 - @ruthwikdasyam — Quest VR teleoperation, phone teleop, arm teleop, webcam rerun viz - @JalajShuklaSS — GraspGen integration - @jca0 — MuJoCo simulation module - @christiefhyang — PR template --- **Full Changelog**: [v0.0.9...v0.0.10](v0.0.9...v0.0.10)
NativeModule arch, Livox Mid-360 LiDAR + FAST-LIO2 Integration, no ros
I have to add screenshots look how cool this sensor is
How do I review?
docs are at https://github.com/dimensionalOS/dimos/blob/3142b5bceb232222982d39d7960319f3d5ec3cf6/docs/usage/native_modules.md
I think NativeModule stuff is important, maybe the way I handle builds via nix, livox/fastlio is just a dumb glue that seems fine in terms of config and computational efficiency so wouldn't bother too much
C++ voxel mapper is just a hashmap. shouldn't look at it, this is vibed and will go away once I write voxel deletion
Summary
NativeModule framework, enables integration third party executables into the dimos module/blueprint system
Native C++ Dimos Module for the Livox mid360
Native C++ Dimos Module for FAST-LIO2
NativeModule
(
dimos/core/native_module.py)should this be named externalmodule or something like that?
Hosts third party process, passes topics to use via CLI to the binary.
Passes also config settings as CLI args
Assumes binary speaks LCM, in the future we can pass also the protocol.
Doesn't support RPC
C++ binaries participate in blueprints like any Python module
Livox Mid-360 driver
dimos/hardware/sensors/lidar/livox/Mid360Modulewith network config (host/lidar IPs, ports)Testing
for native build check cpp/readme.md
FAST-LIO2
(
dimos/hardware/sensors/lidar/fastlio2/)Fastlio binary has livox SDK baked in, talks to mid360 directly, LCM topics lose full spectrum of mid360 data which fastlio depends on.
raw mid360 data is so raw that I assume we'll always use it through fastlio. (for example lidar hits need compensation for rotation state of the scanner and motion of the lidar in space)
for native build check cpp/readme.md
Voxel mapper tests
fastlio has three blueprint configs:
basic ODOM + Pointcloud, ODOM + GlobalMap, ODOM + CPPGlobalMap,
CPP voxel mapper uses PCL library https://pointclouds.org/
and is 2x more efficient then already pretty efficient py/cuda mapper
no voxel deleteons yet
needs a few days of experimenting
Nix build infrastructure
mid360_nativeandfastlio2_nativevia Nix flakesBlueprints
mid360— raw LiDARmid360-fastlio— SLAM with 0.15m voxel filteringmid360-fastlio-voxels— SLAM + downstream VoxelGridMappermid360-fastlio-voxels-native— SLAM + C++ global voxel map at 3Hz