19 #include <boost/make_shared.hpp> 21 #include <sensor_msgs/PointCloud2.h> 22 #include <sensor_msgs/PointField.h> 27 if (datatype == sensor_msgs::PointField::INT8)
return 1;
28 if (datatype == sensor_msgs::PointField::UINT8)
return 1;
29 if (datatype == sensor_msgs::PointField::INT16)
return 2;
30 if (datatype == sensor_msgs::PointField::UINT16)
return 2;
31 if (datatype == sensor_msgs::PointField::INT32)
return 4;
32 if (datatype == sensor_msgs::PointField::UINT32)
return 4;
33 if (datatype == sensor_msgs::PointField::FLOAT32)
return 4;
34 if (datatype == sensor_msgs::PointField::FLOAT64)
return 8;
45 sensor_msgs::PointCloud2Ptr ptr = boost::make_shared<sensor_msgs::PointCloud2>();
51 ros_pointcloud.header =
header;
52 ros_pointcloud.height = 1;
53 ros_pointcloud.width = (int)
model->GetObjectModel3dParams(
"num_points")[0];
54 ros_pointcloud.is_dense =
false;
55 ros_pointcloud.is_bigendian =
false;
56 bool has_normals = ((HalconCpp::HString)
model->GetObjectModel3dParams(
"has_point_normals")) == HalconCpp::HString(
"true");
57 std::vector<sensor_msgs::PointField> fields;
59 ros_pointcloud.point_step = 28;
60 fields = std::vector<sensor_msgs::PointField>(7);
62 ros_pointcloud.point_step = 12;
63 fields = std::vector<sensor_msgs::PointField>(3);
66 ros_pointcloud.row_step = ros_pointcloud.width * ros_pointcloud.point_step;
69 sensor_msgs::PointField x_field;
72 x_field.datatype = sensor_msgs::PointField::FLOAT32;
76 sensor_msgs::PointField y_field;
79 y_field.datatype = sensor_msgs::PointField::FLOAT32;
83 sensor_msgs::PointField z_field;
86 z_field.datatype = sensor_msgs::PointField::FLOAT32;
91 sensor_msgs::PointField x_normals_field;
92 x_normals_field.name =
"normal_x";
93 x_normals_field.count = 1;
94 x_normals_field.datatype = sensor_msgs::PointField::FLOAT32;
95 x_normals_field.offset = 12;
96 fields[3] = x_normals_field;
98 sensor_msgs::PointField y_normals_field;
99 y_normals_field.name =
"normal_y";
100 y_normals_field.count = 1;
101 y_normals_field.datatype = sensor_msgs::PointField::FLOAT32;
102 y_normals_field.offset = 16;
103 fields[4] = y_normals_field;
105 sensor_msgs::PointField z_normals_field;
106 z_normals_field.name =
"normal_z";
107 z_normals_field.count = 1;
108 z_normals_field.datatype = sensor_msgs::PointField::FLOAT32;
109 z_normals_field.offset = 20;
110 fields[5] = z_normals_field;
113 curvature.name =
"curvature";
115 curvature.datatype = sensor_msgs::PointField::FLOAT32;
116 curvature.offset = 24;
121 ros_pointcloud.fields = fields;
124 HalconCpp::HTuple x_values =
model->GetObjectModel3dParams(
"point_coord_x");
125 HalconCpp::HTuple y_values =
model->GetObjectModel3dParams(
"point_coord_y");
126 HalconCpp::HTuple z_values =
model->GetObjectModel3dParams(
"point_coord_z");
128 HalconCpp::HTuple x_normal_values;
129 HalconCpp::HTuple y_normal_values;
130 HalconCpp::HTuple z_normal_values;
133 float *interleavedPoints;
136 x_normal_values =
model->GetObjectModel3dParams(
"point_normal_x");
137 y_normal_values =
model->GetObjectModel3dParams(
"point_normal_y");
138 z_normal_values =
model->GetObjectModel3dParams(
"point_normal_z");
139 interleavedPoints =
new float[ros_pointcloud.width * 7];
141 interleavedPoints =
new float[ros_pointcloud.width * 3];
144 for (
size_t i = 0; i < ros_pointcloud.width; i++) {
145 interleavedPoints[i * 3] = (float)x_values[i];
146 interleavedPoints[i * 3 + 1] = (float)y_values[i];
147 interleavedPoints[i * 3 + 2] = (float)z_values[i];
149 interleavedPoints[i * 3 + 3] = (float)x_normal_values[i];
150 interleavedPoints[i * 3 + 4] = (float)y_normal_values[i];
151 interleavedPoints[i * 3 + 5] = (float)z_normal_values[i];
152 interleavedPoints[i * 3 + 6] = (float)(
curvature)[i];
158 size = ros_pointcloud.width * 7 * 4;
160 size = ros_pointcloud.width * 3 * 4;
162 ros_pointcloud.data.resize(size);
164 memcpy((
float*)(&ros_pointcloud.data[0]), &interleavedPoints[0], size);
177 ptr->header = source.header;
180 int offset_x, offset_y, offset_z, offset_x_normal, offset_y_normal, offset_z_normal, offset_curvature;
181 offset_x = offset_y = offset_z = offset_x_normal = offset_y_normal = offset_z_normal = offset_curvature = 0;
182 int count_x_normal, count_y_normal, count_z_normal, count_curvature;
183 count_x_normal = count_y_normal = count_z_normal = count_curvature = 0;
185 for (
unsigned int i = 0; i < source.fields.size(); i++) {
186 sensor_msgs::PointField field = source.fields[i];
187 if (field.name ==
"x") {
188 offset_x = field.offset;
190 if (field.name ==
"y") {
191 offset_y = field.offset;
193 if (field.name ==
"z") {
194 offset_z = field.offset;
196 if (field.name ==
"normal_x") {
197 offset_x_normal = field.offset;
198 count_x_normal = field.count;
200 if (field.name ==
"normal_y") {
201 offset_y_normal = field.offset;
202 count_y_normal = field.count;
204 if (field.name ==
"normal_z") {
205 offset_z_normal = field.offset;
206 count_z_normal = field.count;
208 if (field.name ==
"curvature") {
209 offset_curvature = field.offset;
210 count_curvature = field.count;
215 HalconCpp::HTuple x_coords = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
216 HalconCpp::HTuple y_coords = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
217 HalconCpp::HTuple z_coords = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
219 HalconCpp::HTuple x_normals = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
220 HalconCpp::HTuple y_normals = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
221 HalconCpp::HTuple z_normals = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
223 HalconCpp::HTuple
curvature = HalconCpp::HTuple::TupleGenConst((
int)(source.width * source.height), 0);
225 for (
int i = 0; i < x_coords.Length(); i++) {
226 x_coords[i] = *(
float*)&source.data[(i * source.point_step) + offset_x];
227 y_coords[i] = *(
float*)&source.data[(i * source.point_step) + offset_y];
228 z_coords[i] = *(
float*)&source.data[(i * source.point_step) + offset_z];
230 if ((count_x_normal > 0) && (count_y_normal > 0) && (count_z_normal > 0)) {
231 x_normals[i] = *(
float*)&source.data[(i * source.point_step) + offset_x_normal];
232 y_normals[i] = *(
float*)&source.data[(i * source.point_step) + offset_y_normal];
233 z_normals[i] = *(
float*)&source.data[(i * source.point_step) + offset_z_normal];
237 ptr->model =
new HalconCpp::HObjectModel3D(x_coords, y_coords, z_coords);
239 if (source.fields.size() > 4) {
240 HalconCpp::HTuple attrib_names(
"point_normal_x");
241 attrib_names.Append(
"point_normal_y");
242 attrib_names.Append(
"point_normal_z");
243 HalconCpp::HTuple attrib_values = (x_normals.TupleConcat(y_normals)).TupleConcat(z_normals);
244 HalconCpp::HObjectModel3D p_n_model = ptr->model->SetObjectModel3dAttrib(attrib_names,
"", attrib_values);
245 *ptr->model = p_n_model;
247 for (
int i = 0; i < curvature.Length(); i++) {
248 curvature[i] = *(
float*)&source.data[(i * source.point_step) + offset_curvature];
int getSizeFromDatatype(int datatype)
HalconCpp::HTuple curvature
HalconImagePtr toHalconCopy(const sensor_msgs::ImageConstPtr &source)
Convert a sensor_msgs::Image message to a Halcon-compatible HImage, copying the image data...
sensor_msgs::PointCloud2Ptr toPointcloudMsg() const
Convert this message to a ROS sensor_msgs::PointCloud2 message.
HalconCpp::HObjectModel3D * model