【问题标题】:How to do collision detection between two point clouds or a point cloud and a robot end effector model using flexible collision library?如何使用灵活的碰撞库在两个点云或点云与机器人末端执行器模型之间进行碰撞检测?
【发布时间】:2021-02-07 04:43:15
【问题描述】:

我正在构建一个 bin-picking 演示,我需要在激光扫描仪生成的点云和机器人的末端执行器之间进行碰撞检查。

我打算用 fcl(灵活碰撞库)和 pcl(点云库)来完成这项工作。但是 fcl 的示例或教程非常有限。我在他们的 github 页面中阅读了 fcl 源代码中的演示,并编写了一个代码示例,但我无法正确理解。以下是我写的代码:

#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <fcl/geometry/bvh/BVH_model.h>
#include <fcl/narrowphase/collision.h>

int main(int argc, char **argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr obj1_cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::PointCloud<pcl::PointXYZ>::Ptr obj2_cloud(new pcl::PointCloud<pcl::PointXYZ>());

    pcl::PLYReader ply_reader;
    ply_reader.read(argv[1], *obj1_cloud);
    ply_reader.read(argv[2], *obj2_cloud);

    std::shared_ptr<fcl::BVHModel<fcl::AABB<double>>> model1(new fcl::BVHModel<fcl::AABB<double>>);
    std::shared_ptr<fcl::BVHModel<fcl::AABB<double>>> model2(new fcl::BVHModel<fcl::AABB<double>>);

    model1->beginModel();
    for (int i = 0; i < obj1_cloud->points.size(); i++)
    {
        fcl::Vector3d point;
        point(0) = obj1_cloud->points[i].x;
        point(1) = obj1_cloud->points[i].y;
        point(2) = obj1_cloud->points[i].z;
        model1->addVertex(point);
    }
    model1->endModel();
    model1->computeLocalAABB();

    model2->beginModel();
    for (int i = 0; i < obj2_cloud->points.size(); i++)
    {
        fcl::Vector3d point;
        point(0) = obj2_cloud->points[i].x;
        point(1) = obj2_cloud->points[i].y;
        point(2) = obj2_cloud->points[i].z;
        model2->addVertex(point);
    }
    model2->endModel();
    model2->computeLocalAABB();

    fcl::Transform3<double> pose1 = fcl::Transform3<double>::Identity();
    fcl::Transform3<double> pose2 = fcl::Transform3<double>::Identity();

    fcl::CollisionRequest<double> collision_request;
    collision_request.gjk_solver_type = fcl::GJKSolverType::GST_INDEP;

    fcl::CollisionResult<double> collision_result;

    fcl::detail::MeshCollisionTraversalNode<fcl::AABB<double>> traveral_node;

    if (!fcl::detail::initialize(traveral_node, *model1, pose1, *model2, pose2, collision_request, collision_result))
        std::cout << "initialize error" << std::endl;
    fcl::detail::collide(&traveral_node);
}

这段代码可以通过编译,但在运行时总是给我错误。

"初始化错误 分段错误”

谁能帮我把它弄好?感谢您的帮助!

【问题讨论】:

  • 在段错误之前它会达到什么程度?当您使用调试器单步调试程序时,您发现了什么?
  • @MaxLanghof 当我运行调试器时,它会向我抛出一条消息“在 fcl_test.exe 中的 0x00007FF69C6F87EE 处抛出异常:0xC0000005:访问冲突读取位置 0x00000000000000D8。”初始化问题fcl::detail::initialize(traveral_node, *model1, pose1, *model2, pose2, collision_request, collision_result) ,不知道怎么解决。

标签: c++ collision-detection point-cloud-library point-clouds


【解决方案1】:

来自fcl 源代码的AFAIK,MeshCollisionTraversalNode 应该用于BVHModel,其ModelTypeBVH_MODEL_TRIANGLES。在你的程序中,你只是将点云的所有顶点添加到BVHModel,所以它的ModelTypeBVH_MODEL_POINTCLOUD,不符合MeshCollisionTraversalNode的要求。

我认为你有两种方法可以解决这个问题:

一种是对点云进行三角剖分(参考:http://pointclouds.org/documentation/tutorials/greedy_projection.php),构造一个BVHModelBVH_MODEL_TRIANGLES。如果从pcl 生成的网格模型是凹的,您可能还需要在碰撞检测之前使用凸分解。

另一种方式是使用八叉树作为点云的表示。详情可参考the answer

【讨论】:

  • 谢谢!用八叉树方式解决了我的问题。
猜你喜欢
  • 2015-08-24
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多