Skip to content

Commit e7bf279

Browse files
committed
3D bbox integrated 🔲⚡
1 parent 01a6fe0 commit e7bf279

File tree

5 files changed

+2061
-18
lines changed

5 files changed

+2061
-18
lines changed

cuboid_detection/launch/iterative_closest_point.launch

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,28 @@
44
<!-- Launch Bounding Box Filter -->
55
<include file="$(find cuboid_detection)/launch/bbox_filter.launch"/>
66

7-
<!-- Template object path for ICP -->
8-
<param
9-
name="template_cuboid_path"
10-
type="string"
11-
value="$(find cuboid_detection)/templates/template_cuboid_L200_W100_H75_3faces.pcd" />
127

138
<!-- Run ICP node -->
149
<node
1510
pkg="cuboid_detection"
1611
type="iterative_closest_point"
1712
name="iterative_closest_point"
1813
output="screen">
14+
15+
<!-- Template object path for ICP -->
16+
<param
17+
name="template_cuboid_path"
18+
type="string"
19+
value="$(find cuboid_detection)/templates/template_cuboid_L200_W75_H100_3faces.pcd" />
20+
21+
<!-- Set topics and params -->
22+
<rosparam>
23+
<!-- Dimensions -->
24+
length: 0.2
25+
width: 0.075
26+
height: 0.1
27+
</rosparam>
28+
1929
</node>
2030

2131
</launch>

cuboid_detection/src/iterative_closest_point.cpp

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,73 @@ using namespace std;
2020

2121
// Globals
2222
ros::Publisher pcl_pub;
23+
ros::Publisher bbox_pub;
2324
ros::Publisher template_pub;
2425
Eigen::Matrix4d icp_transform;
2526
string template_cuboid_filename;
2627
tf::TransformListener *tf_listener;
28+
sensor_msgs::PointCloud2 bbox_msg;
2729
sensor_msgs::PointCloud2 output_msg;
2830
sensor_msgs::PointCloud2 template_msg;
31+
double dimensions[3];
2932

3033
// Flags
3134
bool DEBUG = false;
3235
bool ICP_SUCCESS = false;
36+
bool FIRST = true;
3337

34-
void convert_icp_eigen_to_tf(Eigen::Matrix4d Tm)
38+
void publish_bounding_box(Eigen::Matrix4d H)
39+
{
40+
// Extract cuboid dimensions
41+
double l = dimensions[0];
42+
double w = dimensions[1];
43+
double h = dimensions[2];
44+
45+
// Create a point cloud from the vertices
46+
pcl::PointCloud<pcl::PointXYZ> box_cloud;
47+
box_cloud.push_back(pcl::PointXYZ(0, 0, 0));
48+
box_cloud.push_back(pcl::PointXYZ(0, 0, h));
49+
box_cloud.push_back(pcl::PointXYZ(0, w, 0));
50+
box_cloud.push_back(pcl::PointXYZ(0, w, h));
51+
box_cloud.push_back(pcl::PointXYZ(l, 0, 0));
52+
box_cloud.push_back(pcl::PointXYZ(l, 0, h));
53+
box_cloud.push_back(pcl::PointXYZ(l, w, 0));
54+
box_cloud.push_back(pcl::PointXYZ(l, w, h));
55+
56+
// Transform point cloud
57+
pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>);
58+
pcl::transformPointCloud(box_cloud, *transformed_cloud, H.cast<float>());
59+
60+
if (FIRST)
61+
{
62+
FIRST = false;
63+
cout << "Bounding Box Points:" << endl;
64+
for (int i = 0; i < transformed_cloud->size(); i++)
65+
{
66+
cout << "X: " << transformed_cloud->points[i].x << " | "
67+
<< "Y: " << transformed_cloud->points[i].y << " | "
68+
<< "Z: " << transformed_cloud->points[i].z << endl;
69+
}
70+
}
71+
72+
// Convert to ROS data type and publish
73+
pcl::toROSMsg(*transformed_cloud, bbox_msg);
74+
bbox_msg.header.frame_id = "camera_depth_optical_frame";
75+
bbox_pub.publish(bbox_msg);
76+
}
77+
78+
void convert_icp_eigen_to_tf(Eigen::Matrix4d H)
3579
{
3680
// Set translation
3781
tf::Vector3 origin;
38-
origin.setValue(Tm(0, 3), Tm(1, 3), Tm(2, 3));
82+
origin.setValue(H(0, 3), H(1, 3), H(2, 3));
3983

4084
// Set rotation
4185
tf::Quaternion quaternion;
4286
tf::Matrix3x3 rotation_matrix;
43-
rotation_matrix.setValue(Tm(0, 0), Tm(0, 1), Tm(0, 2),
44-
Tm(1, 0), Tm(1, 1), Tm(1, 2),
45-
Tm(2, 0), Tm(2, 1), Tm(2, 2));
87+
rotation_matrix.setValue(H(0, 0), H(0, 1), H(0, 2),
88+
H(1, 0), H(1, 1), H(1, 2),
89+
H(2, 0), H(2, 1), H(2, 2));
4690
rotation_matrix.getRotation(quaternion);
4791

4892
// Make tf transform message
@@ -64,6 +108,7 @@ void icp_callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
64108
pcl_pub.publish(output_msg);
65109
template_msg.header.frame_id = "camera_depth_optical_frame";
66110
template_pub.publish(template_msg);
111+
publish_bounding_box(icp_transform);
67112
return;
68113
}
69114

