Description of task
Description
Create a ROS node that converts a 2D sonar image into a PointCloud (PCL) expressed in the sonar sensor frame, where:
- Each pixel is converted from image coordinates to metric coordinates (meters)
- The resulting point cloud lies in the XY-plane of the sonar frame
- The Z-coordinate is fixed to 0
- Range limits and pixel scaling are derived from a
SonarInfo message
- A ROS param should decide if the PCL should be dense, with point field PointXYZI, or if the pixels should be thresholded by a static threshold and the PCL should then not be dense but point field can still be PointXYZI.
Inputs
The node shall subscribe to:
-
Sonar image topic
- Type:
sensor_msgs/Image
- Pixels Represents intensity
-
Sonar metadata topic
-
Type: SonarInfo
-
Fields:
std_msgs/Header header
uint32 height
uint32 width
float64 meters_per_pixel_x
float64 meters_per_pixel_y
float64 max_range
float64 min_range
float64 vertical_fov
Outputs
The node shall publish:
-
Point cloud topic
- Type:
sensor_msgs/PointCloud2
- Frame ID: same as input image
- Point type:
pcl::PointXYZ (or PointXYZI if intensity is included)
Expected Behavior
- Subscripe to one message of SonarInfo, then destroy subscriber.
- Generate one 3D point per valid image pixel
- Publish a dense or filtered point cloud
- Preserve timestamp consistency with the sonar image
Example: Creating PCL Points from Image Pixels
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
cloud->header.frame_id = sonar_frame;
cloud->height = 1;
cloud->is_dense = false;
for (uint32_t v = 0; v < sonar_info.height; ++v) {
for (uint32_t u = 0; u < sonar_info.width; ++u) {
double x = pixel_to_meter(sonar_info.width, sonar_info.meters_per_pixel_x, u);
double y = pixel_to_meter(sonar_info.height, sonar_info.meters_per_pixel_y, v);
pcl::PointXYZ p;
p.x = x;
p.y = y;
p.z = 0.0;
cloud->points.push_back(p);
}
}
cloud->width = cloud->points.size();
Conversion to ROS message:
sensor_msgs::PointCloud2 cloud_msg;
pcl::toROSMsg(*cloud, cloud_msg);
cloud_msg.header.stamp = image_msg->header.stamp;
cloud_msg.header.frame_id = sonar_frame;
pointcloud_pub.publish(cloud_msg);
Acceptance Criteria
Suggested Workflow
No response
Specifications
No response
Contacts
No response
Code Quality
Description of task
Description
Create a ROS node that converts a 2D sonar image into a PointCloud (PCL) expressed in the sonar sensor frame, where:
SonarInfomessageInputs
The node shall subscribe to:
Sonar image topic
sensor_msgs/ImageSonar metadata topic
Type:
SonarInfoFields:
Outputs
The node shall publish:
Point cloud topic
sensor_msgs/PointCloud2pcl::PointXYZ(orPointXYZIif intensity is included)Expected Behavior
Example: Creating PCL Points from Image Pixels
Conversion to ROS message:
sensor_msgs::PointCloud2 cloud_msg; pcl::toROSMsg(*cloud, cloud_msg); cloud_msg.header.stamp = image_msg->header.stamp; cloud_msg.header.frame_id = sonar_frame; pointcloud_pub.publish(cloud_msg);Acceptance Criteria
Suggested Workflow
No response
Specifications
No response
Contacts
No response
Code Quality