Skip to content

Commit e8ebfe2

Browse files
committed
Solved Merge Conflicts
2 parents 4e5382c + f5ec347 commit e8ebfe2

File tree

3 files changed

+136
-36
lines changed

3 files changed

+136
-36
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: 18 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: ""
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,11 +211,19 @@ 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
218218
Value: true
219+
- Class: rviz/Marker
220+
Enabled: true
221+
Marker Topic: /object_pose_detection/object_pose_detection/grasp_pose
222+
Name: Marker
223+
Namespaces:
224+
{}
225+
Queue Size: 100
226+
Value: true
219227
Enabled: true
220228
Global Options:
221229
Background Color: 48; 48; 48
@@ -241,25 +249,25 @@ Visualization Manager:
241249
Views:
242250
Current:
243251
Class: rviz/Orbit
244-
Distance: 1.57199478
252+
Distance: 0.911043346
245253
Enable Stereo Rendering:
246254
Stereo Eye Separation: 0.0599999987
247255
Stereo Focal Distance: 1
248256
Swap Stereo Eyes: false
249257
Value: false
250258
Focal Point:
251-
X: 0.380761057
252-
Y: 0.105236754
253-
Z: 0.0502308793
259+
X: -0.012347864
260+
Y: -0.153358907
261+
Z: -0.142543241
254262
Focal Shape Fixed Size: true
255263
Focal Shape Size: 0.0500000007
256264
Invert Z Axis: false
257265
Name: Current View
258266
Near Clip Distance: 0.00999999978
259-
Pitch: 0.725203395
267+
Pitch: 0.550203443
260268
Target Frame: <Fixed Frame>
261269
Value: Orbit (rviz)
262-
Yaw: 2.5242579
270+
Yaw: 2.59425759
263271
Saved: ~
264272
Window Geometry:
265273
3D Bounding Box Image:

object_detection/src/object_pose_detection.cpp

Lines changed: 112 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ target_link_libraries(ground_plane_segmentation ${catkin_LIBRARIES})
1313
*/
1414

1515
#include "object_detection/boost.h"
16-
#include <ros/ros.h>
16+
#include <visualization_msgs/Marker.h>
1717

1818
// TF includes
1919
#include <tf/tf.h>
@@ -57,6 +57,7 @@ ros::Publisher coef_pub;
5757
ros::Publisher bbox_pub;
5858
ros::Publisher template_pub;
5959
ros::Publisher pose_pub;
60+
ros::Publisher marker_pub;
6061

6162
// Globals
6263
bool invert;
@@ -66,24 +67,72 @@ string input_topic;
6667
string output_topic;
6768
string coefficients_topic;
6869

70+
int argmin = -1;
6971
Eigen::Matrix4d icp_transform;
70-
string template_cuboid_filename;
72+
vector<Eigen::Matrix4d> icp_transforms;
7173
sensor_msgs::PointCloud2 bbox_msg;
7274
sensor_msgs::PointCloud2 output_msg;
7375
sensor_msgs::PointCloud2 template_msg;
7476
tf::TransformListener* listener;
7577
geometry_msgs::Pose pose_msg;
7678
Eigen::Affine3d pose_transform;
77-
double dimensions[3];
79+
double dimensions[] = { 0.1, 0.02, 0.02 };
7880
double icp_fitness_score;
7981
pcl::PCLPointCloud2::Ptr input_pcl(new pcl::PCLPointCloud2);
8082

83+
// Template paths
84+
string template_path;
85+
string template_filenames[] = { "", "screwdriver_ascii_tf.pcd", "eraser_ascii_tf.pcd",
86+
"clamp_ascii_tf.pcd", "marker_ascii_tf.pcd" };
87+
8188
// Flags
8289
bool DEBUG = false;
8390
bool ICP_SUCCESS = false;
8491
bool FIRST = true;
8592
bool POSE_FLAG = false;
8693

