Autoware.Auto
velodyne_translator.hpp
Go to the documentation of this file.
1 // Copyright 2018-2020 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
16 
20 
21 #ifndef VELODYNE_DRIVER__VELODYNE_TRANSLATOR_HPP_
22 #define VELODYNE_DRIVER__VELODYNE_TRANSLATOR_HPP_
23 
25 #include <geometry_msgs/msg/point32.hpp>
30 #include <vector>
31 
32 namespace autoware
33 {
36 namespace drivers
37 {
43 namespace velodyne_driver
44 {
47 template<typename SensorData>
48 class VELODYNE_DRIVER_PUBLIC VelodyneTranslator
49 {
50 public:
52  static constexpr uint16_t POINT_BLOCK_CAPACITY = 512U;
53 
54  class Config
55  {
56 public:
59  explicit Config(const float32_t rpm)
60  : m_rpm(rpm)
61  {
62  }
66  {
67  return m_rpm;
68  }
69 
70 private:
72  float32_t m_rpm;
73  };
76  struct DataChannel
77  {
78  uint8_t data[3U];
79  };
80 
82  struct DataBlock
83  {
84  uint8_t flag[2U];
85  uint8_t azimuth_bytes[2U];
87  };
88 
90  struct Packet
91  {
93  uint8_t timestamp_bytes[4U];
94  uint8_t factory_bytes[2U];
95  };
96 
100  explicit VelodyneTranslator(const Config & config)
101  : m_sensor_data(config.get_rpm())
102  {
103  init_trig_tables();
104  init_intensity_table();
105  }
106 
110  void convert(const Packet & pkt, std::vector<autoware::common::types::PointXYZIF> & output)
111  {
112  output.clear();
113 
114  for (uint32_t block_id = 0U; block_id < NUM_BLOCKS_PER_PACKET; ++block_id, ++m_block_counter) {
115  const DataBlock & block = pkt.blocks[block_id];
116  const auto flag_check_result = m_sensor_data.check_flag(block.flag);
117  // Ignore block with invalid flag.
118  if (!flag_check_result.first) {
119  continue;
120  }
121  // Number of points from the sequence that has already been delivered in previous blocks.
122  const auto num_banked_pts = flag_check_result.second;
123  const uint32_t azimuth_base = to_uint32(block.azimuth_bytes[1U], block.azimuth_bytes[0U]);
124 
125  for (uint16_t pt_id = 0U; pt_id < NUM_POINTS_PER_BLOCK; ++pt_id) {
126  const DataChannel & channel = block.channels[pt_id];
127  const uint32_t th = (azimuth_base + m_sensor_data.azimuth_offset(
128  num_banked_pts, block_id, pt_id)) % AZIMUTH_ROTATION_RESOLUTION;
129  const float32_t r = compute_distance_m(channel.data[1U], channel.data[0U]);
130  const uint32_t phi = m_sensor_data.altitude(num_banked_pts, block_id, pt_id);
131 
132  // Compute the point
133  PointXYZIF pt;
134  polar_to_xyz(pt, r, th, phi);
135  pt.intensity = m_intensity_table[channel.data[2U]];
136  pt.id = m_sensor_data.seq_id(m_block_counter, pt_id);
137 
138  output.push_back(pt);
139  }
140 
141  if (static_cast<float32_t>(m_block_counter) > m_sensor_data.num_blocks_per_revolution()) {
142  // full revolution reached.
143  PointXYZIF pt;
144  pt.id =
145  static_cast<uint16_t>(PointXYZIF::END_OF_SCAN_ID);
146  output.push_back(pt);
147  m_block_counter = uint16_t{0U};
148  }
149  }
150  }
151 
152 private:
153  // make sure packet sizes are correct
154  static_assert(sizeof(DataChannel) == 3U, "Error velodyne data channel size is incorrect");
155  static_assert(sizeof(DataBlock) == 100U, "Error velodyne data block size is incorrect");
156  static_assert(sizeof(Packet) == 1206U, "Error velodyne packet size is incorrect");
157  // Ensure that a full packet will fit into a point block
158  static_assert(
159  static_cast<uint32_t>(POINT_BLOCK_CAPACITY) >=
161  "Number of points from one VLP16 packet cannot fit into a point block");
162 
169  inline void polar_to_xyz(
171  const float32_t r_m,
172  const uint32_t th_ind,
173  const uint32_t phi_ind) const
174  {
175  const float32_t r_xy = r_m * m_cos_table[phi_ind];
176  pt.x = r_xy * m_cos_table[th_ind]; // y (vlp-frame)
177  pt.y = -r_xy * m_sin_table[th_ind]; // -x (vlp-frame)
178  pt.z = r_m * m_sin_table[phi_ind];
179  }
180 
185  inline float32_t compute_distance_m(const uint8_t first, const uint8_t second) const
186  {
187  const uint32_t dist_scaled = to_uint32(first, second);
188  return static_cast<float32_t>(dist_scaled) * m_sensor_data.distance_resolution();
189  }
190 
191  template<typename T>
192  inline T clamp(const T val, const T min, const T max) const
193  {
194  return (val < min) ? min : ((val > max) ? max : val);
195  }
196 
198  VELODYNE_DRIVER_LOCAL void init_trig_tables()
199  {
200  constexpr float32_t IDX2RAD =
201  TAU / static_cast<float32_t>(AZIMUTH_ROTATION_RESOLUTION);
202  for (uint64_t idx = 0U; idx < AZIMUTH_ROTATION_RESOLUTION; ++idx) {
203  m_cos_table[idx] = cosf((static_cast<float32_t>(idx)) * IDX2RAD);
204  m_sin_table[idx] = sinf((static_cast<float32_t>(idx)) * IDX2RAD);
205  }
206  }
207 
209  VELODYNE_DRIVER_LOCAL void init_intensity_table()
210  {
211  for (uint64_t idx = 0U; idx < NUM_INTENSITY_VALUES; ++idx) {
212  m_intensity_table[idx] = static_cast<float32_t>(idx);
213  }
214  }
215 
217  static constexpr float32_t TAU = 6.283185307179586476925286766559F;
218 
221  std::array<float32_t, AZIMUTH_ROTATION_RESOLUTION> m_sin_table;
223  std::array<float32_t, AZIMUTH_ROTATION_RESOLUTION> m_cos_table;
225  std::array<float32_t, AZIMUTH_ROTATION_RESOLUTION> m_intensity_table;
226 
228  uint16_t m_block_counter{0U};
229  SensorData m_sensor_data;
230 }; // class Driver
234 
235 } // namespace velodyne_driver
236 } // namespace drivers
237 } // namespace autoware
238 
239 #endif // VELODYNE_DRIVER__VELODYNE_TRANSLATOR_HPP_
autoware::drivers::velodyne_driver::VelodyneTranslator::DataBlock::channels
DataChannel channels[NUM_POINTS_PER_BLOCK]
Definition: velodyne_translator.hpp:86
autoware::common::types::PointXYZIF::x
float32_t x
Definition: types.hpp:50
output
Definition: output_type_trait.hpp:30
catr_diff.T
T
Definition: catr_diff.py:22
autoware::common::types::TAU
constexpr float32_t TAU
tau = 2 pi
Definition: types.hpp:44
autoware::drivers::velodyne_driver::VelodyneTranslator::Config::get_rpm
float32_t get_rpm() const
Gets rpm value.
Definition: velodyne_translator.hpp:65
common.hpp
This file defines a driver for Velodyne LiDARs.
motion::motion_common::clamp
T clamp(T val, T min, T max)
Standard clamp implementation.
Definition: motion_common.hpp:142
autoware::common::types::PointXYZIF::id
uint16_t id
Definition: types.hpp:54
autoware::common::types::PointXYZIF::intensity
float32_t intensity
Definition: types.hpp:53
autoware::drivers::velodyne_driver::AZIMUTH_ROTATION_RESOLUTION
static constexpr uint32_t AZIMUTH_ROTATION_RESOLUTION
resolution of azimuth angle: number of points in a full rotation
Definition: common.hpp:48
autoware::drivers::velodyne_driver::VelodyneTranslator::Config
Definition: velodyne_translator.hpp:54
autoware::drivers::velodyne_driver::VelodyneTranslator::DataBlock
corresponds to a velodyne data block.
Definition: velodyne_translator.hpp:82
autoware::drivers::velodyne_driver::VelodyneTranslator::DataBlock::azimuth_bytes
uint8_t azimuth_bytes[2U]
Definition: velodyne_translator.hpp:85
autoware::common::types::POINT_BLOCK_CAPACITY
static constexpr uint16_t POINT_BLOCK_CAPACITY
Stores basic configuration information, does some simple validity checking.
Definition: types.hpp:70
vls128_data.hpp
This file defines a driver for Velodyne LiDARs.
autoware::common::types::PointXYZIF
Definition: types.hpp:48
autoware::drivers::velodyne_driver::VelodyneTranslator::Packet::blocks
DataBlock blocks[NUM_BLOCKS_PER_PACKET]
Definition: velodyne_translator.hpp:92
autoware::drivers::velodyne_driver::VelodyneTranslator::DataChannel::data
uint8_t data[3U]
Definition: velodyne_translator.hpp:78
visibility_control.hpp
autoware::drivers::velodyne_driver::NUM_BLOCKS_PER_PACKET
static constexpr uint16_t NUM_BLOCKS_PER_PACKET
number of data blocks per data packet
Definition: common.hpp:55
autoware
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24
autoware::drivers::velodyne_driver::NUM_POINTS_PER_BLOCK
static constexpr uint16_t NUM_POINTS_PER_BLOCK
number of points stored in a data block
Definition: common.hpp:57
autoware::common::types::PointXYZIF::END_OF_SCAN_ID
static constexpr uint16_t END_OF_SCAN_ID
Definition: types.hpp:55
vlp32c_data.hpp
This file defines a driver for Velodyne LiDARs.
autoware::common::types::float32_t
float float32_t
Definition: types.hpp:36
autoware::drivers::velodyne_driver::VelodyneTranslator::Packet
stores a Velodyne data packet
Definition: velodyne_translator.hpp:90
autoware::drivers::velodyne_driver::VelodyneTranslator::Config::Config
Config(const float32_t rpm)
Constructor.
Definition: velodyne_translator.hpp:59
autoware::drivers::velodyne_driver::VelodyneTranslator
This class handles converting packets from a velodyne lidar into cartesian points.
Definition: velodyne_translator.hpp:48
autoware::drivers::velodyne_driver::NUM_INTENSITY_VALUES
static constexpr uint32_t NUM_INTENSITY_VALUES
how intensity is quantized: 1 byte = 256 possible values
Definition: common.hpp:52
autoware::drivers::velodyne_driver::VelodyneTranslator::DataChannel
corresponds to an individual laser's firing and return First two bytes are distance,...
Definition: velodyne_translator.hpp:76
autoware::drivers::velodyne_driver::to_uint32
uint32_t to_uint32(const uint8_t first, const uint8_t second)
computes 2 byte representation of two bytes from out of order velodyne packet
Definition: common.hpp:60
autoware::drivers::velodyne_driver::VelodyneTranslator::DataBlock::flag
uint8_t flag[2U]
Definition: velodyne_translator.hpp:84
autoware::common::types::PointXYZIF::z
float32_t z
Definition: types.hpp:52
autoware::drivers::velodyne_driver::VelodyneTranslator::VelodyneTranslator
VelodyneTranslator(const Config &config)
default constructor
Definition: velodyne_translator.hpp:100
vlp16_data.hpp
This file defines a driver for Velodyne LiDARs.
autoware::common::types::PointXYZIF::y
float32_t y
Definition: types.hpp:51
autoware::drivers::velodyne_driver::VelodyneTranslator::convert
void convert(const Packet &pkt, std::vector< autoware::common::types::PointXYZIF > &output)
Convert a packet into a block of cartesian points.
Definition: velodyne_translator.hpp:110
catr_diff.th
th
Definition: catr_diff.py:22