Я создаю демо-версию для сбора мусора, и мне нужно проверить столкновение между облаком точек, созданным лазерным сканером, и рабочим органом робота.
Я планирую выполнить эту работу с помощью fcl (гибкая библиотека столкновений) и pcl (библиотека облаков точек). но примеры или учебник fcl очень ограничены. Я прочитал демо в исходном коде fcl на их странице github и написал пример кода, но не могу понять его правильно. следующий код, который я написал:
#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 Когда я запускаю отладчик, он выдает мне сообщение «Исключение по адресу 0x00007FF69C6F87EE в fcl_test.exe: 0xC0000005: место чтения нарушения доступа 0x00000000000000D8.». Проблема в инициализации fcl::detail::initialize(traveral_node, *model1, pose1, *model2, pose2, collision_request, collision_result)
, но я не знаю, как ее решить.
Насколько я знаю, из исходного кода fcl
, MeshCollisionTraversalNode
предполагается использовать для BVHModel
, чей ModelType
равен BVH_MODEL_TRIANGLES
. В вашей программе вы только добавляете все вершины из облака точек в BVHModel
, поэтому его ModelType
равно BVH_MODEL_POINTCLOUD
, что не соответствует требованию MeshCollisionTraversalNode
.
Я думаю, что у вас есть два пути решения проблемы:
Один из них — выполнить триангуляцию в облаке точек (см. http://pointclouds.org/documentation/tutorials/greedy_projection.php) и построить BVHModel
из BVH_MODEL_TRIANGLES
. Вам также может понадобиться использовать выпуклую декомпозицию перед обнаружением столкновений, если модель сетки, созданная из pcl
, является вогнутой.
Другой способ — использовать октодерево в качестве представления облака точек. Вы можете обратиться к ответ для получения дополнительной информации.
Спасибо! Решил мою проблему с помощью октодерева.
До какого момента он доходит до segfaulting? Что вы обнаружили, пройдясь по программе с помощью отладчика?