feature:add C++ sample
This commit is contained in:
@@ -11,3 +11,5 @@ add_subdirectory(sample/hub)
|
||||
add_subdirectory(sample/lidar)
|
||||
add_subdirectory(sample/hub_lvx_file)
|
||||
add_subdirectory(sample/lidar_lvx_file)
|
||||
add_subdirectory(sample_cc/hub)
|
||||
add_subdirectory(sample_cc/lidar)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
set(DEMO_NAME hub_sample_cc)
|
||||
add_executable(${DEMO_NAME} lds_hub.cpp main.cpp)
|
||||
target_link_libraries(${DEMO_NAME}
|
||||
PRIVATE
|
||||
${PROJECT_NAME}_static
|
||||
)
|
||||
@@ -0,0 +1,385 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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 "lds_hub.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
|
||||
/** Const varible ------------------------------------------------------------------------------- */
|
||||
/** User add broadcast code here */
|
||||
static const char* local_broadcast_code_list[] = {
|
||||
"000000000000001",
|
||||
};
|
||||
|
||||
|
||||
/** For callback use only */
|
||||
static LdsHub* g_lds_hub = nullptr;
|
||||
|
||||
|
||||
/** Global function for common use ---------------------------------------------------------------*/
|
||||
|
||||
/** Lds hub function -----------------------------------------------------------------------------*/
|
||||
LdsHub::LdsHub() {
|
||||
auto_connect_mode_ = true;
|
||||
whitelist_count_ = 0;
|
||||
is_initialized_ = false;
|
||||
|
||||
lidar_count_ = 0;
|
||||
memset(broadcast_code_whitelist_, 0, sizeof(broadcast_code_whitelist_));
|
||||
|
||||
memset(lidars_, 0, sizeof(lidars_));
|
||||
for (uint32_t i=0; i<kMaxLidarCount; i++) {
|
||||
lidars_[i].handle = kMaxLidarCount; /** Unallocated state */
|
||||
lidars_[i].connect_state = kConnectStateOff;
|
||||
}
|
||||
memset(&hub_, 0, sizeof(hub_));
|
||||
hub_.handle = kMaxLidarCount;
|
||||
hub_.connect_state = kConnectStateOff;
|
||||
}
|
||||
|
||||
LdsHub::~LdsHub() {
|
||||
}
|
||||
|
||||
int LdsHub::InitLdsHub(std::vector<std::string>& broadcast_code_strs) {
|
||||
|
||||
if (is_initialized_) {
|
||||
printf("LiDAR data source is already inited!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Init()) {
|
||||
Uninit();
|
||||
printf("Livox-SDK init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LivoxSdkVersion _sdkversion;
|
||||
GetLivoxSdkVersion(&_sdkversion);
|
||||
printf("Livox SDK version %d.%d.%d\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch);
|
||||
|
||||
SetBroadcastCallback(LdsHub::OnDeviceBroadcast);
|
||||
SetDeviceStateUpdateCallback(LdsHub::OnDeviceChange);
|
||||
|
||||
/** Add commandline input broadcast code */
|
||||
for (auto input_str : broadcast_code_strs) {
|
||||
LdsHub::AddBroadcastCodeToWhitelist(input_str.c_str());
|
||||
printf("Cmdline input broadcast code : %s\n", input_str.c_str());
|
||||
}
|
||||
|
||||
/** Add local broadcast code */
|
||||
LdsHub::AddLocalBroadcastCode();
|
||||
|
||||
if (whitelist_count_) {
|
||||
LdsHub::DisableAutoConnectMode();
|
||||
printf("Disable auto connect mode!\n");
|
||||
|
||||
printf("List all broadcast code in whiltelist:\n");
|
||||
for (uint32_t i=0; i<whitelist_count_; i++) {
|
||||
printf("%s\n", broadcast_code_whitelist_[i]);
|
||||
}
|
||||
} else {
|
||||
LdsHub::EnableAutoConnectMode();
|
||||
printf("No broadcast code was added to whitelist, swith to automatic connection mode!\n");
|
||||
}
|
||||
|
||||
/** Start livox sdk to receive lidar data */
|
||||
if (!Start()) {
|
||||
Uninit();
|
||||
printf("Livox-SDK init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Add here, only for callback use */
|
||||
if (g_lds_hub == nullptr) {
|
||||
g_lds_hub = this;
|
||||
}
|
||||
is_initialized_= true;
|
||||
printf("Livox-SDK init success!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LdsHub::DeInitLdsHub(void) {
|
||||
|
||||
if (!is_initialized_) {
|
||||
printf("LiDAR data source is not exit");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uninit();
|
||||
printf("Livox SDK Deinit completely!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Static function in LdsLidar for callback */
|
||||
void LdsHub::GetLidarDataCb(uint8_t hub_handle, LivoxEthPacket *data,
|
||||
uint32_t data_num, void *client_data) {
|
||||
|
||||
LdsHub* lds_hub = static_cast<LdsHub *>(client_data);
|
||||
LivoxEthPacket* eth_packet = data;
|
||||
|
||||
if (!data || !data_num) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** Caculate which lidar this eth packet data belong to */
|
||||
uint8_t handle = HubGetLidarHandle(eth_packet->slot, eth_packet->id);
|
||||
if (handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
lds_hub->receive_packet_count_++;
|
||||
if (0 == (lds_hub->receive_packet_count_ % 100)) {
|
||||
printf("Receive packet count %d %d\n", handle, lds_hub->receive_packet_count_);
|
||||
|
||||
/** Parsing the timestamp and the point cloud data. */
|
||||
uint64_t cur_timestamp = *((uint64_t *)(data->timestamp));
|
||||
LivoxRawPoint *p_point_data = (LivoxRawPoint *)data->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LdsHub::OnDeviceBroadcast(const BroadcastDeviceInfo *info) {
|
||||
if (info == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->dev_type != kDeviceTypeHub) {
|
||||
printf("It's not a hub : %s\n", info->broadcast_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_lds_hub->IsAutoConnectMode()) {
|
||||
printf("In automatic connection mode, will connect %s\n", info->broadcast_code);
|
||||
} else {
|
||||
if (!g_lds_hub->FindInWhitelist(info->broadcast_code)) {
|
||||
printf("Not in the whitelist, please add %s to if want to connect!\n",\
|
||||
info->broadcast_code);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LidarDevice* p_hub = &g_lds_hub->hub_;
|
||||
if (p_hub->connect_state == kConnectStateOff) {
|
||||
bool result = false;
|
||||
uint8_t handle = 0;
|
||||
result = AddHubToConnect(info->broadcast_code, &handle);
|
||||
if (result == kStatusSuccess && handle < kMaxLidarCount) {
|
||||
SetDataCallback(handle, LdsHub::GetLidarDataCb, (void *)g_lds_hub);
|
||||
p_hub->handle = handle;
|
||||
p_hub->connect_state = kConnectStateOff;
|
||||
} else {
|
||||
printf("Add Hub to connect is failed : %d %d \n", result, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of changing of device state. */
|
||||
void LdsHub::OnDeviceChange(const DeviceInfo *info, DeviceEvent type) {
|
||||
if (info == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
LidarDevice* p_hub = &g_lds_hub->hub_;
|
||||
if (type == kEventConnect) {
|
||||
if (p_hub->connect_state == kConnectStateOff) {
|
||||
p_hub->connect_state = kConnectStateOn;
|
||||
p_hub->info = *info;
|
||||
}
|
||||
} else if (type == kEventDisconnect) {
|
||||
p_hub->connect_state = kConnectStateOff;
|
||||
printf("Hub[%s] disconnect!\n", info->broadcast_code);
|
||||
} else if (type == kEventStateChange) {
|
||||
p_hub->info = *info;
|
||||
printf("Hub[%s] StateChange\n", info->broadcast_code);
|
||||
}
|
||||
|
||||
if (p_hub->connect_state == kConnectStateOn) {
|
||||
printf("Hub[%s] status_code[%d] working state[%d] feature[%d]\n", \
|
||||
p_hub->info.broadcast_code,\
|
||||
p_hub->info.status.status_code,\
|
||||
p_hub->info.state,\
|
||||
p_hub->info.feature);
|
||||
if (p_hub->info.state == kLidarStateNormal) {
|
||||
HubQueryLidarInformation(HubQueryLidarInfoCb, g_lds_hub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LdsHub::HubQueryLidarInfoCb(uint8_t status, uint8_t handle, \
|
||||
HubQueryLidarInformationResponse *response,\
|
||||
void *client_data) {
|
||||
LdsHub* lds_hub = static_cast<LdsHub *>(client_data);
|
||||
if (handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == kStatusSuccess) {
|
||||
if (response->count) {
|
||||
printf("Hub have %d lidars:\n", response->count);
|
||||
for (int i = 0; i < response->count; i++) {
|
||||
uint32_t index = (response->device_info_list[i].slot - 1) * 3 +\
|
||||
response->device_info_list[i].id - 1;
|
||||
if (index < kMaxLidarCount) {
|
||||
LidarDevice* p_lidar = &lds_hub->lidars_[index];
|
||||
p_lidar->handle = index;
|
||||
p_lidar->info.handle = index;
|
||||
p_lidar->info.slot = response->device_info_list[i].slot;
|
||||
p_lidar->info.id = response->device_info_list[i].id;
|
||||
p_lidar->info.type = response->device_info_list[i].dev_type;
|
||||
p_lidar->connect_state = kConnectStateSampling;
|
||||
strncpy(p_lidar->info.broadcast_code, \
|
||||
response->device_info_list[i].broadcast_code, \
|
||||
sizeof(p_lidar->info.broadcast_code));
|
||||
printf("[%d]%s DeviceType[%d] Slot[%d] Ver[%d.%d.%d.%d]\n", index, \
|
||||
p_lidar->info.broadcast_code,\
|
||||
p_lidar->info.type, p_lidar->info.slot,\
|
||||
response->device_info_list[i].version[0],\
|
||||
response->device_info_list[i].version[1],\
|
||||
response->device_info_list[i].version[2],\
|
||||
response->device_info_list[i].version[3]);
|
||||
}
|
||||
}
|
||||
|
||||
HubStartSampling(StartSampleCb, lds_hub);
|
||||
lds_hub->hub_.connect_state = kConnectStateSampling;
|
||||
} else {
|
||||
printf("Hub have no lidar, will not start sample!\n");
|
||||
HubQueryLidarInformation(HubQueryLidarInfoCb, lds_hub);
|
||||
}
|
||||
} else {
|
||||
printf("Device Query Informations Failed %d\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of starting sampling. */
|
||||
void LdsHub::StartSampleCb(uint8_t status, uint8_t handle, \
|
||||
uint8_t response, void *clent_data) {
|
||||
LdsHub* lds_hub = static_cast<LdsHub *>(clent_data);
|
||||
if (handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
LidarDevice* p_hub = &lds_hub->hub_;
|
||||
if (status == kStatusSuccess) {
|
||||
if (response != 0) {
|
||||
p_hub->connect_state = kConnectStateOn;
|
||||
printf("Hub start sample fail : state[%d] handle[%d] res[%d]\n", \
|
||||
status, handle, response);
|
||||
} else {
|
||||
printf("Hub start sample success!\n");
|
||||
}
|
||||
} else if (status == kStatusTimeout) {
|
||||
p_hub->connect_state = kConnectStateOn;
|
||||
printf("Hub start sample timeout : state[%d] handle[%d] res[%d]\n", \
|
||||
status, handle, response);
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of stopping sampling. */
|
||||
void LdsHub::StopSampleCb(uint8_t status, uint8_t handle, \
|
||||
uint8_t response, void *clent_data) {
|
||||
}
|
||||
|
||||
/** Add broadcast code to whitelist */
|
||||
int LdsHub::AddBroadcastCodeToWhitelist(const char* broadcast_code) {
|
||||
if (!broadcast_code || (strlen(broadcast_code) > kBroadcastCodeSize) || \
|
||||
(whitelist_count_ >= kMaxLidarCount)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LdsHub::FindInWhitelist(broadcast_code)) {
|
||||
printf("%s is alrealy exist!\n", broadcast_code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(broadcast_code_whitelist_[whitelist_count_], broadcast_code);
|
||||
++whitelist_count_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LdsHub::AddLocalBroadcastCode(void) {
|
||||
for (size_t i=0; i<sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) {
|
||||
std::string invalid_bd = "000000000";
|
||||
printf("Local broadcast code : %s\n", local_broadcast_code_list[i]);
|
||||
if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i])) && \
|
||||
(nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) {
|
||||
LdsHub::AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]);
|
||||
} else {
|
||||
printf("Invalid local broadcast code : %s\n", local_broadcast_code_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LdsHub::FindInWhitelist(const char* broadcast_code) {
|
||||
if (!broadcast_code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i=0; i<whitelist_count_; i++) {
|
||||
if (strncmp(broadcast_code, broadcast_code_whitelist_[i], kBroadcastCodeSize) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Get and update LiDAR info */
|
||||
void LdsHub::UpdateHubLidarinfo(void) {
|
||||
DeviceInfo *_lidars = (DeviceInfo *) malloc(sizeof(DeviceInfo) * kMaxLidarCount);
|
||||
|
||||
uint8_t count = kMaxLidarCount;
|
||||
uint8_t status = GetConnectedDevices(_lidars, &count);
|
||||
if (status == kStatusSuccess) {
|
||||
printf("Hub have lidars : \n");
|
||||
int i = 0;
|
||||
for (i = 0; i < count; ++i) {
|
||||
uint8_t handle = _lidars[i].handle;
|
||||
if (handle < kMaxLidarCount) {
|
||||
lidars_[handle].handle = handle;
|
||||
lidars_[handle].info = _lidars[i];
|
||||
lidars_[handle].connect_state = kConnectStateSampling;
|
||||
printf("[%d] : %s\r\n", _lidars[i].handle, _lidars[i].broadcast_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_lidars) {
|
||||
free(_lidars);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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.
|
||||
//
|
||||
|
||||
/** Livox LiDAR data source, data from hub */
|
||||
|
||||
#ifndef COAT_LDS_HUB_H_
|
||||
#define COAT_LDS_HUB_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "livox_def.h"
|
||||
#include "livox_sdk.h"
|
||||
|
||||
typedef enum {
|
||||
kConnectStateOff = 0,
|
||||
kConnectStateOn = 1,
|
||||
kConnectStateSampling = 2,
|
||||
} LidarConnectState;
|
||||
|
||||
typedef struct {
|
||||
uint8_t handle;
|
||||
LidarConnectState connect_state;
|
||||
DeviceInfo info;
|
||||
} LidarDevice;
|
||||
|
||||
/**
|
||||
* LiDAR data source, data from hub.
|
||||
*/
|
||||
class LdsHub {
|
||||
public:
|
||||
static LdsHub& GetInstance() {
|
||||
static LdsHub lds_hub;
|
||||
return lds_hub;
|
||||
}
|
||||
|
||||
int InitLdsHub(std::vector<std::string>& broadcast_code_strs);
|
||||
int DeInitLdsHub(void);
|
||||
|
||||
private:
|
||||
LdsHub();
|
||||
LdsHub(const LdsHub&) = delete;
|
||||
~LdsHub();
|
||||
LdsHub& operator=(const LdsHub&) = delete;
|
||||
|
||||
/** LiDAR data receive callback */
|
||||
static void GetLidarDataCb(uint8_t hub_handle, LivoxEthPacket *data,\
|
||||
uint32_t data_num, void *client_data);
|
||||
static void OnDeviceBroadcast(const BroadcastDeviceInfo *info);
|
||||
static void OnDeviceChange(const DeviceInfo *info, DeviceEvent type);
|
||||
static void StartSampleCb(uint8_t status, uint8_t handle, uint8_t response, void *clent_data);
|
||||
static void StopSampleCb(uint8_t status, uint8_t handle, uint8_t response, void *clent_data);
|
||||
static void HubQueryLidarInfoCb(uint8_t status, uint8_t handle, \
|
||||
HubQueryLidarInformationResponse *response, void *client_data);
|
||||
|
||||
int AddBroadcastCodeToWhitelist(const char* broadcast_code);
|
||||
void AddLocalBroadcastCode(void);
|
||||
bool FindInWhitelist(const char* broadcast_code);
|
||||
void UpdateHubLidarinfo(void);
|
||||
|
||||
void EnableAutoConnectMode(void) { auto_connect_mode_ = true; }
|
||||
void DisableAutoConnectMode(void) { auto_connect_mode_ = false; }
|
||||
bool IsAutoConnectMode(void) { return auto_connect_mode_; }
|
||||
|
||||
bool auto_connect_mode_;
|
||||
uint32_t whitelist_count_;
|
||||
volatile bool is_initialized_;
|
||||
char broadcast_code_whitelist_[kMaxLidarCount][kBroadcastCodeSize];
|
||||
|
||||
uint32_t lidar_count_;
|
||||
LidarDevice lidars_[kMaxLidarCount];
|
||||
LidarDevice hub_;
|
||||
uint32_t receive_packet_count_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <apr_general.h>
|
||||
#include <apr_getopt.h>
|
||||
#include "lds_hub.h"
|
||||
|
||||
/** Cmdline input broadcast code */
|
||||
static std::vector<std::string> cmdline_broadcast_code;
|
||||
|
||||
/** Set the program options.
|
||||
* You can input the registered device broadcast code and decide whether to save the log file.
|
||||
*/
|
||||
static int SetProgramOption(int argc, const char *argv[]) {
|
||||
apr_status_t rv;
|
||||
apr_pool_t *mp = NULL;
|
||||
static const apr_getopt_option_t opt_option[] = {
|
||||
/** Long-option, short-option, has-arg flag, description */
|
||||
{ "code", 'c', 1, "Register device broadcast code" },
|
||||
{ "log", 'l', 0, "Save the log file" },
|
||||
{ "help", 'h', 0, "Show help" },
|
||||
{ NULL, 0, 0, NULL },
|
||||
};
|
||||
apr_getopt_t *opt = NULL;
|
||||
int optch = 0;
|
||||
const char *optarg = NULL;
|
||||
|
||||
if (apr_initialize() != APR_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (apr_pool_create(&mp, NULL) != APR_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = apr_getopt_init(&opt, mp, argc, argv);
|
||||
if (rv != APR_SUCCESS) {
|
||||
printf("Program options initialization failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Parse the all options based on opt_option[] */
|
||||
bool is_help = false;
|
||||
while ((rv = apr_getopt_long(opt, opt_option, &optch, &optarg)) == APR_SUCCESS) {
|
||||
switch (optch) {
|
||||
case 'c': {
|
||||
printf("Register broadcast code: %s\n", optarg);
|
||||
cmdline_broadcast_code.clear();
|
||||
cmdline_broadcast_code.push_back(optarg);
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
printf("Save the log file.\n");
|
||||
SaveLoggerFile();
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
printf(
|
||||
" [-c] Register device broadcast code\n"
|
||||
" [-l] Save the log file\n"
|
||||
" [-h] Show help\n"
|
||||
);
|
||||
is_help = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv != APR_EOF) {
|
||||
printf("Invalid options.\n");
|
||||
}
|
||||
|
||||
apr_pool_destroy(mp);
|
||||
mp = NULL;
|
||||
apr_terminate();
|
||||
if (is_help)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
/** Set the program options. */
|
||||
if (SetProgramOption(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LdsHub& read_hub = LdsHub::GetInstance();
|
||||
int ret = read_hub.InitLdsHub(cmdline_broadcast_code);
|
||||
if (!ret) {
|
||||
printf("Init lds hub success!\n");
|
||||
} else {
|
||||
printf("Init lds hub fail!\n");
|
||||
}
|
||||
|
||||
printf("Start discovering device.\n");
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(100000);
|
||||
#else
|
||||
sleep(100);
|
||||
#endif
|
||||
|
||||
read_hub.DeInitLdsHub();
|
||||
printf("Livox hub demo end!\n");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
set(DEMO_NAME lidar_sample_cc)
|
||||
add_executable(${DEMO_NAME} main.cpp lds_lidar.cpp)
|
||||
target_link_libraries(${DEMO_NAME}
|
||||
PRIVATE
|
||||
${PROJECT_NAME}_static
|
||||
)
|
||||
@@ -0,0 +1,320 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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 "lds_lidar.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
|
||||
/** Const varible ------------------------------------------------------------------------------- */
|
||||
/** User add broadcast code here */
|
||||
static const char* local_broadcast_code_list[] = {
|
||||
"000000000000001",
|
||||
};
|
||||
|
||||
/** For callback use only */
|
||||
LdsLidar* g_lidars = nullptr;
|
||||
|
||||
/** Lds lidar function ---------------------------------------------------------------------------*/
|
||||
LdsLidar::LdsLidar() {
|
||||
auto_connect_mode_ = true;
|
||||
whitelist_count_ = 0;
|
||||
is_initialized_ = false;
|
||||
|
||||
lidar_count_ = 0;
|
||||
memset(broadcast_code_whitelist_, 0, sizeof(broadcast_code_whitelist_));
|
||||
|
||||
memset(lidars_, 0, sizeof(lidars_));
|
||||
for (uint32_t i=0; i<kMaxLidarCount; i++) {
|
||||
lidars_[i].handle = kMaxLidarCount; /** Unallocated state */
|
||||
lidars_[i].connect_state = kConnectStateOff;
|
||||
}
|
||||
}
|
||||
|
||||
LdsLidar::~LdsLidar() {
|
||||
}
|
||||
|
||||
int LdsLidar::InitLdsLidar(std::vector<std::string>& broadcast_code_strs) {
|
||||
|
||||
if (is_initialized_) {
|
||||
printf("LiDAR data source is already inited!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Init()) {
|
||||
Uninit();
|
||||
printf("Livox-SDK init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LivoxSdkVersion _sdkversion;
|
||||
GetLivoxSdkVersion(&_sdkversion);
|
||||
printf("Livox SDK version %d.%d.%d\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch);
|
||||
|
||||
SetBroadcastCallback(LdsLidar::OnDeviceBroadcast);
|
||||
SetDeviceStateUpdateCallback(LdsLidar::OnDeviceChange);
|
||||
|
||||
/** Add commandline input broadcast code */
|
||||
for (auto input_str : broadcast_code_strs) {
|
||||
LdsLidar::AddBroadcastCodeToWhitelist(input_str.c_str());
|
||||
}
|
||||
|
||||
/** Add local broadcast code */
|
||||
LdsLidar::AddLocalBroadcastCode();
|
||||
|
||||
if (whitelist_count_) {
|
||||
LdsLidar::DisableAutoConnectMode();
|
||||
printf("Disable auto connect mode!\n");
|
||||
|
||||
printf("List all broadcast code in whiltelist:\n");
|
||||
for (uint32_t i=0; i<whitelist_count_; i++) {
|
||||
printf("%s\n", broadcast_code_whitelist_[i]);
|
||||
}
|
||||
} else {
|
||||
LdsLidar::EnableAutoConnectMode();
|
||||
printf("No broadcast code was added to whitelist, swith to automatic connection mode!\n");
|
||||
}
|
||||
|
||||
/** Start livox sdk to receive lidar data */
|
||||
if (!Start()) {
|
||||
Uninit();
|
||||
printf("Livox-SDK init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Add here, only for callback use */
|
||||
if (g_lidars == nullptr) {
|
||||
g_lidars = this;
|
||||
}
|
||||
is_initialized_= true;
|
||||
printf("Livox-SDK init success!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int LdsLidar::DeInitLdsLidar(void) {
|
||||
|
||||
if (!is_initialized_) {
|
||||
printf("LiDAR data source is not exit");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uninit();
|
||||
printf("Livox SDK Deinit completely!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Static function in LdsLidar for callback or event process ------------------------------------*/
|
||||
|
||||
/** Receiving point cloud data from Livox LiDAR. */
|
||||
void LdsLidar::GetLidarDataCb(uint8_t handle, LivoxEthPacket *data,
|
||||
uint32_t data_num, void *client_data) {
|
||||
using namespace std;
|
||||
|
||||
LdsLidar* lidar_this = static_cast<LdsLidar *>(client_data);
|
||||
LivoxEthPacket* eth_packet = data;
|
||||
|
||||
if (!data || !data_num || (handle >= kMaxLidarCount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eth_packet) {
|
||||
lidar_this->data_recveive_count_[handle] += data_num;
|
||||
if (lidar_this->data_recveive_count_[handle] % 10000 == 0) {
|
||||
printf("receive packet count %d %d\n", handle, lidar_this->data_recveive_count_[handle]);
|
||||
|
||||
/** Parsing the timestamp and the point cloud data. */
|
||||
uint64_t cur_timestamp = *((uint64_t *)(data->timestamp));
|
||||
LivoxRawPoint *p_point_data = (LivoxRawPoint *)data->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LdsLidar::OnDeviceBroadcast(const BroadcastDeviceInfo *info) {
|
||||
if (info == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->dev_type == kDeviceTypeHub) {
|
||||
printf("In lidar mode, couldn't connect a hub : %s\n", info->broadcast_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_lidars->IsAutoConnectMode()) {
|
||||
printf("In automatic connection mode, will connect %s\n", info->broadcast_code);
|
||||
} else {
|
||||
if (!g_lidars->FindInWhitelist(info->broadcast_code)) {
|
||||
printf("Not in the whitelist, please add %s to if want to connect!\n",\
|
||||
info->broadcast_code);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
uint8_t handle = 0;
|
||||
result = AddLidarToConnect(info->broadcast_code, &handle);
|
||||
if (result == kStatusSuccess && handle < kMaxLidarCount) {
|
||||
SetDataCallback(handle, LdsLidar::GetLidarDataCb, (void *)g_lidars);
|
||||
g_lidars->lidars_[handle].handle = handle;
|
||||
g_lidars->lidars_[handle].connect_state = kConnectStateOff;
|
||||
} else {
|
||||
printf("Add lidar to connect is failed : %d %d \n", result, handle);
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of changing of device state. */
|
||||
void LdsLidar::OnDeviceChange(const DeviceInfo *info, DeviceEvent type) {
|
||||
if (info == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t handle = info->handle;
|
||||
if (handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
LidarDevice* p_lidar = &(g_lidars->lidars_[handle]);
|
||||
if (type == kEventConnect) {
|
||||
QueryDeviceInformation(handle, DeviceInformationCb, g_lidars);
|
||||
if (p_lidar->connect_state == kConnectStateOff) {
|
||||
p_lidar->connect_state = kConnectStateOn;
|
||||
p_lidar->info = *info;
|
||||
}
|
||||
} else if (type == kEventDisconnect) {
|
||||
p_lidar->connect_state = kConnectStateOff;
|
||||
printf("Lidar[%s] disconnect!\n", info->broadcast_code);
|
||||
} else if (type == kEventStateChange) {
|
||||
p_lidar->info = *info;
|
||||
}
|
||||
|
||||
if (p_lidar->connect_state == kConnectStateOn) {
|
||||
printf("Lidar[%s] status_code[%d] working state[%d] feature[%d]\n", \
|
||||
p_lidar->info.broadcast_code,\
|
||||
p_lidar->info.status.status_code,\
|
||||
p_lidar->info.state,\
|
||||
p_lidar->info.feature);
|
||||
if (p_lidar->info.state == kLidarStateNormal) {
|
||||
LidarStartSampling(handle, LdsLidar::StartSampleCb, g_lidars);
|
||||
p_lidar->connect_state = kConnectStateSampling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Query the firmware version of Livox LiDAR. */
|
||||
void LdsLidar::DeviceInformationCb(uint8_t status, uint8_t handle, \
|
||||
DeviceInformationResponse *ack, void *clent_data) {
|
||||
if (status != kStatusSuccess) {
|
||||
printf("Device Query Informations Failed : %d\n", status);
|
||||
}
|
||||
if (ack) {
|
||||
printf("firm ver: %d.%d.%d.%d\n",
|
||||
ack->firmware_version[0],
|
||||
ack->firmware_version[1],
|
||||
ack->firmware_version[2],
|
||||
ack->firmware_version[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of starting sampling. */
|
||||
void LdsLidar::StartSampleCb(uint8_t status, uint8_t handle, \
|
||||
uint8_t response, void *clent_data) {
|
||||
LdsLidar* lds_lidar = static_cast<LdsLidar *>(clent_data);
|
||||
|
||||
if (handle >= kMaxLidarCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
LidarDevice* p_lidar = &(lds_lidar->lidars_[handle]);
|
||||
if (status == kStatusSuccess) {
|
||||
if (response != 0) {
|
||||
p_lidar->connect_state = kConnectStateOn;
|
||||
printf("Lidar start sample fail : state[%d] handle[%d] res[%d]\n", \
|
||||
status, handle, response);
|
||||
} else {
|
||||
printf("Lidar start sample success\n");
|
||||
}
|
||||
} else if (status == kStatusTimeout) {
|
||||
p_lidar->connect_state = kConnectStateOn;
|
||||
printf("Lidar start sample timeout : state[%d] handle[%d] res[%d]\n", \
|
||||
status, handle, response);
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback function of stopping sampling. */
|
||||
void LdsLidar::StopSampleCb(uint8_t status, uint8_t handle, \
|
||||
uint8_t response, void *clent_data) {
|
||||
}
|
||||
|
||||
/** Add broadcast code to whitelist */
|
||||
int LdsLidar::AddBroadcastCodeToWhitelist(const char* bd_code) {
|
||||
if (!bd_code || (strlen(bd_code) > kBroadcastCodeSize) || \
|
||||
(whitelist_count_ >= kMaxLidarCount)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LdsLidar::FindInWhitelist(bd_code)) {
|
||||
printf("%s is alrealy exist!\n", bd_code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(broadcast_code_whitelist_[whitelist_count_], bd_code);
|
||||
++whitelist_count_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LdsLidar::AddLocalBroadcastCode(void) {
|
||||
for (size_t i=0; i<sizeof(local_broadcast_code_list)/sizeof(intptr_t); ++i) {
|
||||
std::string invalid_bd = "000000000";
|
||||
printf("Local broadcast code : %s\n", local_broadcast_code_list[i]);
|
||||
if ((kBroadcastCodeSize == strlen(local_broadcast_code_list[i])) && \
|
||||
(nullptr == strstr(local_broadcast_code_list[i], invalid_bd.c_str()))) {
|
||||
LdsLidar::AddBroadcastCodeToWhitelist(local_broadcast_code_list[i]);
|
||||
} else {
|
||||
printf("Invalid local broadcast code : %s\n", local_broadcast_code_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LdsLidar::FindInWhitelist(const char* bd_code) {
|
||||
if (!bd_code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i=0; i<whitelist_count_; i++) {
|
||||
if (strncmp(bd_code, broadcast_code_whitelist_[i], kBroadcastCodeSize) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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.
|
||||
//
|
||||
|
||||
/** Livox LiDAR data source, data from dependent lidar */
|
||||
|
||||
#ifndef LDS_LIDAR_H_
|
||||
#define LDS_LIDAR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "livox_def.h"
|
||||
#include "livox_sdk.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
kConnectStateOff = 0,
|
||||
kConnectStateOn = 1,
|
||||
kConnectStateSampling = 2,
|
||||
} LidarConnectState;
|
||||
|
||||
typedef struct {
|
||||
uint8_t handle;
|
||||
LidarConnectState connect_state;
|
||||
DeviceInfo info;
|
||||
} LidarDevice;
|
||||
|
||||
/**
|
||||
* LiDAR data source, data from dependent lidar.
|
||||
*/
|
||||
class LdsLidar {
|
||||
public:
|
||||
|
||||
static LdsLidar& GetInstance() {
|
||||
static LdsLidar lds_lidar;
|
||||
return lds_lidar;
|
||||
}
|
||||
|
||||
int InitLdsLidar(std::vector<std::string>& broadcast_code_strs);
|
||||
int DeInitLdsLidar(void);
|
||||
|
||||
private:
|
||||
LdsLidar();
|
||||
LdsLidar(const LdsLidar&) = delete;
|
||||
~LdsLidar();
|
||||
LdsLidar& operator=(const LdsLidar&) = delete;
|
||||
|
||||
static void GetLidarDataCb(uint8_t handle, LivoxEthPacket *data,\
|
||||
uint32_t data_num, void *client_data);
|
||||
static void OnDeviceBroadcast(const BroadcastDeviceInfo *info);
|
||||
static void OnDeviceChange(const DeviceInfo *info, DeviceEvent type);
|
||||
static void StartSampleCb(uint8_t status, uint8_t handle, uint8_t response, void *clent_data);
|
||||
static void StopSampleCb(uint8_t status, uint8_t handle, uint8_t response, void *clent_data);
|
||||
static void DeviceInformationCb(uint8_t status, uint8_t handle, \
|
||||
DeviceInformationResponse *ack, void *clent_data);
|
||||
|
||||
int AddBroadcastCodeToWhitelist(const char* broadcast_code);
|
||||
void AddLocalBroadcastCode(void);
|
||||
bool FindInWhitelist(const char* broadcast_code);
|
||||
|
||||
void EnableAutoConnectMode(void) { auto_connect_mode_ = true; }
|
||||
void DisableAutoConnectMode(void) { auto_connect_mode_ = false; }
|
||||
bool IsAutoConnectMode(void) { return auto_connect_mode_; }
|
||||
|
||||
bool auto_connect_mode_;
|
||||
uint32_t whitelist_count_;
|
||||
volatile bool is_initialized_;
|
||||
char broadcast_code_whitelist_[kMaxLidarCount][kBroadcastCodeSize];
|
||||
|
||||
uint32_t lidar_count_;
|
||||
LidarDevice lidars_[kMaxLidarCount];
|
||||
|
||||
uint32_t data_recveive_count_[kMaxLidarCount];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2019 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <apr_general.h>
|
||||
#include <apr_getopt.h>
|
||||
#include "lds_lidar.h"
|
||||
|
||||
/** Cmdline input broadcast code */
|
||||
static std::vector<std::string> cmdline_broadcast_code;
|
||||
|
||||
/** Set the program options.
|
||||
* You can input the registered device broadcast code and decide whether to save the log file.
|
||||
*/
|
||||
static int SetProgramOption(int argc, const char *argv[]) {
|
||||
apr_status_t rv;
|
||||
apr_pool_t *mp = NULL;
|
||||
static const apr_getopt_option_t opt_option[] = {
|
||||
/** Long-option, short-option, has-arg flag, description */
|
||||
{ "code", 'c', 1, "Register device broadcast code" },
|
||||
{ "log", 'l', 0, "Save the log file" },
|
||||
{ "help", 'h', 0, "Show help" },
|
||||
{ NULL, 0, 0, NULL },
|
||||
};
|
||||
apr_getopt_t *opt = NULL;
|
||||
int optch = 0;
|
||||
const char *optarg = NULL;
|
||||
|
||||
if (apr_initialize() != APR_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (apr_pool_create(&mp, NULL) != APR_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = apr_getopt_init(&opt, mp, argc, argv);
|
||||
if (rv != APR_SUCCESS) {
|
||||
printf("Program options initialization failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Parse the all options based on opt_option[] */
|
||||
bool is_help = false;
|
||||
while ((rv = apr_getopt_long(opt, opt_option, &optch, &optarg)) == APR_SUCCESS) {
|
||||
switch (optch) {
|
||||
case 'c': {
|
||||
printf("Register broadcast code: %s\n", optarg);
|
||||
char *sn_list = (char *)malloc(sizeof(char)*(strlen(optarg) + 1));
|
||||
strncpy(sn_list, optarg, sizeof(char)*(strlen(optarg) + 1));
|
||||
char *sn_list_head = sn_list;
|
||||
sn_list = strtok(sn_list, "&");
|
||||
cmdline_broadcast_code.clear();
|
||||
while (sn_list) {
|
||||
cmdline_broadcast_code.push_back(sn_list);
|
||||
sn_list = strtok(nullptr, "&");
|
||||
}
|
||||
free(sn_list_head);
|
||||
sn_list_head = nullptr;
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
printf("Save the log file.\n");
|
||||
SaveLoggerFile();
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
printf(
|
||||
" [-c] Register device broadcast code\n"
|
||||
" [-l] Save the log file\n"
|
||||
" [-h] Show help\n"
|
||||
);
|
||||
is_help = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv != APR_EOF) {
|
||||
printf("Invalid options.\n");
|
||||
}
|
||||
|
||||
apr_pool_destroy(mp);
|
||||
mp = NULL;
|
||||
apr_terminate();
|
||||
if (is_help)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
/** Set the program options. */
|
||||
if (SetProgramOption(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LdsLidar& read_lidar = LdsLidar::GetInstance();
|
||||
|
||||
int ret = read_lidar.InitLdsLidar(cmdline_broadcast_code);
|
||||
if (!ret) {
|
||||
printf("Init lds lidar success!\n");
|
||||
} else {
|
||||
printf("Init lds lidar fail!\n");
|
||||
}
|
||||
|
||||
printf("Start discovering device.\n");
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(100000);
|
||||
#else
|
||||
sleep(100);
|
||||
#endif
|
||||
|
||||
read_lidar.DeInitLdsLidar();
|
||||
printf("Livox lidar demo end!\n");
|
||||
|
||||
}
|
||||
@@ -108,4 +108,5 @@ target_sources(${SDK_LIBRARY}
|
||||
install(TARGETS ${SDK_LIBRARY}
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib)
|
||||
LIBRARY DESTINATION lib)
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ std::shared_ptr<spdlog::logger> logger = NULL;
|
||||
bool is_save_log_file = false;
|
||||
|
||||
void InitLogger() {
|
||||
|
||||
if (spdlog::get("console") != nullptr) {
|
||||
logger = spdlog::get("console");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<spdlog::sink_ptr> sinkList;
|
||||
auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
consoleSink->set_level(spdlog::level::debug);
|
||||
|
||||
@@ -110,15 +110,19 @@ void DeviceManager::UpdateDevices(const DeviceInfo &device, DeviceEvent type) {
|
||||
connected_cb_(&device, type);
|
||||
}
|
||||
|
||||
if ((device_mode_ == kDeviceModeHub) && (type == kEventConnect)) {
|
||||
LOG_DEBUG("Send Query lidars command");
|
||||
command_handler().SendCommand(kHubDefaultHandle,
|
||||
kCommandSetHub,
|
||||
kCommandIDHubQueryLidarInformation,
|
||||
NULL,
|
||||
0,
|
||||
MakeCommandCallback<DeviceManager, HubQueryLidarInformationResponse>(
|
||||
this, &DeviceManager::HubLidarInfomationCallback));
|
||||
if (device_mode_ == kDeviceModeHub) {
|
||||
if (type == kEventConnect) {
|
||||
LOG_DEBUG("Send Query lidars command");
|
||||
command_handler().SendCommand(kHubDefaultHandle,
|
||||
kCommandSetHub,
|
||||
kCommandIDHubQueryLidarInformation,
|
||||
NULL,
|
||||
0,
|
||||
MakeCommandCallback<DeviceManager, HubQueryLidarInformationResponse>(
|
||||
this, &DeviceManager::HubLidarInfomationCallback));
|
||||
} else if (connected_cb_) {
|
||||
connected_cb_(&device, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +231,8 @@ void DeviceManager::UpdateDeviceState(uint8_t handle, const HeartbeatResponse &r
|
||||
update = true;
|
||||
}
|
||||
if (info.status.progress != response.error_union.progress) {
|
||||
LOG_INFO(" Update progress {}, device connect {}", (uint16_t)response.error_union.progress, devices_[handle].connected);
|
||||
LOG_INFO(
|
||||
" Update progress {}, device connect {}", (uint16_t)response.error_union.progress, devices_[handle].connected);
|
||||
info.status.progress = response.error_union.progress;
|
||||
update = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user