Skip to content

Commit 84c2385

Browse files
author
Janosch Machowinski
committed
feat: CPU Lidar
1 parent ff8c92b commit 84c2385

5 files changed

Lines changed: 1415 additions & 0 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (C) 2026 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
#ifndef GZ_SENSORS_CPULIDARSENSOR_HH_
18+
#define GZ_SENSORS_CPULIDARSENSOR_HH_
19+
20+
#include <memory>
21+
#include <utility>
22+
#include <vector>
23+
24+
#include <sdf/sdf.hh>
25+
26+
#include <gz/math/Angle.hh>
27+
#include <gz/math/Vector3.hh>
28+
#include <gz/utils/SuppressWarning.hh>
29+
30+
#include <gz/sensors/config.hh>
31+
#include <gz/sensors/cpu_lidar/Export.hh>
32+
33+
#include "gz/sensors/Sensor.hh"
34+
35+
namespace gz
36+
{
37+
namespace sensors
38+
{
39+
inline namespace GZ_SENSORS_VERSION_NAMESPACE {
40+
41+
class CpuLidarSensorPrivate;
42+
43+
/// \brief CPU-based lidar sensor that performs ray casting without
44+
/// depending on gz-rendering.
45+
class GZ_SENSORS_CPU_LIDAR_VISIBLE CpuLidarSensor : public Sensor
46+
{
47+
/// \brief Result of a single ray cast
48+
public: struct RayResult
49+
{
50+
/// \brief Hit point in entity frame
51+
gz::math::Vector3d point;
52+
53+
/// \brief Fraction along the ray [0, 1]. NaN if no hit.
54+
double fraction;
55+
56+
/// \brief Normal at hit point in entity frame
57+
gz::math::Vector3d normal;
58+
59+
/// \brief Intensity value
60+
double intensity = 0.0;
61+
};
62+
/// \brief constructor
63+
public: CpuLidarSensor();
64+
65+
/// \brief destructor
66+
public: virtual ~CpuLidarSensor();
67+
68+
/// \brief Load the sensor based on data from an sdf::Sensor object.
69+
/// \param[in] _sdf SDF Sensor parameters.
70+
/// \return true if loading was successful
71+
public: virtual bool Load(const sdf::Sensor &_sdf) override;
72+
73+
/// \brief Load the sensor with SDF parameters.
74+
/// \param[in] _sdf SDF Sensor parameters.
75+
/// \return true if loading was successful
76+
public: virtual bool Load(sdf::ElementPtr _sdf) override;
77+
78+
using Sensor::Update;
79+
80+
/// \brief Update the sensor and generate data
81+
/// \param[in] _now The current time
82+
/// \return true if the update was successful
83+
public: virtual bool Update(
84+
const std::chrono::steady_clock::duration &_now) override;
85+
86+
/// \brief Check if there are any subscribers
87+
/// \return True if there are subscribers, false otherwise
88+
public: virtual bool HasConnections() const override;
89+
90+
/// \brief Get the minimum horizontal angle
91+
public: gz::math::Angle AngleMin() const;
92+
93+
/// \brief Get the maximum horizontal angle
94+
public: gz::math::Angle AngleMax() const;
95+
96+
/// \brief Get the minimum vertical angle
97+
public: gz::math::Angle VerticalAngleMin() const;
98+
99+
/// \brief Get the maximum vertical angle
100+
public: gz::math::Angle VerticalAngleMax() const;
101+
102+
/// \brief Get the minimum range
103+
public: double RangeMin() const;
104+
105+
/// \brief Get the maximum range
106+
public: double RangeMax() const;
107+
108+
/// \brief Get the horizontal ray count
109+
public: unsigned int RayCount() const;
110+
111+
/// \brief Get the vertical ray count
112+
public: unsigned int VerticalRayCount() const;
113+
114+
/// \brief Generate rays from the lidar configuration.
115+
/// \return Vector of (start, end) pairs in entity frame
116+
public: std::vector<std::pair<gz::math::Vector3d, gz::math::Vector3d>>
117+
GenerateRays() const;
118+
119+
/// \brief Set the raycast results from the physics engine.
120+
/// \param[in] _results Vector of results, one per ray.
121+
public: void SetRaycastResults(
122+
const std::vector<RayResult> &_results);
123+
124+
/// \brief Get all range values.
125+
/// \param[out] _ranges Vector to fill with range data.
126+
public: void Ranges(std::vector<double> &_ranges) const;
127+
128+
GZ_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING
129+
/// \brief Data pointer for private data
130+
/// \internal
131+
private: std::unique_ptr<CpuLidarSensorPrivate> dataPtr;
132+
GZ_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING
133+
};
134+
}
135+
}
136+
}
137+
138+
#endif

src/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ gz_add_component(magnetometer SOURCES ${magnetometer_sources} GET_TARGET_NAME ma
149149
set(imu_sources ImuSensor.cc)
150150
gz_add_component(imu SOURCES ${imu_sources} GET_TARGET_NAME imu_target)
151151

152+
set(cpu_lidar_sources CpuLidarSensor.cc)
153+
gz_add_component(cpu_lidar SOURCES ${cpu_lidar_sources} GET_TARGET_NAME cpu_lidar_target)
154+
target_link_libraries(${cpu_lidar_target}
155+
PRIVATE
156+
gz-msgs::gz-msgs
157+
gz-transport::gz-transport
158+
)
159+
152160
set(altimeter_sources AltimeterSensor.cc)
153161
gz_add_component(altimeter SOURCES ${altimeter_sources} GET_TARGET_NAME altimeter_target)
154162

0 commit comments

Comments
 (0)