<fix> Fix format errors in README, Add rviz configuration loading.
This commit is contained in:
+49
-52
@@ -4,7 +4,7 @@ project(odin_ros_driver)
|
||||
|
||||
if(DEFINED BUILD_SYSTEM)
|
||||
set(ROS_VERSION ${BUILD_SYSTEM})
|
||||
message(STATUS "使用命令行指定的构建系统: ${ROS_VERSION}")
|
||||
message(STATUS "ROS_VERSION: ${ROS_VERSION}")
|
||||
elseif(DEFINED ENV{ROS_DISTRO})
|
||||
if("$ENV{ROS_DISTRO}" MATCHES "foxy|galactic|humble|iron|rolling")
|
||||
set(ROS_VERSION "ROS2")
|
||||
@@ -18,30 +18,30 @@ elseif(DEFINED ENV{ROS_VERSION})
|
||||
set(ROS_VERSION "ROS1")
|
||||
endif()
|
||||
else()
|
||||
# 尝试自动检测
|
||||
# Attempt automatic detection
|
||||
if(COMMAND catkin_package)
|
||||
set(ROS_VERSION "ROS1")
|
||||
elseif(COMMAND ament_package)
|
||||
set(ROS_VERSION "ROS2")
|
||||
else()
|
||||
# 默认使用ROS2
|
||||
# Default to ROS2
|
||||
set(ROS_VERSION "ROS2")
|
||||
message(WARNING "无法确定ROS版本,默认使用ROS2")
|
||||
message(WARNING "Unable to determine ROS version, defaulting to ROS2")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 检测 ROS 版本后添加编译宏
|
||||
# Add compile definitions after detecting ROS version
|
||||
if(ROS_VERSION STREQUAL "ROS2")
|
||||
add_definitions(-DROS2)
|
||||
message(STATUS "定义 ROS2 宏")
|
||||
message(STATUS "Defining ROS2")
|
||||
else()
|
||||
add_definitions(-DROS1)
|
||||
message(STATUS "定义 ROS1 宏")
|
||||
message(STATUS "Defining ROS1")
|
||||
endif()
|
||||
|
||||
message(STATUS "构建系统: ${ROS_VERSION}")
|
||||
message(STATUS "Build system: ${ROS_VERSION}")
|
||||
|
||||
# 平台检测
|
||||
# Platform detection
|
||||
execute_process(
|
||||
COMMAND uname -m
|
||||
OUTPUT_VARIABLE ARCH
|
||||
@@ -50,27 +50,27 @@ execute_process(
|
||||
|
||||
if(ARCH STREQUAL "x86_64")
|
||||
set(TARGET_PLATFORM "x86")
|
||||
message(STATUS "检测到 x86_64 架构")
|
||||
message(STATUS "Detected x86_64 architecture")
|
||||
elseif(ARCH MATCHES "arm|aarch64")
|
||||
set(TARGET_PLATFORM "arm")
|
||||
message(STATUS "检测到 ARM 架构: ${ARCH}")
|
||||
message(STATUS "Detected ARM architecture: ${ARCH}")
|
||||
else()
|
||||
message(WARNING "不支持的架构: ${ARCH}. 使用默认设置")
|
||||
message(WARNING "Unsupported architecture: ${ARCH}. Using default settings")
|
||||
set(TARGET_PLATFORM "unknown")
|
||||
endif()
|
||||
|
||||
# 设置库路径
|
||||
# Set library path
|
||||
set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
|
||||
message(STATUS "库目录: ${LIB_DIR}")
|
||||
message(STATUS "Library directory: ${LIB_DIR}")
|
||||
|
||||
# 根据平台设置库名称
|
||||
# Set library name based on platform
|
||||
if(TARGET_PLATFORM STREQUAL "arm")
|
||||
set(LYD_HOST_API_LIB_NAME "lydHostApi_arm")
|
||||
else()
|
||||
set(LYD_HOST_API_LIB_NAME "lydHostApi_amd")
|
||||
endif()
|
||||
|
||||
# 查找预编译的 lydHostApi 库
|
||||
# Find precompiled lydHostApi library
|
||||
find_library(LYD_HOST_API_LIB
|
||||
NAMES
|
||||
${LYD_HOST_API_LIB_NAME}
|
||||
@@ -81,22 +81,22 @@ find_library(LYD_HOST_API_LIB
|
||||
)
|
||||
|
||||
if(LYD_HOST_API_LIB)
|
||||
message(STATUS "找到 lydHostApi 库: ${LYD_HOST_API_LIB}")
|
||||
message(STATUS "Found lydHostApi library: ${LYD_HOST_API_LIB}")
|
||||
else()
|
||||
file(GLOB LIB_FILES "${LIB_DIR}/lib${LYD_HOST_API_LIB_NAME}.*")
|
||||
if(LIB_FILES)
|
||||
message(STATUS "找到库文件: ${LIB_FILES}")
|
||||
message(STATUS "Found library files: ${LIB_FILES}")
|
||||
set(LYD_HOST_API_LIB ${LIB_FILES})
|
||||
else()
|
||||
message(FATAL_ERROR "在 ${LIB_DIR} 中找不到预编译的 lydHostApi 库")
|
||||
message(FATAL_ERROR "Could not find precompiled lydHostApi library in ${LIB_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 设置公共编译选项
|
||||
# Set common compile options
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# 公共依赖查找
|
||||
# Find common dependencies
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(OpenCV REQUIRED COMPONENTS core imgproc highgui)
|
||||
find_package(Eigen3 REQUIRED)
|
||||
@@ -104,7 +104,7 @@ find_package(yaml-cpp REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
|
||||
|
||||
# 共享包含目录
|
||||
# Shared include directories
|
||||
include_directories(
|
||||
include
|
||||
${EIGEN3_INCLUDE_DIRS}
|
||||
@@ -114,7 +114,7 @@ include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
# 共享链接库列表
|
||||
# Shared library list
|
||||
set(COMMON_LIBS
|
||||
${OpenCV_LIBS}
|
||||
${yaml-cpp_LIBRARIES}
|
||||
@@ -126,9 +126,9 @@ set(COMMON_LIBS
|
||||
${LYD_HOST_API_LIB}
|
||||
)
|
||||
|
||||
# ===== ROS1 专属配置 =====
|
||||
# ===== ROS1 Configuration =====
|
||||
if(ROS_VERSION STREQUAL "ROS1")
|
||||
message(STATUS "配置为 ROS1 构建")
|
||||
message(STATUS "Configuring for ROS1 build")
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
roscpp
|
||||
@@ -146,7 +146,7 @@ if(ROS_VERSION STREQUAL "ROS1")
|
||||
INCLUDE_DIRS include
|
||||
)
|
||||
|
||||
# 设置输出目录
|
||||
# Set output directories
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/${PROJECT_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib)
|
||||
@@ -166,7 +166,7 @@ if(ROS_VERSION STREQUAL "ROS1")
|
||||
usb-1.0
|
||||
)
|
||||
|
||||
# 安装规则
|
||||
# Installation rules
|
||||
install(TARGETS host_sdk_sample
|
||||
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
)
|
||||
@@ -181,11 +181,11 @@ if(ROS_VERSION STREQUAL "ROS1")
|
||||
)
|
||||
endif()
|
||||
|
||||
# ===== ROS2 配置 =====
|
||||
# ===== ROS2 Configuration =====
|
||||
elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
message(STATUS "配置为 ROS2 构建")
|
||||
message(STATUS "Configuring for ROS2 build")
|
||||
|
||||
# 查找所有必要的ROS2包
|
||||
# Find all necessary ROS2 packages
|
||||
find_package(ament_cmake REQUIRED)
|
||||
find_package(rclcpp REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
@@ -194,13 +194,13 @@ elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
find_package(cv_bridge REQUIRED)
|
||||
find_package(image_transport REQUIRED)
|
||||
|
||||
# 创建可执行文件
|
||||
# Create executable
|
||||
add_executable(host_sdk_sample
|
||||
src/host_sdk_sample.cpp
|
||||
src/yaml_parser.cpp
|
||||
)
|
||||
|
||||
# 链接库
|
||||
# Link libraries
|
||||
target_link_libraries(host_sdk_sample
|
||||
${catkin_LIBRARIES}
|
||||
${COMMON_LIBS}
|
||||
@@ -208,7 +208,7 @@ elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
usb-1.0
|
||||
)
|
||||
|
||||
# 添加ROS2依赖
|
||||
# Add ROS2 dependencies
|
||||
ament_target_dependencies(host_sdk_sample
|
||||
rclcpp
|
||||
std_msgs
|
||||
@@ -218,8 +218,8 @@ elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
image_transport
|
||||
)
|
||||
|
||||
# 安装规则 - 确保所有安装目标在 ament_package() 之前定义
|
||||
# 安装可执行文件
|
||||
# Installation rules - ensure all install targets are defined before ament_package()
|
||||
# Install executable
|
||||
install(TARGETS host_sdk_sample
|
||||
EXPORT export_${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION lib
|
||||
@@ -227,39 +227,39 @@ elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
RUNTIME DESTINATION lib/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
# 安装 package.xml
|
||||
# Install package.xml
|
||||
install(FILES package.xml
|
||||
DESTINATION share/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
# 安装头文件
|
||||
# Install headers
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
)
|
||||
# 安装 launch_ROS2 目录
|
||||
# Install launch_ROS2 directory
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/launch_ROS2")
|
||||
install(DIRECTORY launch_ROS2/
|
||||
DESTINATION share/${PROJECT_NAME}/launch
|
||||
)
|
||||
message(STATUS "安装 launch_ROS2 目录到 share/${PROJECT_NAME}/launch")
|
||||
message(STATUS "Installing launch_ROS2 directory to share/${PROJECT_NAME}/launch")
|
||||
else()
|
||||
message(WARNING "未找到 launch_ROS2 目录")
|
||||
message(WARNING "launch_ROS2 directory not found")
|
||||
endif()
|
||||
# 安装配置文件 (如果存在)
|
||||
# Install config files
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/config")
|
||||
install(DIRECTORY config/
|
||||
DESTINATION share/${PROJECT_NAME}/config
|
||||
)
|
||||
endif()
|
||||
|
||||
# 安装启动文件 (如果存在)
|
||||
# Install launch files
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/launch")
|
||||
install(DIRECTORY launch/
|
||||
DESTINATION share/${PROJECT_NAME}/launch
|
||||
)
|
||||
endif()
|
||||
ament_export_targets(export_${PROJECT_NAME})
|
||||
# 声明依赖
|
||||
# Declare dependencies
|
||||
ament_export_dependencies(
|
||||
rclcpp
|
||||
std_msgs
|
||||
@@ -269,28 +269,25 @@ elseif(ROS_VERSION STREQUAL "ROS2")
|
||||
image_transport
|
||||
)
|
||||
|
||||
# 可选的lint检查
|
||||
|
||||
# 完成包配置 - 必须在所有安装规则之后调用
|
||||
ament_package()
|
||||
message(STATUS "安装目标已添加")
|
||||
message(STATUS "Install targets added")
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "无效的 ROS_VERSION: ${ROS_VERSION}")
|
||||
message(FATAL_ERROR "Invalid ROS_VERSION: ${ROS_VERSION}")
|
||||
endif()
|
||||
|
||||
# ARM平台特定的链接选项
|
||||
# ARM platform specific link options
|
||||
if(TARGET_PLATFORM STREQUAL "arm")
|
||||
set_target_properties(host_sdk_sample PROPERTIES
|
||||
LINK_FLAGS "-Wl,--no-as-needed -Wl,--rpath=${LIB_DIR}"
|
||||
)
|
||||
message(STATUS "添加 ARM 特定的链接选项和 RPATH")
|
||||
message(STATUS "Adding ARM-specific link options and RPATH")
|
||||
endif()
|
||||
|
||||
# 添加调试信息
|
||||
# Add debug information
|
||||
message(STATUS "=======================================")
|
||||
message(STATUS "Project: ${PROJECT_NAME}")
|
||||
message(STATUS "ROS 版本: ${ROS_VERSION}")
|
||||
message(STATUS "ROS_VERSION: ${ROS_VERSION}")
|
||||
message(STATUS "Target platform: ${TARGET_PLATFORM}")
|
||||
message(STATUS "lydHostApi library: ${LYD_HOST_API_LIB}")
|
||||
message(STATUS "libusb library: ${LIBUSB_LIBRARIES}")
|
||||
|
||||
@@ -67,13 +67,17 @@ sudo apt-get install libopencv-dev
|
||||
```
|
||||
|
||||
#### 2.3.4 ROS install
|
||||
```shell
|
||||
#Installation method
|
||||
For ROS Melodic installation, please refer to: ROS Melodic installation instructions
|
||||
For ROS Noetic installation, please refer to: ROS Noetic installation instructions
|
||||
For ROS2 Foxy installation, please refer to: ROS Foxy installation instructions
|
||||
For ROS2 Humble installation, please refer to: ROS Humble installation instructions
|
||||
```
|
||||
For ROS Melodic installation, please refer to:
|
||||
[ROS Melodic installation instructions](https://wiki.ros.org/melodic/Installation)
|
||||
|
||||
For ROS Noetic installation, please refer to:
|
||||
[ROS Noetic installation instructions](https://wiki.ros.org/noetic/Installation)
|
||||
|
||||
For ROS2 Foxy installation, please refer to:
|
||||
[ROS Foxy installation instructions](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html)
|
||||
|
||||
For ROS2 Humble installation, please refer to:
|
||||
[ROS Humble installation instructions](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html)
|
||||
|
||||
## 3. Preparation
|
||||
|
||||
@@ -83,7 +87,7 @@ sudo vim /etc/udev/rules.d/99-odin-usb.rules
|
||||
```
|
||||
Add the following content to the 99-odin-usb.rules file
|
||||
```shell
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0019", MODE="0666", GROUP="plugdev
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0019", MODE="0666", GROUP="plugdev"
|
||||
```
|
||||
Reload rules and reinsert devices
|
||||
```shell
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
Panels:
|
||||
- Class: rviz/Displays
|
||||
Help Height: 78
|
||||
Name: Displays
|
||||
Property Tree Widget:
|
||||
Expanded: ~
|
||||
Splitter Ratio: 0.5
|
||||
Tree Height: 489
|
||||
- Class: rviz/Selection
|
||||
Name: Selection
|
||||
- Class: rviz/Tool Properties
|
||||
Expanded:
|
||||
- /2D Pose Estimate1
|
||||
- /2D Nav Goal1
|
||||
- /Publish Point1
|
||||
Name: Tool Properties
|
||||
Splitter Ratio: 0.5886790156364441
|
||||
- Class: rviz/Views
|
||||
Expanded:
|
||||
- /Current View1
|
||||
Name: Views
|
||||
Splitter Ratio: 0.5
|
||||
- Class: rviz/Time
|
||||
Name: Time
|
||||
SyncMode: 0
|
||||
SyncSource: Image
|
||||
Preferences:
|
||||
PromptSaveOnExit: true
|
||||
Toolbars:
|
||||
toolButtonStyle: 2
|
||||
Visualization Manager:
|
||||
Class: ""
|
||||
Displays:
|
||||
- Alpha: 0.5
|
||||
Cell Size: 1
|
||||
Class: rviz/Grid
|
||||
Color: 160; 160; 164
|
||||
Enabled: true
|
||||
Line Style:
|
||||
Line Width: 0.029999999329447746
|
||||
Value: Lines
|
||||
Name: Grid
|
||||
Normal Cell Count: 0
|
||||
Offset:
|
||||
X: 0
|
||||
Y: 0
|
||||
Z: 0
|
||||
Plane: XY
|
||||
Plane Cell Count: 10
|
||||
Reference Frame: <Fixed Frame>
|
||||
Value: true
|
||||
- Class: rviz/Image
|
||||
Enabled: true
|
||||
Image Topic: /odin1/image
|
||||
Max Value: 1
|
||||
Median window: 5
|
||||
Min Value: 0
|
||||
Name: Image
|
||||
Normalize Range: true
|
||||
Queue Size: 2
|
||||
Transport Hint: raw
|
||||
Unreliable: false
|
||||
Value: true
|
||||
- Alpha: 1
|
||||
Autocompute Intensity Bounds: true
|
||||
Autocompute Value Bounds:
|
||||
Max Value: 10
|
||||
Min Value: -10
|
||||
Value: true
|
||||
Axis: Z
|
||||
Channel Name: intensity
|
||||
Class: rviz/PointCloud2
|
||||
Color: 255; 255; 255
|
||||
Color Transformer: Intensity
|
||||
Decay Time: 0
|
||||
Enabled: false
|
||||
Invert Rainbow: false
|
||||
Max Color: 255; 255; 255
|
||||
Min Color: 0; 0; 0
|
||||
Name: PointCloud2
|
||||
Position Transformer: XYZ
|
||||
Queue Size: 10
|
||||
Selectable: true
|
||||
Size (Pixels): 3
|
||||
Size (m): 0.009999999776482582
|
||||
Style: Flat Squares
|
||||
Topic: /odin1/cloud_raw
|
||||
Unreliable: false
|
||||
Use Fixed Frame: true
|
||||
Use rainbow: true
|
||||
Value: false
|
||||
- Angle Tolerance: 0.10000000149011612
|
||||
Class: rviz/Odometry
|
||||
Covariance:
|
||||
Orientation:
|
||||
Alpha: 0.5
|
||||
Color: 255; 255; 127
|
||||
Color Style: Unique
|
||||
Frame: Local
|
||||
Offset: 1
|
||||
Scale: 1
|
||||
Value: true
|
||||
Position:
|
||||
Alpha: 0.30000001192092896
|
||||
Color: 204; 51; 204
|
||||
Scale: 1
|
||||
Value: true
|
||||
Value: false
|
||||
Enabled: true
|
||||
Keep: 1
|
||||
Name: Odometry
|
||||
Position Tolerance: 0.10000000149011612
|
||||
Queue Size: 100
|
||||
Shape:
|
||||
Alpha: 1
|
||||
Axes Length: 1
|
||||
Axes Radius: 0.10000000149011612
|
||||
Color: 255; 25; 0
|
||||
Head Length: 0.30000001192092896
|
||||
Head Radius: 0.10000000149011612
|
||||
Shaft Length: 1
|
||||
Shaft Radius: 0.05000000074505806
|
||||
Value: Axes
|
||||
Topic: /odin1/odometry_map
|
||||
Unreliable: false
|
||||
Value: true
|
||||
- Alpha: 1
|
||||
Autocompute Intensity Bounds: true
|
||||
Autocompute Value Bounds:
|
||||
Max Value: 10
|
||||
Min Value: -10
|
||||
Value: true
|
||||
Axis: Z
|
||||
Channel Name: intensity
|
||||
Class: rviz/PointCloud2
|
||||
Color: 255; 255; 255
|
||||
Color Transformer: RGB8
|
||||
Decay Time: 0
|
||||
Enabled: true
|
||||
Invert Rainbow: false
|
||||
Max Color: 255; 255; 255
|
||||
Min Color: 0; 0; 0
|
||||
Name: PointCloud2
|
||||
Position Transformer: XYZ
|
||||
Queue Size: 10
|
||||
Selectable: true
|
||||
Size (Pixels): 3
|
||||
Size (m): 0.009999999776482582
|
||||
Style: Points
|
||||
Topic: /odin1/cloud_slam
|
||||
Unreliable: false
|
||||
Use Fixed Frame: true
|
||||
Use rainbow: false
|
||||
Value: true
|
||||
Enabled: true
|
||||
Global Options:
|
||||
Background Color: 48; 48; 48
|
||||
Default Light: true
|
||||
Fixed Frame: map
|
||||
Frame Rate: 30
|
||||
Name: root
|
||||
Tools:
|
||||
- Class: rviz/Interact
|
||||
Hide Inactive Objects: true
|
||||
- Class: rviz/MoveCamera
|
||||
- Class: rviz/Select
|
||||
- Class: rviz/FocusCamera
|
||||
- Class: rviz/Measure
|
||||
- Class: rviz/SetInitialPose
|
||||
Theta std deviation: 0.2617993950843811
|
||||
Topic: /initialpose
|
||||
X std deviation: 0.5
|
||||
Y std deviation: 0.5
|
||||
- Class: rviz/SetGoal
|
||||
Topic: /move_base_simple/goal
|
||||
- Class: rviz/PublishPoint
|
||||
Single click: true
|
||||
Topic: /clicked_point
|
||||
Value: true
|
||||
Views:
|
||||
Current:
|
||||
Class: rviz/Orbit
|
||||
Distance: 10.812461853027344
|
||||
Enable Stereo Rendering:
|
||||
Stereo Eye Separation: 0.05999999865889549
|
||||
Stereo Focal Distance: 1
|
||||
Swap Stereo Eyes: false
|
||||
Value: false
|
||||
Field of View: 0.7853981852531433
|
||||
Focal Point:
|
||||
X: -0.4511165916919708
|
||||
Y: -0.1217871829867363
|
||||
Z: 0.8345625996589661
|
||||
Focal Shape Fixed Size: true
|
||||
Focal Shape Size: 0.05000000074505806
|
||||
Invert Z Axis: false
|
||||
Name: Current View
|
||||
Near Clip Distance: 0.009999999776482582
|
||||
Pitch: 0.830398678779602
|
||||
Target Frame: <Fixed Frame>
|
||||
Yaw: 3.0054032802581787
|
||||
Saved: ~
|
||||
Window Geometry:
|
||||
Displays:
|
||||
collapsed: false
|
||||
Height: 1029
|
||||
Hide Left Dock: false
|
||||
Hide Right Dock: false
|
||||
Image:
|
||||
collapsed: false
|
||||
QMainWindow State: 000000ff00000000fd00000004000000000000015600000367fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000274000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000002b7000000ed0000001600ffffff000000010000010f00000367fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d00000367000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000003efc0100000002fb0000000800540069006d00650100000000000007800000033700fffffffb0000000800540069006d006501000000000000045000000000000000000000050f0000036700000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
|
||||
Selection:
|
||||
collapsed: false
|
||||
Time:
|
||||
collapsed: false
|
||||
Tool Properties:
|
||||
collapsed: false
|
||||
Views:
|
||||
collapsed: false
|
||||
Width: 1920
|
||||
X: 0
|
||||
Y: 27
|
||||
@@ -0,0 +1,248 @@
|
||||
Panels:
|
||||
- Class: rviz_common/Displays
|
||||
Help Height: 78
|
||||
Name: Displays
|
||||
Property Tree Widget:
|
||||
Expanded:
|
||||
- /Global Options1
|
||||
- /Status1
|
||||
- /PointCloud21
|
||||
- /PointCloud22
|
||||
- /Image1
|
||||
- /Image1/Topic1
|
||||
- /Odometry1
|
||||
Splitter Ratio: 0.5
|
||||
Tree Height: 472
|
||||
- Class: rviz_common/Selection
|
||||
Name: Selection
|
||||
- Class: rviz_common/Tool Properties
|
||||
Expanded:
|
||||
- /2D Goal Pose1
|
||||
- /Publish Point1
|
||||
Name: Tool Properties
|
||||
Splitter Ratio: 0.5886790156364441
|
||||
- Class: rviz_common/Views
|
||||
Expanded:
|
||||
- /Current View1
|
||||
Name: Views
|
||||
Splitter Ratio: 0.5
|
||||
Visualization Manager:
|
||||
Class: ""
|
||||
Displays:
|
||||
- Alpha: 0.5
|
||||
Cell Size: 1
|
||||
Class: rviz_default_plugins/Grid
|
||||
Color: 160; 160; 164
|
||||
Enabled: true
|
||||
Line Style:
|
||||
Line Width: 0.029999999329447746
|
||||
Value: Lines
|
||||
Name: Grid
|
||||
Normal Cell Count: 0
|
||||
Offset:
|
||||
X: 0
|
||||
Y: 0
|
||||
Z: 0
|
||||
Plane: XY
|
||||
Plane Cell Count: 10
|
||||
Reference Frame: <Fixed Frame>
|
||||
Value: true
|
||||
- Alpha: 1
|
||||
Autocompute Intensity Bounds: true
|
||||
Autocompute Value Bounds:
|
||||
Max Value: 10
|
||||
Min Value: -10
|
||||
Value: true
|
||||
Axis: Z
|
||||
Channel Name: intensity
|
||||
Class: rviz_default_plugins/PointCloud2
|
||||
Color: 255; 255; 255
|
||||
Color Transformer: RGB8
|
||||
Decay Time: 0
|
||||
Enabled: true
|
||||
Invert Rainbow: false
|
||||
Max Color: 255; 255; 255
|
||||
Max Intensity: 4096
|
||||
Min Color: 0; 0; 0
|
||||
Min Intensity: 0
|
||||
Name: PointCloud2
|
||||
Position Transformer: XYZ
|
||||
Selectable: true
|
||||
Size (Pixels): 3
|
||||
Size (m): 0.009999999776482582
|
||||
Style: Flat Squares
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /odin1/cloud_slam
|
||||
Use Fixed Frame: true
|
||||
Use rainbow: true
|
||||
Value: true
|
||||
- Alpha: 1
|
||||
Autocompute Intensity Bounds: true
|
||||
Autocompute Value Bounds:
|
||||
Max Value: 10
|
||||
Min Value: -10
|
||||
Value: true
|
||||
Axis: Z
|
||||
Channel Name: intensity
|
||||
Class: rviz_default_plugins/PointCloud2
|
||||
Color: 255; 255; 255
|
||||
Color Transformer: ""
|
||||
Decay Time: 0
|
||||
Enabled: false
|
||||
Invert Rainbow: false
|
||||
Max Color: 255; 255; 255
|
||||
Max Intensity: 4096
|
||||
Min Color: 0; 0; 0
|
||||
Min Intensity: 0
|
||||
Name: PointCloud2
|
||||
Position Transformer: ""
|
||||
Selectable: true
|
||||
Size (Pixels): 3
|
||||
Size (m): 0.009999999776482582
|
||||
Style: Flat Squares
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /odin1/cloud_raw
|
||||
Use Fixed Frame: true
|
||||
Use rainbow: true
|
||||
Value: false
|
||||
- Class: rviz_default_plugins/Image
|
||||
Enabled: true
|
||||
Max Value: 1
|
||||
Median window: 5
|
||||
Min Value: 0
|
||||
Name: Image
|
||||
Normalize Range: true
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /odin1/image
|
||||
Value: true
|
||||
- Angle Tolerance: 0.10000000149011612
|
||||
Class: rviz_default_plugins/Odometry
|
||||
Covariance:
|
||||
Orientation:
|
||||
Alpha: 0.5
|
||||
Color: 255; 255; 127
|
||||
Color Style: Unique
|
||||
Frame: Local
|
||||
Offset: 1
|
||||
Scale: 1
|
||||
Value: true
|
||||
Position:
|
||||
Alpha: 0.30000001192092896
|
||||
Color: 204; 51; 204
|
||||
Scale: 1
|
||||
Value: true
|
||||
Value: true
|
||||
Enabled: true
|
||||
Keep: 100
|
||||
Name: Odometry
|
||||
Position Tolerance: 0.10000000149011612
|
||||
Shape:
|
||||
Alpha: 1
|
||||
Axes Length: 1
|
||||
Axes Radius: 0.10000000149011612
|
||||
Color: 255; 25; 0
|
||||
Head Length: 0.30000001192092896
|
||||
Head Radius: 0.10000000149011612
|
||||
Shaft Length: 1
|
||||
Shaft Radius: 0.05000000074505806
|
||||
Value: Axes
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /odin1/odometry_map
|
||||
Value: true
|
||||
Enabled: true
|
||||
Global Options:
|
||||
Background Color: 48; 48; 48
|
||||
Fixed Frame: map
|
||||
Frame Rate: 30
|
||||
Name: root
|
||||
Tools:
|
||||
- Class: rviz_default_plugins/Interact
|
||||
Hide Inactive Objects: true
|
||||
- Class: rviz_default_plugins/MoveCamera
|
||||
- Class: rviz_default_plugins/Select
|
||||
- Class: rviz_default_plugins/FocusCamera
|
||||
- Class: rviz_default_plugins/Measure
|
||||
Line color: 128; 128; 0
|
||||
- Class: rviz_default_plugins/SetInitialPose
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /initialpose
|
||||
- Class: rviz_default_plugins/SetGoal
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /goal_pose
|
||||
- Class: rviz_default_plugins/PublishPoint
|
||||
Single click: true
|
||||
Topic:
|
||||
Depth: 5
|
||||
Durability Policy: Volatile
|
||||
History Policy: Keep Last
|
||||
Reliability Policy: Reliable
|
||||
Value: /clicked_point
|
||||
Transformation:
|
||||
Current:
|
||||
Class: rviz_default_plugins/TF
|
||||
Value: true
|
||||
Views:
|
||||
Current:
|
||||
Class: rviz_default_plugins/Orbit
|
||||
Distance: 10.72309398651123
|
||||
Enable Stereo Rendering:
|
||||
Stereo Eye Separation: 0.05999999865889549
|
||||
Stereo Focal Distance: 1
|
||||
Swap Stereo Eyes: false
|
||||
Value: false
|
||||
Focal Point:
|
||||
X: 0
|
||||
Y: 0
|
||||
Z: 0
|
||||
Focal Shape Fixed Size: false
|
||||
Focal Shape Size: 0.05000000074505806
|
||||
Invert Z Axis: false
|
||||
Name: Current View
|
||||
Near Clip Distance: 0.009999999776482582
|
||||
Pitch: 0.7503987550735474
|
||||
Target Frame: <Fixed Frame>
|
||||
Value: Orbit (rviz)
|
||||
Yaw: 2.205399513244629
|
||||
Saved: ~
|
||||
Window Geometry:
|
||||
Displays:
|
||||
collapsed: false
|
||||
Height: 1029
|
||||
Hide Left Dock: false
|
||||
Hide Right Dock: false
|
||||
Image:
|
||||
collapsed: false
|
||||
QMainWindow State: 000000ff00000000fd000000040000000000000242000003abfc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000263000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000002a6000001420000002800ffffff000000010000010f000003abfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d000003ab000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000423000003ab00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
|
||||
Selection:
|
||||
collapsed: false
|
||||
Tool Properties:
|
||||
collapsed: false
|
||||
Views:
|
||||
collapsed: false
|
||||
Width: 1920
|
||||
X: 0
|
||||
Y: 27
|
||||
+14
-16
@@ -67,14 +67,14 @@ limitations under the License.
|
||||
}
|
||||
#endif
|
||||
|
||||
// 公共定义
|
||||
// Common definitions
|
||||
#define GD_ACCL_G 9.7833f
|
||||
#define ACC_1G_ms2 9.8
|
||||
#define ACC_SEN_SCALE 16348
|
||||
#define PAI 3.14159265358979323846
|
||||
#define GYRO_SEN_SCALE 32.8f
|
||||
|
||||
// 公共函数
|
||||
// Common functions
|
||||
inline float accel_convert(int16_t raw, int sen_scale) {
|
||||
return (raw * GD_ACCL_G / sen_scale);
|
||||
}
|
||||
@@ -103,7 +103,7 @@ inline uint64_t ros_time_to_ns(const ros::Time &t) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// 多传感器发布器类
|
||||
// Multi-sensor publisher class
|
||||
class MultiSensorPublisher {
|
||||
public:
|
||||
#ifdef ROS2
|
||||
@@ -175,7 +175,7 @@ void publishIntensityCloud(capture_Image_List_t* stream, int idx)
|
||||
#else
|
||||
sensor_msgs::PointCloud2 msg;
|
||||
msg.header.frame_id = "map";
|
||||
msg.header.stamp = ros::Time::now(); // ROS1使用全局时间
|
||||
msg.header.stamp = ros::Time::now();
|
||||
msg.height = stream->imageList[idx].height;
|
||||
msg.width = stream->imageList[idx].width;
|
||||
msg.is_dense = false;
|
||||
@@ -206,18 +206,18 @@ void publishIntensityCloud(capture_Image_List_t* stream, int idx)
|
||||
|
||||
#ifdef ROS2
|
||||
*iter_x = pf[2] / 1000.0f; ++iter_x;
|
||||
*iter_y = pf[0] / 1000.0f; ++iter_y;
|
||||
*iter_z = -pf[1] / 1000.0f; ++iter_z;
|
||||
*iter_y = -pf[0] / 1000.0f; ++iter_y;
|
||||
*iter_z = pf[1] / 1000.0f; ++iter_z;
|
||||
*iter_intensity = static_cast<uint8_t>(intensity_data[i] >> 8); ++iter_intensity;
|
||||
#else
|
||||
*iter_x = pf[2] / 1000.0f; ++iter_x;
|
||||
*iter_y = pf[0] / 1000.0f; ++iter_y;
|
||||
*iter_z = -pf[1] / 1000.0f; ++iter_z;
|
||||
*iter_y = -pf[0] / 1000.0f; ++iter_y;
|
||||
*iter_z = pf[1] / 1000.0f; ++iter_z;
|
||||
*iter_intensity = static_cast<uint8_t>(intensity_data[i] >> 8); ++iter_intensity;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 发布点云
|
||||
// Publish Intensity point cloud
|
||||
#ifdef ROS2
|
||||
cloud_pub_->publish(std::move(msg));
|
||||
#else
|
||||
@@ -228,7 +228,7 @@ void publishIntensityCloud(capture_Image_List_t* stream, int idx)
|
||||
void publishRgb(capture_Image_List_t *stream) {
|
||||
buffer_List_t &image = stream->imageList[0];
|
||||
|
||||
// 验证图像参数
|
||||
// Validate image parameters
|
||||
if (!image.pAddr) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(node_->get_logger(), "Invalid RGB image: null data pointer");
|
||||
@@ -247,10 +247,10 @@ void publishIntensityCloud(capture_Image_List_t* stream, int idx)
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算 NV12 图像高度
|
||||
// Calculate NV12 image height
|
||||
const int height_nv12 = image.height * 3 / 2;
|
||||
|
||||
// 验证 NV12 图像尺寸
|
||||
// Validate NV12 image size
|
||||
const size_t expected_size = static_cast<size_t>(image.width) * height_nv12;
|
||||
if (image.length < expected_size) {
|
||||
#ifdef ROS2
|
||||
@@ -371,7 +371,7 @@ void publishPC2XYZRGBA(capture_Image_List_t* stream, int idx)
|
||||
sensor_msgs::PointCloud2Iterator<float> iter_rgb(msg, "rgb");
|
||||
#endif
|
||||
|
||||
// 共享的数据处理逻辑
|
||||
// Shared data processing logic
|
||||
int32_t* xyz_data = static_cast<int32_t*>(stream->imageList[idx].pAddr);
|
||||
|
||||
for(uint32_t i = 0; i < points; i++) {
|
||||
@@ -402,7 +402,7 @@ void publishPC2XYZRGBA(capture_Image_List_t* stream, int idx)
|
||||
}
|
||||
|
||||
#ifdef ROS2
|
||||
flag = 0; // 如果flag在其他地方使用,保留赋值
|
||||
flag = 0; // Preserve assignment if flag is used elsewhere
|
||||
xyzrgbacloud_pub_->publish(std::move(msg));
|
||||
#else
|
||||
flag = 0;
|
||||
@@ -476,7 +476,6 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
// 命令行控制类
|
||||
class CommandLineControl {
|
||||
public:
|
||||
using Callback = std::function<void(const std::string&, int)>;
|
||||
@@ -539,7 +538,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
// 控制命令定义
|
||||
#define STREAMCTRL "streamctrl" /* start/stop all streams */
|
||||
#define SENDRGB "sendrgb" /* send RGB data */
|
||||
#define SENDIMU "sendimu" /* send IMU data */
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace odin_ros_driver {
|
||||
|
||||
class YamlParser {
|
||||
public:
|
||||
// 使用一致的成员变量名
|
||||
YamlParser(const std::string& config_file);
|
||||
|
||||
bool loadConfig();
|
||||
@@ -33,6 +32,6 @@ private:
|
||||
std::map<std::string, int> register_keys_;
|
||||
};
|
||||
|
||||
} // namespace odin_ros_driver
|
||||
}
|
||||
|
||||
#endif // YAML_PARSER_H
|
||||
#endif
|
||||
@@ -1,12 +1,22 @@
|
||||
<launch>
|
||||
<!--
|
||||
用法: roslaunch odin_ros_driver odin1_ros1.launch
|
||||
Usage: roslaunch odin_ros_driver odin1_ros1.launch
|
||||
-->
|
||||
|
||||
<!-- 设置节点名称 -->
|
||||
<!-- Set node name -->
|
||||
<arg name="node_name" default="host_sdk_sample"/>
|
||||
|
||||
<!-- 启动节点 -->
|
||||
<!-- Set parameter file path -->
|
||||
<arg name="config_file" default="$(find odin_ros_driver)/config/control_command.yaml"/>
|
||||
|
||||
<!-- Set RViz configuration file path -->
|
||||
<arg name="rviz_config" default="$(find odin_ros_driver)/config/odin_ros.rviz"/>
|
||||
|
||||
<!-- Launch main node -->
|
||||
<node name="$(arg node_name)" pkg="odin_ros_driver" type="host_sdk_sample" output="screen">
|
||||
<param name="config_file" value="$(arg config_file)"/>
|
||||
</node>
|
||||
|
||||
<!-- Launch RViz with configuration -->
|
||||
<node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rviz_config)" output="screen"/>
|
||||
</launch>
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#用法: ros2 launch odin_ros_driver odin1_ros2.launch.py
|
||||
# USAGE: ros2 launch odin_ros_driver odin1_ros2.launch.py
|
||||
import os
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
from launch import LaunchDescription
|
||||
@@ -8,17 +8,24 @@ from launch.substitutions import LaunchConfiguration
|
||||
from launch_ros.actions import Node
|
||||
|
||||
def generate_launch_description():
|
||||
# 获取包目录
|
||||
# Get package directory
|
||||
package_dir = get_package_share_directory('odin_ros_driver')
|
||||
|
||||
# 声明配置参数
|
||||
# Declare configuration parameter
|
||||
config_file_arg = DeclareLaunchArgument(
|
||||
'config_file',
|
||||
default_value=os.path.join(package_dir, 'config', 'control_command.yaml'),
|
||||
description='Path to the control config YAML file'
|
||||
)
|
||||
|
||||
# 创建节点
|
||||
# Add RViz2 configuration file parameter
|
||||
rviz_config_arg = DeclareLaunchArgument(
|
||||
'rviz_config',
|
||||
default_value=os.path.join(package_dir, 'config', 'odin_ros2.rviz'),
|
||||
description='Path to RViz2 config file'
|
||||
)
|
||||
|
||||
# Create main node
|
||||
host_sdk_node = Node(
|
||||
package='odin_ros_driver',
|
||||
executable='host_sdk_sample',
|
||||
@@ -30,9 +37,20 @@ def generate_launch_description():
|
||||
}]
|
||||
)
|
||||
|
||||
# 创建启动描述
|
||||
# Create RViz2 node - loads specified configuration file
|
||||
rviz_node = Node(
|
||||
package='rviz2',
|
||||
executable='rviz2',
|
||||
name='rviz2',
|
||||
output='screen',
|
||||
arguments=['-d', LaunchConfiguration('rviz_config')]
|
||||
)
|
||||
|
||||
# Create launch description
|
||||
ld = LaunchDescription()
|
||||
ld.add_action(config_file_arg)
|
||||
ld.add_action(rviz_config_arg) # Add RViz configuration argument
|
||||
ld.add_action(host_sdk_node)
|
||||
ld.add_action(rviz_node) # Add RViz node
|
||||
|
||||
return ld
|
||||
+4
-4
@@ -6,10 +6,10 @@
|
||||
<maintainer email="[email protected]">rlk</maintainer>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
<!-- ROS1 使用 catkin 作为构建工具 -->
|
||||
<!-- ROS1 uses catkin as the build tool -->
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<!-- ROS1 依赖项 -->
|
||||
<!-- ROS1 dependencies -->
|
||||
<depend>roscpp</depend>
|
||||
<depend>std_msgs</depend>
|
||||
<depend>sensor_msgs</depend>
|
||||
@@ -17,12 +17,12 @@
|
||||
<depend>cv_bridge</depend>
|
||||
<depend>image_transport</depend>
|
||||
|
||||
<!-- 系统依赖项 -->
|
||||
<!-- System dependencies -->
|
||||
<depend>eigen</depend>
|
||||
<depend>opencv</depend>
|
||||
<depend>yaml-cpp</depend>
|
||||
|
||||
<!-- 指定构建类型为 catkin -->
|
||||
<!-- Specify build type as catkin -->
|
||||
<export>
|
||||
<build_type>catkin</build_type>
|
||||
</export>
|
||||
|
||||
+4
-4
@@ -5,17 +5,17 @@
|
||||
<description>ROS2 driver for Odin sensor</description>
|
||||
<maintainer email="[email protected]">rlk</maintainer>
|
||||
<license>Apache 2.0</license>
|
||||
<!-- ROS2 使用 colcon 作为构建工具 -->
|
||||
<!-- ROS2 uses colcon as the build tool -->
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
<!-- ROS2 依赖项 -->
|
||||
<!-- ROS2 dependencies -->
|
||||
<depend>rclcpp</depend>
|
||||
<!-- 系统依赖项 -->
|
||||
<!-- System dependencies -->
|
||||
<depend>std_msgs</depend>
|
||||
<depend>sensor_msgs</depend>
|
||||
<depend>nav_msgs</depend>
|
||||
<depend>cv_bridge</depend>
|
||||
<depend>image_transport</depend>
|
||||
<!-- 指定构建类型为 ament -->
|
||||
<!-- Specify build type as ament -->
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
|
||||
+44
-44
@@ -1,117 +1,117 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 获取脚本所在目录(Odin_ROS_Driver 目录)
|
||||
# Get the directory where the script is located (Odin_ROS_Driver directory)
|
||||
PKG_DIR="$(cd "$(dirname "$0")/.."; pwd)"
|
||||
# 计算工作空间根目录(包含 devel、build、src 的目录)
|
||||
# Calculate the workspace root directory (contains devel, build, src)
|
||||
WORKSPACE_ROOT="$(dirname "$(dirname "$PKG_DIR")")"
|
||||
# 工作空间源码目录(包含所有包的 src)
|
||||
# Workspace source directory (contains all packages)
|
||||
WORKSPACE_SRC="${WORKSPACE_ROOT}/src"
|
||||
PROJECT_NAME="odin_ros_driver"
|
||||
|
||||
# 定义颜色代码
|
||||
# Define color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # 无颜色
|
||||
NC='\033[0m'
|
||||
|
||||
# 清理函数
|
||||
# Clean workspace function
|
||||
clean_workspace() {
|
||||
echo -e "${YELLOW}🧹 清理构建目录${NC}"
|
||||
echo -e "${YELLOW}Cleaning build directories${NC}"
|
||||
|
||||
# 清理工作空间根目录下的构建产物
|
||||
# Clean build artifacts in workspace
|
||||
rm -rf "${WORKSPACE_ROOT}/build"
|
||||
rm -rf "${WORKSPACE_ROOT}/install"
|
||||
rm -rf "${WORKSPACE_ROOT}/log"
|
||||
rm -rf "${WORKSPACE_ROOT}/devel"
|
||||
|
||||
echo -e "${GREEN}✅ 清理完成${NC}"
|
||||
echo -e "${GREEN}Cleanup complete${NC}"
|
||||
}
|
||||
|
||||
# 运行函数
|
||||
# Run node function
|
||||
run_node() {
|
||||
echo -e "${YELLOW}🏃♂️➡️ 运行 ROS1 节点${NC}"
|
||||
echo -e "${YELLOW}Running ROS1 node${NC}"
|
||||
|
||||
# 检查环境文件是否存在
|
||||
# Check if environment file exists
|
||||
if [ ! -f "${WORKSPACE_ROOT}/devel/setup.bash" ]; then
|
||||
echo -e "${RED}❌ 找不到 devel/setup.bash,请先执行 ./build_ros1.sh 构建项目${NC}"
|
||||
echo -e "${RED}Could not find devel/setup.bash, please build the project with ./build_ros1.sh first${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Source 环境并运行节点
|
||||
# Source environment and run node
|
||||
source "${WORKSPACE_ROOT}/devel/setup.bash"
|
||||
|
||||
}
|
||||
|
||||
# 构建函数
|
||||
# Build workspace function
|
||||
build_workspace() {
|
||||
echo -e "${YELLOW}🔍 工作空间结构:${NC}"
|
||||
echo " 工作空间根目录: ${WORKSPACE_ROOT}"
|
||||
echo " 源码目录: ${WORKSPACE_SRC}"
|
||||
echo " 包目录: ${PKG_DIR}"
|
||||
echo " ROS版本: ROS1"
|
||||
echo -e "${YELLOW}Workspace structure:${NC}"
|
||||
echo " Workspace root: ${WORKSPACE_ROOT}"
|
||||
echo " Source directory: ${WORKSPACE_SRC}"
|
||||
echo " Package directory: ${PKG_DIR}"
|
||||
echo " ROS version: ROS1"
|
||||
|
||||
echo -e "${YELLOW}🔧 开始构建 ROS1 工程...${NC}"
|
||||
echo -e "${YELLOW}Starting ROS1 project build...${NC}"
|
||||
|
||||
# 清理
|
||||
# Clean
|
||||
cd $WS_DIR
|
||||
rm -rf build devel install
|
||||
|
||||
# 确保 ROS1 环境已加载
|
||||
# Ensure ROS1 environment is loaded
|
||||
if [ -f "/opt/ros/noetic/setup.bash" ]; then
|
||||
source "/opt/ros/noetic/setup.bash"
|
||||
elif [ -f "/opt/ros/melodic/setup.bash" ]; then
|
||||
source "/opt/ros/melodic/setup.bash"
|
||||
else
|
||||
echo -e "${RED}❌ 找不到 ROS1 的 setup.bash 文件。请确保 ROS1 已安装。${NC}"
|
||||
echo -e "${RED}Could not find ROS1 setup.bash file. Please ensure ROS1 is installed.${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 创建临时 package.xml
|
||||
# Create temporary package.xml
|
||||
if [ -f "${PKG_DIR}/package_ros1.xml" ]; then
|
||||
echo "🔄 创建临时 package.xml(使用 package_ros1.xml)"
|
||||
echo "Creating temporary package.xml (using package_ros1.xml)"
|
||||
cp "${PKG_DIR}/package_ros1.xml" "${PKG_DIR}/package.xml"
|
||||
TEMP_PACKAGE=true
|
||||
elif [ -f "${PKG_DIR}/package.xml" ]; then
|
||||
echo "ℹ️ 使用现有的 package.xml"
|
||||
echo "Using existing package.xml"
|
||||
else
|
||||
echo -e "${RED}❌ 在包目录中找不到 package.xml${NC}"
|
||||
echo -e "${RED}Could not find package.xml in package directory${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 设置构建系统变量
|
||||
# Set build system variable
|
||||
export BUILD_SYSTEM=ROS1
|
||||
|
||||
# 切换到工作空间根目录并构建
|
||||
# Switch to workspace root and build
|
||||
cd "${WORKSPACE_ROOT}" || return 1
|
||||
catkin_make -DBUILD_SYSTEM=ROS1 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -j$(nproc)
|
||||
BUILD_RESULT=$?
|
||||
|
||||
# 构建成功,source 环境
|
||||
# If build successful, source environment
|
||||
if [[ $BUILD_RESULT -eq 0 ]]; then
|
||||
echo -e "${GREEN}✅ ROS1 构建成功,载入环境变量:source devel/setup.bash${NC}"
|
||||
echo -e "${GREEN}ROS1 build successful, loading environment: source devel/setup.bash${NC}"
|
||||
source "${WORKSPACE_ROOT}/devel/setup.bash"
|
||||
else
|
||||
echo -e "${RED}❌ ROS1 构建失败,请检查错误日志${NC}"
|
||||
echo -e "${RED}ROS1 build failed, please check error logs${NC}"
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
# 帮助函数
|
||||
# Help function
|
||||
show_help() {
|
||||
echo -e "${YELLOW}使用说明:${NC}"
|
||||
echo " ./build_ros.sh # 构建项目"
|
||||
echo " ./build_ros.sh -c # 清理构建产物"
|
||||
echo " ./build_ros.sh -h # 显示帮助信息"
|
||||
echo -e "${YELLOW}Usage:${NC}"
|
||||
echo " ./build_ros.sh # Build project"
|
||||
echo " ./build_ros.sh -c # Clean build artifacts"
|
||||
echo " ./build_ros.sh -h # Show help information"
|
||||
echo ""
|
||||
echo -e "${YELLOW}当前配置:${NC}"
|
||||
echo " 项目名称: ${PROJECT_NAME}"
|
||||
echo " 包目录: ${PKG_DIR}"
|
||||
echo " 工作空间根目录: ${WORKSPACE_ROOT}"
|
||||
echo " 源码目录: ${WORKSPACE_SRC}"
|
||||
echo -e "${YELLOW}Current configuration:${NC}"
|
||||
echo " Project name: ${PROJECT_NAME}"
|
||||
echo " Package directory: ${PKG_DIR}"
|
||||
echo " Workspace root: ${WORKSPACE_ROOT}"
|
||||
echo " Source directory: ${WORKSPACE_SRC}"
|
||||
}
|
||||
|
||||
# 主程序
|
||||
# Main
|
||||
case "$1" in
|
||||
-c|--clean)
|
||||
clean_workspace
|
||||
|
||||
+51
-51
@@ -1,73 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 获取脚本所在目录(Odin_ROS_Driver 目录)
|
||||
# Get the directory where the script is located (Odin_ROS_Driver directory)
|
||||
PKG_DIR="$(cd "$(dirname "$0")/.."; pwd)"
|
||||
# 计算工作空间根目录(包含 devel、build、src 的目录)
|
||||
# Calculate the workspace root directory (contains devel, build, src)
|
||||
WORKSPACE_ROOT="$(dirname "$(dirname "$PKG_DIR")")"
|
||||
# 工作空间源码目录(包含所有包的 src)
|
||||
# Workspace source directory (contains all packages)
|
||||
WORKSPACE_SRC="${WORKSPACE_ROOT}/src"
|
||||
PROJECT_NAME="odin_ros_driver"
|
||||
PACKAGE_DIR_NAME=$(basename "$PKG_DIR")
|
||||
|
||||
# 定义颜色代码
|
||||
# Define color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # 无颜色
|
||||
NC='\033[0m'
|
||||
|
||||
# 从 package.xml 中提取包名
|
||||
# Extract package name from package.xml
|
||||
get_package_name() {
|
||||
local package_xml="$1"
|
||||
if [ -f "$package_xml" ]; then
|
||||
# 提取 <name> 标签内容
|
||||
# Extract content of <name> tag
|
||||
grep -oP '<name>\K[^<]+' "$package_xml" | head -1
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# 清理函数
|
||||
# Clean workspace function
|
||||
clean_workspace() {
|
||||
echo -e "${YELLOW}🧹 清理构建目录${NC}"
|
||||
echo -e "${YELLOW}Cleaning build directories${NC}"
|
||||
|
||||
# 清理工作空间根目录下的构建产物
|
||||
# Clean build artifacts in workspace
|
||||
rm -rf "${WORKSPACE_ROOT}/build"
|
||||
rm -rf "${WORKSPACE_ROOT}/install"
|
||||
rm -rf "${WORKSPACE_ROOT}/log"
|
||||
rm -rf "${WORKSPACE_ROOT}/devel"
|
||||
|
||||
echo -e "${GREEN}✅ 清理完成${NC}"
|
||||
echo -e "${GREEN}Cleanup complete${NC}"
|
||||
}
|
||||
|
||||
# 运行函数
|
||||
# Run node function
|
||||
run_node() {
|
||||
echo -e "${YELLOW}🏃♂️➡️ 运行 ROS2 节点${NC}"
|
||||
echo -e "${YELLOW}Running ROS2 node${NC}"
|
||||
|
||||
# 检查环境文件是否存在
|
||||
# Check if environment file exists
|
||||
if [ ! -f "${WORKSPACE_ROOT}/install/setup.bash" ]; then
|
||||
echo -e "${RED}❌ 找不到 install/setup.bash,请先执行 ./build_ros2.sh 构建项目${NC}"
|
||||
echo -e "${RED}Could not find install/setup.bash, please build the project with ./build_ros2.sh first${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Source 环境并运行节点
|
||||
# Source environment and run node
|
||||
source "${WORKSPACE_ROOT}/install/setup.bash"
|
||||
|
||||
}
|
||||
|
||||
# 构建函数
|
||||
# Build workspace function
|
||||
build_workspace() {
|
||||
echo -e "${YELLOW}🔍 工作空间结构:${NC}"
|
||||
echo " 工作空间根目录: ${WORKSPACE_ROOT}"
|
||||
echo " 源码目录: ${WORKSPACE_SRC}"
|
||||
echo " 包目录: ${PKG_DIR}"
|
||||
echo " 目录名: ${PACKAGE_DIR_NAME}"
|
||||
echo " ROS版本: ROS2"
|
||||
echo -e "${YELLOW}Workspace structure:${NC}"
|
||||
echo " Workspace root: ${WORKSPACE_ROOT}"
|
||||
echo " Source directory: ${WORKSPACE_SRC}"
|
||||
echo " Package directory: ${PKG_DIR}"
|
||||
echo " Directory name: ${PACKAGE_DIR_NAME}"
|
||||
echo " ROS version: ROS2"
|
||||
|
||||
echo -e "${YELLOW}Starting ROS2 project build...${NC}"
|
||||
|
||||
echo -e "${YELLOW}🔧 开始构建 ROS2 工程...${NC}"
|
||||
# 清理
|
||||
cd $WS_DIR
|
||||
rm -rf build install log
|
||||
# 确保 ROS2 环境已加载
|
||||
# Ensure ROS2 environment is loaded
|
||||
if [ -f "/opt/ros/foxy/setup.bash" ]; then
|
||||
source "/opt/ros/foxy/setup.bash"
|
||||
elif [ -f "/opt/ros/galactic/setup.bash" ]; then
|
||||
@@ -75,38 +75,38 @@ build_workspace() {
|
||||
elif [ -f "/opt/ros/humble/setup.bash" ]; then
|
||||
source "/opt/ros/humble/setup.bash"
|
||||
else
|
||||
echo -e "${RED}❌ 找不到 ROS2 的 setup.bash 文件。请确保 ROS2 已安装。${NC}"
|
||||
echo -e "${RED}Could not find ROS2 setup.bash file. Please ensure ROS2 is installed.${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 创建临时 package.xml
|
||||
# Create temporary package.xml
|
||||
if [ -f "${PKG_DIR}/package_ros2.xml" ]; then
|
||||
echo "🔄 创建临时 package.xml(使用 package_ros2.xml)"
|
||||
echo "Creating temporary package.xml (using package_ros2.xml)"
|
||||
cp "${PKG_DIR}/package_ros2.xml" "${PKG_DIR}/package.xml"
|
||||
TEMP_PACKAGE=true
|
||||
elif [ -f "${PKG_DIR}/package.xml" ]; then
|
||||
echo "ℹ️ 使用现有的 package.xml"
|
||||
echo "Using existing package.xml"
|
||||
TEMP_PACKAGE=false
|
||||
else
|
||||
echo -e "${RED}❌ 在包目录中找不到 package.xml${NC}"
|
||||
echo -e "${RED}Could not find package.xml in package directory${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 从 package.xml 中提取包名
|
||||
# Extract package name from package.xml
|
||||
PACKAGE_NAME=$(get_package_name "${PKG_DIR}/package.xml")
|
||||
if [ -z "$PACKAGE_NAME" ]; then
|
||||
echo -e "${RED}❌ 无法从 package.xml 中提取包名${NC}"
|
||||
echo -e "${RED}Failed to extract package name from package.xml${NC}"
|
||||
return 1
|
||||
fi
|
||||
echo " 包名: ${PACKAGE_NAME}"
|
||||
echo " Package name: ${PACKAGE_NAME}"
|
||||
|
||||
# 设置构建系统变量
|
||||
# Set build system variable
|
||||
export BUILD_SYSTEM=ROS2
|
||||
|
||||
# 切换到工作空间根目录并构建
|
||||
# Switch to workspace root and build
|
||||
cd "${WORKSPACE_ROOT}" || return 1
|
||||
|
||||
# 使用正确的包名构建
|
||||
# Build with correct package name
|
||||
colcon build \
|
||||
--packages-select "${PACKAGE_NAME}" \
|
||||
--parallel-workers $(nproc) \
|
||||
@@ -116,32 +116,32 @@ build_workspace() {
|
||||
|
||||
BUILD_RESULT=$?
|
||||
|
||||
# 构建成功,source 环境
|
||||
# If build successful, source environment
|
||||
if [[ $BUILD_RESULT -eq 0 ]]; then
|
||||
echo -e "${GREEN}✅ ROS2 构建成功,载入环境变量:source install/setup.bash${NC}"
|
||||
echo -e "${GREEN}ROS2 build successful, loading environment: source install/setup.bash${NC}"
|
||||
source "${WORKSPACE_ROOT}/install/setup.bash"
|
||||
|
||||
else
|
||||
echo -e "${RED}❌ ROS2 构建失败,请检查错误日志${NC}"
|
||||
echo -e "${RED}ROS2 build failed, please check error logs${NC}"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# 帮助函数
|
||||
# Help function
|
||||
show_help() {
|
||||
echo -e "${YELLOW}使用说明:${NC}"
|
||||
echo " ./build_ros2.sh # 构建项目"
|
||||
echo " ./build_ros2.sh -c # 清理构建产物"
|
||||
echo " ./build_ros2.sh -h # 显示帮助信息"
|
||||
echo -e "${YELLOW}Usage:${NC}"
|
||||
echo " ./build_ros2.sh # Build project"
|
||||
echo " ./build_ros2.sh -c # Clean build artifacts"
|
||||
echo " ./build_ros2.sh -h # Show help information"
|
||||
echo ""
|
||||
echo -e "${YELLOW}当前配置:${NC}"
|
||||
echo " 项目名称: ${PROJECT_NAME}"
|
||||
echo " 包目录: ${PKG_DIR}"
|
||||
echo " 工作空间根目录: ${WORKSPACE_ROOT}"
|
||||
echo " 源码目录: ${WORKSPACE_SRC}"
|
||||
echo -e "${YELLOW}Current configuration:${NC}"
|
||||
echo " Project name: ${PROJECT_NAME}"
|
||||
echo " Package directory: ${PKG_DIR}"
|
||||
echo " Workspace root: ${WORKSPACE_ROOT}"
|
||||
echo " Source directory: ${WORKSPACE_SRC}"
|
||||
}
|
||||
|
||||
# 主程序
|
||||
# Main program
|
||||
case "$1" in
|
||||
-c|--clean)
|
||||
clean_workspace
|
||||
|
||||
+20
-21
@@ -16,7 +16,7 @@ static device_handle odinDevice = nullptr;
|
||||
static std::shared_ptr<MultiSensorPublisher> g_ros_object;
|
||||
static std::atomic<bool> deviceConnected(false);
|
||||
|
||||
// 定义获取包路径的函数
|
||||
// Function to get package share path
|
||||
std::string get_package_share_path(const std::string& package_name) {
|
||||
#ifdef ROS2
|
||||
try {
|
||||
@@ -33,7 +33,7 @@ std::string get_package_share_path(const std::string& package_name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// 全局配置变量
|
||||
// Global configuration variables
|
||||
static int g_sendrgb = 1;
|
||||
static int g_sendimu = 1;
|
||||
static int g_senddtof = 1;
|
||||
@@ -93,7 +93,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
ROS_INFO("Device attaching...");
|
||||
#endif
|
||||
|
||||
// 清理任何已存在的设备
|
||||
// Clean up any existing device
|
||||
if (odinDevice) {
|
||||
lidar_stop_stream(odinDevice, type);
|
||||
lidar_unregister_stream_callback(odinDevice);
|
||||
@@ -102,7 +102,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
odinDevice = nullptr;
|
||||
}
|
||||
|
||||
// 修复:使用const_cast移除const限定符
|
||||
// Use const_cast to remove const qualifier
|
||||
if (lidar_create_device(const_cast<lidar_device_info_t*>(device), &odinDevice)) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Create device failed");
|
||||
@@ -112,7 +112,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
return;
|
||||
}
|
||||
|
||||
// 打开设备
|
||||
// Open device
|
||||
if (lidar_open_device(odinDevice)) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Open device failed");
|
||||
@@ -124,7 +124,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置模式
|
||||
// Set mode
|
||||
if (lidar_set_mode(odinDevice, type)) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Set mode failed");
|
||||
@@ -137,7 +137,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
return;
|
||||
}
|
||||
|
||||
// 注册回调
|
||||
// Register callback
|
||||
lidar_data_callback_info_t data_callback_info;
|
||||
data_callback_info.data_callback = lidar_data_callback;
|
||||
data_callback_info.user_data = &odinDevice;
|
||||
@@ -154,7 +154,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
return;
|
||||
}
|
||||
|
||||
// 启动数据流
|
||||
// Start data stream
|
||||
if (lidar_start_stream(odinDevice, type)) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Start stream failed");
|
||||
@@ -167,7 +167,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据配置激活数据流类型
|
||||
// Activate stream types based on configuration
|
||||
if (g_sendrgb) {
|
||||
lidar_activate_stream_type(odinDevice, LIDAR_DT_RAW_RGB);
|
||||
}
|
||||
@@ -211,7 +211,7 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// ROS初始化
|
||||
// ROS initialization
|
||||
#ifdef ROS2
|
||||
rclcpp::init(argc, argv);
|
||||
auto node = std::make_shared<rclcpp::Node>("lydros_node");
|
||||
@@ -226,10 +226,10 @@ int main(int argc, char *argv[])
|
||||
std::string package_path = get_package_share_path("odin_ros_driver");
|
||||
std::string config_file = package_path + "/config/control_command.yaml";
|
||||
|
||||
// 创建 YAML 解析器
|
||||
// Create YAML parser
|
||||
odin_ros_driver::YamlParser parser(config_file);
|
||||
|
||||
// 加载配置
|
||||
// Load configuration
|
||||
if (!parser.loadConfig()) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(node->get_logger(), "Failed to load config file: %s", config_file.c_str());
|
||||
@@ -239,13 +239,12 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 获取键值映射
|
||||
// Get key-value
|
||||
auto keys = parser.getRegisterKeys();
|
||||
|
||||
// 打印配置
|
||||
// Print configuration
|
||||
parser.printConfig();
|
||||
|
||||
// 获取键值函数
|
||||
auto get_key_value = [&](const std::string& key_name, int default_value) -> int {
|
||||
auto it = keys.find(key_name);
|
||||
if (it != keys.end()) {
|
||||
@@ -254,17 +253,17 @@ int main(int argc, char *argv[])
|
||||
return default_value;
|
||||
};
|
||||
|
||||
// 读取配置值到全局变量
|
||||
// Read configuration values into global variables
|
||||
g_sendrgb = get_key_value("sendrgb", 1);
|
||||
g_sendimu = get_key_value("sendimu", 1);
|
||||
g_senddtof = get_key_value("senddtof", 1);
|
||||
g_sendodom = get_key_value("sendodom", 1);
|
||||
g_sendcloudslam = get_key_value("sendcloudslam", 0);
|
||||
|
||||
// 设置日志级别
|
||||
// Set log level
|
||||
lidar_log_set_level(LIDAR_LOG_INFO);
|
||||
|
||||
// 初始化系统,启动USB监控
|
||||
// Initialize system and start USB monitoring
|
||||
if(lidar_system_init(lidar_device_callback)) {
|
||||
#ifdef ROS2
|
||||
RCLCPP_ERROR(node->get_logger(), "Lidar system init failed");
|
||||
@@ -274,7 +273,7 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 等待设备连接(最长30秒)
|
||||
// wait device connect
|
||||
#ifdef ROS2
|
||||
RCLCPP_INFO(node->get_logger(), "Waiting for device connection...");
|
||||
#else
|
||||
@@ -308,7 +307,7 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ROS主循环
|
||||
// ROS loop
|
||||
#ifdef ROS2
|
||||
rclcpp::spin(node);
|
||||
rclcpp::shutdown();
|
||||
@@ -317,7 +316,7 @@ int main(int argc, char *argv[])
|
||||
ros::shutdown();
|
||||
#endif
|
||||
|
||||
// 清理
|
||||
// Cleanup
|
||||
if (odinDevice) {
|
||||
lidar_stop_stream(odinDevice, LIDAR_MODE_SLAM);
|
||||
lidar_unregister_stream_callback(odinDevice);
|
||||
|
||||
+10
-11
@@ -2,35 +2,34 @@
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <algorithm> // 用于 std::transform
|
||||
#include <algorithm>
|
||||
|
||||
namespace odin_ros_driver {
|
||||
|
||||
// 使用一致的成员变量名
|
||||
YamlParser::YamlParser(const std::string& config_file)
|
||||
: config_file_(config_file) {} // 这里使用 config_file_
|
||||
: config_file_(config_file) {} // // Using config_file_ member variable
|
||||
|
||||
bool YamlParser::loadConfig() {
|
||||
try {
|
||||
// 使用成员变量 config_file_
|
||||
// Using member variable config_file_
|
||||
std::cerr << "Loading config file: " << config_file_ << std::endl;
|
||||
|
||||
// 检查文件是否存在
|
||||
// Check if file exists
|
||||
if (!std::filesystem::exists(config_file_)) {
|
||||
std::cerr << "Config file not found: " << config_file_ << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 打印文件内容
|
||||
// Print file contents
|
||||
std::ifstream file(config_file_);
|
||||
std::string content((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
std::cerr << "Config file content:\n" << content << "\n--- End of file ---" << std::endl;
|
||||
|
||||
// 加载 YAML - 使用成员变量 config_file_
|
||||
// Load YAML
|
||||
YAML::Node config = YAML::LoadFile(config_file_);
|
||||
|
||||
// 检查是否存在 register_keys 节点
|
||||
// Check if 'register_keys' node exists
|
||||
if (!config["register_keys"]) {
|
||||
std::cerr << "Missing 'register_keys' section in config file" << std::endl;
|
||||
return false;
|
||||
@@ -39,14 +38,14 @@ bool YamlParser::loadConfig() {
|
||||
YAML::Node register_keys = config["register_keys"];
|
||||
register_keys_.clear();
|
||||
|
||||
// 打印键值对数量
|
||||
// Print number of key-value pairs found
|
||||
std::cerr << "Found " << register_keys.size() << " keys in config" << std::endl;
|
||||
|
||||
for (YAML::const_iterator it = register_keys.begin(); it != register_keys.end(); ++it) {
|
||||
std::string key = it->first.as<std::string>();
|
||||
int value = it->second.as<int>();
|
||||
|
||||
// 转换为小写
|
||||
// Convert key to lowercase
|
||||
std::transform(key.begin(), key.end(), key.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
@@ -80,4 +79,4 @@ void YamlParser::printConfig() const {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace odin_ros_driver
|
||||
}
|
||||
Reference in New Issue
Block a user