6 Commits

Author SHA1 Message Date
Livox-SDK eb19d42ce4 feat:support Mid70 and Avia 2020-10-26 20:25:42 +08:00
livox 9f316ced0a LiDAR UTC sychronization ignore millisecond from GPRMC/GNRMC data 2020-08-04 20:18:38 +08:00
livox e61a6a18ad Update README_CN.md 2020-06-17 20:52:40 +08:00
livox 8fac7ef71d Update README.md 2020-06-17 20:52:07 +08:00
livox 58f76a01df Update README_CN.md 2020-06-17 20:31:25 +08:00
livox efa1703459 Update README.md 2020-06-17 20:29:52 +08:00
23 changed files with 446 additions and 118 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = "Livox SDK API"
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = V2.1.1 PROJECT_NUMBER = V2.2.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
+3 -3
View File
@@ -8,7 +8,7 @@ Livox SDK consists of Livox SDK communication protocol, Livox SDK core, Livox SD
## Prerequisites ## Prerequisites
* Ubuntu 14.04/Ubuntu 16.04/Ubuntu 18.04, both x86 and ARM (Nvidia TX2) * Ubuntu 14.04/Ubuntu 16.04/Ubuntu 18.04, both x86 and ARM (Nvidia TX2)
* Windows 7/10, Visual Studio 2015/2017 * Windows 7/10, Visual Studio 2015 Update3/2017
* C++11 compiler * C++11 compiler
# 2 Livox SDK Communication Protocol # 2 Livox SDK Communication Protocol
@@ -27,7 +27,7 @@ The Livox LiDAR sensors can be connected to host directly or through the Livox H
# 4 Livox SDK API # 4 Livox SDK API
Livox SDK API provides a set of C style functions which can be conveniently integrated in C/C++ programs. Please refer to the [Livox SDK API Reference](https://livox-sdk.github.io/Livox-SDK/) for further information. Livox SDK API provides a set of C style functions which can be conveniently integrated in C/C++ programs. Please refer to the [Livox SDK API Reference](https://livox-sdk.github.io/Livox-SDK-Doc/) for further information.
## 4.1 Installation ## 4.1 Installation
The installation procedures in Ubuntu 18.04/16.04/14.04 LTS and Windows 7/10 are shown here as examples. For Ubuntu 18.04/16.04/14.04 32-bit LTS and Mac, you can get it in [Livox-SDK wiki](https://github.com/Livox-SDK/Livox-SDK/wiki). The installation procedures in Ubuntu 18.04/16.04/14.04 LTS and Windows 7/10 are shown here as examples. For Ubuntu 18.04/16.04/14.04 32-bit LTS and Mac, you can get it in [Livox-SDK wiki](https://github.com/Livox-SDK/Livox-SDK/wiki).
@@ -67,7 +67,7 @@ sudo make install
### 4.1.2 Windows 7/10 ### 4.1.2 Windows 7/10
#### Dependencies #### Dependencies
Livox SDK supports Visual Studio 2015/2017 and requires install [CMake 3.0.0+](https://cmake.org/) as dependencies. Livox SDK supports Visual Studio 2015 Update3/2017 and requires install [CMake 3.0.0+](https://cmake.org/) as dependencies.
In the Livox SDK directory, run the following commands to create the Visual Studio solution file. In the Livox SDK directory, run the following commands to create the Visual Studio solution file.
Generate the 32-bit project: Generate the 32-bit project:
+3 -3
View File
@@ -7,7 +7,7 @@ Livox SDK 包括了 Livox SDK 通信协议,Livox SDK 内核,Livox SDK 应用
## 前置依赖 ## 前置依赖
* Ubuntu 14.04/Ubuntu 16.04/Ubuntu 18.04, x86 和 ARM (Nvidia TX2) * Ubuntu 14.04/Ubuntu 16.04/Ubuntu 18.04, x86 和 ARM (Nvidia TX2)
* Windows 7/10, Visual Studio 2015/2017 * Windows 7/10, Visual Studio 2015 Update3/2017
* C++11 编译器 * C++11 编译器
# 2 Livox SDK 通信协议 # 2 Livox SDK 通信协议
@@ -26,7 +26,7 @@ Livox LiDAR 传感器可以直接连接主机或者通过 Livox Hub 连接到主
# 4 Livox SDK 应用接口 # 4 Livox SDK 应用接口
Livox SDK 应用接口提供了一系列 C 风格的接口,可以很方便地集成进 C/C++ 程序。请查阅 [Livox SDK API Reference](https://livox-sdk.github.io/Livox-SDK/) 获取更多信息。 Livox SDK 应用接口提供了一系列 C 风格的接口,可以很方便地集成进 C/C++ 程序。请查阅 [Livox SDK API Reference](https://livox-sdk.github.io/Livox-SDK-Doc/) 获取更多信息。
## 4.1 安装 ## 4.1 安装
以下将介绍 Ubuntu 18.04/16.04/14.04 LTS 系统、 Windows 7/10 系统和 ARM-Linux 交叉编译的安装过程. 对于 Ubuntu 18.04/16.04/14.04 32-bit LTS 和 Mac 系统, 您可以查阅 [Livox-SDK wiki](https://github.com/Livox-SDK/Livox-SDK/wiki)。 以下将介绍 Ubuntu 18.04/16.04/14.04 LTS 系统、 Windows 7/10 系统和 ARM-Linux 交叉编译的安装过程. 对于 Ubuntu 18.04/16.04/14.04 32-bit LTS 和 Mac 系统, 您可以查阅 [Livox-SDK wiki](https://github.com/Livox-SDK/Livox-SDK/wiki)。
@@ -68,7 +68,7 @@ sudo make install
### 4.1.2 Windows 7/10 ### 4.1.2 Windows 7/10
#### 依赖 #### 依赖
Livox SDK 支持 Visual Studio 2015/2017,需要安装 [CMake 3.0.0+](https://cmake.org/) 依赖。 Livox SDK 支持 Visual Studio 2015 Update3/2017,需要安装 [CMake 3.0.0+](https://cmake.org/) 依赖。
在 Livox SDK 目录中,执行以下指令生成 Visual Studio solution 文件。 在 Livox SDK 目录中,执行以下指令生成 Visual Studio solution 文件。
生成 32-bit 工程: 生成 32-bit 工程:
+4
View File
@@ -100,6 +100,10 @@ void GetHubData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *c
LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data; LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data;
}else if ( data ->data_type == kImu) { }else if ( data ->data_type == kImu) {
LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data; LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data;
}else if ( data ->data_type == kTripleExtendCartesian) {
LivoxTripleExtendRawPoint *p_point_data = (LivoxTripleExtendRawPoint *)data->data;
}else if ( data ->data_type == kTripleExtendSpherical) {
LivoxTripleExtendSpherPoint *p_point_data = (LivoxTripleExtendSpherPoint *)data->data;
} }
printf("data_type %d data num %d\n", data->data_type, data_num); printf("data_type %d data num %d\n", data->data_type, data_num);
} }
+41 -22
View File
@@ -31,6 +31,7 @@
#define RAW_POINT_NUM 100 #define RAW_POINT_NUM 100
#define SINGLE_POINT_NUM 96 #define SINGLE_POINT_NUM 96
#define DUAL_POINT_NUM 48 #define DUAL_POINT_NUM 48
#define TRIPLE_POINT_NUM 30
#define IMU_POINT_NUM 1 #define IMU_POINT_NUM 1
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
@@ -133,27 +134,45 @@ void LvxFileHandle::BasePointsHandle(LivoxEthPacket *data, LvxBasePackDetail &pa
packet.timestamp_type = data->timestamp_type; packet.timestamp_type = data->timestamp_type;
packet.data_type = data->data_type; packet.data_type = data->data_type;
memcpy(packet.timestamp, data->timestamp, 8 * sizeof(uint8_t)); memcpy(packet.timestamp, data->timestamp, 8 * sizeof(uint8_t));
if (packet.data_type == 0) { switch (packet.data_type) {
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point) - \ case PointDataType::kCartesian:
sizeof(packet.pack_size) + RAW_POINT_NUM*sizeof(LivoxRawPoint); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point) - \
memcpy(packet.raw_point,(void *)data->data,RAW_POINT_NUM*sizeof(LivoxRawPoint)); sizeof(packet.pack_size) + RAW_POINT_NUM*sizeof(LivoxRawPoint);
} else if(packet.data_type == 1){ memcpy(packet.raw_point,(void *)data->data, RAW_POINT_NUM*sizeof(LivoxRawPoint));
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +RAW_POINT_NUM*sizeof(LivoxSpherPoint); break;
memcpy(packet.raw_point,(void *)data->data,RAW_POINT_NUM*sizeof(LivoxSpherPoint)); case PointDataType::kSpherical :
} else if(packet.data_type == 2){ packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +RAW_POINT_NUM*sizeof(LivoxSpherPoint);
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint); memcpy(packet.raw_point,(void *)data->data, RAW_POINT_NUM*sizeof(LivoxSpherPoint));
memcpy(packet.raw_point,(void *)data->data,SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint)); break;
} else if(packet.data_type == 3){ case PointDataType::kExtendCartesian :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint);
memcpy(packet.raw_point,(void *)data->data,SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint)); memcpy(packet.raw_point,(void *)data->data, SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint));
} else if(packet.data_type == 4){ break;
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint); case PointDataType::kExtendSpherical :
memcpy(packet.raw_point,(void *)data->data,DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint)); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint);
} else if(packet.data_type == 5){ memcpy(packet.raw_point,(void *)data->data, SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint));
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint); break;
memcpy(packet.raw_point,(void *)data->data,DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint)); case PointDataType::kDualExtendCartesian :
} else if(packet.data_type == 6){ packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint);
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +IMU_POINT_NUM*sizeof(LivoxImuPoint); memcpy(packet.raw_point,(void *)data->data, DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint));
memcpy(packet.raw_point,(void *)data->data,IMU_POINT_NUM*sizeof(LivoxImuPoint)); break;
case PointDataType::kDualExtendSpherical :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint);
memcpy(packet.raw_point,(void *)data->data, DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint));
break;
case PointDataType::kImu :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +IMU_POINT_NUM*sizeof(LivoxImuPoint);
memcpy(packet.raw_point,(void *)data->data, IMU_POINT_NUM*sizeof(LivoxImuPoint));
break;
case PointDataType::kTripleExtendCartesian :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendRawPoint);
memcpy(packet.raw_point,(void *)data->data, TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendRawPoint));
break;
case PointDataType::kTripleExtendSpherical :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendSpherPoint);
memcpy(packet.raw_point,(void *)data->data, TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendSpherPoint));
break;
default:
break;
} }
} }
+4
View File
@@ -105,6 +105,10 @@ void GetLidarData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void
LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data; LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data;
}else if ( data ->data_type == kImu) { }else if ( data ->data_type == kImu) {
LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data; LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data;
}else if ( data ->data_type == kTripleExtendCartesian) {
LivoxTripleExtendRawPoint *p_point_data = (LivoxTripleExtendRawPoint *)data->data;
}else if ( data ->data_type == kTripleExtendSpherical) {
LivoxTripleExtendSpherPoint *p_point_data = (LivoxTripleExtendSpherPoint *)data->data;
} }
printf("data_type %d packet num %d\n", data->data_type, data_recveive_count[handle]); printf("data_type %d packet num %d\n", data->data_type, data_recveive_count[handle]);
} }
+41 -21
View File
@@ -33,6 +33,7 @@
#define RAW_POINT_NUM 100 #define RAW_POINT_NUM 100
#define SINGLE_POINT_NUM 96 #define SINGLE_POINT_NUM 96
#define DUAL_POINT_NUM 48 #define DUAL_POINT_NUM 48
#define TRIPLE_POINT_NUM 30
#define IMU_POINT_NUM 1 #define IMU_POINT_NUM 1
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
@@ -135,27 +136,46 @@ void LvxFileHandle::BasePointsHandle(LivoxEthPacket *data, LvxBasePackDetail &pa
packet.timestamp_type = data->timestamp_type; packet.timestamp_type = data->timestamp_type;
packet.data_type = data->data_type; packet.data_type = data->data_type;
memcpy(packet.timestamp, data->timestamp, 8 * sizeof(uint8_t)); memcpy(packet.timestamp, data->timestamp, 8 * sizeof(uint8_t));
if (packet.data_type == 0) { switch (packet.data_type) {
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) + RAW_POINT_NUM*sizeof(LivoxRawPoint); case PointDataType::kCartesian:
memcpy(packet.raw_point,(void *)data->data,RAW_POINT_NUM*sizeof(LivoxRawPoint)); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point) - \
} else if(packet.data_type == 1){ sizeof(packet.pack_size) + RAW_POINT_NUM*sizeof(LivoxRawPoint);
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +RAW_POINT_NUM*sizeof(LivoxSpherPoint); memcpy(packet.raw_point,(void *)data->data, RAW_POINT_NUM*sizeof(LivoxRawPoint));
memcpy(packet.raw_point,(void *)data->data,RAW_POINT_NUM*sizeof(LivoxSpherPoint)); break;
} else if(packet.data_type == 2){ case PointDataType::kSpherical :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +RAW_POINT_NUM*sizeof(LivoxSpherPoint);
memcpy(packet.raw_point,(void *)data->data,SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint)); memcpy(packet.raw_point,(void *)data->data, RAW_POINT_NUM*sizeof(LivoxSpherPoint));
} else if(packet.data_type == 3){ break;
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint); case PointDataType::kExtendCartesian :
memcpy(packet.raw_point,(void *)data->data,SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint)); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint);
} else if(packet.data_type == 4){ memcpy(packet.raw_point,(void *)data->data, SINGLE_POINT_NUM*sizeof(LivoxExtendRawPoint));
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint); break;
memcpy(packet.raw_point,(void *)data->data,DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint)); case PointDataType::kExtendSpherical :
} else if(packet.data_type == 5){ packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint);
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint); memcpy(packet.raw_point,(void *)data->data, SINGLE_POINT_NUM*sizeof(LivoxExtendSpherPoint));
memcpy(packet.raw_point,(void *)data->data,DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint)); break;
} else if(packet.data_type == 6){ case PointDataType::kDualExtendCartesian :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +IMU_POINT_NUM*sizeof(LivoxImuPoint); packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint);
memcpy(packet.raw_point,(void *)data->data,IMU_POINT_NUM*sizeof(LivoxImuPoint)); memcpy(packet.raw_point,(void *)data->data, DUAL_POINT_NUM*sizeof(LivoxDualExtendRawPoint));
break;
case PointDataType::kDualExtendSpherical :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint);
memcpy(packet.raw_point,(void *)data->data, DUAL_POINT_NUM*sizeof(LivoxDualExtendSpherPoint));
break;
case PointDataType::kImu :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +IMU_POINT_NUM*sizeof(LivoxImuPoint);
memcpy(packet.raw_point,(void *)data->data, IMU_POINT_NUM*sizeof(LivoxImuPoint));
break;
case PointDataType::kTripleExtendCartesian :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendRawPoint);
memcpy(packet.raw_point,(void *)data->data, TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendRawPoint));
break;
case PointDataType::kTripleExtendSpherical :
packet.pack_size = sizeof(LvxBasePackDetail) - sizeof(packet.raw_point)- sizeof(packet.pack_size) +TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendSpherPoint);
memcpy(packet.raw_point,(void *)data->data, TRIPLE_POINT_NUM*sizeof(LivoxTripleExtendSpherPoint));
break;
default:
break;
} }
} }
+1
View File
@@ -140,6 +140,7 @@ void LidarGetExtrinsicFromXml(uint8_t handle) {
LvxDeviceInfo lidar_info; LvxDeviceInfo lidar_info;
ParseExtrinsicXml(devices[handle], lidar_info); ParseExtrinsicXml(devices[handle], lidar_info);
lvx_file_handler.AddDeviceInfo(lidar_info); lvx_file_handler.AddDeviceInfo(lidar_info);
lidar_info.extrinsic_enable = true;
if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) { if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) {
is_finish_extrinsic_parameter = true; is_finish_extrinsic_parameter = true;
extrinsic_condition.notify_one(); extrinsic_condition.notify_one();
+5 -1
View File
@@ -175,6 +175,10 @@ void LdsHub::OnHubDataCb(uint8_t hub_handle, LivoxEthPacket *data,
LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data; LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data;
}else if ( data ->data_type == kImu) { }else if ( data ->data_type == kImu) {
LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data; LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data;
}else if ( data ->data_type == kTripleExtendCartesian) {
LivoxTripleExtendRawPoint *p_point_data = (LivoxTripleExtendRawPoint *)data->data;
}else if ( data ->data_type == kTripleExtendSpherical) {
LivoxTripleExtendSpherPoint *p_point_data = (LivoxTripleExtendSpherPoint *)data->data;
} }
} }
} }
@@ -517,7 +521,7 @@ void LdsHub::AddLocalBroadcastCode(void) {
for (size_t i = 0; i < sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) { for (size_t i = 0; i < sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) {
std::string invalid_bd = "000000000"; std::string invalid_bd = "000000000";
printf("Local broadcast code : %s\n", local_broadcast_code_list[i]); printf("Local broadcast code : %s\n", local_broadcast_code_list[i]);
if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i]) - 1) && \ if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i]) + 1) && \
(nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) { (nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) {
AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]); AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]);
} else { } else {
+6 -2
View File
@@ -167,6 +167,10 @@ void LdsLidar::GetLidarDataCb(uint8_t handle, LivoxEthPacket *data,
LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data; LivoxDualExtendSpherPoint *p_point_data = (LivoxDualExtendSpherPoint *)data->data;
}else if ( data ->data_type == kImu) { }else if ( data ->data_type == kImu) {
LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data; LivoxImuPoint *p_point_data = (LivoxImuPoint *)data->data;
}else if ( data ->data_type == kTripleExtendCartesian) {
LivoxTripleExtendRawPoint *p_point_data = (LivoxTripleExtendRawPoint *)data->data;
}else if ( data ->data_type == kTripleExtendSpherical) {
LivoxTripleExtendSpherPoint *p_point_data = (LivoxTripleExtendSpherPoint *)data->data;
} }
} }
} }
@@ -261,7 +265,7 @@ void LdsLidar::OnDeviceChange(const DeviceInfo *info, DeviceEvent type) {
p_lidar->config.set_bits |= kConfigReturnMode; p_lidar->config.set_bits |= kConfigReturnMode;
} }
if (kDeviceTypeLidarMid40 != info->type) { if (kDeviceTypeLidarMid40 != info->type && kDeviceTypeLidarMid70 != info->type) {
LidarSetImuPushFrequency(handle, (ImuFreq)(p_lidar->config.imu_rate),\ LidarSetImuPushFrequency(handle, (ImuFreq)(p_lidar->config.imu_rate),\
LdsLidar::SetImuRatePushFrequencyCb, g_lidars); LdsLidar::SetImuRatePushFrequencyCb, g_lidars);
p_lidar->config.set_bits |= kConfigImuRate; p_lidar->config.set_bits |= kConfigImuRate;
@@ -443,7 +447,7 @@ void LdsLidar::AddLocalBroadcastCode(void) {
for (size_t i=0; i<sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) { for (size_t i=0; i<sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) {
std::string invalid_bd = "000000000"; std::string invalid_bd = "000000000";
printf("Local broadcast code : %s\n", local_broadcast_code_list[i]); printf("Local broadcast code : %s\n", local_broadcast_code_list[i]);
if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i]) - 1) && \ if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i]) + 1) && \
(nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) { (nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) {
LdsLidar::AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]); LdsLidar::AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]);
} else { } else {
+60 -4
View File
@@ -34,7 +34,9 @@ typedef enum {
kDeviceTypeHub = 0, /**< Livox Hub. */ kDeviceTypeHub = 0, /**< Livox Hub. */
kDeviceTypeLidarMid40 = 1, /**< Mid-40. */ kDeviceTypeLidarMid40 = 1, /**< Mid-40. */
kDeviceTypeLidarTele = 2, /**< Tele. */ kDeviceTypeLidarTele = 2, /**< Tele. */
kDeviceTypeLidarHorizon = 3 /**< Horizon. */ kDeviceTypeLidarHorizon = 3, /**< Horizon. */
kDeviceTypeLidarMid70 = 6, /**< Livox Mid-70. */
kDeviceTypeLidarAvia = 7 /**< Avia. */
} DeviceType; } DeviceType;
/** Lidar state. */ /** Lidar state. */
@@ -66,6 +68,12 @@ typedef enum {
kLidarStaticIpMode = 1 /**< Static IP. */ kLidarStaticIpMode = 1 /**< Static IP. */
} LidarIpMode; } LidarIpMode;
/** Lidar Scan Pattern. */
typedef enum {
kNoneRepetitiveScanPattern = 0, /**< None Repetitive Scan Pattern. */
kRepetitiveScanPattern = 1, /**< Repetitive Scan Pattern. */
} LidarScanPattern;
/** Function return value definition. */ /** Function return value definition. */
typedef enum { typedef enum {
kStatusSendFailed = -9, /**< Command send failed. */ kStatusSendFailed = -9, /**< Command send failed. */
@@ -110,6 +118,8 @@ typedef enum {
kDualExtendCartesian, /**< Dual extend cartesian coordinate point cloud. */ kDualExtendCartesian, /**< Dual extend cartesian coordinate point cloud. */
kDualExtendSpherical, /**< Dual extend spherical coordinate point cloud. */ kDualExtendSpherical, /**< Dual extend spherical coordinate point cloud. */
kImu, /**< IMU data. */ kImu, /**< IMU data. */
kTripleExtendCartesian, /**< Triple extend cartesian coordinate point cloud. */
kTripleExtendSpherical, /**< Triple extend spherical coordinate point cloud. */
kMaxPointDataType /**< Max Point Data Type. */ kMaxPointDataType /**< Max Point Data Type. */
} PointDataType; } PointDataType;
@@ -117,7 +127,8 @@ typedef enum {
typedef enum { typedef enum {
kFirstReturn, /**< First single return mode . */ kFirstReturn, /**< First single return mode . */
kStrongestReturn, /**< Strongest single return mode. */ kStrongestReturn, /**< Strongest single return mode. */
kDualReturn /**< Dual return mode. */ kDualReturn, /**< Dual return mode. */
kTripleReturn, /**< Triple return mode. */
} PointCloudReturnMode; } PointCloudReturnMode;
/** IMU push frequency. */ /** IMU push frequency. */
@@ -129,8 +140,8 @@ typedef enum {
#pragma pack(1) #pragma pack(1)
#define LIVOX_SDK_MAJOR_VERSION 2 #define LIVOX_SDK_MAJOR_VERSION 2
#define LIVOX_SDK_MINOR_VERSION 1 #define LIVOX_SDK_MINOR_VERSION 2
#define LIVOX_SDK_PATCH_VERSION 1 #define LIVOX_SDK_PATCH_VERSION 0
#define kBroadcastCodeSize 16 #define kBroadcastCodeSize 16
@@ -209,6 +220,40 @@ typedef struct {
uint8_t tag2; /**< Tag */ uint8_t tag2; /**< Tag */
} LivoxDualExtendSpherPoint; } LivoxDualExtendSpherPoint;
/** Triple extend cartesian coordinate format. */
typedef struct {
int32_t x1; /**< X axis, Unit:mm */
int32_t y1; /**< Y axis, Unit:mm */
int32_t z1; /**< Z axis, Unit:mm */
uint8_t reflectivity1; /**< Reflectivity */
uint8_t tag1; /**< Tag */
int32_t x2; /**< X axis, Unit:mm */
int32_t y2; /**< Y axis, Unit:mm */
int32_t z2; /**< Z axis, Unit:mm */
uint8_t reflectivity2; /**< Reflectivity */
uint8_t tag2; /**< Tag */
int32_t x3; /**< X axis, Unit:mm */
int32_t y3; /**< Y axis, Unit:mm */
int32_t z3; /**< Z axis, Unit:mm */
uint8_t reflectivity3; /**< Reflectivity */
uint8_t tag3; /**< Tag */
} LivoxTripleExtendRawPoint;
/** Triple extend spherical coordinate format. */
typedef struct {
uint16_t theta; /**< Zenith angle[0, 18000], Unit: 0.01 degree */
uint16_t phi; /**< Azimuth[0, 36000], Unit: 0.01 degree */
uint32_t depth1; /**< Depth, Unit: mm */
uint8_t reflectivity1; /**< Reflectivity */
uint8_t tag1; /**< Tag */
uint32_t depth2; /**< Depth, Unit: mm */
uint8_t reflectivity2; /**< Reflectivity */
uint8_t tag2; /**< Tag */
uint32_t depth3; /**< Depth, Unit: mm */
uint8_t reflectivity3; /**< Reflectivity */
uint8_t tag3; /**< Tag */
} LivoxTripleExtendSpherPoint;
/** IMU data format. */ /** IMU data format. */
typedef struct { typedef struct {
float gyro_x; /**< Gyroscope X axis, Unit:rad/s */ float gyro_x; /**< Gyroscope X axis, Unit:rad/s */
@@ -502,6 +547,8 @@ typedef struct {
typedef enum { typedef enum {
kKeyDefault = 0, /**< Default key name. */ kKeyDefault = 0, /**< Default key name. */
kKeyHighSensetivity = 1, /**< Key to get/set LiDAR' Sensetivity. */ kKeyHighSensetivity = 1, /**< Key to get/set LiDAR' Sensetivity. */
kKeyScanPattern = 2, /**< Key to get/set LiDAR' ScanPattern. */
kKeySlotNum = 3, /**< Key to get/set LiDAR' Slot number. */
} DeviceParamKeyName; } DeviceParamKeyName;
/** /**
@@ -529,6 +576,15 @@ typedef struct {
uint16_t key[1]; /*< Key, refer to \ref DeviceParamKeyName. */ uint16_t key[1]; /*< Key, refer to \ref DeviceParamKeyName. */
} GetDeviceParameterRequest; } GetDeviceParameterRequest;
/**
* The request body for the command of resetting device's parameters.
*/
typedef struct {
uint8_t flag; /*< 0: for resetting all keys, 1: for resetting part of keys. */
uint8_t key_num; /*< number of keys to reset. */
uint16_t key[1]; /*< Keys to reset, refer to \ref DeviceParamKeyName. */
} ResetDeviceParameterRequest;
/** /**
* The request body for the command of setting Livox LiDAR's parameters. * The request body for the command of setting Livox LiDAR's parameters.
*/ */
+85 -1
View File
@@ -163,6 +163,11 @@ typedef void (*DataCallback)(uint8_t handle, LivoxEthPacket *data, uint32_t data
* cloud data callback before beginning sampling. * cloud data callback before beginning sampling.
* @param handle device handle. * @param handle device handle.
* @param cb callback to receive point cloud data. * @param cb callback to receive point cloud data.
* @note 1: Don't do any blocking operations in callback function, it will affects further data's receiving;
* 2: For different device handle, callback to receive point cloud data will run on its own thread. If you bind
* different handle to same callback function, please make sure that operations in callback function are thread-safe;
* 3: callback function's data pointer will be invalid after callback fuction returns. It's recommended to
* copy all data_num of point cloud every time callback is triggered.
* @param client_data user data associated with the command. * @param client_data user data associated with the command.
*/ */
void SetDataCallback(uint8_t handle, DataCallback cb, void *client_data); void SetDataCallback(uint8_t handle, DataCallback cb, void *client_data);
@@ -332,6 +337,7 @@ typedef void (*SetDeviceParametersCallback)(livox_status status,
/** /**
* LiDAR Enable HighSensitivity. * LiDAR Enable HighSensitivity.
* @note \ref LidarEnableHighSensitivity only support for Tele/Avia.
* @param handle device handle. * @param handle device handle.
* @param cb callback for the command. * @param cb callback for the command.
* @param client_data user data associated with the command. * @param client_data user data associated with the command.
@@ -341,6 +347,7 @@ livox_status LidarEnableHighSensitivity(uint8_t handle, SetDeviceParametersCallb
/** /**
* LiDAR Disable HighSensitivity. * LiDAR Disable HighSensitivity.
* @note \ref LidarDisableHighSensitivity only support for Tele/Avia.
* @param handle device handle. * @param handle device handle.
* @param cb callback for the command. * @param cb callback for the command.
* @param client_data user data associated with the command. * @param client_data user data associated with the command.
@@ -363,6 +370,7 @@ typedef void (*GetDeviceParametersCallback)(livox_status status,
/** /**
* LiDAR Get HighSensitivity State. * LiDAR Get HighSensitivity State.
* @note \ref LidarGetHighSensitivityState only support for Tele/Avia.
* @param handle device handle. * @param handle device handle.
* @param cb callback for the command. * @param cb callback for the command.
* @param client_data user data associated with the command. * @param client_data user data associated with the command.
@@ -370,6 +378,82 @@ typedef void (*GetDeviceParametersCallback)(livox_status status,
*/ */
livox_status LidarGetHighSensitivityState(uint8_t handle, GetDeviceParametersCallback cb, void *client_data); livox_status LidarGetHighSensitivityState(uint8_t handle, GetDeviceParametersCallback cb, void *client_data);
/**
* LiDAR Set Scan Pattern.
* @note \ref LidarSetScanPattern only support for Avia.
* @param handle device handle.
* @param pattern scan pattern of LiDAR, see \ref LidarScanPattern for detail.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status LidarSetScanPattern(uint8_t handle, LidarScanPattern pattern, SetDeviceParametersCallback cb, void *client_data);
/**
* LiDAR Get Scan Pattern.
* @note \ref LidarGetScanPattern only support for Avia.
* @param handle device handle.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status LidarGetScanPattern(uint8_t handle, GetDeviceParametersCallback cb, void *client_data);
/**
* LiDAR Set Slot Number.
* @note \ref LidarSetSlotNum only support for Mid70/Avia.
* @param handle device handle.
* @param slot slot number of LiDAR, range from 1 to 9.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status LidarSetSlotNum(uint8_t handle, uint8_t slot, SetDeviceParametersCallback cb, void *client_data);
/**
* LiDAR Get Slot Number.
* @note \ref LidarGetSlotNum only support for Mid70/Avia.
* @param handle device handle.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status LidarGetSlotNum(uint8_t handle, GetDeviceParametersCallback cb, void *client_data);
/**
* @c DeviceResetParameters' response callback function.
* @param status kStatusSuccess on successful return, kStatusTimeout on timeout, see \ref LivoxStatus for other
* error code.
* @param handle device handle.
* @param response response from the device.
* @param client_data user data associated with the command.
*/
typedef void (*DeviceResetParametersCallback)(livox_status status,
uint8_t handle,
DeviceParameterResponse *response,
void *client_data);
/**
* Reset LiDAR/Hub's All Parameters, see \ref DeviceParamKeyName for all parameters.
* @param handle device handle.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status DeviceResetAllParameters(uint8_t handle, DeviceResetParametersCallback cb, void *client_data);
/**
* Reset LiDAR/Hub's Parameters, see \ref DeviceParamKeyName for all parameters.
* @param handle device handle.
* @param keys keys to reset, see \ref DeviceParamKeyName for all parameters.
* @param num num of keys to reset.
* @param cb callback for the command.
* @param client_data user data associated with the command.
* @return kStatusSuccess on successful return, see \ref LivoxStatus for other error code.
*/
livox_status DeviceResetParameters(uint8_t handle, DeviceParamKeyName * keys, uint8_t num, DeviceResetParametersCallback cb, void *client_data);
/** /**
* @c HubQueryLidarInformation response callback function. * @c HubQueryLidarInformation response callback function.
* @param status kStatusSuccess on successful return, kStatusTimeout on timeout, see \ref LivoxStatus for other * @param status kStatusSuccess on successful return, kStatusTimeout on timeout, see \ref LivoxStatus for other
@@ -882,7 +966,7 @@ livox_status LidarGetImuPushFrequency(uint8_t handle, LidarGetImuPushFrequencyCa
* Set GPRMC formate synchronization time. * Set GPRMC formate synchronization time.
* @note \ref LidarSetRmcSyncTime is not supported for Mid40/100 firmware version < 03.07.0000. * @note \ref LidarSetRmcSyncTime is not supported for Mid40/100 firmware version < 03.07.0000.
* @param handle device handle. * @param handle device handle.
* @param rmc GPRMC\GNRMC format data. * @param rmc GPRMC/GNRMC format data.
* @param rmc_length lenth of gprmc. * @param rmc_length lenth of gprmc.
* @param cb callback for the command. * @param cb callback for the command.
* @param client_data user data associated with the command. * @param client_data user data associated with the command.
+3 -2
View File
@@ -31,6 +31,7 @@
using std::lock_guard; using std::lock_guard;
using std::mutex; using std::mutex;
using std::vector; using std::vector;
using std::chrono::steady_clock;
namespace livox { namespace livox {
@@ -111,8 +112,8 @@ void IOLoop::Loop() {
} }
if (enable_timer_) { if (enable_timer_) {
apr_time_t t = apr_time_now(); TimePoint t = steady_clock::now();;
if (last_timeout_ == 0 || t - last_timeout_ > apr_time_from_msec(50)) { if (last_timeout_ == TimePoint() || t - last_timeout_ > std::chrono::milliseconds(50)) {
last_timeout_ = t; last_timeout_ = t;
// copy delegates_ in case delegate is removed in callback. // copy delegates_ in case delegate is removed in callback.
DelegatesType delegates = delegates_; DelegatesType delegates = delegates_;
+4 -3
View File
@@ -43,10 +43,11 @@ namespace livox {
class IOLoop : public noncopyable { class IOLoop : public noncopyable {
public: public:
typedef std::chrono::steady_clock::time_point TimePoint;
class IOLoopDelegate { class IOLoopDelegate {
public: public:
virtual void OnData(apr_socket_t *, void *) {} virtual void OnData(apr_socket_t *, void *) {}
virtual void OnTimer(apr_time_t) {} virtual void OnTimer(TimePoint) {}
virtual void OnWake() {} virtual void OnWake() {}
}; };
@@ -54,7 +55,7 @@ class IOLoop : public noncopyable {
public: public:
explicit IOLoop(apr_pool_t *mem_pool, bool enable_timer = true, bool enable_wake = true) explicit IOLoop(apr_pool_t *mem_pool, bool enable_timer = true, bool enable_wake = true)
: pollset_(NULL), mem_pool_(mem_pool), last_timeout_(0), enable_timer_(enable_timer), enable_wake_(enable_wake){}; : pollset_(NULL), mem_pool_(mem_pool), last_timeout_(), enable_timer_(enable_timer), enable_wake_(enable_wake){};
bool Init(); bool Init();
void Uninit(); void Uninit();
@@ -78,7 +79,7 @@ class IOLoop : public noncopyable {
DelegatesType delegates_; DelegatesType delegates_;
apr_pollset_t *pollset_; apr_pollset_t *pollset_;
apr_pool_t *mem_pool_; apr_pool_t *mem_pool_;
apr_time_t last_timeout_; TimePoint last_timeout_;
std::mutex mutex_; std::mutex mutex_;
bool enable_timer_; bool enable_timer_;
bool enable_wake_; bool enable_wake_;
@@ -37,6 +37,7 @@ using std::make_pair;
using std::map; using std::map;
using std::pair; using std::pair;
using std::string; using std::string;
using std::chrono::steady_clock;
namespace livox { namespace livox {
@@ -52,9 +53,9 @@ CommandChannel::CommandChannel(apr_port_t port,
loop_(NULL), loop_(NULL),
callback_(cb), callback_(cb),
comm_port_(new CommPort), comm_port_(new CommPort),
heartbeat_time_(0), heartbeat_time_(),
remote_ip_(remote_ip), remote_ip_(remote_ip),
last_heartbeat_(0) {} last_heartbeat_() {}
bool CommandChannel::Bind(IOLoop *loop) { bool CommandChannel::Bind(IOLoop *loop) {
if (loop == NULL) { if (loop == NULL) {
@@ -67,6 +68,7 @@ bool CommandChannel::Bind(IOLoop *loop) {
} }
loop_->AddDelegate(sock_, this); loop_->AddDelegate(sock_, this);
last_heartbeat_ = steady_clock::now();
return true; return true;
} }
@@ -118,11 +120,11 @@ void CommandChannel::SendAsync(const Command &command) {
} }
} }
void CommandChannel::OnTimer(apr_time_t now) { void CommandChannel::OnTimer(TimePoint now) {
list<Command> timeout_commands; list<Command> timeout_commands;
map<uint16_t, pair<Command, apr_time_t> >::iterator ite = commands_.begin(); map<uint16_t, pair<Command, TimePoint> >::iterator ite = commands_.begin();
while (ite != commands_.end()) { while (ite != commands_.end()) {
pair<Command, apr_time_t> &command_pair = ite->second; pair<Command, TimePoint> &command_pair = ite->second;
if (now > command_pair.second) { if (now > command_pair.second) {
timeout_commands.push_back(command_pair.first); timeout_commands.push_back(command_pair.first);
commands_.erase(ite++); commands_.erase(ite++);
@@ -132,7 +134,7 @@ void CommandChannel::OnTimer(apr_time_t now) {
} }
for (list<Command>::iterator ite = timeout_commands.begin(); ite != timeout_commands.end(); ++ite) { for (list<Command>::iterator ite = timeout_commands.begin(); ite != timeout_commands.end(); ++ite) {
LOG_WARN("Apr time now: {}, Command Timeout: Set {}, Id {}, Seq {}", PrintAPRTime(apr_time_now()), LOG_WARN("Command Timeout: Set {}, Id {}, Seq {}",
(uint16_t)ite->packet.cmd_set, ite->packet.cmd_code, ite->packet.seq_num); (uint16_t)ite->packet.cmd_set, ite->packet.cmd_code, ite->packet.seq_num);
if (callback_) { if (callback_) {
ite->packet.packet_type = kCommandTypeAck; ite->packet.packet_type = kCommandTypeAck;
@@ -140,7 +142,7 @@ void CommandChannel::OnTimer(apr_time_t now) {
} }
} }
if ((last_heartbeat_ != 0) && (now - last_heartbeat_ > apr_time_from_sec(3))) { if (now - last_heartbeat_ > std::chrono::seconds(3)) {
DeviceDisconnect(handle_); DeviceDisconnect(handle_);
} else { } else {
HeartBeat(now); HeartBeat(now);
@@ -165,13 +167,13 @@ void CommandChannel::Uninit() {
} }
commands_.clear(); commands_.clear();
last_heartbeat_ = 0; last_heartbeat_ = {};
heartbeat_time_ = 0; heartbeat_time_ = {};
remote_ip_ = ""; remote_ip_ = "";
} }
void CommandChannel::HeartBeat(apr_time_t t) { void CommandChannel::HeartBeat(TimePoint t) {
if (heartbeat_time_ == 0 || (t - heartbeat_time_) > apr_time_from_msec(kHeartbeatTimer)) { if (heartbeat_time_ == TimePoint() || (t - heartbeat_time_) > kHeartbeatTimer) {
heartbeat_time_ = t; heartbeat_time_ = t;
Command command(handle_, Command command(handle_,
@@ -230,7 +232,7 @@ Command CommandChannel::DeepCopy(const Command &cmd) {
} }
void CommandChannel::OnHeartbeatAck(const CommPacket &) { void CommandChannel::OnHeartbeatAck(const CommPacket &) {
last_heartbeat_ = apr_time_now(); last_heartbeat_ = steady_clock::now();
} }
void CommandChannel::DeviceDisconnect(uint8_t handle) { void CommandChannel::DeviceDisconnect(uint8_t handle) {
@@ -240,7 +242,7 @@ void CommandChannel::DeviceDisconnect(uint8_t handle) {
void CommandChannel::Send(const Command &command) { void CommandChannel::Send(const Command &command) {
LOG_INFO(" Send Command: Set {} Id {} Seq {}", (uint16_t)command.packet.cmd_set, command.packet.cmd_code, command.packet.seq_num); LOG_INFO(" Send Command: Set {} Id {} Seq {}", (uint16_t)command.packet.cmd_set, command.packet.cmd_code, command.packet.seq_num);
SendInternal(command); SendInternal(command);
commands_[command.packet.seq_num] = make_pair(command, apr_time_now() + apr_time_from_msec(command.time_out)); commands_[command.packet.seq_num] = make_pair(command, steady_clock::now() + std::chrono::milliseconds(command.time_out));
Command &cmd = commands_[command.packet.seq_num].first; Command &cmd = commands_[command.packet.seq_num].first;
if (cmd.packet.data != NULL) { if (cmd.packet.data != NULL) {
delete[] cmd.packet.data; delete[] cmd.packet.data;
@@ -28,6 +28,7 @@
#include <map> #include <map>
#include <list> #include <list>
#include <string> #include <string>
#include <chrono>
#include "apr_network_io.h" #include "apr_network_io.h"
#include "base/io_loop.h" #include "base/io_loop.h"
#include "comm/comm_port.h" #include "comm/comm_port.h"
@@ -71,6 +72,8 @@ class CommandChannelDelegate {
*/ */
class CommandChannel : public IOLoop::IOLoopDelegate { class CommandChannel : public IOLoop::IOLoopDelegate {
public: public:
typedef std::chrono::steady_clock::time_point TimePoint;
CommandChannel(apr_port_t port, CommandChannel(apr_port_t port,
uint8_t handle, uint8_t handle,
const std::string &remote_ip, const std::string &remote_ip,
@@ -95,31 +98,31 @@ class CommandChannel : public IOLoop::IOLoopDelegate {
void SendAsync(const Command &command); void SendAsync(const Command &command);
void OnData(apr_socket_t *, void *); void OnData(apr_socket_t *, void *);
void OnTimer(apr_time_t now); void OnTimer(TimePoint now);
static uint16_t GenerateSeq(); static uint16_t GenerateSeq();
private: private:
void Send(const Command &cmd); void Send(const Command &cmd);
void HeartBeat(apr_time_t t); void HeartBeat(TimePoint t);
void SendInternal(const Command &command); void SendInternal(const Command &command);
Command DeepCopy(const Command &cmd); Command DeepCopy(const Command &cmd);
void OnHeartbeatAck(const CommPacket &packet); void OnHeartbeatAck(const CommPacket &packet);
void DeviceDisconnect(uint8_t handle); void DeviceDisconnect(uint8_t handle);
private: private:
static const int kHeartbeatTimer = 800; const std::chrono::milliseconds kHeartbeatTimer = std::chrono::milliseconds(800);
uint8_t handle_; uint8_t handle_;
apr_port_t port_; apr_port_t port_;
apr_socket_t *sock_; apr_socket_t *sock_;
apr_pool_t *mem_pool_; apr_pool_t *mem_pool_;
IOLoop *loop_; IOLoop *loop_;
CommandChannelDelegate *callback_; CommandChannelDelegate *callback_;
std::map<uint16_t, std::pair<Command, apr_time_t> > commands_; std::map<uint16_t, std::pair<Command, TimePoint> > commands_;
std::unique_ptr<CommPort> comm_port_; std::unique_ptr<CommPort> comm_port_;
apr_time_t heartbeat_time_; TimePoint heartbeat_time_;
std::string remote_ip_; std::string remote_ip_;
apr_time_t last_heartbeat_; TimePoint last_heartbeat_;
}; };
} // namespace livox } // namespace livox
+119 -26
View File
@@ -158,7 +158,7 @@ bool ParseRmcTime(const char* rmc, uint16_t rmc_len, LidarSetUtcSyncTimeRequest*
char utc_hms_buff[HMS_PARSE_BUF] = { 0 }; char utc_hms_buff[HMS_PARSE_BUF] = { 0 };
char utc_yy_buff[YY_PARSE_BUF] = { 0 }; char utc_yy_buff[YY_PARSE_BUF] = { 0 };
int hour = 0, minute = 0, second = 0, millisecond = 0; int hour = 0, minute = 0, second = 0;
memset(utc_time_req, 0, sizeof(LidarSetUtcSyncTimeRequest)); memset(utc_time_req, 0, sizeof(LidarSetUtcSyncTimeRequest));
@@ -204,25 +204,12 @@ bool ParseRmcTime(const char* rmc, uint16_t rmc_len, LidarSetUtcSyncTimeRequest*
return false; return false;
} }
time_buff_size = strlen(utc_hms_buff); if (3 != sscanf(utc_hms_buff, "%2d%2d%2d", &hour, &minute, &second)) {
switch (time_buff_size) { return false;
case sizeof("hhmmss")-1:
if (3 != sscanf(utc_hms_buff, "%2d%2d%2d", &hour, &minute, &second)) {
return false;
}
break;
case sizeof("hhmmss.s")-1:
case sizeof("hhmmss.ss")-1:
case sizeof("hhmmss.sss")-1:
if (4 != sscanf(utc_hms_buff, "%2d%2d%2d.%2d", &hour, &minute, &second, &millisecond)) {
return false;
}
break;
default:
return false;
} }
utc_time_req->hour = hour; utc_time_req->hour = hour;
utc_time_req->mircrosecond = (minute * 60 * 1000 + second * 1000 + millisecond) * 1000; utc_time_req->mircrosecond = (minute * 60 * 1000 + second * 1000) * 1000;
return true; return true;
} }
@@ -391,7 +378,8 @@ livox_status RebootDevice(uint8_t handle, uint16_t timeout, CommonCommandCallbac
} }
livox_status LidarEnableHighSensitivity(uint8_t handle, SetDeviceParametersCallback cb, void *client_data) { livox_status LidarEnableHighSensitivity(uint8_t handle, SetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarTele(handle)) { if (!device_manager().IsLidarTele(handle)
&& !device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
@@ -407,7 +395,8 @@ livox_status LidarEnableHighSensitivity(uint8_t handle, SetDeviceParametersCallb
} }
livox_status LidarDisableHighSensitivity(uint8_t handle, SetDeviceParametersCallback cb, void *client_data) { livox_status LidarDisableHighSensitivity(uint8_t handle, SetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarTele(handle)) { if (!device_manager().IsLidarTele(handle)
&& !device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
uint8_t req_buff[kMaxCommandBufferSize] = {0}; uint8_t req_buff[kMaxCommandBufferSize] = {0};
@@ -422,7 +411,8 @@ livox_status LidarDisableHighSensitivity(uint8_t handle, SetDeviceParametersCall
} }
livox_status LidarGetHighSensitivityState(uint8_t handle, GetDeviceParametersCallback cb, void *client_data) { livox_status LidarGetHighSensitivityState(uint8_t handle, GetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarTele(handle)) { if (!device_manager().IsLidarTele(handle)
&& !device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
@@ -432,6 +422,101 @@ livox_status LidarGetHighSensitivityState(uint8_t handle, GetDeviceParametersCal
return GetDeiveParameter(handle, &req, cb, client_data); return GetDeiveParameter(handle, &req, cb, client_data);
} }
livox_status LidarSetSlotNum(uint8_t handle, uint8_t slot, SetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarMid70(handle)
&& !device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported;
}
uint8_t req_buff[kMaxCommandBufferSize] = {0};
uint16_t req_len = 0;
KeyValueParam * kv = (KeyValueParam *)&req_buff[0];
kv->key = static_cast<uint16_t>(kKeySlotNum);
kv->length = 1;
kv->value[0] = slot;
req_len = sizeof(KeyValueParam);
return SetDeviceParameters(handle, req_buff, req_len, cb, client_data);
}
livox_status LidarGetSlotNum(uint8_t handle, GetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarMid70(handle)
&& !device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported;
}
GetDeviceParameterRequest req;
req.param_num = 1;
req.key[0] = static_cast<uint16_t>(kKeySlotNum);
return GetDeiveParameter(handle, &req, cb, client_data);
}
livox_status LidarGetScanPattern(uint8_t handle, GetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported;
}
GetDeviceParameterRequest req;
req.param_num = 1;
req.key[0] = static_cast<uint16_t>(kKeyScanPattern);
return GetDeiveParameter(handle, &req, cb, client_data);
}
livox_status LidarSetScanPattern(uint8_t handle, LidarScanPattern pattern, SetDeviceParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported;
}
uint8_t req_buff[kMaxCommandBufferSize] = {0};
uint16_t req_len = 0;
KeyValueParam * kv = (KeyValueParam *)&req_buff[0];
kv->key = static_cast<uint16_t>(kKeyScanPattern);
kv->length = 1;
kv->value[0] = static_cast<uint8_t>(pattern);
req_len = sizeof(KeyValueParam);
return SetDeviceParameters(handle, req_buff, req_len, cb, client_data);
}
livox_status DeviceResetAllParameters(uint8_t handle, DeviceResetParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarAvia(handle)
&& !device_manager().IsLidarMid70(handle)
&& !device_manager().IsLidarTele(handle)) {
return kStatusNotSupported;
}
ResetDeviceParameterRequest req = {};
req.flag = 0; //Reset all keys
livox_status result = command_handler().SendCommand(handle,
kCommandSetGeneral,
kCommandIDGeneralResetDeviceParam,
(uint8_t *)&req,
sizeof(req),
MakeCommandCallback<DeviceParameterResponse>(cb, client_data));
return result;
}
livox_status DeviceResetParameters(uint8_t handle, DeviceParamKeyName * keys, uint8_t keys_num, DeviceResetParametersCallback cb, void *client_data) {
if (!device_manager().IsLidarAvia(handle)
&& !device_manager().IsLidarMid70(handle)
&& !device_manager().IsLidarTele(handle)) {
return kStatusNotSupported;
}
uint8_t req_buff[kMaxCommandBufferSize] = {0};
uint16_t req_len = 0;
ResetDeviceParameterRequest * req = (ResetDeviceParameterRequest *)&req_buff[0];
req->flag = 1; //Reset some keys
req->key_num = keys_num;
for (uint8_t i = 0; i < keys_num; i++) {
req->key[i] = static_cast<uint16_t>(keys[i]);
}
req_len = sizeof(ResetDeviceParameterRequest) + (keys_num - 1) * sizeof(uint16_t);
livox_status result = command_handler().SendCommand(handle,
kCommandSetGeneral,
kCommandIDGeneralResetDeviceParam,
(uint8_t *)req,
req_len,
MakeCommandCallback<DeviceParameterResponse>(cb, client_data));
return result;
}
livox_status LidarSetMode(uint8_t handle, LidarMode mode, CommonCommandCallback cb, void *client_data) { livox_status LidarSetMode(uint8_t handle, LidarMode mode, CommonCommandCallback cb, void *client_data) {
if (device_manager().device_mode() != kDeviceModeLidar) { if (device_manager().device_mode() != kDeviceModeLidar) {
return kStatusNotSupported; return kStatusNotSupported;
@@ -492,7 +577,9 @@ livox_status LidarRainFogSuppress(uint8_t handle, bool enable, CommonCommandCall
livox_status LidarTurnOnFan(uint8_t handle, CommonCommandCallback cb, void *client_data) { livox_status LidarTurnOnFan(uint8_t handle, CommonCommandCallback cb, void *client_data) {
if (device_manager().device_mode() != kDeviceModeLidar if (device_manager().device_mode() != kDeviceModeLidar
|| device_manager().IsLidarMid40(handle)) { || device_manager().IsLidarMid40(handle)
|| device_manager().IsLidarMid70(handle)
|| device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
return LidarFanControl(handle, true, cb, client_data); return LidarFanControl(handle, true, cb, client_data);
@@ -500,7 +587,9 @@ livox_status LidarTurnOnFan(uint8_t handle, CommonCommandCallback cb, void *clie
livox_status LidarTurnOffFan(uint8_t handle, CommonCommandCallback cb, void *client_data) { livox_status LidarTurnOffFan(uint8_t handle, CommonCommandCallback cb, void *client_data) {
if (device_manager().device_mode() != kDeviceModeLidar if (device_manager().device_mode() != kDeviceModeLidar
|| device_manager().IsLidarMid40(handle)) { || device_manager().IsLidarMid40(handle)
|| device_manager().IsLidarMid70(handle)
|| device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
return LidarFanControl(handle, false, cb, client_data); return LidarFanControl(handle, false, cb, client_data);
@@ -508,7 +597,9 @@ livox_status LidarTurnOffFan(uint8_t handle, CommonCommandCallback cb, void *cli
livox_status LidarGetFanState(uint8_t handle, LidarGetFanStateCallback cb, void * data) { livox_status LidarGetFanState(uint8_t handle, LidarGetFanStateCallback cb, void * data) {
if (device_manager().device_mode() != kDeviceModeLidar if (device_manager().device_mode() != kDeviceModeLidar
|| device_manager().IsLidarMid40(handle)) { || device_manager().IsLidarMid40(handle)
|| device_manager().IsLidarMid70(handle)
|| device_manager().IsLidarAvia(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
livox_status result = command_handler().SendCommand(handle, livox_status result = command_handler().SendCommand(handle,
@@ -551,7 +642,8 @@ livox_status LidarGetPointCloudReturnMode(uint8_t handle, LidarGetPointCloudRetu
livox_status LidarSetImuPushFrequency(uint8_t handle, ImuFreq freq, CommonCommandCallback cb, void * client_data) { livox_status LidarSetImuPushFrequency(uint8_t handle, ImuFreq freq, CommonCommandCallback cb, void * client_data) {
if (device_manager().device_mode() != kDeviceModeLidar if (device_manager().device_mode() != kDeviceModeLidar
|| device_manager().IsLidarMid40(handle)) { || device_manager().IsLidarMid40(handle)
|| device_manager().IsLidarMid70(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
uint8_t req = static_cast<uint8_t>(freq); uint8_t req = static_cast<uint8_t>(freq);
@@ -566,7 +658,8 @@ livox_status LidarSetImuPushFrequency(uint8_t handle, ImuFreq freq, CommonComman
livox_status LidarGetImuPushFrequency(uint8_t handle, LidarGetImuPushFrequencyCallback cb, void * data) { livox_status LidarGetImuPushFrequency(uint8_t handle, LidarGetImuPushFrequencyCallback cb, void * data) {
if (device_manager().device_mode() != kDeviceModeLidar if (device_manager().device_mode() != kDeviceModeLidar
|| device_manager().IsLidarMid40(handle)) { || device_manager().IsLidarMid40(handle)
|| device_manager().IsLidarMid70(handle)) {
return kStatusNotSupported; return kStatusNotSupported;
} }
livox_status result = command_handler().SendCommand(handle, livox_status result = command_handler().SendCommand(handle,
@@ -115,6 +115,7 @@ static const uint16_t GeneralCommandTimeout[kCommandIDGeneralCommandCount] = {KD
KDefaultTimeOut, KDefaultTimeOut,
KDefaultTimeOut, KDefaultTimeOut,
KDefaultTimeOut, KDefaultTimeOut,
KDefaultTimeOut,
KDefaultTimeOut,}; KDefaultTimeOut,};
/** Enum that represents the command id. */ /** Enum that represents the command id. */
@@ -111,6 +111,12 @@ void DataHandler::OnDataCallback(uint8_t handle, void *data, uint16_t size) {
case kImu: case kImu:
size = (size - kPrefixDataSize) / sizeof(LivoxImuPoint); size = (size - kPrefixDataSize) / sizeof(LivoxImuPoint);
break; break;
case kTripleExtendCartesian:
size = (size - kPrefixDataSize) / sizeof(LivoxTripleExtendRawPoint);
break;
case kTripleExtendSpherical:
size = (size - kPrefixDataSize) / sizeof(LivoxTripleExtendSpherPoint);
break;
default: default:
return; return;
} }
+6 -5
View File
@@ -43,6 +43,7 @@
using std::tuple; using std::tuple;
using std::string; using std::string;
using std::vector; using std::vector;
using std::chrono::steady_clock;
namespace livox { namespace livox {
@@ -119,11 +120,11 @@ void DeviceDiscovery::OnData(apr_socket_t *sock, void *) {
} }
} }
void DeviceDiscovery::OnTimer(apr_time_t now) { void DeviceDiscovery::OnTimer(TimePoint now) {
ConnectingDeviceMap::iterator ite = connecting_devices_.begin(); ConnectingDeviceMap::iterator ite = connecting_devices_.begin();
while (ite != connecting_devices_.end()) { while (ite != connecting_devices_.end()) {
tuple<apr_pool_t *, apr_time_t, DeviceInfo> &device_tuple = ite->second; tuple<apr_pool_t *, TimePoint, DeviceInfo> &device_tuple = ite->second;
if (now - std::get<1>(device_tuple) > apr_time_from_msec(500)) { if (now - std::get<1>(device_tuple) > std::chrono::milliseconds(500)) {
loop_->RemoveDelegate(ite->first, this); loop_->RemoveDelegate(ite->first, this);
apr_socket_close(ite->first); apr_socket_close(ite->first);
apr_pool_destroy(std::get<0>(device_tuple)); apr_pool_destroy(std::get<0>(device_tuple));
@@ -209,7 +210,7 @@ void DeviceDiscovery::OnBroadcast(const CommPacket &packet, apr_sockaddr_t *addr
} }
loop_->AddDelegate(cmd_sock, this); loop_->AddDelegate(cmd_sock, this);
OnTimer(apr_time_now()); OnTimer(steady_clock::now());
std::get<0>(connecting_devices_[cmd_sock]) = pool; std::get<0>(connecting_devices_[cmd_sock]) = pool;
std::get<2>(connecting_devices_[cmd_sock]) = lidar_info; std::get<2>(connecting_devices_[cmd_sock]) = lidar_info;
@@ -246,7 +247,7 @@ void DeviceDiscovery::OnBroadcast(const CommPacket &packet, apr_sockaddr_t *addr
result = false; result = false;
break; break;
} }
std::get<1>(connecting_devices_[cmd_sock]) = apr_time_now(); std::get<1>(connecting_devices_[cmd_sock]) = steady_clock::now();
result = true; result = true;
} while (0); } while (0);
+4 -2
View File
@@ -43,6 +43,8 @@ namespace livox {
*/ */
class DeviceDiscovery : public noncopyable, IOLoop::IOLoopDelegate { class DeviceDiscovery : public noncopyable, IOLoop::IOLoopDelegate {
public: public:
typedef std::chrono::steady_clock::time_point TimePoint;
DeviceDiscovery() : sock_(NULL), mem_pool_(NULL), loop_(NULL), comm_port_(nullptr) {} DeviceDiscovery() : sock_(NULL), mem_pool_(NULL), loop_(NULL), comm_port_(nullptr) {}
bool Init(); bool Init();
void Uninit(); void Uninit();
@@ -59,7 +61,7 @@ class DeviceDiscovery : public noncopyable, IOLoop::IOLoopDelegate {
* @param client_data client data passed in IOLoop::AddDelegate * @param client_data client data passed in IOLoop::AddDelegate
*/ */
void OnData(apr_socket_t *, void *client_data); void OnData(apr_socket_t *, void *client_data);
void OnTimer(apr_time_t now); void OnTimer(TimePoint now);
private: private:
void OnBroadcast(const CommPacket &packet, apr_sockaddr_t *addr); void OnBroadcast(const CommPacket &packet, apr_sockaddr_t *addr);
@@ -81,7 +83,7 @@ class DeviceDiscovery : public noncopyable, IOLoop::IOLoopDelegate {
IOLoop *loop_; IOLoop *loop_;
std::unique_ptr<CommPort> comm_port_; std::unique_ptr<CommPort> comm_port_;
std::mutex mutex_; std::mutex mutex_;
typedef std::map<apr_socket_t *, std::tuple<apr_pool_t *, apr_time_t, DeviceInfo> > ConnectingDeviceMap; typedef std::map<apr_socket_t *, std::tuple<apr_pool_t *, TimePoint, DeviceInfo> > ConnectingDeviceMap;
ConnectingDeviceMap connecting_devices_; ConnectingDeviceMap connecting_devices_;
}; };
+21 -1
View File
@@ -43,7 +43,9 @@ inline bool IsHub(uint8_t mode) {
} }
inline bool IsLidar(uint8_t mode) { inline bool IsLidar(uint8_t mode) {
return mode == kDeviceTypeLidarTele || mode == kDeviceTypeLidarMid40 || mode == kDeviceTypeLidarHorizon; return mode == kDeviceTypeLidarTele || mode == kDeviceTypeLidarMid40
|| mode == kDeviceTypeLidarHorizon || mode == kDeviceTypeLidarMid70
|| mode == kDeviceTypeLidarAvia;
} }
bool DeviceManager::Init() { bool DeviceManager::Init() {
@@ -301,6 +303,24 @@ bool DeviceManager::IsLidarMid40(uint8_t handle) {
return false; return false;
} }
bool DeviceManager::IsLidarMid70(uint8_t handle) {
DeviceInfo lidar_info;
bool found = device_manager().FindDevice(handle, lidar_info);
if ( found && lidar_info.type == kDeviceTypeLidarMid70) {
return true;
}
return false;
}
bool DeviceManager::IsLidarAvia(uint8_t handle) {
DeviceInfo lidar_info;
bool found = device_manager().FindDevice(handle, lidar_info);
if ( found && lidar_info.type == kDeviceTypeLidarAvia) {
return true;
}
return false;
}
bool DeviceManager::IsLidarTele(uint8_t handle) { bool DeviceManager::IsLidarTele(uint8_t handle) {
DeviceInfo lidar_info; DeviceInfo lidar_info;
bool found = device_manager().FindDevice(handle, lidar_info); bool found = device_manager().FindDevice(handle, lidar_info);
+2
View File
@@ -103,7 +103,9 @@ class DeviceManager : public noncopyable {
void GetConnectedDevices(std::vector<DeviceInfo> &devices); void GetConnectedDevices(std::vector<DeviceInfo> &devices);
bool AddListeningDevice(const std::string &broadcast_code, DeviceMode mode, uint8_t &handle); bool AddListeningDevice(const std::string &broadcast_code, DeviceMode mode, uint8_t &handle);
bool IsLidarMid40(uint8_t handle); bool IsLidarMid40(uint8_t handle);
bool IsLidarMid70(uint8_t handle);
bool IsLidarTele(uint8_t handle); bool IsLidarTele(uint8_t handle);
bool IsLidarAvia(uint8_t handle);
bool GetLidarFirmwareVersion(uint8_t handle, uint32_t &firmware_version); bool GetLidarFirmwareVersion(uint8_t handle, uint32_t &firmware_version);
private: private: