feat: 初始化 Go2 导航代码与配置

This commit is contained in:
2026-10-14 11:08:44 +08:00
parent 8e16ecceba
commit 9dab37e8c8
1258 changed files with 1936673 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.0)
project(livox_sdk2)
set(CMAKE_CXX_STANDARD 11)
message(STATUS "main project dir: " ${PROJECT_SOURCE_DIR})
if (CMAKE_CROSSCOMPILING)
set(THREADS_PTHREAD_ARG
"PLEASE_FILL_OUT-FAILED_TO_RUN"
CACHE STRING "Result from TRY_RUN" FORCE)
endif()
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif(UNIX)
add_subdirectory(livox_lidar_quick_start)
add_subdirectory(multi_lidars_upgrade)
add_subdirectory(logger)
add_subdirectory(debug_point_cloud)
add_subdirectory(lidar_cmd_observer)
add_subdirectory(livox_lidar_rmc_time_sync)
add_subdirectory(livox_lidar_ip_set)
add_subdirectory(livox_lidar_info_get)

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME debug_point_cloud)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static)

View File

@@ -0,0 +1,21 @@
{
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,23 @@
{
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,24 @@
{
"lidar_log_path": "./",
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,148 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <map>
#include <csignal>
std::condition_variable quit_condition;
std::mutex mtx;
void PointCloudCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
printf("point cloud handle: %d, data_num: %d, data_type: %d, length: %d, frame_counter: %d\n",
handle, data->dot_num, data->data_type, data->length, data->frame_cnt);
}
void ImuDataCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
printf("Imu data callback handle:%u, data_num:%u, data_type:%u, length:%u, frame_counter:%u.\n",
handle, data->dot_num, data->data_type, data->length, data->frame_cnt);
}
void WorkModeCallback(livox_status status, uint32_t handle,LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("WorkModeCallack, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
void LoggerStartCallback(livox_status status, uint32_t handle, LivoxLidarLoggerResponse* response, void* client_data) {
if (status != kLivoxLidarStatusSuccess) {
printf("Start logger failed, the status :%d\n", status);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
if (response == nullptr) {
printf("Start logger failed, the response is nullptr.\n");
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
if (response->ret_code != 0) {
printf("Start logger failed, the response ret_Code:%d.\n", response->ret_code);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
printf("The lidar[%u] start logger succ.\n", handle);
}
void DebugPointCloudCallback(livox_status status, uint32_t handle, LivoxLidarLoggerResponse* response, void* client_data) {
printf("--------------------------------------------------------------------------------\n");
printf("livox_status = %d, Lidar: %u response is %d\n", status, handle, response->ret_code);
printf("--------------------------------------------------------------------------------\n");
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void* client_data) {
if (info == nullptr) {
printf("lidar info change callback failed, the info is nullptr.\n");
return;
}
printf("LidarInfoChangeCallback Lidar handle: %u SN: %s\n", handle, info->sn);
SetLivoxLidarWorkMode(handle, kLivoxLidarNormal, WorkModeCallback, nullptr);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
SetLivoxLidarDebugPointCloud(handle, true, DebugPointCloudCallback, nullptr);
// sleep(10);
// SetLivoxLidarDebugPointCloud(handle, false, DebugPointCloudCallback, nullptr);
}
void Stop(int signal) {
quit_condition.notify_all();
}
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("Params Invalid, must input config path.\n");
return -1;
}
const std::string path = argv[1];
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
// SetLivoxLidarPointCloudCallBack(PointCloudCallback, nullptr);
// SetLivoxLidarImuDataCallback(ImuDataCallback, nullptr);
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
// capture Ctrl + C signal.
std::signal(SIGINT, Stop);
std::unique_lock<std::mutex> lock(mtx);
quit_condition.wait(lock);
printf("Deivice Logger exit.\n");
LivoxLidarSdkUninit();
printf("Livox Quick Start Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,24 @@
{
"lidar_log_path": "./",
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,24 @@
{
"lidar_log_path": "./",
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME lidar_cmd_observer)
add_executable(${DEMO_NAME} main.cpp)
target_include_directories(
${DEMO_NAME}
PRIVATE
../../3rdparty/
)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,23 @@
{
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,22 @@
{
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,89 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
#include "FastCRC/FastCRC.h"
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("Params Invalid, must input config path.\n");
return -1;
}
const std::string path = argv[1];
// REQUIRED, to init Livox SDK2
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
LivoxLidarAddCmdObserver([](const uint32_t handle, const LivoxLidarCmdPacket* data, void* client_data) {
static FastCRC16 crc_16;
static FastCRC32 crc_32;
static const uint8_t offset_of_crc16 = offsetof(LivoxLidarCmdPacket, crc16_h);
static const uint8_t offset_of_data = offsetof(LivoxLidarCmdPacket, data);
struct in_addr tmp_addr;
tmp_addr.s_addr = handle;
if (crc_16.ccitt(reinterpret_cast<const uint8_t*>(data), offset_of_crc16) != data->crc16_h) {
printf("Error: liadr: %s, crc16 check failure.\n", inet_ntoa(tmp_addr));
exit(-1);
}
if (crc_32.crc32(reinterpret_cast<const uint8_t*>(data) + offset_of_data, data->length - offset_of_data) != data->crc32_d) {
printf("Error: liadr: %s, crc32 check failure.\n", inet_ntoa(tmp_addr));
exit(-1);
}
printf("--------------------------------------------------\n");
printf("liadr: %s, crc check success.\n", inet_ntoa(tmp_addr));
printf("--------------------------------------------------\n");
}, nullptr);
#ifdef WIN32
Sleep(300000);
#else
sleep(300);
#endif
LivoxLidarRemoveCmdObserver();
LivoxLidarSdkUninit();
printf("Livox Quick Start Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,22 @@
{
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,22 @@
{
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME livox_lidar_info_get)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,21 @@
{
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,189 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Sample: actively query the lidar's current state info.
// Call QueryLivoxLidarInternalInfo when the lidar comes online; SDK sends
// a query for the dev_type's registered key set (Avia2 has 19 keys, see
// GeneralCommandHandler::GetQueryLidarInternalInfoKeys) and returns them
// as a packed KV list. This demo decodes every key into a readable value.
#include "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>
static std::atomic<bool> g_done{false};
static void PrintIpPortPair(const char* label, const uint8_t* value) {
uint8_t ip[4] = {value[0], value[1], value[2], value[3]};
uint16_t host_port = 0;
uint16_t lidar_port = 0;
memcpy(&host_port, value + 4, sizeof(uint16_t));
memcpy(&lidar_port, value + 6, sizeof(uint16_t));
printf(" %-32s host_ip:%u.%u.%u.%u host_port:%u lidar_port:%u\n",
label, ip[0], ip[1], ip[2], ip[3], host_port, lidar_port);
}
static void PrintKey(const LivoxLidarKeyValueParam* kv) {
const uint8_t* v = &kv->value[0];
switch (kv->key) {
case kKeyPclDataType:
printf(" %-32s %u\n", "pcl_data_type (0x0000)", v[0]);
break;
case kKeyLidarIpCfg:
printf(" %-32s ip:%u.%u.%u.%u mask:%u.%u.%u.%u gw:%u.%u.%u.%u\n",
"lidar_ip_cfg (0x0004)",
v[0], v[1], v[2], v[3],
v[4], v[5], v[6], v[7],
v[8], v[9], v[10], v[11]);
break;
case kKeyStateInfoHostIpCfg:
PrintIpPortPair("state_info_host_ip_cfg (0x0005)", v);
break;
case kKeyLidarPointDataHostIpCfg:
PrintIpPortPair("pointcloud_host_ip_cfg (0x0006)", v);
break;
case kKeyLidarImuHostIpCfg:
PrintIpPortPair("imu_host_ip_cfg (0x0007)", v);
break;
case kKeyWorkMode:
printf(" %-32s %u\n", "work_mode (0x001A)", v[0]);
break;
case kKeyImuDataEn:
printf(" %-32s %u\n", "imu_data_en (0x001C)", v[0]);
break;
case kKeySetFovMode:
printf(" %-32s %u\n", "fov_mode (0x0022)", v[0]);
break;
case kKeySetEchoMode:
printf(" %-32s %u\n", "echo_mode (0x0024)", v[0]);
break;
case kKeySetNTPServerIp:
printf(" %-32s %u.%u.%u.%u\n", "ntp_server_ip (0x0025)", v[0], v[1], v[2], v[3]);
break;
case kKeySetITOCtrl:
printf(" %-32s %u\n", "ito_mode (0x0027)", v[0]);
break;
case kKeySetFogNoiseFilter:
printf(" %-32s %u\n", "fog_noise_filter (0x0028)", v[0]);
break;
case kKeySn: {
char sn[17] = {0};
memcpy(sn, v, kv->length < 16 ? kv->length : 16);
printf(" %-32s %s\n", "sn (0x8000)", sn);
break;
}
case kKeyVersionApp:
printf(" %-32s %u.%u.%u.%u\n", "version_app (0x8002)", v[0], v[1], v[2], v[3]);
break;
case kKeyVersionLoader:
printf(" %-32s %u.%u.%u.%u\n", "version_loader (0x8003)", v[0], v[1], v[2], v[3]);
break;
case kKeyCurWorkState:
printf(" %-32s %u\n", "cur_work_state (0x8006)", v[0]);
break;
case kKeyCoreTemp: {
int32_t core_temp = 0;
memcpy(&core_temp, v, sizeof(int32_t));
printf(" %-32s %d\n", "core_temp (0x8007)", core_temp);
break;
}
case kKeyFwType:
printf(" %-32s %u\n", "fw_type (0x8010)", v[0]);
break;
case kKeyHmsCode: {
uint32_t hms[8] = {0};
memcpy(hms, v, sizeof(hms));
printf(" %-32s [%u,%u,%u,%u,%u,%u,%u,%u]\n", "hms_code (0x8011)",
hms[0], hms[1], hms[2], hms[3], hms[4], hms[5], hms[6], hms[7]);
break;
}
default:
printf(" UNKNOWN key:0x%04X len:%u\n", kv->key, kv->length);
break;
}
}
void QueryInternalInfoCallback(livox_status status, uint32_t handle,
LivoxLidarDiagInternalInfoResponse* response, void*) {
if (status != kLivoxLidarStatusSuccess) {
printf("Query failed, status:%u handle:%u\n", status, handle);
g_done.store(true);
return;
}
if (response == nullptr) {
printf("Query response is null.\n");
g_done.store(true);
return;
}
if (response->ret_code != 0) {
printf("Query ret_code:%u\n", response->ret_code);
g_done.store(true);
return;
}
printf("Query OK, param_num:%u\n", response->param_num);
uint16_t off = 0;
for (uint16_t i = 0; i < response->param_num; ++i) {
LivoxLidarKeyValueParam* kv = (LivoxLidarKeyValueParam*)&response->data[off];
PrintKey(kv);
off += sizeof(uint16_t) * 2;
off += kv->length;
}
g_done.store(true);
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void*) {
if (info == nullptr) {
printf("LidarInfoChangeCallback: info is null.\n");
return;
}
struct in_addr addr;
addr.s_addr = handle;
printf("Lidar online, handle:%u ip:%s sn:%s dev_type:%u\n",
handle, inet_ntoa(addr), info->sn, info->dev_type);
QueryLivoxLidarInternalInfo(handle, QueryInternalInfoCallback, nullptr);
}
int main(int argc, const char* argv[]) {
if (argc != 2) {
printf("Usage: %s <config.json>\n", argv[0]);
return -1;
}
const std::string path = argv[1];
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
const int timeout_sec = 30;
for (int i = 0; i < timeout_sec && !g_done.load(); ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
LivoxLidarSdkUninit();
printf("info_get demo end.\n");
return 0;
}

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME livox_lidar_ip_set)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,21 @@
{
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,107 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
#include "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>
// Target lidar IP config to apply. Override via CLI: <config> <ip> <mask> <gw>
static char g_target_ip[16] = "192.168.1.10";
static char g_target_mask[16] = "255.255.255.0";
static char g_target_gw[16] = "192.168.1.1";
static std::atomic<bool> g_done{false};
void RebootCallback(livox_status status, uint32_t handle, LivoxLidarRebootResponse* response, void*) {
if (response == nullptr) {
printf("Reboot response is null, status:%u handle:%u\n", status, handle);
return;
}
printf("Reboot ack, status:%u handle:%u ret_code:%u\n", status, handle, response->ret_code);
g_done.store(true);
}
void SetIpInfoCallback(livox_status status, uint32_t handle, LivoxLidarAsyncControlResponse* response, void*) {
if (response == nullptr) {
printf("SetIp response is null, status:%u handle:%u\n", status, handle);
return;
}
printf("SetLivoxLidarIp ack, status:%u handle:%u ret_code:%u error_key:%u\n",
status, handle, response->ret_code, response->error_key);
if (status == kLivoxLidarStatusSuccess && response->ret_code == 0 && response->error_key == 0) {
printf("SetLivoxLidarIp OK, rebooting lidar to apply new IP...\n");
LivoxLidarRequestReboot(handle, RebootCallback, nullptr);
} else {
printf("SetLivoxLidarIp failed, skip reboot.\n");
g_done.store(true);
}
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void*) {
if (info == nullptr) {
printf("LidarInfoChangeCallback: info is null.\n");
return;
}
struct in_addr addr;
addr.s_addr = handle;
printf("Lidar online, handle:%u ip:%s sn:%s dev_type:%u\n",
handle, inet_ntoa(addr), info->sn, info->dev_type);
LivoxLidarIpInfo lidar_ip_info;
memset(&lidar_ip_info, 0, sizeof(lidar_ip_info));
strncpy(lidar_ip_info.ip_addr, g_target_ip, sizeof(lidar_ip_info.ip_addr) - 1);
strncpy(lidar_ip_info.net_mask, g_target_mask, sizeof(lidar_ip_info.net_mask) - 1);
strncpy(lidar_ip_info.gw_addr, g_target_gw, sizeof(lidar_ip_info.gw_addr) - 1);
printf("Apply lidar ip -> %s / mask %s / gw %s\n",
lidar_ip_info.ip_addr, lidar_ip_info.net_mask, lidar_ip_info.gw_addr);
SetLivoxLidarIp(handle, &lidar_ip_info, SetIpInfoCallback, nullptr);
}
int main(int argc, const char* argv[]) {
if (argc < 2 || argc > 5) {
printf("Usage: %s <config.json> [lidar_ip] [subnet_mask] [gateway]\n", argv[0]);
printf(" defaults: %s %s %s\n", g_target_ip, g_target_mask, g_target_gw);
return -1;
}
const std::string path = argv[1];
if (argc >= 3) strncpy(g_target_ip, argv[2], sizeof(g_target_ip) - 1);
if (argc >= 4) strncpy(g_target_mask, argv[3], sizeof(g_target_mask) - 1);
if (argc >= 5) strncpy(g_target_gw, argv[4], sizeof(g_target_gw) - 1);
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
const int timeout_sec = 60;
for (int i = 0; i < timeout_sec && !g_done.load(); ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
LivoxLidarSdkUninit();
printf("set_lidar_ip demo end.\n");
return 0;
}

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME livox_lidar_quick_start)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,21 @@
{
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,23 @@
{
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,22 @@
{
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,252 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
void PointCloudCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
printf("point cloud handle: %u, data_num: %d, data_type: %d, length: %d, udp_counter: %d\n",
handle, data->dot_num, data->data_type, data->length, data->udp_cnt);
if (data->data_type == kLivoxLidarCartesianCoordinateHighData) {
LivoxLidarCartesianHighRawPoint *p_point_data = (LivoxLidarCartesianHighRawPoint *)data->data;
for (uint32_t i = 0; i < data->dot_num; i++) {
//p_point_data[i].x;
//p_point_data[i].y;
//p_point_data[i].z;
}
}
else if (data->data_type == kLivoxLidarCartesianCoordinateLowData) {
LivoxLidarCartesianLowRawPoint *p_point_data = (LivoxLidarCartesianLowRawPoint *)data->data;
} else if (data->data_type == kLivoxLidarSphericalCoordinateData) {
LivoxLidarSpherPoint* p_point_data = (LivoxLidarSpherPoint *)data->data;
} else if (data->data_type == kLivoxLidarDoubleEchoData) {
LivoxLidarDoubleEchoRawPoint* p_point_data = (LivoxLidarDoubleEchoRawPoint *)data->data;
for (uint32_t i = 0; i < data->dot_num; i++) {
//p_point_data[i].x1;
//p_point_data[i].y1;
//p_point_data[i].z1;
//p_point_data[i].reflectivity1;
//p_point_data[i].tag1;
//p_point_data[i].x2;
//p_point_data[i].y2;
//p_point_data[i].z2;
//p_point_data[i].reflectivity2;
//p_point_data[i].tag2;
}
}
}
void ImuDataCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
printf("Imu data callback handle:%u, data_num:%u, data_type:%u, length:%u, frame_counter:%u.\n",
handle, data->dot_num, data->data_type, data->length, data->frame_cnt);
}
// void OnLidarSetIpCallback(livox_vehicle_status status, uint32_t handle, uint8_t ret_code, void*) {
// if (status == kVehicleStatusSuccess) {
// printf("lidar set ip slot: %d, ret_code: %d\n",
// slot, ret_code);
// } else if (status == kVehicleStatusTimeout) {
// printf("lidar set ip number timeout\n");
// }
// }
void EscModeSetCallback(livox_status status, uint32_t handle, LivoxLidarAsyncControlResponse *response, void *client_data) {
printf("set lidar esc mode, please power off and on lidar!!!!\n");
if (response == nullptr) {
return;
}
printf("EscModeSetCallback, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
void PclTypeCallback(livox_status status, uint32_t handle, LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("PclTypeCallback, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
void WorkModeCallback(livox_status status, uint32_t handle,LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("WorkModeCallack, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
void RebootCallback(livox_status status, uint32_t handle, LivoxLidarRebootResponse* response, void* client_data) {
if (response == nullptr) {
return;
}
printf("RebootCallback, status:%u, handle:%u, ret_code:%u",
status, handle, response->ret_code);
}
void SetIpInfoCallback(livox_status status, uint32_t handle, LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("LivoxLidarIpInfoCallback, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
if (response->ret_code == 0 && response->error_key == 0) {
LivoxLidarRequestReboot(handle, RebootCallback, nullptr);
}
}
void QueryInternalInfoCallback(livox_status status, uint32_t handle,
LivoxLidarDiagInternalInfoResponse* response, void* client_data) {
if (status != kLivoxLidarStatusSuccess) {
printf("Query lidar internal info failed.\n");
QueryLivoxLidarInternalInfo(handle, QueryInternalInfoCallback, nullptr);
return;
}
if (response == nullptr) {
return;
}
uint8_t host_point_ipaddr[4] {0};
uint16_t host_point_port = 0;
uint16_t lidar_point_port = 0;
uint8_t host_imu_ipaddr[4] {0};
uint16_t host_imu_data_port = 0;
uint16_t lidar_imu_data_port = 0;
uint16_t off = 0;
for (uint8_t i = 0; i < response->param_num; ++i) {
LivoxLidarKeyValueParam* kv = (LivoxLidarKeyValueParam*)&response->data[off];
if (kv->key == kKeyLidarPointDataHostIpCfg) {
memcpy(host_point_ipaddr, &(kv->value[0]), sizeof(uint8_t) * 4);
memcpy(&(host_point_port), &(kv->value[4]), sizeof(uint16_t));
memcpy(&(lidar_point_port), &(kv->value[6]), sizeof(uint16_t));
} else if (kv->key == kKeyLidarImuHostIpCfg) {
memcpy(host_imu_ipaddr, &(kv->value[0]), sizeof(uint8_t) * 4);
memcpy(&(host_imu_data_port), &(kv->value[4]), sizeof(uint16_t));
memcpy(&(lidar_imu_data_port), &(kv->value[6]), sizeof(uint16_t));
}
off += sizeof(uint16_t) * 2;
off += kv->length;
}
printf("Host point cloud ip addr:%u.%u.%u.%u, host point cloud port:%u, lidar point cloud port:%u.\n",
host_point_ipaddr[0], host_point_ipaddr[1], host_point_ipaddr[2], host_point_ipaddr[3], host_point_port, lidar_point_port);
printf("Host imu ip addr:%u.%u.%u.%u, host imu port:%u, lidar imu port:%u.\n",
host_imu_ipaddr[0], host_imu_ipaddr[1], host_imu_ipaddr[2], host_imu_ipaddr[3], host_imu_data_port, lidar_imu_data_port);
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void* client_data) {
if (info == nullptr) {
printf("lidar info change callback failed, the info is nullptr.\n");
return;
}
printf("LidarInfoChangeCallback Lidar handle: %u SN: %s\n", handle, info->sn);
// set lidar esc mode
SetLivoxLidarEscMode(handle, kLivoxEscSpeedSlow, EscModeSetCallback, nullptr);
// set the work mode to kLivoxLidarNormal, namely start the lidar
SetLivoxLidarWorkMode(handle, kLivoxLidarNormal, WorkModeCallback, nullptr);
// set the data type to
SetLivoxLidarPclDataType(handle, kLivoxLidarDoubleEchoData, PclTypeCallback, nullptr);
QueryLivoxLidarInternalInfo(handle, QueryInternalInfoCallback, nullptr);
// LivoxLidarIpInfo lidar_ip_info;
// strcpy(lidar_ip_info.ip_addr, "192.168.1.10");
// strcpy(lidar_ip_info.net_mask, "255.255.255.0");
// strcpy(lidar_ip_info.gw_addr, "192.168.1.1");
// SetLivoxLidarLidarIp(handle, &lidar_ip_info, SetIpInfoCallback, nullptr);
}
void LivoxLidarPushMsgCallback(const uint32_t handle, const uint8_t dev_type, const char* info, void* client_data) {
struct in_addr tmp_addr;
tmp_addr.s_addr = handle;
std::cout << "handle: " << handle << ", ip: " << inet_ntoa(tmp_addr) << ", push msg info: " << std::endl;
std::cout << info << std::endl;
return;
}
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("Params Invalid, must input config path.\n");
return -1;
}
const std::string path = argv[1];
// REQUIRED, to init Livox SDK2
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
// REQUIRED, to get point cloud data via 'PointCloudCallback'
SetLivoxLidarPointCloudCallBack(PointCloudCallback, nullptr);
// OPTIONAL, to get imu data via 'ImuDataCallback'
// some lidar types DO NOT contain an imu component
SetLivoxLidarImuDataCallback(ImuDataCallback, nullptr);
SetLivoxLidarInfoCallback(LivoxLidarPushMsgCallback, nullptr);
// REQUIRED, to get a handle to targeted lidar and set its work mode to NORMAL
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
#ifdef WIN32
Sleep(300000);
#else
sleep(300);
#endif
LivoxLidarSdkUninit();
printf("Livox Quick Start Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,22 @@
{
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,21 @@
{
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME livox_lidar_rmc_time_sync)
if (WIN32)
add_executable(${DEMO_NAME} main.cpp win/synchro.cpp)
elseif(UNIX)
add_executable(${DEMO_NAME} main.cpp linux/synchro.cpp)
endif()
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,23 @@
{
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,22 @@
{
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,254 @@
//
// 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 "../synchro.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <fcntl.h>
Synchro::Synchro() {
fd_ = 0;
is_quit_ = false;
rmc_buff_.resize(128,0);
}
Synchro::~Synchro() {
Stop();
}
void Synchro::SetBaudRate(BaudRate baudrate) {
baudrate_ = baudrate;
}
void Synchro::SetParity(Parity parity) {
parity_ = parity;
}
void Synchro::SetPortName(std::string port_name) {
port_name_ = std::move(port_name);
}
bool Synchro::Start() {
if (!Open()) {
return false;
}
is_quit_ = false;
listener_ = std::make_shared<std::thread>(&Synchro::IOLoop, this);
return true;
}
void Synchro::Stop() {
is_quit_ = true;
if (listener_) {
listener_->join();
listener_ = nullptr;
}
Close();
}
void Synchro::IOLoop() {
uint8_t buff[READ_BUF];
size_t size = 0;
while (!is_quit_) {
if (0 < (size = Read(buff, READ_BUF))) {
Decode(buff, size);
}
}
}
bool Synchro::ParseGps(uint8_t in_byte) {
if (cur_len_ < strlen(kGPRMC)) {
rmc_buff_[0] = rmc_buff_[1];
rmc_buff_[1] = rmc_buff_[2];
rmc_buff_[2] = rmc_buff_[3];
rmc_buff_[3] = rmc_buff_[4];
rmc_buff_[4] = rmc_buff_[5];
rmc_buff_[5] = in_byte;
cur_len_++;
if (cur_len_ == strlen(kGPRMC)) {
if (strncmp((const char*)&rmc_buff_[0], kGPRMC, strlen(kGPRMC)) != 0 && \
strncmp((const char*)&rmc_buff_[0], kGNRMC, strlen(kGNRMC)) != 0) {
cur_len_--;
}
}
return false;
}
if (cur_len_ >= rmc_buff_.size()) {
Clear();
return false;
}
rmc_buff_[cur_len_] = in_byte;
/** Checksum $GPRMC/$GNRMC. */
if (rmc_buff_[cur_len_ - 2] == '*') {
uint8_t result = 0;
for (int i = 1; i < cur_len_ - 2; i++) {
result ^= rmc_buff_[i];
}
char crc[3] = {0};
uint32_t crc_num = 0;
strncpy(crc, &rmc_buff_[cur_len_ - 1], 2);
sscanf(crc, "%x", &crc_num);
result ^= (uint8_t)crc_num;
if (result == 0) {
return true;
}
}
cur_len_++;
return false;
}
void Synchro::SetSyncTimerCallback(UtcTimerCallback cb) {
sync_timer_cb_ = cb;
}
void Synchro::Decode(uint8_t * buff, size_t size) {
for (size_t i = 0; i < size; i++) {
if (ParseGps(buff[i])) {
if (sync_timer_cb_) {
sync_timer_cb_(&rmc_buff_.at(0), cur_len_);
Clear();
}
}
}
}
void Synchro::Clear() {
cur_len_ = 0;
std::fill(rmc_buff_.begin(), rmc_buff_.end(), 0);
}
bool Synchro::Open() {
fd_ = open(port_name_.c_str(), O_RDONLY | O_NOCTTY | O_NONBLOCK);
if (fd_ < 0) {
printf("Open %s serials fail!\n", port_name_.c_str());
return false;
}
/* Set baudrate and parity,etc. */
Setup(baudrate_, parity_);
printf("Set baudrate success.\n");
return true;
}
void Synchro::Close() {
if (fd_ > 0) {
/* Flush the port */
tcflush(fd_,TCOFLUSH);
tcflush(fd_,TCIFLUSH);
close(fd_);
}
fd_ = 0;
}
/* Sets up the port parameters */
int Synchro::Setup(enum BaudRate baud, enum Parity parity) {
static uint32_t baud_map[19] = {
B2400, B4800, B9600, B19200, B38400, B57600,B115200, B230400
};
tcflag_t baudrate;
struct termios options;
/* Clear old setting completely,must add here for A3 CDC serial */
tcgetattr(fd_, &options);
memset(&options, 0, sizeof(options));
tcflush(fd_, TCIOFLUSH);
tcsetattr(fd_, TCSANOW, &options);
// usleep(100);
/* Minimum number of characters to read */
options.c_cc[VMIN] = 0;
/* Time to wait for data */
options.c_cc[VTIME] = 100;
/* Enable the receiver and set local mode... */
options.c_cflag |= (CLOCAL | CREAD);
/* Set boadrate */
baudrate = baud_map[baud];
cfsetispeed(&options, baudrate);
cfsetospeed(&options, baudrate);
printf("[Baudrate]: %d %u\r\n", baud, baudrate);
switch (parity) {
case P_8N1:
/* No parity (8N1) */
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
break;
case P_7E1:
/* Even parity (7E1) */
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;
break;
case P_7O1:
/* Odd parity (7O1) */
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;
break;
case P_7S1:
/* Space parity is setup the same as no parity (7S1) */
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
break;
default:
return -1;
}
/* flush the port */
tcflush(fd_, TCIOFLUSH);
/* send new config to the port */
tcsetattr(fd_, TCSANOW, &options);
return 0;
}
size_t Synchro::Read(uint8_t *buffer, size_t size) {
if (fd_ > 0) {
auto len = read(fd_, buffer, size);
return len < 0 ? 0 : len;
} else {
return 0;
}
}

View File

@@ -0,0 +1,125 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
#include "synchro.h"
static void WorkModeCallback(livox_status status, uint32_t handle,LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("WorkModeCallack, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
static void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void* client_data) {
if (info == nullptr) {
printf("lidar info change callback failed, the info is nullptr.\n");
return;
}
printf("LidarInfoChangeCallback Lidar handle: %u SN: %s\n", handle, info->sn);
// set the work mode to kLivoxLidarNormal, namely start the lidar
SetLivoxLidarWorkMode(handle, kLivoxLidarNormal, WorkModeCallback, nullptr);
Synchro& synchro = Synchro::GetInstance();
#ifdef WIN32
synchro.SetPortName("COM3");
#else
synchro.SetPortName("/dev/ttyUSB0");
#endif
/** Set Synchro's Baudrate: 9600. */
synchro.SetBaudRate(BR9600);
/** Set Synchro's Parity: No parity (8N1). */
synchro.SetParity(P_8N1);
/** SyncTimer Callback will trigger when Synchro's GPRMC/GNRMC signal is ready. */
synchro.SetSyncTimerCallback([handle](const char* rmc, uint16_t rmc_length) {
printf("GPRMC is:%s", rmc);
SetLivoxLidarRmcSyncTime(handle, rmc, rmc_length, [](livox_status status, uint32_t handle, LivoxLidarRmcSyncTimeResponse* data, void* client_data){
std::cout << "Lidar handle:" << handle << " response is: " << +data->ret << std::endl;
}, nullptr);
std::this_thread::sleep_for(std::chrono::milliseconds(800));
});
if (synchro.Start()) {
printf("Synchro start success.");
} else {
printf("Synchro start failed.");
return;
}
}
static void LivoxLidarPushMsgCallback(const uint32_t handle, const uint8_t dev_type, const char* info, void* client_data) {
struct in_addr tmp_addr;
tmp_addr.s_addr = handle;
std::cout << "handle: " << handle << ", ip: " << inet_ntoa(tmp_addr) << ", push msg info: " << std::endl;
std::cout << info << std::endl;
return;
}
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("Params Invalid, must input config path.\n");
return -1;
}
const std::string path = argv[1];
// REQUIRED, to init Livox SDK2
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarInfoCallback(LivoxLidarPushMsgCallback, nullptr);
// REQUIRED, to get a handle to targeted lidar and set its work mode to NORMAL
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
#ifdef WIN32
Sleep(300000);
#else
sleep(300);
#endif
LivoxLidarSdkUninit();
printf("Livox Quick Start Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,22 @@
{
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,22 @@
{
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,121 @@
//
// 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.
//
#ifndef SYNCHRO_H_
#define SYNCHRO_H_
#include <stdint.h>
#include <memory>
#include <thread>
#include <vector>
#include <string>
#include <functional>
#ifdef WIN32
#include <Windows.h>
#endif
using UtcTimerCallback = std::function<void(const char* rmc, uint16_t rmc_length)>;
# define READ_BUF (256)
const char * const kGPRMC{"$GPRMC"};
const char * const kGNRMC{"$GNRMC"};
enum Parity {
P_8N1, /* No parity (8N1) */
P_7E1, /* Even parity (7E1)*/
P_7O1, /* Odd parity (7O1) */
P_7S1 /* Space parity is setup the same as no parity (7S1) */
};
enum BaudRate {
BR2400,
BR4800,
BR9600,
BR19200,
BR38400,
BR57600,
BR115200,
BR230400,
BR460800,
BR500000,
BR576000,
BR921600,
BR1152000,
BR1500000,
BR2000000,
BR2500000,
BR3000000,
BR3500000,
BR4000000,
};
class Synchro {
public:
Synchro();
~Synchro();
static Synchro& GetInstance() {
static Synchro synchro;
return synchro;
}
bool Start();
void Stop();
void SetBaudRate(BaudRate baudrate);
void SetPortName(std::string port_name);
void SetParity(Parity parity);
void SetSyncTimerCallback(UtcTimerCallback cb);
private:
int Setup(enum BaudRate baud, enum Parity parity);
void Close();
bool Open();
void IOLoop();
size_t Read(uint8_t *buffer, size_t size);
void Decode(uint8_t* buff, size_t size);
bool ParseGps(uint8_t in_byte);
void Clear();
#ifdef WIN32
HANDLE hfile_;
#else
int fd_;
#endif
enum BaudRate baudrate_;
enum Parity parity_;
std::string port_name_;
std::function<void(const char* rmc, uint16_t rmc_length)> sync_timer_cb_;
bool is_quit_;
std::shared_ptr<std::thread> listener_;
std::vector<char> rmc_buff_;
uint16_t cur_len_;
};
#endif

View File

@@ -0,0 +1,226 @@
//
// 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 "../synchro.h"
#include <stdio.h>
#include <string.h>
#include <Windows.h>
Synchro::Synchro() {
hfile_ = INVALID_HANDLE_VALUE;
is_quit_ = false;
rmc_buff_.resize(128,0);
}
Synchro::~Synchro() {
Stop();
}
void Synchro::SetBaudRate(BaudRate baudrate) {
baudrate_ = baudrate;
}
void Synchro::SetParity(Parity parity) {
parity_ = parity;
}
void Synchro::SetPortName(std::string port_name) {
port_name_ = std::move(port_name);
}
bool Synchro::Start() {
if (!Open()) {
return false;
}
is_quit_ = false;
listener_ = std::make_shared<std::thread>(&Synchro::IOLoop, this);
return true;
}
void Synchro::Stop() {
is_quit_ = true;
if (listener_) {
listener_->join();
listener_ = nullptr;
}
Close();
}
void Synchro::IOLoop() {
uint8_t buff[READ_BUF];
size_t size = 0;
while (!is_quit_) {
if (0 < (size = Read(buff, READ_BUF))) {
Decode(buff, size);
}
}
}
bool Synchro::ParseGps(uint8_t in_byte) {
if (cur_len_ < strlen(kGPRMC)) {
rmc_buff_[0] = rmc_buff_[1];
rmc_buff_[1] = rmc_buff_[2];
rmc_buff_[2] = rmc_buff_[3];
rmc_buff_[3] = rmc_buff_[4];
rmc_buff_[4] = rmc_buff_[5];
rmc_buff_[5] = in_byte;
cur_len_++;
if (cur_len_ == strlen(kGPRMC)) {
if (strncmp((const char*)&rmc_buff_[0], kGPRMC, strlen(kGPRMC)) != 0 && \
strncmp((const char*)&rmc_buff_[0], kGNRMC, strlen(kGNRMC)) != 0) {
cur_len_--;
}
}
return false;
}
if (cur_len_ >= rmc_buff_.size()) {
Clear();
return false;
}
rmc_buff_[cur_len_] = in_byte;
/** Checksum $GPRMC/$GNRMC. */
if (rmc_buff_[cur_len_ - 2] == '*') {
uint8_t result = 0;
for (int i = 1; i < cur_len_ - 2; i++) {
result ^= rmc_buff_[i];
}
char crc[3] = {0};
uint32_t crc_num = 0;
strncpy(crc, &rmc_buff_[cur_len_ - 1], 2);
sscanf(crc, "%x", &crc_num);
result ^= (uint8_t)crc_num;
if (result == 0) {
return true;
}
}
cur_len_++;
return false;
}
void Synchro::SetSyncTimerCallback(UtcTimerCallback cb) {
sync_timer_cb_ = cb;
}
void Synchro::Decode(uint8_t * buff, size_t size) {
for (size_t i = 0; i < size; i++) {
if (ParseGps(buff[i])) {
if (sync_timer_cb_) {
sync_timer_cb_(&rmc_buff_.at(0), cur_len_);
Clear();
}
}
}
}
void Synchro::Clear() {
cur_len_ = 0;
std::fill(rmc_buff_.begin(), rmc_buff_.end(), 0);
}
bool Synchro::Open() {
hfile_ = CreateFile(port_name_.c_str(),
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hfile_ == INVALID_HANDLE_VALUE) {
printf("Open %s serials fail!\n", port_name_.c_str());
return false;
}
/* Set baudrate and parity,etc. */
Setup(baudrate_, parity_);
printf("Set baudrate success.\n");
return true;
}
void Synchro::Close() {
if (hfile_ != INVALID_HANDLE_VALUE) {
PurgeComm(hfile_, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
CloseHandle(hfile_);
}
hfile_ = INVALID_HANDLE_VALUE;
}
/* Sets up the port parameters */
int Synchro::Setup(enum BaudRate baud, enum Parity parity) {
static uint32_t baud_map[19] = {\
2400, 4800, 9600, 19200, 38400, 57600,115200, 230400,\
460800, 500000, 576000,921600,1152000, 1500000, 2000000,\
2500000, 3000000, 3500000, 4000000\
};
DCB dcb;
GetCommState(hfile_, &dcb);
dcb.BaudRate = DWORD(baud_map[baud]);
switch (parity) {
case P_8N1:
/* No parity (8N1) */
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
break;
case P_7E1:
/* Even parity (7E1) */
dcb.ByteSize = 7;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
break;
case P_7O1:
/* Odd parity (7O1) */
dcb.ByteSize = 7;
dcb.Parity = ODDPARITY;
dcb.StopBits = ONESTOPBIT;
break;
case P_7S1:
/* Space parity is setup the same as no parity (7S1) */
dcb.ByteSize = 7;
dcb.Parity = SPACEPARITY;
dcb.StopBits = ONESTOPBIT;
break;
default:
return -1;
}
SetCommState(hfile_, &dcb);
PurgeComm(hfile_, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
return 0;
}
size_t Synchro::Read(uint8_t *buffer, size_t size) {
DWORD len = 0;
if (hfile_ != INVALID_HANDLE_VALUE) {
ReadFile(hfile_, buffer, size, &len, NULL);
return len;
} else {
return 0;
}
}

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME logger)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static)

View File

@@ -0,0 +1,26 @@
{
"lidar_log_enable": true,
"lidar_log_cache_size_MB": 500,
"lidar_log_path": "./",
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,27 @@
{
"lidar_log_enable": true,
"lidar_log_cache_size_MB": 500,
"lidar_log_path": "./",
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,26 @@
{
"lidar_log_enable": true,
"lidar_log_cache_size_MB": 500,
"lidar_log_path": "./",
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,143 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <map>
#include <csignal>
std::condition_variable quit_condition;
std::mutex mtx;
void PointCloudCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
// printf("point cloud handle: %d, data_num: %d, data_type: %d, length: %d, frame_counter: %d\n",
// handle, data->dot_num, data->data_type, data->length, data->frame_cnt);
}
void ImuDataCallback(uint32_t handle, const uint8_t dev_type, LivoxLidarEthernetPacket* data, void* client_data) {
if (data == nullptr) {
return;
}
// printf("Imu data callback handle:%u, data_num:%u, data_type:%u, length:%u, frame_counter:%u.\n",
// handle, data->dot_num, data->data_type, data->length, data->frame_cnt);
}
void WorkModeCallback(livox_status status, uint32_t handle,LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("WorkModeCallack, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
}
void LoggerStartCallback(livox_status status, uint32_t handle, LivoxLidarLoggerResponse* response, void* client_data) {
if (status != kLivoxLidarStatusSuccess) {
printf("Start logger failed, the status :%d\n", status);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
if (response == nullptr) {
printf("Start logger failed, the response is nullptr.\n");
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
if (response->ret_code != 0) {
printf("Start logger failed, the response ret_Code:%d.\n", response->ret_code);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
return;
}
printf("The lidar[%u] start logger succ.\n", handle);
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void* client_data) {
if (info == nullptr) {
printf("lidar info change callback failed, the info is nullptr.\n");
return;
}
printf("LidarInfoChangeCallback Lidar handle: %u SN: %s\n", handle, info->sn);
SetLivoxLidarWorkMode(handle, kLivoxLidarNormal, WorkModeCallback, nullptr);
LivoxLidarStartLogger(handle, kLivoxLidarRealTimeLog, LoggerStartCallback, nullptr);
}
void Stop(int signal) {
quit_condition.notify_all();
}
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("Params Invalid, must input config path.\n");
return -1;
}
const std::string path = argv[1];
SaveLivoxLidarSdkLoggerFile();
//DisableLivoxSdkConsoleLogger();
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarPointCloudCallBack(PointCloudCallback, nullptr);
SetLivoxLidarImuDataCallback(ImuDataCallback, nullptr);
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
// capture Ctrl + C signal.
std::signal(SIGINT, Stop);
std::unique_lock<std::mutex> lock(mtx);
quit_condition.wait(lock);
printf("Deivice Logger exit.\n");
LivoxLidarSdkUninit();
printf("Livox Quick Start Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,26 @@
{
"lidar_log_enable": true,
"lidar_log_cache_size_MB": 500,
"lidar_log_path": "./",
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,26 @@
{
"lidar_log_enable": true,
"lidar_log_cache_size_MB": 500,
"lidar_log_path": "./",
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0)
set(DEMO_NAME multi_lidars_upgrade)
add_executable(${DEMO_NAME} main.cpp)
target_link_libraries(${DEMO_NAME}
PUBLIC
livox_lidar_sdk_static
)

View File

@@ -0,0 +1,21 @@
{
"Avia2": {
"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" : [
{
"host_ip" : "192.168.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,23 @@
{
"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.5",
"cmd_data_port": 56101,
"push_msg_ip": "192.168.1.5",
"push_msg_port": 56201,
"point_data_ip": "192.168.1.5",
"point_data_port": 56301,
"imu_data_ip" : "192.168.1.5",
"imu_data_port": 56401,
"log_data_ip" : "192.168.1.5",
"log_data_port": 56501
}
}
}

View File

@@ -0,0 +1,22 @@
{
"HAP": {
"lidar_net_info" : {
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
},
"host_net_info" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56000,
"push_msg_port" : 0,
"point_data_port": 57000,
"imu_data_port" : 58000,
"log_data_port" : 59000
}
]
}
}

View File

@@ -0,0 +1,131 @@
//
// 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 "livox_lidar_def.h"
#include "livox_lidar_api.h"
#include <condition_variable>
#include <mutex>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <chrono>
#include <vector>
#include <iostream>
#include <set>
std::condition_variable cv;
std::mutex mtx;
uint8_t lidars_num = 1; // lidar num
std::vector<uint32_t> handles;
void WorkModeCallback(livox_status status, uint32_t handle,LivoxLidarAsyncControlResponse *response, void *client_data) {
if (response == nullptr) {
return;
}
printf("Work_Mode_Call_Back, status:%u, handle:%u, ret_code:%u, error_key:%u",
status, handle, response->ret_code, response->error_key);
cv.notify_one();
}
void QueryInternalInfoCallback(livox_status status, uint32_t handle,
LivoxLidarDiagInternalInfoResponse* response, void* client_data) {
if (response == nullptr) {
return;
}
printf("QueryInternalInfoCallback, status:%u, handle:%u, ret_code:%u.\n",
status, handle, response->ret_code);
}
void LidarInfoChangeCallback(const uint32_t handle, const LivoxLidarInfo* info, void* client_data) {
if (info == nullptr) {
return;
}
printf("LidarInfoChangeCallback Lidar handle: %u SN: %s\n", handle, info->sn);
SetLivoxLidarWorkMode(handle, kLivoxLidarUpgrade, WorkModeCallback, nullptr);
handles.push_back(handle);
}
void LivoxLidarUpgradeProgressCallback(uint32_t handle, LivoxLidarUpgradeState state, void* client_data) {
printf("Upgrade Progress Callback, handle: %u, state: %d progress: %d\n", handle, state.state, state.progress);
if (state.progress == 100) {
cv.notify_one();
}
}
int main(int argc, const char *argv[]) {
if (argc != 3) {
printf("Params Invalid, must input config path and firmware path.\n");
return -1;
}
const std::string path = argv[1];
const std::string firmware_path = argv[2];
printf("path:%s.\n", path.c_str());
printf("firmware_path:%s.\n", firmware_path.c_str());
if (!LivoxLidarSdkInit(path.c_str())) {
printf("Livox Init Failed\n");
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarInfoChangeCallback(LidarInfoChangeCallback, nullptr);
//Lidar Upgrade
if (!SetLivoxLidarUpgradeFirmwarePath(firmware_path.c_str())) {
LivoxLidarSdkUninit();
return -1;
}
SetLivoxLidarUpgradeProgressCallback(LivoxLidarUpgradeProgressCallback, nullptr);
while(handles.size() < lidars_num) {
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock);
}
UpgradeLivoxLidars(handles.data(), handles.size());
break;
}
#ifdef WIN32
Sleep(3000000000);
#else
sleep(3000000);
#endif
LivoxLidarSdkUninit();
printf("Livox Lidars Update Demo End!\n");
return 0;
}

View File

@@ -0,0 +1,22 @@
{
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}

View File

@@ -0,0 +1,22 @@
{
"Mid360s": {
"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" : [
{
"host_ip" : "192.168.1.5",
"multicast_ip" : "224.1.1.5",
"cmd_data_port" : 56101,
"push_msg_port" : 56201,
"point_data_port": 56301,
"imu_data_port" : 56401,
"log_data_port" : 56501
}
]
}
}