47 Eigen::Matrix3Xf axes(3, 15);
49 axes.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
50 axes.block<3, 3>(0, 3) = rightPose.block<3, 3>(0, 0);
53 for (
int i = 0; i < 3; i++)
55 for (
int j = 0; j < 3; j++)
57 Eigen::Vector3f
a = leftPose.col(i).head<3>();
58 Eigen::Vector3f b = rightPose.col(j).head<3>();
59 int idx = 6 + (i * 3 + j);
60 Eigen::Vector3f
c =
a.cross(b);
63 axes.col(idx) = Eigen::Vector3f::Zero();
67 axes.col(idx) =
c /
c.norm();
72 for (
int i = 0; i < 15; i++)
77 Eigen::Vector3f axis = axes.col(i);
84 for (
int j = 0; j < 3; j++)
86 Eigen::Vector3f
a = leftPose.col(j).head<3>();
87 Eigen::Vector3f b = rightPose.col(j).head<3>();
89 ra += fabs(axis.dot(
a) * leftExtent(j));
90 rb += fabs(axis.dot(b) * rightExtent(j));
93 Eigen::Vector3f t = projectVector(axis, leftPose.col(3).head<3>());
94 t = t - projectVector(axis, rightPose.col(3).head<3>());
96 if (t.norm() > (ra + rb))
105 Eigen::Vector3f PrimitiveFusion::projectVector(Eigen::Vector3f axis, Eigen::Vector3f u)
107 float v = u.dot(axis) / axis.squaredNorm();
113 void PrimitiveFusion::getIntersectingPrimitives(memoryx::EnvironmentalPrimitiveBaseList& primitives, memoryx::EnvironmentalPrimitiveBasePtr primitive, memoryx::EnvironmentalPrimitiveBaseList& intersectingPrimitives,
float eps)
115 Eigen::Matrix4f leftPose = FramedPosePtr::dynamicCast(primitive->getPose())->toEigen();
116 Eigen::Vector3f leftExtent = Vector3Ptr::dynamicCast(primitive->getOBBDimensions())->toEigen() / 2.0 + eps * Eigen::Vector3f::Ones();
118 for (memoryx::EnvironmentalPrimitiveBasePtr& p : primitives)
120 Eigen::Matrix4f rightPose = FramedPosePtr::dynamicCast(p->getPose())->toEigen();
121 Eigen::Vector3f rightExtent = Vector3Ptr::dynamicCast(p->getOBBDimensions())->toEigen() / 2.0 + eps * Eigen::Vector3f::Ones();
123 if (primitive->ice_staticId() != p->ice_staticId())
127 if (primitive->getId() == p->getId())
133 intersectingPrimitives.push_back(p);
141 memoryx::EnvironmentalPrimitiveBaseList candidates;
145 for (memoryx::EnvironmentalPrimitiveBasePtr p : candidates)
147 if (testPlane(p, primitive))
149 intersectingPrimitives.push_back(p);
152 else if (testCylinder(p, primitive))
154 intersectingPrimitives.push_back(p);
163 bool PrimitiveFusion::testCylinder(memoryx::EnvironmentalPrimitiveBasePtr leftPrimitive, memoryx::EnvironmentalPrimitiveBasePtr rightPrimitive)
168 if (!leftCylinder || !rightCylinder)
173 Eigen::Vector3f leftAxisDirection = Vector3Ptr::dynamicCast(leftCylinder->getCylinderAxisDirection())->toEigen();
174 Eigen::Vector3f rightAxisDirection = Vector3Ptr::dynamicCast(rightCylinder->getCylinderAxisDirection())->toEigen();
176 float r = leftAxisDirection.dot(rightAxisDirection);
178 if (std::acos(r) > pcl::deg2rad(15.0))
192 Eigen::Matrix4f leftPose = FramedPosePtr::dynamicCast(leftCylinder->getPose())->toEigen();
193 Eigen::Vector3f leftExtent = Eigen::Vector3f(leftCylinder->getLength() / 2.0, leftCylinder->getCylinderRadius(), leftCylinder->getCylinderRadius());
196 Eigen::Matrix4f rightPose = FramedPosePtr::dynamicCast(rightCylinder->getPose())->toEigen();
197 Eigen::Vector3f rightExtent = Eigen::Vector3f(rightCylinder->getLength() / 2.0, rightCylinder->getCylinderRadius(), rightCylinder->getCylinderRadius());
208 bool PrimitiveFusion::testPlane(memoryx::EnvironmentalPrimitiveBasePtr leftPrimitive, memoryx::EnvironmentalPrimitiveBasePtr rightPrimitive)
213 if (!leftPlane || !rightPlane)
218 Eigen::Vector3f leftPlaneNormal = Vector3Ptr::dynamicCast(leftPlane->getPlaneNormal())->toEigen();
219 Eigen::Vector3f rightPlaneNormal = Vector3Ptr::dynamicCast(rightPlane->getPlaneNormal())->toEigen();
221 if ((leftPlaneNormal - rightPlaneNormal).
norm() < 0.001)
226 float alpha = std::acos(leftPlaneNormal.dot(rightPlaneNormal));
228 if (alpha > pcl::deg2rad(10.0))
240 if (leftPrimitive->ice_staticId() != rightPrimitive->ice_staticId())
245 Eigen::Vector3f leftOBB = Vector3Ptr::dynamicCast(leftPrimitive->getOBBDimensions())->toEigen();
246 Eigen::Vector3f rightOBB = Vector3Ptr::dynamicCast(rightPrimitive->getOBBDimensions())->toEigen();
248 if ((leftOBB - rightOBB).
norm() > 10.0)
253 Eigen::Vector3f leftPosition = Vector3Ptr::dynamicCast(leftPrimitive->getPose()->position)->toEigen();
254 Eigen::Vector3f rightPosition = Vector3Ptr::dynamicCast(rightPrimitive->getPose()->position)->toEigen();
256 if ((leftPosition - rightPosition).
norm() > 5.0)
261 Eigen::Matrix3f leftRotation = QuaternionPtr::dynamicCast(leftPrimitive->getPose()->orientation)->toEigen();
262 Eigen::Matrix3f rightRotation = QuaternionPtr::dynamicCast(rightPrimitive->getPose()->orientation)->toEigen();
264 Eigen::Vector3f ea = (leftRotation.transpose() * rightRotation).eulerAngles(0, 1, 2);
267 float delta = pcl::deg2rad(15.0);
268 for (
int i = 0; i < 3; i++)
270 ea[i] = std::fabs(ea[i]);
271 ea[i] = std::fmod(ea[i],
M_PI);
272 if (ea[i] > delta && ea[i] < (
M_PI - delta))
283 void PrimitiveFusion::findBoxPrimitives(memoryx::EnvironmentalPrimitiveBaseList& primitives, std::vector<memoryx::EntityBasePtr>& boxes, memoryx::EnvironmentalPrimitiveSegmentBasePrx environmentalPrimitiveSegment)
285 for (memoryx::EnvironmentalPrimitiveBasePtr& currentPrimitive : primitives)
293 Eigen::Vector3f planeNormal = Vector3Ptr::dynamicCast(plane->getPlaneNormal())->toEigen();
294 float alpha = std::acos(planeNormal.dot(Eigen::Vector3f::UnitZ()));
295 if (alpha < pcl::deg2rad(15.0))
297 std::vector<memoryx::PlanePrimitivePtr> boxSides;
298 boxSides.push_back(plane);
300 std::vector<memoryx::EnvironmentalPrimitiveBasePtr> intersectingPrimitives;
303 for (memoryx::EnvironmentalPrimitiveBasePtr& i : intersectingPrimitives)
310 else if (plane->getPose()->position->z < sideCandidate->getPose()->position->z)
315 bool isPerpendicular =
true;
318 Eigen::Vector3f sideNormal = Vector3Ptr::dynamicCast(sideCandidate->getPlaneNormal())->toEigen();
319 Eigen::Vector3f otherNormal = Vector3Ptr::dynamicCast(side->getPlaneNormal())->toEigen();
321 float beta = std::acos(sideNormal.dot(otherNormal));
325 ARMARX_LOG_S <<
"found a parallel side. doing nothing at the moment";
327 isPerpendicular =
false;
330 else if (std::fabs(beta - M_PI_2) > pcl::deg2rad(5.0))
332 isPerpendicular =
false;
338 boxSides.push_back(sideCandidate);
342 if (boxSides.size() == 3)
344 memoryx::EntityRefList entityRefList;
345 memoryx::PointList graspPoints;
346 std::vector<Eigen::Vector3f> normals;
347 std::vector<Eigen::Vector3f> positions;
348 for (
size_t i = 0; i < 3; i++)
351 normals.push_back(Vector3Ptr::dynamicCast(side->getPlaneNormal())->toEigen());
352 positions.push_back(Vector3Ptr::dynamicCast(side->getPose()->position)->toEigen());
354 memoryx::EntityRefBasePtr entityRef = environmentalPrimitiveSegment->getEntityRefById(side->getId());
355 entityRefList.push_back(entityRef);
357 for (armarx::Vector3BasePtr& g : side->getGraspPoints())
359 graspPoints.push_back(g);
365 rot.col(0) = normals[0];
366 rot.col(1) = normals[1];
367 rot.col(2) = normals[0].cross(normals[1]);
369 Eigen::Vector3f position = positions[0];
370 position(2) = positions[1](2);
374 Eigen::Vector3f dimE;
375 dimE(0) = normals[0].dot(positions[0] - position);
376 dimE(1) = normals[1].dot(positions[1] - position);
377 dimE(2) = normals[2].dot(positions[2] - position);
378 dimE = 2.0 * dimE.cwiseAbs();
381 boxPrimitive->setBoxSides(entityRefList);
382 boxPrimitive->setGraspPoints(graspPoints);
383 boxPrimitive->setLabel(0);
384 boxPrimitive->setOBBDimensions(
new Vector3(dimE));
385 boxPrimitive->setPose(pose);
387 boxPrimitive->setProbability(1.0);
393 boxPrimitive->setTime(boxSides[0]->getTime());
394 boxPrimitive->setName(
"box");
396 boxes.push_back(boxPrimitive);
398 bool mirrorSides =
true;
401 for (
size_t i = 1; i < 3; i++)
404 Eigen::Matrix4f p = FramedPosePtr::dynamicCast(side->getPose())->toEigen();
405 Eigen::Vector3f m = p.block<3, 3>(0, 0).
transpose() * normals[i];
407 Eigen::Vector3f mPosition = position - normals[i] * dimE(2);
410 memoryx::PointList graspPoints;
411 for (armarx::Vector3BasePtr& g : side->getGraspPoints())
414 point.head<3>() = Vector3Ptr::dynamicCast(g)->toEigen();
416 point = p.inverse() * point;
417 point.head<3>() = point.head<3>() - m * dimE(i);
420 Eigen::Vector3f temp = point.head<3>();
421 graspPoints.push_back(
new Vector3(temp));
426 mSide->setOBBDimensions(side->getOBBDimensions());
427 mSide->setGraspPoints(graspPoints);
428 mSide->setPose(mPose);
430 mSide->setPlaneNormal(side->getPlaneNormal());
432 mSide->setTime(side->getTime());
433 mSide->setProbability(0.0);
435 boxes.push_back(mSide);