Skip to content

Commit db91413

Browse files
committed
Pose detection working for all objects now
1 parent c0554d2 commit db91413

File tree

3 files changed

+78
-35
lines changed

3 files changed

+78
-35
lines changed

object_detection/launch/object_detection.launch

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
name="object_pose_detection"
1919
output="screen">
2020

21+
<!-- Template object folder for ICP -->
22+
<param
23+
name="template_path"
24+
type="string"
25+
value="$(find object_detection)/templates/" />
26+
2127
<!-- Set topics and params -->
2228
<rosparam>
2329
<!-- invert (default: true): True > Box; False > Ground Plane -->

object_detection/perception.rviz

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Panels:
2525
Experimental: false
2626
Name: Time
2727
SyncMode: 0
28-
SyncSource: Ground Truth
28+
SyncSource: Clean Object PCL
2929
Visualization Manager:
3030
Class: ""
3131
Displays:
@@ -138,7 +138,7 @@ Visualization Manager:
138138
Color: 0; 255; 0
139139
Color Transformer: FlatColor
140140
Decay Time: 0
141-
Enabled: false
141+
Enabled: true
142142
Invert Rainbow: false
143143
Max Color: 255; 255; 255
144144
Max Intensity: 4096
@@ -155,7 +155,7 @@ Visualization Manager:
155155
Unreliable: false
156156
Use Fixed Frame: true
157157
Use rainbow: true
158-
Value: false
158+
Value: true
159159
- Alpha: 1
160160
Autocompute Intensity Bounds: true
161161
Autocompute Value Bounds:
@@ -211,7 +211,7 @@ Visualization Manager:
211211
Size (Pixels): 3
212212
Size (m): 0.00999999978
213213
Style: Points
214-
Topic: /ground_plane_segmentation/points
214+
Topic: /object_pose_detection/points
215215
Unreliable: false
216216
Use Fixed Frame: true
217217
Use rainbow: true
@@ -241,25 +241,25 @@ Visualization Manager:
241241
Views:
242242
Current:
243243
Class: rviz/Orbit
244-
Distance: 1.57199478
244+
Distance: 0.911043346
245245
Enable Stereo Rendering:
246246
Stereo Eye Separation: 0.0599999987
247247
Stereo Focal Distance: 1
248248
Swap Stereo Eyes: false
249249
Value: false
250250
Focal Point:
251-
X: 0.380761057
252-
Y: 0.105236754
253-
Z: 0.0502308793
251+
X: -0.012347864
252+
Y: -0.153358907
253+
Z: -0.142543241
254254
Focal Shape Fixed Size: true
255255
Focal Shape Size: 0.0500000007
256256
Invert Z Axis: false
257257
Name: Current View
258258
Near Clip Distance: 0.00999999978
259-
Pitch: 0.725203395
259+
Pitch: 0.550203443
260260
Target Frame: <Fixed Frame>
261261
Value: Orbit (rviz)
262-
Yaw: 2.5242579
262+
Yaw: 2.59425759
263263
Saved: ~
264264
Window Geometry:
265265
3D Bounding Box Image:

object_detection/src/object_pose_detection.cpp

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ string input_topic;
6666
string output_topic;
6767
string coefficients_topic;
6868

69+
int argmin = -1;
6970
Eigen::Matrix4d icp_transform;
70-
string template_cuboid_filename;
71+
vector<Eigen::Matrix4d> icp_transforms;
7172
sensor_msgs::PointCloud2 bbox_msg;
7273
sensor_msgs::PointCloud2 output_msg;
7374
sensor_msgs::PointCloud2 template_msg;
@@ -78,6 +79,11 @@ double dimensions[3];
7879
double icp_fitness_score;
7980
pcl::PCLPointCloud2::Ptr input_pcl(new pcl::PCLPointCloud2);
8081

