8 Commits

Author SHA1 Message Date
Matt Spencer 24c330df91 Fix patch application in container. 2026-07-17 14:38:53 +00:00
Matt Spencer 2fffa0edb8 Update the livox patches. 2026-07-17 11:36:53 +00:00
Matt Spencer 6ca2d063d6 Get fast_lio cmake execute the git submodule init 2026-07-17 10:42:40 +00:00
Matt Spencer a9234a90be Patch to add symlinks to livox_ros_driver2 2026-07-17 10:23:25 +00:00
Matt Spencer b439d420df Fix unilidar_sdk2 for jazzy colcon build 2026-07-17 10:05:14 +00:00
Matt Spencer b3553348a0 Fix fast_lio for jazzy build 2026-07-17 09:34:33 +00:00
Matt Spencer c5c0ed092a Add the ARG TARGETARCH to the deploy image build 2026-07-16 07:24:34 +00:00
Matt Spencer f8beede100 Create better caching of rosdep dependencies
For both  devcontainer and deployable container.
Also add ability to use docker from inside the devcontainer.
2026-07-16 07:12:48 +00:00
11 changed files with 340 additions and 38 deletions
+13 -14
View File
@@ -2,6 +2,7 @@ FROM osrf/ros:jazzy-desktop-full
ARG USERNAME=USERNAME ARG USERNAME=USERNAME
ARG USER_UID=1000 ARG USER_UID=1000
ARG USER_GID=$USER_UID ARG USER_GID=$USER_UID
ARG TARGETARCH
# Delete user if it exists in container (e.g Ubuntu Noble: ubuntu) # Delete user if it exists in container (e.g Ubuntu Noble: ubuntu)
RUN if id -u $USER_UID ; then userdel `id -un $USER_UID` ; fi RUN if id -u $USER_UID ; then userdel `id -un $USER_UID` ; fi
@@ -47,13 +48,18 @@ RUN apt-get update \
python3-vcstool \ python3-vcstool \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Optional: pre-install apt dependencies resolved from rosdep on a previous run. # system deps from frozen rosdep manifest — no rosdep at build or startup
COPY .devcontainer/jazzy/ /tmp/devcontainer-jazzy/ # NOTE: There should be a check in your CI that this file is up to date.
# Something like:
RUN apt-get update \ # ./scripts/freeze-rosdep.sh && git diff --exit-code rosdep-packages.txt
&& if [ -f /tmp/devcontainer-jazzy/rosdep-apt-packages.txt ]; then \ COPY rosdep-packages.txt /tmp/rosdep-packages.txt
grep -Ev '^\s*($|#)' /tmp/devcontainer-jazzy/rosdep-apt-packages.txt | xargs -r apt-get install -y --no-install-recommends; \ # The --mount=type=cache option caches the apt packages with buildkit
fi \ # The id-apt-cache-${TARGETARCH} option allows for separate caches for different architectures
# this enables parallel builds for different architectures without cache conflicts
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-cache-${TARGETARCH} \
rm -f /etc/apt/apt.conf.d/docker-clean \
&& apt-get update \
&& xargs -r -a /tmp/rosdep-packages.txt apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN apt-get update \ RUN apt-get update \
@@ -61,13 +67,6 @@ RUN apt-get update \
ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \ ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# ROS 2 ament build tools
# RUN apt-get install -y \
# ros-${ROS_DISTRO}-ament-cmake \
# ros-${ROS_DISTRO}-ament-cmake-auto \
# ros-${ROS_DISTRO}-ament-python \
# ros-${ROS_DISTRO}-ament-lint-auto \
# ros-${ROS_DISTRO}-ament-lint-common
ENV SHELL=/bin/bash ENV SHELL=/bin/bash
@@ -0,0 +1,9 @@
{
"features": {
"ghcr.io/devcontainers/features/docker-from-docker:1": {
"version": "1.10.0",
"resolved": "ghcr.io/devcontainers/features/docker-from-docker@sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e",
"integrity": "sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e"
}
}
}
+6
View File
@@ -10,6 +10,12 @@
} }
}, },
"workspaceFolder": "/workspaces/agv_pro_ros2", "workspaceFolder": "/workspaces/agv_pro_ros2",
"features": {
"ghcr.io/devcontainers/features/docker-from-docker:1": {
"version": "latest",
"moby": true
}
},
"customizations": { "customizations": {
"vscode": { "vscode": {
"extensions": [ "extensions": [
+20 -23
View File
@@ -2,46 +2,43 @@ FROM ros:jazzy
# Create the workspace and copy all source directories into it # Create the workspace and copy all source directories into it
WORKDIR /ros2_ws WORKDIR /ros2_ws
ARG TARGETARCH
COPY src ./src/ COPY src ./src/
COPY patches ./patches/ COPY patches ./patches/
COPY upstream.jazzy.repos ./upstream.jazzy.repos COPY upstream.jazzy.repos ./upstream.jazzy.repos
# Stage any dual ROS1/ROS2 packages (e.g. livox_ros_driver2) for ROS2 without
# modifying their upstream source: generate package.xml from package_ROS2.xml so
# colcon can discover them. The ROS2 build is selected via -DROS_EDITION below.
# RUN for d in $(find /ros2_ws/src -type f -name package_ROS2.xml -exec dirname {} \;); do \
# cp -f "$d/package_ROS2.xml" "$d/package.xml"; \
# done
# Import all upstream repostories # Import all upstream repostories
RUN vcs import ./src/upstream < ./upstream.jazzy.repos RUN mkdir -p src/upstream && vcs import ./src/upstream < ./upstream.jazzy.repos
# Fixup the livox package for ros2 build
RUN cd ./src/upstream/livox_ros_driver2 && \
rm -rf launch package.xml && \
ln -sfn launch_ROS2 launch && \
ln -sfn package_ROS2.xml package.xml
# Apply patches to upstream # Apply patches to upstream
# RUN ./patches/apply_patches.sh RUN ./patches/apply_patches.sh
# system deps from frozen rosdep manifest — no rosdep at build or startup
# NOTE: There should be a check in your CI that this file is up to date.
# Something like:
# ./scripts/freeze-rosdep.sh && git diff --exit-code rosdep-packages.txt
COPY rosdep-packages.txt /tmp/rosdep-packages.txt
# The --mount=type=cache option caches the apt packages with buildkit
# The id-apt-cache-${TARGETARCH} option allows for separate caches for different architectures
# this enables parallel builds for different architectures without cache conflicts
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-cache-${TARGETARCH} \
rm -f /etc/apt/apt.conf.d/docker-clean \
&& apt-get update \
&& xargs -r -a /tmp/rosdep-packages.txt apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# Install dependencies with rosdep # Install dependencies with rosdep
# This will catch anything that wasn't installed via .deb's from the frozen rosdep manifest.
RUN apt-get update && \ RUN apt-get update && \
rosdep update && \ rosdep update && \
rosdep install --from-paths src --ignore-src -r -y && \ rosdep install --from-paths src --ignore-src -r -y && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
RUN cd src/upstream/livox_sdk && \
mkdir -p build && \
cd build && rm -rf * && \
cmake .. -DCMAKE_BUILD_TYPE=Release && \
make -j && \
make install
# Build the workspace with symlink install # Build the workspace with symlink install
# livox_sdk is now an ament_cmake package built by colcon (no manual /usr/local install needed).
RUN . /opt/ros/jazzy/setup.sh && \ RUN . /opt/ros/jazzy/setup.sh && \
colcon build --symlink-install \ colcon build --symlink-install \
--packages-ignore unitree_lidar_ros2 unitree_lidar_ros unitree_lidar_sdk fast_lio \
--cmake-args -DROS_EDITION=ROS2 -DDISTRO_ROS=jazzy --cmake-args -DROS_EDITION=ROS2 -DDISTRO_ROS=jazzy
# Source the overlay on container startup # Source the overlay on container startup
+5 -1
View File
@@ -1,7 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -u set -u
ROOT_DIR="/workspaces/agv_pro_ros2" PATCH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$PATCH_DIR")"
PATCH_DIR="$ROOT_DIR/patches" PATCH_DIR="$ROOT_DIR/patches"
apply_patch_once() { apply_patch_once() {
@@ -23,5 +24,8 @@ apply_patch_once() {
|| git -C "$target_dir" apply --reverse --check "$patch_file" >/dev/null 2>&1 || git -C "$target_dir" apply --reverse --check "$patch_file" >/dev/null 2>&1
} }
apply_patch_once "$ROOT_DIR/src/upstream/FAST_LIO" "$PATCH_DIR/fast_lio.patch"
apply_patch_once "$ROOT_DIR/src/upstream/livox_sdk" "$PATCH_DIR/livox_sdk.patch" apply_patch_once "$ROOT_DIR/src/upstream/livox_sdk" "$PATCH_DIR/livox_sdk.patch"
apply_patch_once "$ROOT_DIR/src/upstream/livox_ros_driver2" "$PATCH_DIR/livox_ros_driver2.patch"
apply_patch_once "$ROOT_DIR/src/upstream/slam_gmapping" "$PATCH_DIR/slam_gmapping.patch" apply_patch_once "$ROOT_DIR/src/upstream/slam_gmapping" "$PATCH_DIR/slam_gmapping.patch"
apply_patch_once "$ROOT_DIR/src/upstream/unilidar_sdk2" "$PATCH_DIR/unilidar_sdk2.patch"
+49
View File
@@ -0,0 +1,49 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index be3040b..3176847 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,17 +5,39 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
-ADD_COMPILE_OPTIONS(-std=c++14)
-ADD_COMPILE_OPTIONS(-std=c++14)
-set(CMAKE_CXX_FLAGS "-std=c++14 -O3")
+# Ensure the bundled ikd-Tree submodule (include/ikd-Tree/ikd_Tree.cpp) is present.
+# Auto-initialize it when building from a git checkout; otherwise fail with guidance.
+if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include/ikd-Tree/ikd_Tree.cpp")
+ find_package(Git QUIET)
+ if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
+ message(STATUS "fast_lio: initializing git submodule include/ikd-Tree")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ RESULT_VARIABLE GIT_SUBMOD_RESULT)
+ if(NOT GIT_SUBMOD_RESULT EQUAL "0")
+ message(FATAL_ERROR
+ "git submodule update --init failed with ${GIT_SUBMOD_RESULT}. "
+ "Run it manually in ${CMAKE_CURRENT_SOURCE_DIR}.")
+ endif()
+ endif()
+ if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include/ikd-Tree/ikd_Tree.cpp")
+ message(FATAL_ERROR
+ "include/ikd-Tree/ikd_Tree.cpp is missing and could not be fetched automatically "
+ "(no git checkout available). Run: git submodule update --init --recursive")
+ endif()
+endif()
+
+ADD_COMPILE_OPTIONS(-std=c++17)
+set(CMAKE_CXX_FLAGS "-std=c++17 -O3")
add_definitions(-DROOT_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions")
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pthread -std=c++0x -std=c++14 -fexceptions")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread -fexceptions")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
message("Current CPU archtecture: ${CMAKE_SYSTEM_PROCESSOR}")
+28
View File
@@ -0,0 +1,28 @@
diff --git a/launch b/launch
new file mode 120000
index 0000000..163fb01
--- /dev/null
+++ b/launch
@@ -0,0 +1 @@
+launch_ROS2
\ No newline at end of file
diff --git a/package.xml b/package.xml
new file mode 120000
index 0000000..36804a4
--- /dev/null
+++ b/package.xml
@@ -0,0 +1 @@
+package_ROS2.xml
\ No newline at end of file
diff --git a/package_ROS2.xml b/package_ROS2.xml
index 96f5762..c66785b 100644
--- a/package_ROS2.xml
+++ b/package_ROS2.xml
@@ -28,6 +28,7 @@
<depend>git</depend>
<depend>apr</depend>
+ <depend>livox_sdk2</depend>
<export>
<build_type>ament_cmake</build_type>
+25
View File
@@ -1,3 +1,28 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 05f84c5..4fb6f31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,9 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.5)
project(livox_sdk2)
+find_package(ament_cmake REQUIRED)
+
set(CMAKE_CXX_STANDARD 11)
message(STATUS "main project dir: " ${PROJECT_SOURCE_DIR})
@@ -18,3 +20,9 @@ endif(UNIX)
add_subdirectory(sdk_core)
add_subdirectory(samples)
+
+# Export the installed headers/libraries so ament packages (e.g. livox_ros_driver2)
+# find the SDK from the colcon install space via CMAKE_PREFIX_PATH.
+ament_export_include_directories(include)
+ament_export_libraries(livox_lidar_sdk_shared)
+ament_package()
diff --git a/sdk_core/comm/define.h b/sdk_core/comm/define.h diff --git a/sdk_core/comm/define.h b/sdk_core/comm/define.h
index 0872328..28d989b 100644 index 0872328..28d989b 100644
--- a/sdk_core/comm/define.h --- a/sdk_core/comm/define.h
+105
View File
@@ -0,0 +1,105 @@
diff --git a/unitree_lidar_ros2/src/unitree_lidar_ros2/CMakeLists.txt b/unitree_lidar_ros2/src/unitree_lidar_ros2/CMakeLists.txt
index 041ef0d..dd57d47 100644
--- a/unitree_lidar_ros2/src/unitree_lidar_ros2/CMakeLists.txt
+++ b/unitree_lidar_ros2/src/unitree_lidar_ros2/CMakeLists.txt
@@ -23,16 +23,15 @@ find_package(pcl_conversions REQUIRED)
find_package(PCL REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(sensor_msgs REQUIRED)
+find_package(unitree_lidar_sdk REQUIRED)
include_directories(
${PCL_INCLUDE_DIRS}
include
- ../../../unitree_lidar_sdk/include
)
link_directories(
${PCL_LIBRARY_DIRS}
- ../../../unitree_lidar_sdk/lib/${CMAKE_SYSTEM_PROCESSOR}
)
add_definitions(${PCL_DEFINITIONS})
@@ -42,7 +41,6 @@ add_executable(unitree_lidar_ros2_node src/unitree_lidar_ros2_node.cpp)
target_link_libraries( unitree_lidar_ros2_node
${Boost_SYSTEM_LIBRARY}
${PCL_LIBRARIES}
- libunilidar_sdk2.a
)
ament_target_dependencies(
@@ -52,6 +50,7 @@ ament_target_dependencies(
geometry_msgs
tf2_ros
pcl_conversions
+ unitree_lidar_sdk
)
install(TARGETS
diff --git a/unitree_lidar_ros2/src/unitree_lidar_ros2/package.xml b/unitree_lidar_ros2/src/unitree_lidar_ros2/package.xml
index 74539aa..b5febb2 100644
--- a/unitree_lidar_ros2/src/unitree_lidar_ros2/package.xml
+++ b/unitree_lidar_ros2/src/unitree_lidar_ros2/package.xml
@@ -21,6 +21,7 @@
<depend>geometry_msgs</depend>
<depend>tf2_ros</depend>
+ <depend>unitree_lidar_sdk</depend>
<export>
<build_type>ament_cmake</build_type>
diff --git a/unitree_lidar_sdk/CMakeLists.txt b/unitree_lidar_sdk/CMakeLists.txt
index 80af9c9..0d9a334 100644
--- a/unitree_lidar_sdk/CMakeLists.txt
+++ b/unitree_lidar_sdk/CMakeLists.txt
@@ -1,39 +1,14 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.5)
project(unitree_lidar_sdk)
-set(CMAKE_BUILD_TYPE "Release")
-set(CMAKE_CXX_FLAGS "-std=c++17")
-set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
-set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -DNDEBUG")
+find_package(ament_cmake REQUIRED)
-include_directories(include)
+# Install the SDK headers and the architecture-specific prebuilt static library.
+install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})
+install(FILES lib/${CMAKE_SYSTEM_PROCESSOR}/libunilidar_sdk2.a DESTINATION lib)
-link_directories(lib/${CMAKE_SYSTEM_PROCESSOR})
+# Export them so ament packages can consume the SDK via find_package().
+ament_export_include_directories(include/${PROJECT_NAME})
+ament_export_libraries(unilidar_sdk2)
-SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR})
-
-add_executable(example_lidar_udp
- examples/example_lidar_udp.cpp
-)
-target_link_libraries(example_lidar_udp libunilidar_sdk2.a )
-
-add_executable(example_lidar_serial
- examples/example_lidar_serial.cpp
-)
-target_link_libraries(example_lidar_serial libunilidar_sdk2.a )
-
-add_executable(set_ip_address
- examples/set_ip_address.cpp
-)
-target_link_libraries(set_ip_address libunilidar_sdk2.a )
-
-add_executable(set_to_serial_mode
- examples/set_to_serial_mode.cpp
-)
-target_link_libraries(set_to_serial_mode libunilidar_sdk2.a )
-
-add_executable(set_to_udp_mode
- examples/set_to_udp_mode.cpp
-)
-target_link_libraries(set_to_udp_mode libunilidar_sdk2.a )
\ No newline at end of file
+ament_package()
\ No newline at end of file
+73
View File
@@ -0,0 +1,73 @@
git
libapr1-dev libaprutil1-dev
libboost-all-dev
libpcap0.8-dev
libpcl-apps1.14 libpcl-common1.14 libpcl-features1.14 libpcl-filters1.14 libpcl-io1.14 libpcl-kdtree1.14 libpcl-keypoints1.14 libpcl-ml1.14 libpcl-octree1.14 libpcl-outofcore1.14 libpcl-people1.14 libpcl-recognition1.14 libpcl-registration1.14 libpcl-sample-consensus1.14 libpcl-search1.14 libpcl-segmentation1.14 libpcl-stereo1.14 libpcl-surface1.14 libpcl-tracking1.14 libpcl-visualization1.14
libpcl-dev
libqt5core5t64
libqt5gui5t64
libqt5opengl5t64
libqt5widgets5t64
python3-pytest
qtbase5-dev
ros-jazzy-ament-cmake
ros-jazzy-ament-cmake-auto
ros-jazzy-ament-cmake-black
ros-jazzy-ament-cmake-clang-format
ros-jazzy-ament-cmake-clang-tidy
ros-jazzy-ament-cmake-copyright
ros-jazzy-ament-cmake-xmllint
ros-jazzy-ament-copyright
ros-jazzy-ament-flake8
ros-jazzy-ament-index-cpp
ros-jazzy-ament-lint-auto
ros-jazzy-ament-lint-common
ros-jazzy-ament-pep257
ros-jazzy-asio-cmake-module
ros-jazzy-builtin-interfaces
ros-jazzy-cartographer-ros
ros-jazzy-common-interfaces
ros-jazzy-controller-manager
ros-jazzy-diff-drive-controller
ros-jazzy-geometry-msgs
ros-jazzy-io-context
ros-jazzy-joint-state-broadcaster
ros-jazzy-joint-state-publisher
ros-jazzy-message-filters
ros-jazzy-nav-msgs
ros-jazzy-nav2-bringup
ros-jazzy-nav2-simple-commander
ros-jazzy-orbbec-camera
ros-jazzy-pcl-conversions
ros-jazzy-pcl-ros
ros-jazzy-pluginlib
ros-jazzy-rcl-interfaces
ros-jazzy-rclcpp
ros-jazzy-rclcpp-components
ros-jazzy-rclpy
ros-jazzy-rcutils
ros-jazzy-resource-retriever
ros-jazzy-robot-state-publisher
ros-jazzy-ros2-control
ros-jazzy-rosbag2
ros-jazzy-rosidl-default-generators
ros-jazzy-rosidl-default-runtime
ros-jazzy-rtabmap-demos
ros-jazzy-rtabmap-slam
ros-jazzy-rtabmap-sync
ros-jazzy-rtabmap-util
ros-jazzy-rtabmap-viz
ros-jazzy-rviz-common
ros-jazzy-rviz-default-plugins
ros-jazzy-rviz-ogre-vendor
ros-jazzy-rviz-rendering
ros-jazzy-rviz2
ros-jazzy-sensor-msgs
ros-jazzy-serial-driver
ros-jazzy-std-msgs
ros-jazzy-teleop-twist-keyboard
ros-jazzy-tf2
ros-jazzy-tf2-geometry-msgs
ros-jazzy-tf2-ros
ros-jazzy-visualization-msgs
ros-jazzy-xacro
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
ROS_DISTRO="${ROS_DISTRO:-jazzy}"
rosdep update --rosdistro "$ROS_DISTRO" >/dev/null 2>&1 || true
rosdep keys --from-paths src --ignore-src --rosdistro "$ROS_DISTRO" 2>/dev/null \
| xargs rosdep resolve --rosdistro "$ROS_DISTRO" 2>/dev/null \
| awk '/^#apt/{a=1;next} /^#/{a=0} a' | sort -u > rosdep-packages.txt