octomap使用及与PCL中pointcloud之间的相互转换处理

目录

一、octomap安装及基本介绍;

二、octomap与OccupancyGrid,OccupancyMap;

三、octomap与pointcloud类型相互转换;


一、octomap安装及基本介绍;

  octomap是专门开发用于三维导航的栅格地图格式,其采用了八叉树数据结构。其可以用来做三维空间中的导航、避障,也可以用来实现3D激光SLAM中的动态障碍物消除,动态地图更新等操作,是一个比较实用的功能包。

具体的可以参考高博写的一篇博客:

https://www.cnblogs.com/gaoxiang12/p/5041142.html

octomap官网:

https://octomap.github.io/

octomap源码安装:

1.编译octomap

如果没有git请安装git:
sudo apt-get install git

sudo git clone https://github.com/OctoMap/octomap

git会把代码拷贝到当前目录/octomap下。进入该目录,进行安装:

mkdir build
cd build
sudo cmake ..
sudo make

octomap_server 安装:octomap_server是ROS中的一个基于octomap的功能包。

sudo apt-get install ros-kinetic-octomap-ros #安装octomap-ros
sudo apt-get install ros-kinetic-octomap-msgs
sudo apt-get install ros-kinetic-octomap-server
 
安装octomap 在 rviz 中的插件
sudo apt-get install ros-kinetic-octomap-rviz-plugins

安装成功后,打卡rviz:

二、octomap中OccupancyGrid, OccupancyMap ;

在octomap中提供了很多转换函数可以使用:

1、ROS中提供了关于octomap的转换接口:

pcl::toROSMsg(*current_pointcloud, filtered_points);
sensor_msgs::PointCloud2 filtered_points;
octomap::Pointcloud octo_cloud;  
octomap::pointCloud2ToOctomap(filtered_points, octo_cloud);

2、octomap中转为二维栅格地图OccupancyMap ;

//octomap二维占据栅格地图;
ros::Publisher _octomap_pub;
_octomap_pub = node.advertise<octomap_msgs::Octomap>("/octomap", 5);
if(_octomap_pub.getNumSubscribers() != 0){
    octomap_msgs::Octomap octomap_msg;
    octomap::OcTree *octo_map_all;
    octomap_msgs::binaryMapToMsg(*octo_map_all, octomap_msg);
    octomap_msg.header.frame_id = "map";
    octomap_msg.header.stamp = stamp_now;
    octomap_msg.id = 1;
    octomap_msg.binary = 1;
    octomap_msg.resolution = octo_map_all->getResolution();
    _octomap_pub.publish(octomap_msg);
//    std::cout << "DistMap:: update distance map. map leaf node size " << octo_map_all->getNumLeafNodes() << std::endl;
}

 

3、octomap中发布三维栅格地图OccupancyGrid ;

//三维栅格地图;
ros::Publisher _octomap3D_pub;
_octomap3D_pub = node.advertise<octomap_msgs::Octomap>("/octo3Dmap", 5);
if(_octomap3D_pub.getNumSubscribers() != 0){
  octomap::OcTree *octo_map_all;
  octomap_msgs::Octomap octomap_fullmsg;
  octomap_msgs::fullMapToMsg(*octo_map_all, octomap_fullmsg);
  octomap_fullmsg.header.frame_id = "map";
  octomap_fullmsg.header.stamp = stamp_now;
  _octomap3D_pub.publish(octomap_fullmsg);
}

三、octomap 与 pointcloud 类型相互转换;

1、octomap转pcd;

pcl::PointCloud<pcl::PointXYZI>::Ptr occupied_nodes(new pcl::PointCloud<pcl::PointXYZI>());

for(octomap::OcTree::leaf_iterator it = _map_ptr->begin_leafs(), end = _map_ptr->end_leafs();it != end; ++it){
    pcl::PointXYZI cube_center;
    cube_center.x = it.getX();
    cube_center.y = it.getY();
    cube_center.z = it.getZ();
    cube_center.intensity = it.getDepth();

    if(_map_ptr->isNodeOccupied(*it)){
      occupied_nodes->points.push_back(cube_center);
    }
  }
  occupied_nodes->header.frame_id = "map";
  mapUpdate_pub.publish(occupied_nodes);

2、pcd转octomap;

void pcd2octomap(const pcl::PointCloud<pcl::PointXYZI>::Ptr cloud,octomap::OcTree* tree)
{
    //cout<<"convert pcl pointcloud to octomap, point size = " << cloud->points.size() <<endl;
    for (auto p : cloud->points){
     // 将点云里的点插入到octomap中
        tree->updateNode( octomap::point3d(p.x, p.y, p.z), float(20.0));
    }
    // 更新octomap
    tree->updateInnerOccupancy();
}

int main()
{
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filter(new pcl::PointCloud<pcl::PointXYZI>());
    octo_map_all = new octomap::OcTree(_octree_resolution);
    pcd2octomap(cloud_filter, octo_map_all);
}

推荐一个可以用来学习octomap基础使用的github代码包,里面有很多基础操作:

https://github.com/dan-riley/octomap_merger

  • 9
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
您好!将一个点云(PointCloud)转换为另一个点云(PointCloud)可以通过以下步骤实现: 1. 创建一个空的目标点云对象,具有与源点云相同的属性,例如坐标、颜色和法线等。 2. 遍历源点云的每个点,将其属性复制到目标点云对应的点上。 下面是一个简单的示例代码,使用PCL库来完成这个转换: ```cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/point_cloud.h> int main() { // 读取源点云 pcl::PointCloud<pcl::PointXYZRGB>::Ptr source_cloud(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::io::loadPCDFile<pcl::PointXYZRGB>("source_cloud.pcd", *source_cloud); // 创建目标点云 pcl::PointCloud<pcl::PointXYZRGB>::Ptr target_cloud(new pcl::PointCloud<pcl::PointXYZRGB>); target_cloud->width = source_cloud->width; target_cloud->height = source_cloud->height; target_cloud->is_dense = source_cloud->is_dense; target_cloud->points.resize(source_cloud->points.size()); // 复制属性 for (size_t i = 0; i < source_cloud->points.size(); ++i) { target_cloud->points[i].x = source_cloud->points[i].x; target_cloud->points[i].y = source_cloud->points[i].y; target_cloud->points[i].z = source_cloud->points[i].z; target_cloud->points[i].r = source_cloud->points[i].r; target_cloud->points[i].g = source_cloud->points[i].g; target_cloud->points[i].b = source_cloud->points[i].b; } // 保存目标点云 pcl::io::savePCDFile<pcl::PointXYZRGB>("target_cloud.pcd", *target_cloud); return 0; } ``` 在上述示例,我们假设源点云的类型为pcl::PointXYZRGB,您可以根据实际情况更改点云类型。请确保已经安装了PCL库,并将源点云保存为名为"source_cloud.pcd"的PCD文件。转换后的目标点云将保存为名为"target_cloud.pcd"的PCD文件。 希望这个示例能帮到您!如有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值