1414 * limitations under the License.
1515 *
1616*/
17+
18+ #include < algorithm>
19+
1720#if defined(_MSC_VER)
1821 #pragma warning(push)
1922 #pragma warning(disable: 4005)
@@ -56,6 +59,9 @@ class gz::sensors::LidarPrivate
5659
5760 // / \brief Sdf sensor.
5861 public: sdf::Lidar sdfLidar;
62+
63+ // / \brief Number of channels of the raw lidar buffer
64+ public: const unsigned int kChannelCount = 3u ;
5965};
6066
6167// ////////////////////////////////////////////////
@@ -166,8 +172,16 @@ bool Lidar::Load(const sdf::Sensor &_sdf)
166172 {
167173 if (noiseSdf.Type () == sdf::NoiseType::GAUSSIAN)
168174 {
169- this ->dataPtr ->noises [noiseType] =
170- NoiseFactory::NewNoiseModel (noiseSdf);
175+ // Skip applying noise if gaussian noise params are all 0s
176+ if (!math::equal (noiseSdf.Mean (), 0.0 ) ||
177+ !math::equal (noiseSdf.StdDev (), 0.0 ) ||
178+ !math::equal (noiseSdf.BiasMean (), 0.0 ) ||
179+ !math::equal (noiseSdf.DynamicBiasStdDev (), 0.0 ) ||
180+ !math::equal (noiseSdf.DynamicBiasCorrelationTime (), 0.0 ))
181+ {
182+ this ->dataPtr ->noises [noiseType] =
183+ NoiseFactory::NewNoiseModel (noiseSdf);
184+ }
171185 }
172186 else if (noiseSdf.Type () != sdf::NoiseType::NONE)
173187 {
@@ -215,14 +229,10 @@ void Lidar::ApplyNoise()
215229 for (unsigned int i = 0 ; i < this ->RayCount (); ++i)
216230 {
217231 int index = j * this ->RayCount () + i;
218- double range = this ->laserBuffer [index* 3 ];
232+ double range = this ->laserBuffer [index * this -> dataPtr -> kChannelCount ];
219233 range = this ->dataPtr ->noises [LIDAR_NOISE]->Apply (range);
220- if (std::isfinite (range))
221- {
222- range = gz::math::clamp (range,
223- this ->RangeMin (), this ->RangeMax ());
224- }
225- this ->laserBuffer [index*3 ] = range;
234+ this ->laserBuffer [index * this ->dataPtr ->kChannelCount ] =
235+ this ->Clamp (range);
226236 }
227237 }
228238 }
@@ -232,6 +242,12 @@ void Lidar::ApplyNoise()
232242bool Lidar::PublishLidarScan (const std::chrono::steady_clock::duration &_now)
233243{
234244 GZ_PROFILE (" Lidar::PublishLidarScan" );
245+
246+ if (!this ->dataPtr ->pub .HasConnections ())
247+ {
248+ return false ;
249+ }
250+
235251 if (!this ->laserBuffer )
236252 return false ;
237253
@@ -246,7 +262,7 @@ bool Lidar::PublishLidarScan(const std::chrono::steady_clock::duration &_now)
246262 // keeping here the sensor name instead of frame_id because the visualizeLidar
247263 // plugin relies on this value to get the position of the lidar.
248264 // the ros_gz plugin is using the laserscan.proto 'frame' field
249- frame->add_value (this ->Name ());
265+ frame->add_value (this ->FrameId ());
250266 this ->dataPtr ->laserMsg .set_frame (this ->FrameId ());
251267
252268 // Store the latest laser scans into laserMsg
@@ -266,17 +282,18 @@ bool Lidar::PublishLidarScan(const std::chrono::steady_clock::duration &_now)
266282 }
267283 }
268284
285+ // \todo(iche033) interpolate if ray count != range count, i.e. resolution > 1
269286 for (unsigned int j = 0 ; j < this ->VerticalRangeCount (); ++j)
270287 {
271288 for (unsigned int i = 0 ; i < this ->RangeCount (); ++i)
272289 {
273290 int index = j * this ->RangeCount () + i;
274- double range = this ->laserBuffer [index* 3 ];
291+ double range = this ->laserBuffer [index * this -> dataPtr -> kChannelCount ];
275292
276- range = gz::math::isnan (range) ? this ->RangeMax () : range;
293+ range = this ->Clamp ( range) ;
277294 this ->dataPtr ->laserMsg .set_ranges (index, range);
278295 this ->dataPtr ->laserMsg .set_intensities (index,
279- this ->laserBuffer [index * 3 + 1 ]);
296+ this ->laserBuffer [index * this -> dataPtr -> kChannelCount + 1 ]);
280297 }
281298 }
282299
@@ -420,35 +437,54 @@ void Lidar::SetVerticalAngleMax(const double _angle)
420437void Lidar::Ranges (std::vector<double > &_ranges) const
421438{
422439 std::lock_guard<std::mutex> lock (this ->lidarMutex );
440+ if (!this ->laserBuffer )
441+ {
442+ gzwarn << " Lidar ranges not available" << std::endl;
443+ return ;
444+ }
445+
446+ // \todo(iche033) interpolate if ray count != range count, i.e. resolution > 1
447+ unsigned int size = this ->RayCount () * this ->VerticalRayCount ();
448+ _ranges.resize (size);
423449
424- _ranges.resize (this ->dataPtr ->laserMsg .ranges_size ());
425- memcpy (&_ranges[0 ], this ->dataPtr ->laserMsg .ranges ().data (),
426- sizeof (_ranges[0 ]) * this ->dataPtr ->laserMsg .ranges_size ());
450+ for (unsigned int i = 0 ; i < size; ++i)
451+ {
452+ _ranges[i] = this ->Clamp (
453+ this ->laserBuffer [i * this ->dataPtr ->kChannelCount ]);
454+ }
427455}
428456
429457// ////////////////////////////////////////////////
430458double Lidar::Range (const int _index) const
431459{
432460 std::lock_guard<std::mutex> lock (this ->lidarMutex );
433461
434- if (this ->dataPtr ->laserMsg .ranges_size () == 0 )
435- {
436- gzwarn << " ranges not constructed yet (zero sized)\n " ;
437- return 0.0 ;
438- }
439- if (_index < 0 || _index > this ->dataPtr ->laserMsg .ranges_size ())
462+ // \todo(iche033) interpolate if ray count != range count, i.e. resolution > 1
463+ if (!this ->laserBuffer || _index >= static_cast <int >(
464+ this ->RayCount () * this ->VerticalRayCount () *
465+ this ->dataPtr ->kChannelCount ))
440466 {
441- gzerr << " Invalid range index[ " << _index << " ] \n " ;
467+ gzwarn << " Lidar range not available for index: " << _index << std::endl ;
442468 return 0.0 ;
443469 }
444470
445- return this ->dataPtr -> laserMsg . ranges ( _index);
471+ return this ->Clamp ( this -> laserBuffer [ _index * this -> dataPtr -> kChannelCount ] );
446472}
447473
448474// ////////////////////////////////////////////////
449- double Lidar::Retro (const int /* _index*/ ) const
475+ double Lidar::Retro (const int _index) const
450476{
451- return 0.0 ;
477+ std::lock_guard<std::mutex> lock (this ->lidarMutex );
478+
479+ // \todo(iche033) interpolate if ray count != range count, i.e. resolution > 1
480+ if (!this ->laserBuffer || _index >= static_cast <int >(
481+ this ->RayCount () * this ->VerticalRayCount () *
482+ this ->dataPtr ->kChannelCount ))
483+ {
484+ gzwarn << " Lidar retro not available for index: " << _index << std::endl;
485+ return 0.0 ;
486+ }
487+ return this ->laserBuffer [_index * this ->dataPtr ->kChannelCount + 1 ];
452488}
453489
454490// ////////////////////////////////////////////////
@@ -476,3 +512,15 @@ bool Lidar::HasConnections() const
476512{
477513 return this ->dataPtr ->pub && this ->dataPtr ->pub .HasConnections ();
478514}
515+
516+ // ////////////////////////////////////////////////
517+ double Lidar::Clamp (double _range) const
518+ {
519+ if (gz::math::isnan (_range))
520+ return this ->RangeMax ();
521+
522+ if (std::isfinite (_range))
523+ return std::clamp (_range, this ->RangeMin (), this ->RangeMax ());
524+
525+ return _range;
526+ }
0 commit comments