@@ -90,7 +135,7 @@ void icp_callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
90135
icp.setTransformationEpsilon(1e-9);
91136
// icp.setMaxCorrespondenceDistance(0.05);
92137
// icp.setEuclideanFitnessEpsilon(1);
93-
// icp.setRANSACOutlierRejectionThreshold(1.5);
138+
icp.setRANSACOutlierRejectionThreshold(1.5);
94139
icp.align(*output_cloud);
95140
icp_transform = icp.getFinalTransformation().cast<double>().inverse();
96141

@@ -118,17 +163,26 @@ int main(int argc, char **argv)
118163
{
119164
// Init node
120165
ros::init(argc, argv, "iterative_closest_point");
121-
ros::NodeHandle nh;
166+
ros::NodeHandle nh("~");
122167

123168
// Handle params
124169
nh.getParam("template_cuboid_path", template_cuboid_filename);
125-
cerr << "\nTemplate filename: " << template_cuboid_filename;
170+
nh.getParam("length", dimensions[0]);
171+
nh.getParam("width", dimensions[1]);
172+
nh.getParam("height", dimensions[2]);
173+
174+
// Display params
175+
cerr << "\nTemplate filename: " << template_cuboid_filename << endl;
176+
cerr << "Length (m): " << dimensions[0] << endl;
177+
cerr << "Width (m): " << dimensions[1] << endl;
178+
cerr << "Height (m): " << dimensions[2] << endl;
126179

127180
// Subscribers
128181
ros::Subscriber pcl_sub = nh.subscribe<sensor_msgs::PointCloud2>("/ground_plane_segmentation/points", 1, icp_callback);
129182

130183
// Publishers
131184
pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("/icp/aligned_points", 1);
185+
bbox_pub = nh.advertise<sensor_msgs::PointCloud2>("/icp/bbox_points", 1);
132186
template_pub = nh.advertise<sensor_msgs::PointCloud2>("/icp/template", 1);
133187

134188
ros::spin();

cuboid_detection/templates/make_cuboid.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# Handle filename
1818
if not args.filename:
19-
args.filename = 'template_cuboid_L%d_W%d_H%d.pcd' % (L * 1000, W * 1000, H * 1000)
19+
args.filename = 'template_cuboid_L%d_W%d_H%d_3faces.pcd' % (L * 1000, W * 1000, H * 1000)
2020
elif not args.filename.endswith('.pcd'):
2121
args.filename += '.pcd'
2222

@@ -49,13 +49,14 @@ def face(xin, yin):
4949
column = lambda x: np.full((x[1], 1), x[0])
5050

5151
# Make all 6 faces
52-
faces = [None] * 6
52+
faces = [None] * 3
5353
faces[0] = np.hstack((face(X, Y), column([0, N[2]])))
5454
faces[1] = np.hstack((face(X, Z)[:, 0], column([0, N[1]]), face(X, Z)[:, 1]))
5555
faces[2] = np.hstack((column([0, N[0]]), face(Y, Z)[:, 0], face(Y, Z)[:, 1]))
56-
faces[3] = np.hstack((face(X, Y), column([H, N[2]])))
57-
faces[4] = np.hstack((face(X, Z)[:, 0], column([W, N[1]]), face(X, Z)[:, 1]))
58-
faces[5] = np.hstack((column([L, N[0]]), face(Y, Z)[:, 0], face(Y, Z)[:, 1]))
56+
# faces[3] = np.hstack((face(X, Y), column([H, N[2]])))
57+
# faces[4] = np.hstack((face(X, Z)[:, 0], column([W, N[1]]), face(X, Z)[:, 1]))
58+
# faces[5] = np.hstack((column([L, N[0]]), face(Y, Z)[:, 0], face(Y, Z)[:, 1]))
59+
5960
faces = np.vstack(faces)
6061

6162
# Save PCD file

0 commit comments

Comments
 (0)