Skip to content

Commit 6537fe5

Browse files
committed
added methods to publish the pointcloud information
1 parent b6df286 commit 6537fe5

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

include/realsense_gazebo_plugin/RealSensePlugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class RealSensePlugin : public ModelPlugin {
126126

127127
bool pointCloud_ = false;
128128
std::string pointCloudTopic_;
129-
double pointCloudCutOff_;
129+
double pointCloudCutOff_, pointCloudCutOffMax_;
130130

131131
double colorUpdateRate_;
132132
double infraredUpdateRate_;

include/realsense_gazebo_plugin/gazebo_ros_realsense.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <ros/ros.h>
77
#include <sensor_msgs/CameraInfo.h>
88
#include <sensor_msgs/Image.h>
9+
#include <sensor_msgs/PointCloud2.h>
910
#include <sensor_msgs/image_encodings.h>
1011

1112
#include <camera_info_manager/camera_info_manager.h>
@@ -34,6 +35,10 @@ class GazeboRosRealsense : public RealSensePlugin {
3435
public:
3536
virtual void OnNewDepthFrame();
3637

38+
/// \brief Helper function to fill the pointcloud information
39+
bool FillPointCloudHelper(sensor_msgs::PointCloud2 &point_cloud_msg, uint32_t rows_arg,
40+
uint32_t cols_arg, uint32_t step_arg, void *data_arg);
41+
3742
/// \brief Callback that publishes a received Camera Frame as an
3843
/// ImageStamped message.
3944
public:
@@ -51,13 +56,15 @@ class GazeboRosRealsense : public RealSensePlugin {
5156

5257
private:
5358
image_transport::ImageTransport *itnode_;
59+
ros::Publisher pointcloud_pub_;
5460

5561
protected:
5662
image_transport::CameraPublisher color_pub_, ir1_pub_, ir2_pub_, depth_pub_;
5763

5864
/// \brief ROS image messages
5965
protected:
6066
sensor_msgs::Image image_msg_, depth_msg_;
67+
sensor_msgs::PointCloud2 pointcloud_msg_;
6168
};
6269
}
6370
#endif /* _GAZEBO_ROS_REALSENSE_PLUGIN_ */

src/RealSensePlugin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ RealSensePlugin::RealSensePlugin() {
3535
this->ired2Cam = nullptr;
3636
this->colorCam = nullptr;
3737
this->prefix = "";
38+
this->pointCloudCutOffMax_ = 5.0;
3839
}
3940

4041
/////////////////////////////////////////////////
@@ -109,6 +110,8 @@ void RealSensePlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) {
109110
pointCloudTopic_ = _sdf->GetValue()->GetAsString();
110111
else if (name == "pointCloudCutoff")
111112
_sdf->GetValue()->Get(pointCloudCutOff_);
113+
else if (name == "pointCloudCutoffMax")
114+
_sdf->GetValue()->Get(pointCloudCutOffMax_);
112115
else if (name == "prefix")
113116
this->prefix = _sdf->GetValue()->GetAsString();
114117
else if (name == "robotNamespace")

src/gazebo_ros_realsense.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "realsense_gazebo_plugin/gazebo_ros_realsense.h"
22
#include <sensor_msgs/fill_image.h>
3+
#include <sensor_msgs/point_cloud2_iterator.h>
34

45
namespace {
56
std::string extractCameraName(const std::string &name);
@@ -47,6 +48,11 @@ void GazeboRosRealsense::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) {
4748
cameraParamsMap_[IRED2_CAMERA_NAME].topic_name, 2);
4849
this->depth_pub_ = this->itnode_->advertiseCamera(
4950
cameraParamsMap_[DEPTH_CAMERA_NAME].topic_name, 2);
51+
if (pointCloud_)
52+
{
53+
this->pointcloud_pub_ =
54+
this->rosnode_->advertise<sensor_msgs::PointCloud2>(pointCloudTopic_, 2, false);
55+
}
5056
}
5157