82+
// Template paths
83+
string template_path;
84+
string template_filenames[] = {"", "screwdriver_ascii_tf.pcd", "eraser_ascii_tf.pcd",
85+
"clamp_ascii_tf.pcd", "marker_ascii_tf.pcd"};
86+
8187
// Flags
8288
bool DEBUG = false;
8389
bool ICP_SUCCESS = false;
@@ -141,26 +147,23 @@ void publish_bounding_box(Eigen::Matrix4d H)
141147
pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>);
142148
pcl::transformPointCloud(box_cloud, *transformed_cloud, H.cast<float>());
143149

144-
if (FIRST)
145-
{
146-
FIRST = false;
147-
cout << "Bounding Box Points:" << endl;
148-
for (int i = 0; i < transformed_cloud->size(); i++)
149-
{
150-
cout << "X: " << transformed_cloud->points[i].x << " | "
151-
<< "Y: " << transformed_cloud->points[i].y << " | "
152-
<< "Z: " << transformed_cloud->points[i].z << endl;
153-
}
154-
}
150+
// cout << "Bounding Box Points:" << endl;
151+
// for (int i = 0; i < transformed_cloud->size(); i++)
152+
// {
153+
// cout << "X: " << transformed_cloud->points[i].x << " | "
154+
// << "Y: " << transformed_cloud->points[i].y << " | "
155+
// << "Z: " << transformed_cloud->points[i].z << endl;
156+
// }
155157

156158
// Convert to ROS data type and publish
157159
pcl::toROSMsg(*transformed_cloud, bbox_msg);
158160
bbox_msg.header.frame_id = "camera_depth_optical_frame";
159161
bbox_pub.publish(bbox_msg);
160162
}
161163

162-
void icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl)
164+
double icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl)
163165
{
166+
int max_iter = 0;
164167
while (1)
165168
{
166169
// Point cloud containers
@@ -176,21 +179,22 @@ void icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointC
176179
icp.setEuclideanFitnessEpsilon(icp_fitness_score);
177180
icp.setRANSACOutlierRejectionThreshold(1.5);
178181
icp.align(*output_cloud);
179-
icp_transform = icp.getFinalTransformation().cast<double>().inverse();
182+
Eigen::Matrix4d icp_transform_local = icp.getFinalTransformation().cast<double>().inverse();
183+
icp_transforms.push_back(icp_transform_local);
180184

181185
cerr << "ICP Score Before: " << icp.getFitnessScore() << endl;
186+
max_iter++;
182187

183-
if (icp.hasConverged() && icp.getFitnessScore() < icp_fitness_score)
188+
if ((icp.hasConverged() && icp.getFitnessScore() < icp_fitness_score) || (max_iter > 10))
184189
{
185190
// Display ICP results
186191
cerr << "\nICP Score: " << icp.getFitnessScore() << endl;
187-
cerr << "ICP Transform:\n" << icp_transform << endl;
192+
cerr << "ICP Transform:\n" << icp_transform_local << endl;
188193

189194
// Convert to ROS data type
190195
pcl::toROSMsg(*output_cloud, output_msg);
191196
pcl::toROSMsg(*template_pcl, template_msg);
192-
ICP_SUCCESS = true;
193-
return;
197+
return icp.getFitnessScore();
194198
}
195199
}
196200
}
@@ -202,7 +206,7 @@ void pcl_callback(const sensor_msgs::PointCloud2ConstPtr& input)
202206
if (DEBUG) cerr << "PointCloud before filtering: " << input_pcl->width << " " << input_pcl->height << " data points." << endl;
203207

