效果:

 一,需求

基于osg 和fcl实现碰撞仿真。

前期使用osg 结合bullet 实现,但是项目中涉及到点云的碰撞,没有找到bullet如何实现点云的碰撞,因此放弃了bullet。而FCL对点云的碰撞支持很好,所以果断选择FCL。

二,实现

FCL碰撞检测流程与bullet基本相似,构造集合体,设置位姿矩阵,我们以box为例。

(1),构造几何体

void FCLManager::addBox(const std::string& name,float w, float d, float h)
{auto box_geometry = std::make_shared<fcl::Boxf>(w, d, h);auto ob = new fcl::CollisionObjectf(box_geometry);obstacleMap.emplace(name,ob);
}

(2),更新位姿矩阵

void FCLManager::updateTrans(const std::string &name, const fcl::Transform3f &trans)
{fcl::CollisionObjectf *ob=getCollisionObject(name);if(ob){ob->setTransform(trans);}
}//osg 矩阵转fcl矩阵
osg::Vec3 osgTrans = mt.getTrans(); // 获取平移分量
osg::Quat osgQuat = mt.getRotate(); // 获取旋转分量fcl::Quaternionf rotation(osgQuat.w(), osgQuat.x(), osgQuat.y(), osgQuat.z());
fcl::Vector3f translation(osgTrans.x(), osgTrans.y(), osgTrans.z());
fcl::Transform3f fclTrans=fcl::Transform3f::Identity();
fclTrans.translation() = translation;
fclTrans.linear()=rotation.toRotationMatrix();
FCLManager::getInstance()->updateTrans(this->getName(),fclTrans);

(3),检测碰撞

这里把机器人关节放到一个集合中,把其它障碍物放到另一个集合中


bool FCLManager::detectCollision()
{fcl::CollisionRequestf request;fcl::CollisionResultf result;for(auto &ob1:jointMap){for(auto &ob2:obstacleMap){collide(ob1.second, ob2.second, request, result);if(result.isCollision()){return true;}}}return false;
}

三,更简单的方法

FCL支持三角面的碰撞检测,因此可以将所有OSG  的node转为三角面 进行检测。

void FCLManager::addTriMesh(const std::string &name, osg::Node *node)
{fcl::CollisionObjectf *obj = createNodeCollisionObject(node);obstacleMap.emplace(name,obj);
}fcl::CollisionObjectf *FCLManager::createNodeCollisionObject(osg::Node *node)
{MyComputeTriMeshVisitor visitor;node->accept( visitor );osg::Vec3Array* vertices = visitor.getTriMesh();typedef fcl::BVHModel<fcl::OBBRSSf> Model;Model* model = new Model();std::shared_ptr<fcl::CollisionGeometryf> m1_ptr(model);model->beginModel();osg::Vec3 p1, p2, p3;for( size_t i = 0; i + 2 < vertices->size(); i += 3 ){p1 = vertices->at( i );p2 = vertices->at( i + 1 );p3 = vertices->at( i + 2 );fcl::Vector3<float> pp1{p1.x(),p1.y(),p1.z()};fcl::Vector3<float> pp2{p2.x(),p2.y(),p2.z()};fcl::Vector3<float> pp3{p3.x(),p3.y(),p3.z()};model->addTriangle(pp1, pp2, pp3);}model->endModel();model->computeLocalAABB();return new  fcl::CollisionObjectf(m1_ptr);
}

四,点云的碰撞

点云的碰撞 使用了一种叫做八叉树的算法。

首先将点云转成pcl的点云 格式,然后可以直接构造出fcl实体

fcl::CollisionObjectf* FCLManager::createPointCloudCollisionObject(const pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud_ptr, const octomap::point3d &origin_3d)
{// octomap octree settingsconst double resolution = 0.01;const double prob_hit = 0.9;const double prob_miss = 0.1;const double clamping_thres_min = 0.12;const double clamping_thres_max = 0.98;std::shared_ptr<octomap::OcTree> octomap_octree = std::make_shared<octomap::OcTree>(resolution);octomap_octree->setProbHit(prob_hit);octomap_octree->setProbMiss(prob_miss);octomap_octree->setClampingThresMin(clamping_thres_min);octomap_octree->setClampingThresMax(clamping_thres_max);octomap::KeySet free_cells;octomap::KeySet occupied_cells;#if defined(_OPENMP)
#pragma omp parallel
#endif{
#if defined(_OPENMP)auto thread_id = omp_get_thread_num();auto thread_num = omp_get_num_threads();
#elseint thread_id = 0;int thread_num = 1;
#endifint start_idx = static_cast<int>(pointcloud_ptr->size() / thread_num) * thread_id;int end_idx = static_cast<int>(pointcloud_ptr->size() / thread_num) * (thread_id + 1);if (thread_id == thread_num - 1){end_idx = pointcloud_ptr->size();}octomap::KeySet local_free_cells;octomap::KeySet local_occupied_cells;for (auto i = start_idx; i < end_idx; i++){octomap::point3d point((*pointcloud_ptr)[i].x, (*pointcloud_ptr)[i].y, (*pointcloud_ptr)[i].z);octomap::KeyRay key_ray;if (octomap_octree->computeRayKeys(origin_3d, point, key_ray)){local_free_cells.insert(key_ray.begin(), key_ray.end());}octomap::OcTreeKey tree_key;if (octomap_octree->coordToKeyChecked(point, tree_key)){local_occupied_cells.insert(tree_key);}}#if defined(_OPENMP)
#pragma omp critical
#endif{free_cells.insert(local_free_cells.begin(), local_free_cells.end());occupied_cells.insert(local_occupied_cells.begin(), local_occupied_cells.end());}}// free cells only if not occupied in this cloudfor (auto it = free_cells.begin(); it != free_cells.end(); ++it){if (occupied_cells.find(*it) == occupied_cells.end()){octomap_octree->updateNode(*it, false);}}// occupied cellsfor (auto it = occupied_cells.begin(); it != occupied_cells.end(); ++it){octomap_octree->updateNode(*it, true);}auto fcl_octree = std::make_shared<fcl::OcTree<float>>(octomap_octree);std::shared_ptr<fcl::CollisionGeometryf> fcl_geometry = fcl_octree;return new fcl::CollisionObjectf(fcl_geometry);
}

