1111
1212#include " point_types.hpp"
1313
14+ #include < rclcpp/rclcpp.hpp>
1415#include < rclcpp/serialization.hpp>
1516
1617#include < sensor_msgs/msg/point_cloud2.hpp>
1718
18- #include < pcl/point_cloud.h>
19- #include < pcl/point_types.h>
20-
2119#include < memory>
2220
2321namespace bag_converter ::decoder
2422{
2523
24+ namespace defaults
25+ {
26+
27+ inline constexpr size_t min_points_per_scan = 1000 ;
28+
29+ } // namespace defaults
30+
2631/* *
2732 * @brief Abstract base class for PCD decoders using type erasure pattern
2833 *
@@ -49,7 +54,8 @@ class BasePCDDecoder
4954 * Derived classes deserialize the message internally and convert to PointCloud2.
5055 *
5156 * @param serialized_msg The serialized ROS message to decode
52- * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails
57+ * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails, the point cloud
58+ * is empty, or the point cloud contains too few points
5359 */
5460 virtual sensor_msgs::msg::PointCloud2::SharedPtr decode (
5561 const rclcpp::SerializedMessage & serialized_msg) = 0;
@@ -82,17 +88,33 @@ class PCDDecoder : public BasePCDDecoder
8288 /* *
8389 * @brief Decode serialized message to PointCloud2 (implements PCDDecoderBase)
8490 *
85- * Deserializes the message and delegates to the typed decode method.
91+ * Deserializes the message and delegates to the typed decode method. Returns nullptr if the
92+ * decoded PointCloud2 is empty or contains too few points.
8693 *
8794 * @param serialized_msg The serialized ROS message to decode
88- * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails
95+ * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails, the point cloud
96+ * is empty, or the point cloud contains too few points
8997 */
9098 sensor_msgs::msg::PointCloud2::SharedPtr decode (
9199 const rclcpp::SerializedMessage & serialized_msg) override
92100 {
93101 InputScanT input_msg;
94102 serializer_.deserialize_message (&serialized_msg, &input_msg);
95- return decode_typed (input_msg);
103+ auto decoded_msg = decode_typed (input_msg);
104+ if (!decoded_msg) {
105+ return nullptr ;
106+ }
107+
108+ if (decoded_msg->width == 0 || decoded_msg->data .empty ()) {
109+ return nullptr ;
110+ }
111+
112+ const size_t num_points = decoded_msg->width * decoded_msg->height ;
113+ if (num_points < defaults::min_points_per_scan) {
114+ return nullptr ;
115+ }
116+
117+ return decoded_msg;
96118 }
97119
98120 /* *
@@ -102,10 +124,12 @@ class PCDDecoder : public BasePCDDecoder
102124 * Converts the input scan message of type InputScanT to a PointCloud2 message.
103125 *
104126 * @param input The input scan message to decode
105- * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails
127+ * @return Shared pointer to PointCloud2 message, or nullptr if decoding fails or contains no
128+ * points
106129 */
107130 virtual sensor_msgs::msg::PointCloud2::SharedPtr decode_typed (const InputScanT & input) = 0;
108131
132+ protected:
109133private:
110134 rclcpp::Serialization<InputScanT> serializer_;
111135};
0 commit comments