204208
// Publish template point cloud
205-
if (ICP_SUCCESS)
209+
if (ICP_SUCCESS and argmin != -1)
206210
{
207211
icp_pub.publish(output_msg);
208212
template_msg.header.frame_id = "camera_depth_optical_frame";
@@ -274,7 +278,7 @@ bool service_callback(object_detection::ObjectDetection::Request &req,
274278
pcl::PassThrough<pcl::PCLPointCloud2> pass_z2;
275279
pass_z2.setInputCloud(plane_cloud_ptr);
276280
pass_z2.setFilterFieldName("z");
277-
pass_z2.setFilterLimits(0.0, 0.7);
281+
pass_z2.setFilterLimits(0.0, 0.75);
278282
pass_z2.filter(*cloud_filtered_ptr_z2);
279283
if (DEBUG) cerr << "PointCloud after filtering: " << cloud_filtered_ptr_z2->width << " " << cloud_filtered_ptr->height << " data points." << endl;
280284

@@ -298,10 +302,15 @@ bool service_callback(object_detection::ObjectDetection::Request &req,
298302
ec.extract(object_cluster_indices);
299303

300304
// Display number of objects detceted
305+
cerr << "\nRequested Object: " << template_filenames[req.object_id] << endl;
301306
cerr << "Objects Detected: " << object_cluster_indices.size() << endl;
302-
int obj_id = 1;
303307

304-
// What is this?
308+
// Find the best registered object
309+
int obj_id = req.object_id;
310+
vector<double> icp_scores;
311+
icp_transforms.clear();
312+
ICP_SUCCESS = false;
313+
305314
for (vector<pcl::PointIndices>::const_iterator it = object_cluster_indices.begin(); it != object_cluster_indices.end(); ++it)
306315
{
307316
// Create a pcl object to hold the extracted cluster
@@ -323,7 +332,7 @@ bool service_callback(object_detection::ObjectDetection::Request &req,
323332
pcl_pub.publish(output);
324333

325334
// Read template point cloud
326-
string template_filename = "/home/heethesh/ROS-Workspaces/dash_ws/src/perception/object_detection/templates/eraser_ascii_tf.pcd";
335+
string template_filename = template_path + template_filenames[req.object_id];
327336
pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl(new pcl::PointCloud<pcl::PointXYZ>);
328337
if (pcl::io::loadPCDFile<pcl::PointXYZ>(template_filename, *template_pcl) == -1)
329338
{
@@ -333,9 +342,35 @@ bool service_callback(object_detection::ObjectDetection::Request &req,
333342
}
334343

335344
// Register using ICP and broadcast TF
336-
icp_registration(object_cluster_pcl, template_pcl);
345+
double score = icp_registration(object_cluster_pcl, template_pcl);
346+
icp_scores.push_back(score);
347+
}
348+
349+
// Find the object with best ICP score
350+
double min_score = 1000;
351+
argmin = -1;
352+
for (int i = 0; i < icp_scores.size(); i++)
353+
{
354+
if (icp_scores[i] < min_score)
355+
{
356+
argmin = i;
357+
min_score = icp_scores[i];
358+
}
359+
}
360+
361+
cerr << "\nLowest Object Index: " << argmin << " with Score: " << min_score << endl;
362+
icp_transform = icp_transforms[argmin];
363+
364+
if (min_score < icp_fitness_score) {
365+
cerr << "ICP Registration Success!\n" << endl;
366+
ICP_SUCCESS = true;
337367
res.success = true;
338368
return true;
369+
} else {
370+
cerr << "ICP Registration Failed to Converge within Threshold!\n" << endl;
371+
ICP_SUCCESS = false;
372+
res.success = false;
373+
return false;
339374
}
340375
}
341376

@@ -352,6 +387,7 @@ int main(int argc, char** argv)
352387
nh.getParam("input", input_topic);
353388
nh.getParam("output", output_topic);
354389
nh.getParam("icp_fitness_score", icp_fitness_score);
390+
nh.getParam("template_path", template_path);
355391

356392
// Params defaults
357393
nh.param<bool>("invert", invert, true);
@@ -366,7 +402,8 @@ int main(int argc, char** argv)
366402
cout << "Distance Threshold: " << distance_threshold << endl;
367403
cout << "Input Topic: " << input_topic << endl;
368404
cout << "Output Topic: " << output_topic << endl;
369-
cerr << "ICP Fitness Score:" << icp_fitness_score << endl;
405+
cerr << "ICP Fitness Score: " << icp_fitness_score << endl;
406+
cerr << "ICP Template Folder: " << template_path << endl;
370407

371408
// Create a ROS subscriber for the input point cloud
372409
ros::Subscriber sub = nh.subscribe(input_topic, 1, pcl_callback);

0 commit comments

Comments
 (0)