94+
void publish_grasp_marker(geometry_msgs::Pose& p)
95+
{
96+
visualization_msgs::Marker marker;
97+
// Set the frame ID and timestamp. See the TF tutorials for information on these.
98+
marker.header.frame_id = "camera_depth_optical_frame";
99+
marker.header.stamp = ros::Time::now();
100+
101+
// Set the namespace and id for this marker
102+
marker.ns = "grasp_pose";
103+
marker.id = 0;
104+
105+
// Set the marker type. Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
106+
marker.type = visualization_msgs::Marker::CUBE;
107+
108+
// Set the marker action. Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
109+
marker.action = visualization_msgs::Marker::ADD;
110+
111+
// Set the pose of the marker. This is a full 6DOF pose relative to the frame/time specified in the header
112+
marker.pose.position.x = p.position.x;
113+
marker.pose.position.y = p.position.y;
114+
marker.pose.position.z = p.position.z;
115+
marker.pose.orientation.x = p.orientation.x;
116+
marker.pose.orientation.y = p.orientation.y;
117+
marker.pose.orientation.z = p.orientation.z;
118+
marker.pose.orientation.w = p.orientation.w;
119+
120+
// Set the scale of the marker -- 1x1x1 here means 1m on a side
121+
marker.scale.x = dimensions[0];
122+
marker.scale.y = dimensions[1];
123+
marker.scale.z = dimensions[2];
124+
125+
// Set the color -- be sure to set alpha to something non-zero!
126+
marker.color.r = 1.0f;
127+
marker.color.g = 0.0f;
128+
marker.color.b = 0.0f;
129+
marker.color.a = 0.5f;
130+
131+
// Publish the marker
132+
marker.lifetime = ros::Duration();
133+
marker_pub.publish(marker);
134+
}
135+
87136
void publish_pose(Eigen::Matrix4d H)
88137
{
89138
// Set translation
@@ -113,6 +162,9 @@ void publish_pose(Eigen::Matrix4d H)
113162
p.orientation.z = quaternion.z();
114163
p.orientation.w = quaternion.w();
115164

165+
// Publish visualization marker
166+
publish_grasp_marker(p);
167+
116168
// Broadcast the transforms
117169
static tf::TransformBroadcaster br;
118170
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "camera_depth_optical_frame", "object_frame"));
@@ -141,24 +193,23 @@ void publish_bounding_box(Eigen::Matrix4d H)
141193
pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>);
142194
pcl::transformPointCloud(box_cloud, *transformed_cloud, H.cast<float>());
143195

144-
if (FIRST) {
145-
FIRST = false;
146-
cout << "Bounding Box Points:" << endl;
147-
for (int i = 0; i < transformed_cloud->size(); i++) {
148-
cout << "X: " << transformed_cloud->points[i].x << " | "
149-
<< "Y: " << transformed_cloud->points[i].y << " | "
150-
<< "Z: " << transformed_cloud->points[i].z << endl;
151-
}
152-
}
196+
// cout << "Bounding Box Points:" << endl;
197+
// for (int i = 0; i < transformed_cloud->size(); i++)
198+
// {
199+
// cout << "X: " << transformed_cloud->points[i].x << " | "
200+
// << "Y: " << transformed_cloud->points[i].y << " | "
201+
// << "Z: " << transformed_cloud->points[i].z << endl;
202+
// }
153203

154204
// Convert to ROS data type and publish
155205
pcl::toROSMsg(*transformed_cloud, bbox_msg);
156206
bbox_msg.header.frame_id = "camera_depth_optical_frame";
157207
bbox_pub.publish(bbox_msg);
158208
}
159209

