從零搭建3D激光slam框架-基于mid360雷達節點實現

目錄

MID360雷達介紹

雷達SDK編譯與測試

雷達驅動的修改、編譯與測試

去ros的編譯方式

?livox_ros_driver2的代碼框架介紹

?livox_ros_driver2編譯

雷達IP配置文件介紹

常見問題介紹

優化改進


MID360雷達介紹

1 硬件介紹:

livox-mid360是大疆的一款非重復掃描固態激光雷達,20萬點/秒,可以調整幀率,內部自帶6軸IMU,與點云實現硬件同步。售價3999,線纜399,線纜包括網線電源與串口線,網線與雷達通信負責傳輸雷達點云與IMU數據,電源12V2A,給雷達供電,串口用于與雷達通信,獲取雷達工作狀態。

? ? ? ? ? ? ? ? ??? ??

2 軟件介紹:

? ? ? ?雷達軟件分為上位機點云測試軟件LivoxViewer_2.3.0_Win64,雷達LIVOX-SDK2(https://github.com/Livox-SDK/Livox-SDK2.git),livox-ros_driver2(https://github.com/Livox-SDK/livox_ros_driver2.git)雷達驅動ROS2節點,點云測試軟件可以查看點云形態,測試點云質量和通信穩定性。雷達LIVOX-SDK2,負責從雷達通過socket獲取網絡包,網絡包包含點云與imu數據,livox-ros_driver2 負責將livox-sdk2獲取的socket網絡包進行解析,解析出imu,lidar數據,填充到ros2話題消息中,填充消息有三種格式pclmsg,custommsg,sensor::pointcloud::msg,通常使用第二種自定義消息custommsg。

? ? ? ?livox_lidar_quick_start, 雷達快速啟動程序可以用于測試雷達通信和IP地址讀取,實現快速驗證雷達功能和軟件功能。

雷達SDK編譯與測試

Liovx-SDK2編譯

編譯cmakelists.txt是常規的格式,直接編譯即可?

mkdir build?

cd build

cmake ..

make

編譯后生成依賴庫 liblivox_sdk_shared.so 用于驅動的依賴,如果需要交叉編譯,只需在cmakelists.txt增加交叉編譯工具鏈聲明。

同時編譯后在sample目錄下生成 livox_lidar_quick_start,雷達快速啟動程序,用于測試雷達網絡IP和數據傳輸。

雷達驅動的修改、編譯與測試

去ros的編譯方式

修改cmakelists.txt如下,包含自定義頭文件目錄和庫目錄

# judge which cmake codes to use # Copyright(c) 2020 livoxtech limited.cmake_minimum_required(VERSION 3.14)
project(livox_ros_driver2)ADD_COMPILE_OPTIONS(-std=c++17)
set(CMAKE_CXX_FLAGS "-std=c++17 -O3 -g")add_definitions(-DROOT_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions")
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++17 -pthread -std=c++0x -std=c++17 -fexceptions")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/3rdparty)include_directories(/usr/include/pcl-1.12)
include_directories(/usr/include/eigen3)
include_directories(/usr/include/opencv4)# livox ros2 driver target
add_library(${PROJECT_NAME} SHAREDsrc/livox_ros_driver2.cppsrc/lddc.cppsrc/driver_node.cppsrc/lds.cppsrc/lds_lidar.cppsrc/comm/comm.cppsrc/comm/ldq.cppsrc/comm/semaphore.cppsrc/comm/lidar_imu_data_queue.cppsrc/comm/cache_index.cppsrc/comm/pub_handler.cppsrc/parse_cfg_file/parse_cfg_file.cppsrc/parse_cfg_file/parse_livox_lidar_cfg.cppsrc/call_back/lidar_common_callback.cppsrc/call_back/livox_lidar_callback.cpp
)target_link_libraries(${PROJECT_NAME}/usr/local/wy_slam_lib/livox2lib/liblivox_lidar_sdk_shared.so  )add_executable(${PROJECT_NAME}_nodesrc/livox_ros_driver2.cpp
)target_link_libraries(${PROJECT_NAME}_node /usr/local/wy_slam_lib/commonlib/libyaml-cpp.so/usr/local/wy_slam_lib/commonlib/libglog.so/usr/local/wy_slam_lib/commonlib/libgflags.so/usr/local/wy_slam_lib/commonlib/libtbb.so/usr/local/wy_slam_lib/commonlib/libtbbmalloc.so/usr/local/wy_slam_lib/commonlib/libtbbmalloc_proxy.so/usr/local/wy_slam_lib/pcllib/libpcl_filters.so/usr/local/wy_slam_lib/pcllib/libpcl_kdtree.so/usr/local/wy_slam_lib/pcllib/libpcl_common.so/usr/local/wy_slam_lib/pcllib/libpcl_registration.so/usr/local/wy_slam_lib/pcllib/libpcl_search.so/usr/local/wy_slam_lib/pcllib/libpcl_io.so/usr/local/wy_slam_lib/pcllib/libpcl_segmentation.so/home/yanyu/Downloads/livox_ros_driver2/src/livox_ros_driver2_no_ros/build/liblivox_ros_driver2.so      )

?livox_ros_driver2的代碼框架介紹

主節點,driver_node.h/cpp,聲明ros2節點,定義lidar/imu數據輪詢線程。

lddc.h/cpp負責實際從處理雷達sdk接收的點云與imu數據,通過信號量進行通信,填充lidar/imu數據和時間戳到自定義數據結構或ros2話題消息中。

lds_lidar.h/cpp 調用livox-sdk,并注冊雷達點云IMU數據回調函數到sdk,接收socket client_data,并通過信號量通知ROS2節點,處理與發送雷達數據。

?livox_ros_driver2編譯

編譯使用ros格式的編譯工具鏈,支持ros1/ros2,新建 ws_livox_ros_driver2目錄,./build.sh humble用于編譯ros2格式。

編譯后生成liblivox_ros_driver2.so 和雷達節點livox_ros_driver2_node?

其中雷達節點livox_ros_driver2_node依賴 liblivox_ros_driver2.so庫,是ros2節點,啟動后向外發送雷達數據話題和IMU話題 /livox/lidar, /livox/imu, 發布頻率默認10hz, 200hz,雷達話題帶基準時間戳base_time,也是每一幀第一個點的時間戳,以及每個點的時間戳偏移offset_time, 格式是uint64, 單位ns,方便進行后續時間戳對齊,以及點云畸變校準。

雷達IP配置文件介紹

MID360_config.json,包含雷達IP,雷達類型,格式等數據定義。雷達IP,可以通過機身二維碼下標后兩位讀取和1組成三位的雷達IP地址,例如后兩位為95,則雷達IP為192.168.1.195。也可以通過livox_lidar_quick_start直接獲取雷達IP,寫入配置文件。

{"lidar_summary_info" : {"lidar_type": 8},"MID360": {"lidar_net_info" : {"cmd_data_port": 56100,"push_msg_port": 56200,"point_data_port": 56300,"imu_data_port": 56400,"log_data_port": 56500},"host_net_info" : {"cmd_data_ip" : "192.168.1.50","cmd_data_port": 56101,"push_msg_ip": "192.168.1.50","push_msg_port": 56201,"point_data_ip": "192.168.1.50","point_data_port": 56301,"imu_data_ip" : "192.168.1.50","imu_data_port": 56401,"log_data_ip" : "","log_data_port": 56501}},"lidar_configs" : [{"ip" : "192.168.1.190","pcl_data_type" : 1,"pattern_mode" : 0,"extrinsic_parameter" : {"roll": 0.0,"pitch": 0.0,"yaw": 0.0,"x": 0,"y": 0,"z": 0}}]
}

配置文件中,雷達IP為192.168.1.190, 網絡ip配置為手動192.168.1.50。?

常見問題介紹

1 雷達沒數據:

檢測電源是否接通,電流是否2A以上1A的無法帶動,網線是否接通,電腦網卡是否選擇正確,配置網絡為192.168.1.1,192.168.1.50,255,255,255,0。

用viewer工具查看雷達點云是否正常。

2 雷達數據中斷或降頻:

用 ros2 topic bw /livox/lidar 查看帶寬是否為0.4MB/s,減少其他ROS2話題的訂閱,保證流量正常。

3 雷達sdk崩潰

可能與IMU時間戳有關,雷達過熱,加裝風扇散熱。加打印日志用gdb 調試。

優化改進

1 去ros修改,去掉所有的ros 相關的頭文件與代碼,及編譯腳本。

?去掉話題發布,用回調函數代替數據傳輸,增加數據傳輸穩定性。

2 windows下雷達imu數據獲取與建圖:

由于viewer可視化軟件沒有imu數據,以及雷達sdk僅支持linux-ubuntu下的源碼開發,因此需要自行修改編譯為win-x64格式,去ros后編譯為win-x64版本,用回調函數直接獲取雷達和IMU數據,實現windows-x64離線建圖。

3 部分去ros節點代碼修改如下

//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//#include <iostream>
#include <chrono>
#include <vector>
#include <csignal>
#include <thread>#include "include/livox_ros_driver2.h"
#include "include/ros_headers.h"
#include "driver_node.h"
#include "lddc.h"
#include "lds_lidar.h"using namespace livox_ros;namespace livox_ros
{
bool thread_alive_ = true;
DriverNode::DriverNode()
{//DRIVER_INFO(*this, "Livox Ros Driver2 Version: %s", LIVOX_ROS_DRIVER2_VERSION_STRING);/** Init default system parameter */int xfer_format = kPointCloud2Msg;//kPclPxyziMsg;//kLivoxCustomMsg;//kPointCloud2Msg;//int multi_topic = 0;int data_src = kSourceRawLidar;double publish_freq = 10.0; /* Hz */int output_type = kOutputToRos;std::string frame_id =  "frame_default";if (publish_freq > 100.0) {publish_freq = 100.0;} else if (publish_freq < 0.5) {publish_freq = 0.5;} else {publish_freq = publish_freq;}future_ = exit_signal_.get_future();/** Lidar data distribute control and lidar data source set */lddc_ptr_ = std::make_unique<Lddc>(xfer_format, multi_topic, data_src, output_type, publish_freq, frame_id);//lddc_ptr_->SetRosNode(this);if (data_src == kSourceRawLidar) {//DRIVER_INFO(*this, "Data Source is raw lidar.");std::string user_config_path = "../config/MID360_config.json";//this->get_parameter("user_config_path", user_config_path);//DRIVER_INFO(*this, "Config file : %s", user_config_path.c_str());std::string cmdline_bd_code = "000000000000001";//this->get_parameter("cmdline_input_bd_code", cmdline_bd_code);LdsLidar *read_lidar = LdsLidar::GetInstance(publish_freq);lddc_ptr_->RegisterLds(static_cast<Lds *>(read_lidar));if ((read_lidar->InitLdsLidar(user_config_path))) {//DRIVER_INFO(*this, "Init lds lidar success!");std::cout<<" Init lds lidar success! "<<std::endl;} else {//DRIVER_ERROR(*this, "Init lds lidar fail!");std::cout<<" Init lds lidar fail! "<<std::endl;}} else {//DRIVER_ERROR(*this, "Invalid data src (%d), please check the launch file", data_src);std::cout<<" Invalid data src, please check the launch file "<<std::endl;}pointclouddata_poll_thread_ = std::make_shared<std::thread>(&DriverNode::PointCloudDataPollThread, this);imudata_poll_thread_ = std::make_shared<std::thread>(&DriverNode::ImuDataPollThread, this);
}}  // namespace livox_rosvoid DriverNode::PointCloudDataPollThread()
{std::future_status status;std::this_thread::sleep_for(std::chrono::seconds(3));do {lddc_ptr_->DistributePointCloudData();status = future_.wait_for(std::chrono::microseconds(0));} while (status == std::future_status::timeout);
}void DriverNode::ImuDataPollThread()
{std::future_status status;std::this_thread::sleep_for(std::chrono::seconds(3));do {lddc_ptr_->DistributeImuData();status = future_.wait_for(std::chrono::microseconds(0));} while (status == std::future_status::timeout);
}void SigHandle(int sig)
{std::cout << "catch sig %d" << sig << std::endl;//rclcpp::shutdown();thread_alive_=false;
}int main(int argc, char** argv)
{//rclcpp::init(argc, argv);signal(SIGINT, SigHandle);//rclcpp::NodeOptions node_options;auto livox_driver_node = std::make_shared<livox_ros::DriverNode>();//rclcpp::spin(livox_driver_node);//if (rclcpp::ok())//    rclcpp::shutdown();while(thread_alive_){usleep(10000);}return 0;
}

增加點云與IMU的回調函數到lddc.h/lddc.cpp,接收數據即可.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916716.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916716.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916716.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Spring】日志級別的分類和使用

文章目錄介紹日志級別的分類日志級別的順序日志級別的使用介紹 日志級別代表著日志信息對應問題的嚴重性&#xff0c;為了更快的篩選符合目標的日志信息 試想一下這樣的場景&#xff0c;假設你是一家 2 萬人公司的老板&#xff0c;如果每個員工的日常工作和瑣碎的信息都要反饋…

【C++】第十九節—一文萬字詳解 | AVL樹實現

好久不見&#xff0c;我是云邊有個稻草人&#xff0c;偶爾中二博主與你分享C領域專業知識^(*&#xffe3;(oo)&#xffe3;)^ 《C》—本篇文章所屬專欄—持續更新中—歡迎訂閱~喔 目錄 一、AVL的概念 二、AVL樹的實現 2.1 AVL樹的結構 2.2 AVL樹的插入 【AVL樹插入?個值…

【Delphi】快速理解泛型(Generics)

Delphi的泛型&#xff08;generics&#xff09;是一項強大的特性&#xff0c;它使得代碼更加靈活、類型安全&#xff0c;并且可以實現各種通用的數據結構和算法。下面我將為你詳細介紹Delphi中的泛型&#xff0c;包括基本概念、語法、常用實例&#xff0c;以及使用建議。Delphi…

Java Stream流的使用

獲取Stream流 單列集合直接使用stream()方法 List<String> list Arrays.asList("a", "b", "c"); Stream<String> stream list.stream(); // 獲取順序流數組使用靜態方法Arrays.stream() String[] array {"a", "b&…

前端實現添加水印,兩種方式

一、自定義指令的方式/*需求&#xff1a;給整個頁面添加背景水印。思路&#xff1a;1、使用 canvas 特性生成 base64 格式的圖片文件&#xff0c;設置其字體大小&#xff0c;顏色等。2、將其設置為背景圖片&#xff0c;從而實現頁面或組件水印效果使用&#xff1a;設置水印文案…

使用LangChain構建法庭預定智能體:結合vLLM部署的Qwen3-32B模型

文章目錄 技術架構概述 核心實現步驟 1. 配置vLLM與Qwen3-32B模型 2. 定義工具(Tools) 3. 構建Agent系統 4. 運行與交互 關鍵技術亮點 1. 工具調用自動化 2. Hermes解析器優勢 3. 對話記憶管理 實際運行效果 性能優化建議 擴展應用場景 總結 在人工智能應用開發中,如何讓大語…

vscode開發微信小程序

下載插件 插件下載位置 1.微信小程序開發工具 2.vscode weapp api 3.vscode wxml 4.vscode-wechat 創建項目 終端運行命令 cd 到要創建項目的目錄執行命令&#xff1a;vue create -p dcloudio/uni-preset-vue test test就是項目名稱 選擇默認模板&#xff0c;回車 出現下圖這…

板凳-------Mysql cookbook學習 (十二--------3_3)

https://cloud.tencent.com/developer/article/1454690 侯哥的Python分享 # 創建節點 class Node(object):def __init__(self,item):self.element itemself.next None# 創建單鏈表類 class SingleLinkList(object):def __init__(self):self.header Noneself.length 0# 1、判…

Flutter開發實戰之CI/CD與發布流程

第12章:CI/CD與發布流程 在前面的章節中,我們學習了Flutter應用開發的各個方面,從基礎UI構建到復雜的狀態管理,從網絡請求到本地存儲。現在,我們將探討一個同樣重要但常被忽視的話題:如何將我們精心開發的應用高效、可靠地發布到各大應用商店。 想象一下,你花費了數月…

ElasticSearch 的3種數據遷移方案

在實際工作中&#xff0c;我們經常會遇到需要將自建的 Elasticsearch 遷移上云&#xff0c;或者遷移到其他 ES 集群的情況。這時&#xff0c;選擇合適的數據遷移方案就顯得尤為重要啦。今天就來給大家介紹三種常用的遷移方案&#xff0c;分別是 COS 快照、logstash 和 elastics…

MySQL 中的“雙路排序”與“單路排序”:原理、判別與實戰調優

一句話導讀 ORDER BY 不能走索引時&#xff0c;MySQL 會在 Server 層做一次 filesort。內部實現分 單路&#xff08;全字段&#xff09; 與 雙路&#xff08;rowid&#xff09; 兩種&#xff1b;了解它們的觸發條件、判別方法與調優思路&#xff0c;是 SQL 性能優化的必修課。一…

OpenLayers 綜合案例-信息窗體-彈窗

看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大家&#xff0c;助你少走彎路&#xff01; OpenLayers…

GaussDB 開發基本規范

1 集中式1.1數據庫價值特性推薦特性分類特性列表說明表類型PARTITION表數據分區存儲引擎行存儲按行順序存儲表&#xff0c;建議點查&#xff0c;增刪改操作較多場景下使用事務事務塊顯式啟動事務單語句事務不顯式啟動事務&#xff0c;單語句即為事務擴容在線擴容擴節點和數據重…

工作中使用git可能遇到的場景

1.main歷史發布版本出問題需要查看&#xff0c;怎么切換歷史發布版本&#xff1f;git reset --hard commitid 更新本地庫和代碼2.A分支的代碼已經做過一些功能&#xff0c;想遷移到B分支當前在A分支git checkout B &#xff08;切換到B分支&#xff09;git cherry-pick A的com…

【Spring AI】本地大型語言模型工具-Ollama

Ollama 是一個專注于在本地運行大型語言模型&#xff08;LLM&#xff09;的工具&#xff0c;支持多種開源模型&#xff08;如 Llama 3、Mistral、Gemma 等&#xff09;&#xff0c;提供簡單的命令行和 API 接口。<dependency><groupId>org.springframework.ai</…

電機S加減速

STM32步進電機S型加減速算法_stm32___build__-2048 AI社區 以上&#xff0c;電機加減速說的非常清楚&#xff0c;收藏點贊&#xff01;

一、初識 Linux 與基本命令

作者&#xff1a;IvanCodes 日期&#xff1a;2025年7月28日 專欄&#xff1a;Linux教程 思維導圖 一、Linux 簡介 1.1 什么是 Linux? Linux 是一種自由、開源的類Unix操作系統內核&#xff0c;由林納斯托瓦茲 (Linus Torvalds) 在1991年首次發布。我們通常所說的 “Linux 系統…

解決angular與jetty websocket 每30s自動斷連的問題

背景&#xff1a;前端&#xff1a;angular 12&#xff0c;websocket接口由lib.dom.d.ts提供后端&#xff1a;java&#xff0c;websocket接口由jetty 12提供問題現象&#xff1a;前端連上server后&#xff0c;每隔30s就會斷開&#xff0c;由于長時間空閑&#xff0c;會導致webso…

【機器學習深度學習】模型私有化部署與微調訓練:賦能特定問題處理能力

目錄 前言 一、私有化部署的背景&#xff1a;通用能力 ≠ 企業實用 暴露問題 二、微調訓練的核心目的 2.1 動作一&#xff1a;私有化部署&#xff08;Private Deployment&#xff09; 2.2 動作二&#xff1a;領域微調&#xff08;Domain Fine-Tuning&#xff09; 2.3 微…

Seq2Seq學習筆記

Seq2Seq模型概述Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;是一種基于深度學習的序列生成模型&#xff0c;主要用于處理輸入和輸出均為序列的任務&#xff0c;如機器翻譯、文本摘要、對話生成等。其核心思想是將可變長度的輸入序列映射為另一個可變長度的輸出序列。…