Skip to content

Commit d87c97b

Browse files
committed
refine the algorithm
1 parent 5ba9358 commit d87c97b

File tree

4 files changed

+124
-30
lines changed

4 files changed

+124
-30
lines changed

drv_grasp/src/drv_put.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ int main(int argc, char **argv)
222222

223223
geometry_msgs::PoseStamped put_pose;
224224
geometry_msgs::PoseStamped ref_pose;
225-
// Pass the distance between gripper center and bottom of grasped object
225+
// Set the distance between gripper center and bottom of grasped object
226226
m_od_.setZOffset(center_to_bottom_);
227227
if (m_od_.detectPutTable(put_pose, ref_pose, offsetNeedPub_)) {
228228
// Table found

drv_grasp/src/obstacledetect.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ bool ObstacleDetect::analysePutPose(geometry_msgs::PoseStamped &put_pose,
324324
PointCloudMono::Ptr cloud = plane_max_hull_;
325325

326326
pcl::PointXY p;
327-
// Cause the camera field is limited, we consider a hull is in reach
328-
// When the nearest point on hull
327+
// Cause the camera view field is limited, we consider a hull is in reach
328+
// when the center point plus a toletance in x direction is in hull
329329
p.x = grasp_area_x_ + tolerance_;
330330
p.y = grasp_area_y_;
331331

drv_grasp/src/utilities.cpp

Lines changed: 101 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void Utilities::pointTypeTransfer(PointCloudRGBN::Ptr cloud_in,
9898
}
9999
}
100100

101-
void Utilities::cutCloud(pcl::ModelCoefficients::Ptr coeff_in, double th_distance,
101+
void Utilities::cutCloud(pcl::ModelCoefficients::Ptr coeff_in, float th_distance,
102102
PointCloudRGBN::Ptr cloud_in,
103103
PointCloudMono::Ptr &cloud_out)
104104
{
@@ -263,27 +263,27 @@ void Utilities::shrinkHull(PointCloudMono::Ptr cloud,
263263
float theta = atan(d_y/d_x);
264264
if (d_x > 0 && d_y >= 0) {
265265
cloud_sk->points[i].x = (pit->x - fabs(dis*sin(theta)))>center_x?
266-
(pit->x - fabs(dis*sin(theta))):pit->x;
266+
(pit->x - fabs(dis*sin(theta))):pit->x;
267267
cloud_sk->points[i].y = (pit->y - fabs(dis*cos(theta)))>center_y?
268-
(pit->y - fabs(dis*cos(theta))):pit->y;
268+
(pit->y - fabs(dis*cos(theta))):pit->y;
269269
}
270270
else if (d_x < 0 && d_y >= 0) {
271271
cloud_sk->points[i].x = (pit->x + fabs(dis*sin(theta)))<center_x?
272-
(pit->x + fabs(dis*sin(theta))):pit->x;
272+
(pit->x + fabs(dis*sin(theta))):pit->x;
273273
cloud_sk->points[i].y = (pit->y - fabs(dis*cos(theta)))>center_y?
274-
(pit->y - fabs(dis*cos(theta))):pit->y;
274+
(pit->y - fabs(dis*cos(theta))):pit->y;
275275
}
276276
else if (d_x < 0 && d_y < 0) {
277277
cloud_sk->points[i].x = (pit->x + fabs(dis*sin(theta)))<center_x?
278-
(pit->x + fabs(dis*sin(theta))):pit->x;
278+
(pit->x + fabs(dis*sin(theta))):pit->x;
279279
cloud_sk->points[i].y = (pit->y + fabs(dis*cos(theta)))<center_y?
280-
(pit->y + fabs(dis*cos(theta))):pit->y;
280+
(pit->y + fabs(dis*cos(theta))):pit->y;
281281
}
282282
else {
283283
cloud_sk->points[i].x = (pit->x - fabs(dis*sin(theta)))>center_x?
284-
(pit->x - fabs(dis*sin(theta))):pit->x;
284+
(pit->x - fabs(dis*sin(theta))):pit->x;
285285
cloud_sk->points[i].y = (pit->y + fabs(dis*cos(theta)))<center_y?
286-
(pit->y + fabs(dis*cos(theta))):pit->y;
286+
(pit->y + fabs(dis*cos(theta))):pit->y;
287287
}
288288
}
289289
}
@@ -292,38 +292,53 @@ void Utilities::shrinkHull(PointCloudMono::Ptr cloud,
292292
bool Utilities::isInHull(PointCloudMono::Ptr hull, pcl::PointXY p_in,
293293
pcl::PointXY &offset, pcl::PointXY &p_closest)
294294
{
295-
float x_temp = 1.0;
296-
float y_temp = 1.0;
297295
float dis_temp = 30.0;
298296

297+
// Step 1: get the nearest 2 points of p_in on hull
299298
size_t i = 0;
299+
pcl::PointXY p_n1;
300+
pcl::PointXY p_n2;
300301
for (PointCloudMono::const_iterator pit = hull->begin();
301302
pit != hull->end(); ++pit) {
302303
float delta_x = pit->x - p_in.x;
303-
x_temp *= delta_x;
304304
float delta_y = pit->y - p_in.y;
305-
y_temp *= delta_y;
305+
float distance = sqrt(pow(delta_x, 2) + pow(delta_y, 2));
306306

307-
// Use Manhattan distance
308-
float dis = fabs(delta_x) + fabs(delta_y);
309-
if (dis < dis_temp) {
310-
offset.x = delta_x;
311-
offset.y = delta_y;
312-
p_closest.x = pit->x;
313-
p_closest.y = pit->y;
314-
dis_temp = dis;
307+
if (distance < dis_temp) {
308+
p_n2.x = p_n1.x;
309+
p_n2.y = p_n1.y;
310+
p_n1.x = pit->x;
311+
p_n1.y = pit->y;
312+
dis_temp = distance;
315313
}
316314
++i;
317315
}
318-
if (x_temp <= 0 && y_temp <= 0) {
319-
// The p_in is surrounded by hull
316+
317+
// Step 2: form the line segment (pn1, pn2) and (p_in, p_c)
318+
// p_c is the center of the hull, judge if the 2 line segment
319+
// cross each other, if true, the p_in is not in hull
320+
pcl::PointXYZ minPt, maxPt;
321+
pcl::getMinMax3D(*hull, minPt, maxPt);
322+
pcl::PointXY p_c;
323+
p_c.x = (minPt.x + maxPt.x)/2;
324+
p_c.y = (minPt.y + maxPt.y)/2;
325+
bool cross = isIntersect(p_n1, p_n2, p_in, p_c);
326+
327+
if (cross) {
328+
// The p_in is not in hull
329+
// Here we use a less accurate but simple way
330+
// to calculate the closest point on hull of p_in
331+
getClosestPoint(p_n1, p_n2, p_in, p_closest);
332+
333+
offset.x = p_closest.x - p_in.x;
334+
offset.y = p_closest.y - p_in.y;
335+
return false;
336+
}
337+
else {
320338
offset.x = 0;
321339
offset.y = 0;
322340
return true;
323341
}
324-
else {
325-
return false;
326-
}
327342
}
328343

329344
bool Utilities::tryExpandROI(int &minx, int &miny, int &maxx, int &maxy,
@@ -341,3 +356,63 @@ bool Utilities::tryExpandROI(int &minx, int &miny, int &maxx, int &maxy,
341356
if (miny < 0) miny = 0;
342357
if (maxy > height) maxy = height - 1;
343358
}
359+
360+
float Utilities::determinant(float v1, float v2, float v3, float v4)
361+
{
362+
return (v1 * v3 - v2 * v4);
363+
}
364+
365+
bool Utilities::isIntersect(pcl::PointXY p1, pcl::PointXY p2,
366+
pcl::PointXY p3, pcl::PointXY p4)
367+
{
368+
float delta = determinant(p2.x-p1.x, p3.x-p4.x, p2.y-p1.y, p3.y-p4.y);
369+
if ( delta<=(1e-6) && delta>=-(1e-6) ) {
370+
return false;
371+
}
372+
float lameda = determinant(p3.x-p1.x, p3.x-p4.x, p3.y-p1.y, p3.y-p4.y) / delta;
373+
if ( lameda > 1 || lameda < 0 ) {
374+
return false;
375+
}
376+
float miu = determinant(p2.x-p1.x, p3.x-p1.x, p2.y-p1.y, p3.y-p1.y) / delta;
377+
if ( miu > 1 || miu < 0 ) {
378+
return false;
379+
}
380+
return true;
381+
}
382+
383+
void Utilities::getClosestPoint(pcl::PointXY p1, pcl::PointXY p2,
384+
pcl::PointXY p, pcl::PointXY &pc)
385+
{
386+
float A = p1.x - p2.x;
387+
float B = p1.y - p2.y;
388+
389+
if (A == 0) {
390+
pc.x = p1.x;
391+
pc.y = p.y;
392+
return;
393+
}
394+
if (B == 0) {
395+
pc.x = p.x;
396+
pc.y = p1.y;
397+
return;
398+
}
399+
400+
pc.x = (A*(A*p.x + B*p.y)/B - A*p1.y + B*p1.x)/(B + A*A/B);
401+
pc.y = B*(pc.x - p1.x)/A + p1.y;
402+
}
403+
404+
float Utilities::pointToSegDist(float x, float y, float x1, float y1, float x2, float y2)
405+
{
406+
float cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
407+
if (cross <= 0)
408+
return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
409+
410+
float d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
411+
if (cross >= d2)
412+
return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
413+
414+
float r = cross / d2;
415+
float px = x1 + (x2 - x1) * r;
416+
float py = y1 + (y2 - y1) * r;
417+
return sqrt((x - px) * (x - px) + (py - y) * (py - y));
418+
}

drv_grasp/src/utilities.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class Utilities
7878
vector<pcl::PointIndices> &cluster_indices,
7979
float th_cluster, int minsize, int maxsize);
8080

81-
static void cutCloud(pcl::ModelCoefficients::Ptr coeff_in, double th_distance,
81+
static void cutCloud(pcl::ModelCoefficients::Ptr coeff_in, float th_distance,
8282
PointCloudRGBN::Ptr cloud_in,
8383
PointCloudMono::Ptr &cloud_out);
8484

@@ -139,6 +139,25 @@ class Utilities
139139
static bool tryExpandROI(int &minx, int &miny, int &maxx, int &maxy, int pad,
140140
int width = 640, int height = 480);
141141

142+
static float pointToSegDist(float x, float y, float x1, float y1, float x2, float y2);
143+
144+
/**
145+
* @brief getClosestPoint
146+
* Given line segment (p1,p2) and point p, get the closest point p_c of p on (p1,p2)
147+
* with accuracy acc
148+
* @param p1
149+
* @param p2
150+
* @param p
151+
* @param p_c
152+
* @param acc
153+
*/
154+
static void getClosestPoint(pcl::PointXY p1, pcl::PointXY p2,
155+
pcl::PointXY p, pcl::PointXY &pc);
156+
157+
private:
158+
static float determinant(float v1, float v2, float v3, float v4);
159+
160+
static bool isIntersect(pcl::PointXY p1, pcl::PointXY p2, pcl::PointXY p3, pcl::PointXY p4);
142161
};
143162

144163
#endif // UTILITIES_H

0 commit comments

Comments
 (0)