5258
void GazeboRosRealsense::OnNewFrame(const rendering::CameraPtr cam,
@@ -93,6 +99,99 @@ void GazeboRosRealsense::OnNewFrame(const rendering::CameraPtr cam,
9399
image_pub->publish(this->image_msg_, camera_info_msg);
94100
}
95101

102+
// Referenced from gazebo_plugins
103+
// https://github.com/ros-simulation/gazebo_ros_pkgs/blob/kinetic-devel/gazebo_plugins/src/gazebo_ros_openni_kinect.cpp#L302
104+
// Fill depth information
105+
bool GazeboRosRealsense::FillPointCloudHelper(sensor_msgs::PointCloud2 &point_cloud_msg,
106+
uint32_t rows_arg, uint32_t cols_arg,
107+
uint32_t step_arg, void *data_arg)
108+
{
109+
sensor_msgs::PointCloud2Modifier pcd_modifier(point_cloud_msg);
110+
pcd_modifier.setPointCloud2FieldsByString(2, "xyz", "rgb");
111+
// convert to flat array shape, we need to reconvert later
112+
pcd_modifier.resize(rows_arg * cols_arg);
113+
point_cloud_msg.is_dense = true;
114+
115+
sensor_msgs::PointCloud2Iterator<float> iter_x(pointcloud_msg_, "x");
116+
sensor_msgs::PointCloud2Iterator<float> iter_y(pointcloud_msg_, "y");
117+
sensor_msgs::PointCloud2Iterator<float> iter_z(pointcloud_msg_, "z");
118+
sensor_msgs::PointCloud2Iterator<uint8_t> iter_rgb(pointcloud_msg_, "rgb");
119+
120+
float *toCopyFrom = (float *)data_arg;
121+
int index = 0;
122+
123+
double hfov = this->depthCam->HFOV().Radian();
124+
double fl = ((double)this->depthCam->ImageWidth()) / (2.0 * tan(hfov / 2.0));
125+
126+
// convert depth to point cloud
127+
for (uint32_t j = 0; j < rows_arg; j++)
128+
{
129+
double pAngle;
130+
if (rows_arg > 1)
131+
pAngle = atan2((double)j - 0.5 * (double)(rows_arg - 1), fl);
132+
else
133+
pAngle = 0.0;
134+
135+
for (uint32_t i = 0; i < cols_arg; i++, ++iter_x, ++iter_y, ++iter_z, ++iter_rgb)
136+
{
137+
double yAngle;
138+
if (cols_arg > 1)
139+
yAngle = atan2((double)i - 0.5 * (double)(cols_arg - 1), fl);
140+
else
141+
yAngle = 0.0;
142+
143+
double depth = toCopyFrom[index++]; // + 0.0*this->myParent->GetNearClip();
144+
145+
if (depth > pointCloudCutOff_ && depth < pointCloudCutOffMax_)
146+
{
147+
// in optical frame
148+
// hardcoded rotation rpy(-M_PI/2, 0, -M_PI/2) is built-in
149+
// to urdf, where the *_optical_frame should have above relative
150+
// rotation from the physical camera *_frame
151+
*iter_x = depth * tan(yAngle);
152+
*iter_y = depth * tan(pAngle);
153+
*iter_z = depth;
154+
}
155+
else // point in the unseeable range
156+
{
157+
*iter_x = *iter_y = *iter_z = std::numeric_limits<float>::quiet_NaN();
158+
point_cloud_msg.is_dense = false;
159+
}
160+
161+
// put image color data for each point
162+
uint8_t *image_src = (uint8_t *)(&(this->image_msg_.data[0]));
163+
if (this->image_msg_.data.size() == rows_arg * cols_arg * 3)
164+
{
165+
// color
166+
iter_rgb[0] = image_src[i * 3 + j * cols_arg * 3 + 0];
167+
iter_rgb[1] = image_src[i * 3 + j * cols_arg * 3 + 1];
168+
iter_rgb[2] = image_src[i * 3 + j * cols_arg * 3 + 2];
169+
}
170+
else if (this->image_msg_.data.size() == rows_arg * cols_arg)
171+
{
172+
// mono (or bayer? @todo; fix for bayer)
173+
iter_rgb[0] = image_src[i + j * cols_arg];
174+
iter_rgb[1] = image_src[i + j * cols_arg];
175+
iter_rgb[2] = image_src[i + j * cols_arg];
176+
}
177+
else
178+
{
179+
// no image
180+
iter_rgb[0] = 0;
181+
iter_rgb[1] = 0;
182+
iter_rgb[2] = 0;
183+
}
184+
}
185+
}
186+
187+
// reconvert to original height and width after the flat reshape
188+
point_cloud_msg.height = rows_arg;
189+
point_cloud_msg.width = cols_arg;
190+
point_cloud_msg.row_step = point_cloud_msg.point_step * point_cloud_msg.width;
191+
192+
return true;
193+
}
194+
96195
void GazeboRosRealsense::OnNewDepthFrame() {
97196
// get current time
98197
common::Time current_time = this->world->SimTime();
@@ -118,6 +217,19 @@ void GazeboRosRealsense::OnNewDepthFrame() {
118217
auto depth_info_msg =
119218
cameraInfo(this->depth_msg_, this->depthCam->HFOV().Radian());
120219
this->depth_pub_.publish(this->depth_msg_, depth_info_msg);
220+
221+
if (pointCloud_ && this->pointcloud_pub_.getNumSubscribers() > 0)
222+
{
223+
this->pointcloud_msg_.header = this->depth_msg_.header;
224+
this->pointcloud_msg_.width = this->depthCam->ImageWidth();
225+
this->pointcloud_msg_.height = this->depthCam->ImageHeight();
226+
this->pointcloud_msg_.row_step =
227+
this->pointcloud_msg_.point_step * this->depthCam->ImageWidth();
228+
FillPointCloudHelper(this->pointcloud_msg_, this->depthCam->ImageHeight(),
229+
this->depthCam->ImageWidth(), 2 * this->depthCam->ImageWidth(),
230+
(void *)this->depthCam->DepthData());
231+
this->pointcloud_pub_.publish(this->pointcloud_msg_);
232+
}
121233
}
122234
}
123235

0 commit comments

Comments
 (0)