lds_lvx.cpp
Go to the documentation of this file.
1 //
2 // The MIT License (MIT)
3 //
4 // Copyright (c) 2019 Livox. All rights reserved.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //
24 
25 #include "lds_lvx.h"
26 
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <functional>
31 #include <memory>
32 #include <thread>
33 
34 #include "lvx_file.h"
35 
36 namespace livox_ros {
37 
40 
42 LdsLvx::LdsLvx(uint32_t interval_ms) : Lds(interval_ms, kSourceLvxFile) {
43  start_read_lvx_ = false;
44  is_initialized_ = false;
45  lvx_file_ = std::make_shared<LvxFileHandle>();
47  kMaxPacketsNumOfFrame * sizeof(LvxFilePacket);
49  new uint8_t[kMaxPacketsNumOfFrame * sizeof(LvxFilePacket)];
50 }
51 
53  if (packets_of_frame_.packet != nullptr) {
54  delete[] packets_of_frame_.packet;
55  }
56  if (t_read_lvx_->joinable()) {
57  t_read_lvx_->join();
58  }
59 }
60 
61 void LdsLvx::PrepareExit(void) {
62  lvx_file_->CloseLvxFile();
63  printf("Convert complete, Press [Ctrl+C] to exit!\n");
64 }
65 
66 int LdsLvx::InitLdsLvx(const char *lvx_path) {
67  if (is_initialized_) {
68  printf("Livox file data source is already inited!\n");
69  return -1;
70  }
71 
72  int ret = lvx_file_->Open(lvx_path, std::ios::in);
73  if (ret) {
74  printf("Open %s file fail[%d]!\n", lvx_path, ret);
75  return ret;
76  }
77 
78  if (lvx_file_->GetFileVersion() == kLvxFileV1) {
80  } else {
82  }
83 
84  uint32_t valid_lidar_count_ = lvx_file_->GetDeviceCount();
85  if (!valid_lidar_count_ || (valid_lidar_count_ >= kMaxSourceLidar)) {
86  lvx_file_->CloseLvxFile();
87  printf("Lidar count error in %s : %d\n", lvx_path, valid_lidar_count_);
88  return -1;
89  }
90  printf("LvxFile[%s] have %d lidars\n", lvx_path, valid_lidar_count_);
91 
92  for (uint32_t i = 0; i < valid_lidar_count_; i++) {
93  LvxFileDeviceInfo lvx_dev_info;
94  lvx_file_->GetDeviceInfo(i, &lvx_dev_info);
95  uint8_t handle = lvx_dev_info.device_index;
96  if (handle >= kMaxSourceLidar) {
97  printf("Invalid hanle from lvx file!\n");
98  continue;
99  }
100  lidars_[handle].handle = handle;
102  lidars_[handle].info.handle = handle;
103  lidars_[handle].info.type = lvx_dev_info.device_type;
104  memcpy(lidars_[handle].info.broadcast_code, \
105  lvx_dev_info.lidar_broadcast_code, \
106  sizeof(lidars_[handle].info.broadcast_code));
107 
108  if (lvx_file_->GetFileVersion() == kLvxFileV1) {
109  lidars_[handle].data_src = kSourceRawLidar;
110  } else {
111  lidars_[handle].data_src = kSourceLvxFile;
112  }
113 
114  ExtrinsicParameter *p_extrinsic = &lidars_[handle].extrinsic_parameter;
115  p_extrinsic->euler[0] = lvx_dev_info.roll * PI / 180.0;
116  p_extrinsic->euler[1] = lvx_dev_info.pitch * PI / 180.0;
117  p_extrinsic->euler[2] = lvx_dev_info.yaw * PI / 180.0;
118  p_extrinsic->trans[0] = lvx_dev_info.x;
119  p_extrinsic->trans[1] = lvx_dev_info.y;
120  p_extrinsic->trans[2] = lvx_dev_info.z;
121  EulerAnglesToRotationMatrix(p_extrinsic->euler, p_extrinsic->rotation);
122  p_extrinsic->enable = lvx_dev_info.extrinsic_enable;
123  }
124 
125  t_read_lvx_ =
126  std::make_shared<std::thread>(std::bind(&LdsLvx::ReadLvxFile, this));
127  is_initialized_ = true;
128 
129  StartRead();
130 
131  return ret;
132 }
133 
136  while (!start_read_lvx_);
137  printf("Start to read lvx file.\n");
138 
139  int file_state = kLvxFileOk;
140  int progress = 0;
141  while (start_read_lvx_) {
142  file_state = lvx_file_->GetPacketsOfFrame(&packets_of_frame_);
143  if (!file_state) {
145  uint8_t *packet_base = packets_of_frame_.packet;
146  uint32_t data_offset = 0;
147  while (data_offset < data_size) {
148  LivoxEthPacket *eth_packet;
149  int32_t handle;
150  uint8_t data_type;
151  if (lvx_file_->GetFileVersion()) {
152  LvxFilePacket *detail_packet =
153  (LvxFilePacket *)&packet_base[data_offset];
154  eth_packet = (LivoxEthPacket *)(&detail_packet->version);
155  handle = detail_packet->device_index;
156  } else {
157  LvxFilePacketV0 *detail_packet =
158  (LvxFilePacketV0 *)&packet_base[data_offset];
159  eth_packet = (LivoxEthPacket *)(&detail_packet->version);
160  handle = detail_packet->device_index;
161  }
162 
163  data_type = eth_packet->data_type;
164  if (handle >= lvx_file_->GetDeviceCount()) {
165  printf("Raw data handle error, error handle is %d\n", handle);
166  break;
167  }
168  if (data_type >= kMaxPointDataType) {
169  printf("Raw data type error, error data_type is %d\n", data_type);
170  break;
171  }
172  if (eth_packet->version != 5) {
173  printf("EthPacket version[%d] not supported\n", eth_packet->version);
174  break;
175  }
176 
178  data_offset += (GetEthPacketLen(data_type) + 1);
179  StorageRawPacket(handle, eth_packet);
180 
181  LidarDataQueue *p_queue = &lidars_[handle].data;
182  if (p_queue != nullptr) {
183  while (QueueIsFull(p_queue)) {
184  std::this_thread::sleep_for(std::chrono::milliseconds(1));
185  }
186  }
187  p_queue = &lidars_[handle].imu_data;
188  if (p_queue != nullptr) {
189  while (QueueIsFull(p_queue)) {
190  std::this_thread::sleep_for(std::chrono::milliseconds(1));
191  }
192  }
193  }
194  } else {
195  if (file_state != kLvxFileAtEnd) {
196  printf("Exit read the lvx file, read file state[%d]!\n", file_state);
197  } else {
198  printf("Read the lvx file complete!\n");
199  }
200  break;
201  }
202 
203  if (progress != lvx_file_->GetLvxFileReadProgress()) {
204  progress = lvx_file_->GetLvxFileReadProgress();
205  printf("Read progress : %d \n", progress);
206  }
207  }
208  printf("Wait for file conversion to complete!\n");
209  int32_t wait_cnt = 5;
210  while (!IsAllQueueEmpty()) {
211  std::this_thread::sleep_for(std::chrono::milliseconds(40));
212  if (semaphore_.GetCount() <= 0) {
213  semaphore_.Signal();
214  }
215  if (IsAllQueueReadStop()) {
216  --wait_cnt;
217  if (wait_cnt <= 0) {
218  break;
219  }
220  }
221  }
222 
223  RequestExit();
224  while(semaphore_.GetCount() > 0) {
225  std::this_thread::sleep_for(std::chrono::milliseconds(10));
226  }
227  semaphore_.Signal();
228 }
229 
230 } // namespace livox_ros
TranslationVector trans
Definition: lds.h:166
DeviceInfo info
Definition: lds.h:185
std::shared_ptr< std::thread > t_read_lvx_
Definition: lds_lvx.h:67
const double PI
Definition: lds.h:74
volatile bool is_initialized_
Definition: lds_lvx.h:64
const uint32_t kMaxSourceLidar
Definition: lds.h:46
LidarDataQueue data
Definition: lds.h:187
const uint32_t kMaxPacketsNumOfFrame
Definition: lds_lvx.cpp:39
void StartRead()
Definition: lds_lvx.h:58
volatile bool start_read_lvx_
Definition: lds_lvx.h:68
ExtrinsicParameter extrinsic_parameter
Definition: lds.h:191
Semaphore semaphore_
Definition: lds.h:447
uint32_t QueueIsFull(LidarDataQueue *queue)
Definition: ldq.cpp:101
std::shared_ptr< LvxFileHandle > lvx_file_
Definition: lds_lvx.h:66
unsigned char uint8_t
Definition: stdint.h:125
bool IsAllQueueEmpty()
Definition: lds.cpp:592
LidarDataQueue imu_data
Definition: lds.h:188
unsigned int uint32_t
Definition: stdint.h:127
LdsLvx(uint32_t interval_ms)
Definition: lds_lvx.cpp:42
bool IsAllQueueReadStop()
Definition: lds.cpp:602
uint8_t data_src
Definition: lds.h:174
RotationMatrix rotation
Definition: lds.h:167
void StorageRawPacket(uint8_t handle, LivoxEthPacket *eth_packet)
Definition: lds.cpp:637
int InitLdsLvx(const char *lvx_path)
Definition: lds_lvx.cpp:66
uint8_t lidar_broadcast_code[16]
Definition: lvx_file.h:86
void RequestExit()
Definition: lds.cpp:588
void EulerAnglesToRotationMatrix(EulerAngle euler, RotationMatrix matrix)
Definition: lds.cpp:150
OutPacketBuffer packets_of_frame_
Definition: lds_lvx.h:65
void ReadLvxFile()
Definition: lds_lvx.cpp:135
void ResetLds(uint8_t data_src)
Definition: lds.cpp:581
signed int int32_t
Definition: stdint.h:124
LidarDevice lidars_[kMaxSourceLidar]
Definition: lds.h:446
int GetCount()
Definition: lds.h:414
uint32_t GetEthPacketLen(uint32_t data_type)
Definition: lds.h:308
void Signal()
Definition: lds.h:402
volatile LidarConnectState connect_state
Definition: lds.h:184
void PrepareExit(void)
Definition: lds_lvx.cpp:61
uint8_t handle
Definition: lds.h:173


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:46