参考:

Flexible Collision Library(FCL)简介及使用流程_yht9306的博客-CSDN博客_fcl碰撞检测

GitHub - mccdo/osgbullet: Bullet physics and OpenSceneGraph integration

GitHub - flexible-collision-library/fcl: Flexible Collision Library

基于OSG 和FCL 的碰撞仿真相关推荐

  1. 基于锁相环的调制解调仿真实现

    基于锁相环的调制解调仿真实现 论文+代码+实验结果下载地址:下载地址 摘要 随着现代集成电路技术的发展,锁相环已经成为集成电路设计中非常重要的一个部分,所以对锁相环的研究具有积极的现实意义.锁相环电路 ...

  2. 计算机联锁仿真软件设计,一种基于LabVIEW的计算机联锁仿真系统的制作方法

    本发明涉及一种计算机联锁仿真系统,尤其是涉及一种基于labview的计算机联锁仿真系统. 背景技术: 计算机联锁系统的仿真系统,通常是采用c/c++等传统的编程语言实现,一方面该方式需要专业的程序员去 ...

  3. 基于FPGA实现PCIE IP功能仿真

    基于FPGA实现PCIE IP功能仿真 1 开发工具 modelsim simulator或vivado simulator,本设计采用modelsim进行仿真. 2 参数配置

  4. matlab频分复用,基于MATLAB的频分复用系统的仿真_.doc

    基于MATLAB的频分复用系统的仿真_ 基于MATLAB的频分复用系统的仿真_毕业论文(设计) Abstract With the development of communication techn ...

  5. matlab故障识别,基于Matlab的电力系统故障分析与仿真(V2.1)最新版

    <基于Matlab的电力系统故障分析与仿真.doc>由会员分享,可免费在线阅读全文,更多与<基于Matlab的电力系统故障分析与仿真(V2.1)>相关文档资源请在帮帮文库(ww ...

  6. matlab非线性系统频域标识,基于MATLAB的最小二乘法系统辨识与仿真

    第 29卷 第 2期 许昌学院学报 Vol. 29. No. 2 2010年 3月 JOURNAL OF XUCHANG UN IVERSITY Mar. 2010 收稿日期: 2008 - 10 - ...

  7. matlab 自激振荡,基于Simulink的非线性系统自激振荡的仿真

    基于Simulink的非线性系统自激振荡的仿真研究 张 聚,杨马英,王万良 (浙江工业大学 信息工程学院 自动化系,浙江杭州310032) 摘 要:针对描述函数法分析非线性系统自激振荡的局限性,提出了 ...

  8. tcsc工作原理matlab仿真,基于Matlab的TCSC建模与仿真研究.doc

    基于Matlab的TCSC建模与仿真研究 基于Matlab的TCSC建模与仿真研究 第17卷第5期 2006年1O月 巾原T学院 JOURNALOFZHONGYUANINSTIT[ITEOFTECHN ...

  9. 【基于MATLAB的火灾疏散模拟仿真】——安全隐患提前发现,疏散方案优化

    [基于MATLAB的火灾疏散模拟仿真]--安全隐患提前发现,疏散方案优化 随着城市化进程的不断加速,人口密度越来越大,特别是在高层建筑中.万一发生火灾,往往会对人的生命和财产造成严重损失.因此,火灾疏 ...

最新文章

  1. MySQL优化篇:索引
  2. Java中的比较总结
  3. 详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名及手工脚本创建oracle数据库...
  4. mysql存储netcdf数据_关于NetCDF与HDF5存储科学数据的观点?
  5. 大型Javascript应用架构的模式(译文)
  6. 安卓期末作品小项目_学在澎雅 | 探索红叶李,闯关我最棒——杭州市澎雅小学二年级期末游园活动...
  7. Android 移动应用开发模拟题
  8. 教师国培计算机计划,教师国培计划大全
  9. windows ghost系统下载
  10. 微信小程序 一键下载所有图片和视频
  11. iOS新闻类App内容页技术探索
  12. 《快速上手ARM体系结构》网易公开课
  13. 纯CSS实现下雪、下雨、落叶效果
  14. 路由器网口1一直闪烁正常吗_网口1一直闪烁上不了网(图文)
  15. (java)判断a是奇数还是偶数
  16. 微分,泰勒公式及其在图像处理中的应用
  17. Springboot中new出来的实例中含有@Autowired注入时的Spring Bean为NULL
  18. warning:suggest parentheses around assignment used as truth value
  19. Matlab生成stm32代码
  20. Vue(三)——过滤器,内置指令,自定义指令,组件

热门文章

  1. 抖音快手最新去水印视频下载教程
  2. VR虚拟现实的工作原理,你知道多少?【转】
  3. mysql创建数据库的五个步骤,mysql创建数据库步骤 创建网上书店数据库
  4. 【python教程入门学习】Python的内存管理机制
  5. 17103 基站建设(优先做)
  6. 基于JAVA学校旧书交易网站计算机毕业设计源码+系统+数据库+lw文档+部署
  7. @RunWith(SpringJUnit4ClassRunner.class)报错
  8. Rust开发——Vec与Struct的使用示例
  9. ElasticSearch在数据量很大的情况下如何提高查询效率
  10. 算法竞赛中的线性代数