23 LslidarN301Decoder::LslidarN301Decoder(
27 publish_point_cloud(true),
31 sweep_start_time(0.0),
32 packet_start_time(0.0),
33 sweep_data(new lslidar_n301_msgs::LslidarN301Sweep()){
52 ROS_WARN(
"Using GPS timestamp or not %d", use_gps_ts);
62 "lslidar_point_cloud", 10);
70 ROS_ERROR(
"Cannot load all required parameters...");
80 for (
size_t scan_idx = 0; scan_idx < 16; ++scan_idx) {
81 size_t remapped_scan_idx = scan_idx%2 == 0 ? scan_idx/2 : scan_idx/2+8;
86 for (
size_t i = 0; i < 6300; ++i) {
87 double angle =
static_cast<double>(i) / 1000.0;
98 ROS_WARN(
"Skip invalid LS-16 packet: block %lu header is %x",
111 double timestamp =
sweep_data->header.stamp.toSec();
112 point_cloud->header.stamp =
115 point_cloud->height = 1;
117 for (
size_t i = 0; i < 16; ++i) {
118 const lslidar_n301_msgs::LslidarN301Scan& scan =
sweep_data->scans[i];
123 if (scan.points.size() == 0)
continue;
125 for (j = 1; j < scan.points.size()-1; ++j) {
128 point.
timestamp = timestamp - (scan.points.size()-1 - j)*0.05;
129 point.x = scan.points[j].x;
130 point.y = scan.points[j].y;
131 point.z = scan.points[j].z;
132 point.
intensity = scan.points[j].intensity;
133 point_cloud->points.push_back(point);
134 ++point_cloud->width;
150 sensor_msgs::LaserScan::Ptr scan(
new sensor_msgs::LaserScan);
156 tm = *localtime(&tick);
163 scan->header.stamp =
sweep_data->header.stamp;
166 scan->angle_min = 0.0;
167 scan->angle_max = 2.0*M_PI;
168 scan->angle_increment = (scan->angle_max - scan->angle_min)/
point_num;
170 scan->time_increment = 0.05;
171 scan->scan_time =1/10.0;
175 scan->ranges.assign(
point_num, std::numeric_limits<float>::infinity());
178 scan->intensities.assign(
point_num, std::numeric_limits<float>::infinity());
180 for(uint16_t i = 0; i <
sweep_data->scans[0].points.size(); i++)
196 scan->ranges[i] = std::numeric_limits<float>::infinity();
206 int num = clusters.size();
209 tmp.
distance = std::numeric_limits<float>::infinity();
210 tmp.
intensity = std::numeric_limits<float>::infinity();
215 double mean_distance = 0, mean_intensity = 0;
217 for (
int i = 0; i < num; i++)
219 mean_distance += clusters[i].distance;
220 mean_intensity += clusters[i].intensity;
241 size_t blk_idx = fir_idx / 2;
248 size_t lfir_idx = fir_idx - 1;
249 size_t rfir_idx = fir_idx + 1;
252 if (fir_idx == FIRINGS_PER_PACKET - 1) {
253 lfir_idx = fir_idx - 3;
254 rfir_idx = fir_idx - 1;
259 azimuth_diff = azimuth_diff < 0 ? azimuth_diff + 2*M_PI : azimuth_diff;
275 size_t fir_idx = blk_idx*FIRINGS_PER_BLOCK + blk_fir_idx;
277 double azimuth_diff = 0.0;
278 if (fir_idx < FIRINGS_PER_PACKET - 1)
285 for (
size_t scan_fir_idx = 0; scan_fir_idx <
SCANS_PER_FIRING; ++scan_fir_idx){
287 SCANS_PER_FIRING*blk_fir_idx + scan_fir_idx);
295 raw_distance.
bytes[0] = raw_block.
data[byte_idx];
296 raw_distance.
bytes[1] = raw_block.
data[byte_idx+1];
302 raw_block.
data[byte_idx+2]);
308 pTime.tm_year = raw_block.
data[90]+2000-1900;
329 const lslidar_n301_msgs::LslidarN301PacketConstPtr& msg) {
343 size_t new_sweep_start = 0;
357 size_t start_fir_idx = 0;
358 size_t end_fir_idx = new_sweep_start;
366 start_fir_idx = new_sweep_start;
374 for (
size_t fir_idx = start_fir_idx; fir_idx < end_fir_idx; ++fir_idx) {
380 size_t table_idx = floor(
firings[fir_idx].azimuth[scan_idx]*1000.0+0.5);
411 int remapped_scan_idx = scan_idx%2 == 0 ? scan_idx/2 : scan_idx/2+8;
412 sweep_data->scans[remapped_scan_idx].points.push_back(
413 lslidar_n301_msgs::LslidarN301Point());
415 lslidar_n301_msgs::LslidarN301Point& new_point =
417 sweep_data->scans[remapped_scan_idx].points.size()-1];
420 new_point.time = time;
421 new_point.x = x_coord;
422 new_point.y = y_coord;
423 new_point.z = z_coord;
453 sweep_data = lslidar_n301_msgs::LslidarN301SweepPtr(
454 new lslidar_n301_msgs::LslidarN301Sweep());
464 start_fir_idx = end_fir_idx;
467 for (
size_t fir_idx = start_fir_idx; fir_idx < end_fir_idx; ++fir_idx) {
473 size_t table_idx = floor(
firings[fir_idx].azimuth[scan_idx]*1000.0+0.5);
504 int remapped_scan_idx = scan_idx%2 == 0 ? scan_idx/2 : scan_idx/2+8;
505 sweep_data->scans[remapped_scan_idx].points.push_back(
506 lslidar_n301_msgs::LslidarN301Point());
507 lslidar_n301_msgs::LslidarN301Point& new_point =
509 sweep_data->scans[remapped_scan_idx].points.size()-1];
512 new_point.time = time;
513 new_point.x = x_coord;
514 new_point.y = y_coord;
515 new_point.z = z_coord;
static const double scan_altitude[16]
uint64_t packet_timestamp
point_struct getMeans(std::vector< point_struct > clusters)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
double cos_azimuth_table[6300]
lslidar_n301_msgs::LslidarN301SweepPtr sweep_data
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
static const int SCANS_PER_FIRING
uint16_t header
UPPER_BANK or LOWER_BANK.
pcl::PointCloud< VPoint > VPointCloud
uint64_t get_gps_stamp(tm t)
static const int BLOCKS_PER_PACKET
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
double azimuth[SCANS_PER_FIRING]
uint8_t data[BLOCK_DATA_SIZE]
uint64_t sweep_end_time_gps
RawBlock blocks[BLOCKS_PER_PACKET]
ros::Publisher point_cloud_pub
static const double FIRING_TOFFSET
void packetCallback(const lslidar_n301_msgs::LslidarN301PacketConstPtr &msg)
static const double cos_scan_altitude[16]
static const double sin_scan_altitude[16]
double rawAzimuthToDouble(const uint16_t &raw_azimuth)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
uint16_t rotation
0-35999, divide by 100 to get degrees
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool isPointInRange(const double &distance)
TFSIMD_FORCE_INLINE const tfScalar & z() const
std::string child_frame_id
bool checkPacketValidity(const RawPacket *packet)
static const double DSR_TOFFSET
static const int FIRINGS_PER_PACKET
double intensity[SCANS_PER_FIRING]
static const int RAW_SCAN_SIZE
void decodePacket(const RawPacket *packet)
double sin_azimuth_table[6300]
static const uint16_t UPPER_BANK
Firing firings[FIRINGS_PER_PACKET]
static const int FIRINGS_PER_BLOCK
std::string fixed_frame_id
static const double DISTANCE_RESOLUTION
double distance[SCANS_PER_FIRING]
void toPCL(const ros::Time &stamp, pcl::uint64_t &pcl_stamp)
ros::Subscriber packet_sub
uint64_t sweep_end_time_hardware