160-
void icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl)
210+
double icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl)
161211
{
212+
int max_iter = 0;
162213
while (1) {
163214
// Point cloud containers
164215
pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud(new pcl::PointCloud<pcl::PointXYZ>);
@@ -173,21 +224,22 @@ void icp_registration(pcl::PointCloud<pcl::PointXYZ>::Ptr input_pcl, pcl::PointC
173224
icp.setEuclideanFitnessEpsilon(icp_fitness_score);
174225
icp.setRANSACOutlierRejectionThreshold(1.5);
175226
icp.align(*output_cloud);
176-
icp_transform = icp.getFinalTransformation().cast<double>().inverse();
227+
Eigen::Matrix4d icp_transform_local = icp.getFinalTransformation().cast<double>().inverse();
228+
icp_transforms.push_back(icp_transform_local);
177229

178230
cerr << "ICP Score Before: " << icp.getFitnessScore() << endl;
231+
max_iter++;
179232

180-
if (icp.hasConverged() && icp.getFitnessScore() < icp_fitness_score) {
233+
if ((icp.hasConverged() && icp.getFitnessScore() < icp_fitness_score) || (max_iter > 10)) {
181234
// Display ICP results
182235
cerr << "\nICP Score: " << icp.getFitnessScore() << endl;
183236
cerr << "ICP Transform:\n"
184-
<< icp_transform << endl;
237+
<< icp_transform_local << endl;
185238

186239
// Convert to ROS data type
187240
pcl::toROSMsg(*output_cloud, output_msg);
188241
pcl::toROSMsg(*template_pcl, template_msg);
189-
ICP_SUCCESS = true;
190-
return;
242+
return icp.getFitnessScore();
191243
}
192244
}
193245
}
@@ -200,11 +252,11 @@ void pcl_callback(const sensor_msgs::PointCloud2ConstPtr& input)
200252
cerr << "PointCloud before filtering: " << input_pcl->width << " " << input_pcl->height << " data points." << endl;
201253

202254
// Publish template point cloud
203-
if (ICP_SUCCESS) {
255+
if (ICP_SUCCESS and argmin != -1) {
204256
icp_pub.publish(output_msg);
205257
template_msg.header.frame_id = "camera_depth_optical_frame";
206258
template_pub.publish(template_msg);
207-
publish_bounding_box(icp_transform);
259+
// publish_bounding_box(icp_transform);
208260
publish_pose(icp_transform);
209261
}
210262
}
@@ -274,7 +326,7 @@ bool service_callback(object_detection::ObjectDetection::Request& req,
274326
pcl::PassThrough<pcl::PCLPointCloud2> pass_z2;
275327
pass_z2.setInputCloud(plane_cloud_ptr);
276328
pass_z2.setFilterFieldName("z");
277-
pass_z2.setFilterLimits(0.0, 0.7);
329+
pass_z2.setFilterLimits(0.0, 0.75);
278330
pass_z2.filter(*cloud_filtered_ptr_z2);
279331
if (DEBUG)
280332
cerr << "PointCloud after filtering: " << cloud_filtered_ptr_z2->width << " " << cloud_filtered_ptr->height << " data points." << endl;
@@ -299,10 +351,15 @@ bool service_callback(object_detection::ObjectDetection::Request& req,
299351
ec.extract(object_cluster_indices);
300352

301353
// Display number of objects detceted
354+
cerr << "\nRequested Object: " << template_filenames[req.object_id] << endl;
302355
cerr << "Objects Detected: " << object_cluster_indices.size() << endl;
303-
int obj_id = 1;
304356

305-
// What is this?
357+
// Find the best registered object
358+
int obj_id = req.object_id;
359+
vector<double> icp_scores;
360+
icp_transforms.clear();
361+
ICP_SUCCESS = false;
362+
306363
for (vector<pcl::PointIndices>::const_iterator it = object_cluster_indices.begin(); it != object_cluster_indices.end(); ++it) {
307364
// Create a pcl object to hold the extracted cluster
308365
pcl::PCLPointCloud2::Ptr object_cluster(new pcl::PCLPointCloud2);
@@ -323,7 +380,7 @@ bool service_callback(object_detection::ObjectDetection::Request& req,
323380
pcl_pub.publish(output);
324381

325382
// Read template point cloud
326-
string template_filename = "/home/karmesh/dash_ws/src/perception/object_detection/templates/eraser_ascii_tf.pcd";
383+
string template_filename = template_path + template_filenames[req.object_id];
327384
pcl::PointCloud<pcl::PointXYZ>::Ptr template_pcl(new pcl::PointCloud<pcl::PointXYZ>);
328385
if (pcl::io::loadPCDFile<pcl::PointXYZ>(template_filename, *template_pcl) == -1) {
329386
PCL_ERROR("Couldn't read the template PCL file");
@@ -332,9 +389,35 @@ bool service_callback(object_detection::ObjectDetection::Request& req,
332389
}
333390

334391
// Register using ICP and broadcast TF
335-
icp_registration(object_cluster_pcl, template_pcl);
392+
double score = icp_registration(object_cluster_pcl, template_pcl);
393+
icp_scores.push_back(score);
394+
}
395+
396+
// Find the object with best ICP score
397+
double min_score = 1000;
398+
argmin = -1;
399+
for (int i = 0; i < icp_scores.size(); i++) {
400+
if (icp_scores[i] < min_score) {
401+
argmin = i;
402+
min_score = icp_scores[i];
403+
}
404+
}
405+
406+
cerr << "\nLowest Object Index: " << argmin << " with Score: " << min_score << endl;
407+
icp_transform = icp_transforms[argmin];
408+
409+
if (min_score < icp_fitness_score) {
410+
cerr << "ICP Registration Success!\n"
411+
<< endl;
412+
ICP_SUCCESS = true;
336413
res.success = true;
337414
return true;
415+
} else {
416+
cerr << "ICP Registration Failed to Converge within Threshold!\n"
417+
<< endl;
418+
ICP_SUCCESS = false;
419+
res.success = false;
420+
return false;
338421
}
339422
}
340423

@@ -351,6 +434,7 @@ int main(int argc, char** argv)
351434
nh.getParam("input", input_topic);
352435
nh.getParam("output", output_topic);
353436
nh.getParam("icp_fitness_score", icp_fitness_score);
437+
nh.getParam("template_path", template_path);
354438

355439
// Params defaults
356440
nh.param<bool>("invert", invert, true);
@@ -365,7 +449,8 @@ int main(int argc, char** argv)
365449
cout << "Distance Threshold: " << distance_threshold << endl;
366450
cout << "Input Topic: " << input_topic << endl;
367451
cout << "Output Topic: " << output_topic << endl;
368-
cerr << "ICP Fitness Score:" << icp_fitness_score << endl;
452+
cerr << "ICP Fitness Score: " << icp_fitness_score << endl;
453+
cerr << "ICP Template Folder: " << template_path << endl;
369454

370455
// Create a ROS subscriber for the input point cloud
371456
ros::Subscriber sub = nh.subscribe(input_topic, 1, pcl_callback);
@@ -377,6 +462,7 @@ int main(int argc, char** argv)
377462
bbox_pub = nh.advertise<sensor_msgs::PointCloud2>("/icp/bbox_points", 1);
378463
template_pub = nh.advertise<sensor_msgs::PointCloud2>("/icp/template", 1);
379464
pose_pub = nh.advertise<geometry_msgs::Pose>("/icp/pose", 1);
465+
marker_pub = nh.advertise<visualization_msgs::Marker>("object_pose_detection/grasp_pose", 1);
380466

381467
// Spin
382468
ros::spin();

0 commit comments

Comments
 (0)