Octomap的使用

下载编译安装见之前博客:编程开发常用的第三方库安装

安装octomap_ros(cmake+make+install)

git clone https://github.com/OctoMap/octomap_ros

安装genmsg(cmake+make+install) ( octomap_msgs的依赖项)

git clone https://github.com/ros/genmsg 

安装octomap_msgs(cmake+make+install)

git clone https://github.com/OctoMap/octomap_msgs

相关头文件:

#include <octomap/octomap.h>
#include <octomap/ColorOcTree.h>
#include <octomap/math/Pose6D.h> // 可以用octomath::Pose6D来存储位姿

常用接口:

// 创建不带颜色的八叉树对象,参数为分辨率,
octomap::OcTree tree(0.05); // 5cm x 5cm x 5cm
// 创建带颜色的八叉树对象
octomap::ColorOcTree tree(0.05);

// 清空octomap
tree.clear()

// 将点插入到octomap中
tree.updateNode(octomap::point3d(x, y, z), true); // true为occupy, false为free
// 射线的形式,只有末端才存在被占据的点,中途的点则是没被占据的
octomap::Pointcloud cloud_octo;
for (auto p:temp->points)
    cloud_octo.push_back(p.x, p.y, p.z);
tree.insertPointCloud(cloud_octo, octomap::point3d(translation_beam_to_world[0], translation_beam_to_world[1],translation_beam_to_world[2]));

// 设置颜色
tree.integrateNodeColor( p.x, p.y, p.z, p.r, p.g, p.b );
tree.setNodeColor(x, y, z, R, G, B);

// 更新octomap
tree.updateInnerOccupancy();

// 存储octomap
// octomap存储的文件后缀名是.bt(二进制文件)和.ot(普通文件),带颜色的八叉树要存成.ot文件
tree.writeBinary(output_file);
tree.write(output_file);

先把图像转成pcl的点云,变换后再放到octotree中。这种做法的原因是比较便于处理颜色,因为我希望做出带有颜色的地图。如果你不关心颜色,完全可以不用pcl,直接用octomap自带的octomap::pointcloud来完成这件事。

insertPointCloud会比单纯的插入点更好一些。octomap里的pointcloud是一种射线的形式,只有末端才存在被占据的点,中途的点则是没被占据的。这会使一些重叠地方处理的更好。

CMakeList.txt:

find_package(octomap REQUIRED)
include_directories(${OCTOMAP_INCLUDE_DIRS})

add_executable(main main.cpp)
target_link_libraries(main ${OCTOMAP_LIBRARIES})

转换为ROSmsg:

octomap::ColorOcTree* octomap = new octomap::OcTree(0.05);

//声明advertise,octomap rviz plug in 默认接受topic为octomap_full的message
pub_octomap = n.advertise<octomap_msgs::Octomap>("octomap_full", 1, true);
 
//声明message
Octomap map_msg;
//设置header
map_msg.header.frame_id = "map";
map_msg.header.stamp = ros::Time::now();
//fullMapToMsg负责转换成message
if (octomap_msgs::fullMapToMsg(*octomap, map_msg))
    pub_octomap.publish(map_msg);
else
    ROS_ERROR("Error serializing OctoMap");

在RVIZ中实时显示:

 

octovis可视化.ot和.bt文件

octovis xxx.ot

 

地图障碍占据情况查询:

 

C++例子:

 

参考:

SLAM拾萃(1):octomap

ROS octomap常用函数介绍和实时显示octomap

Octomap使用总结

https://github.com/OctoMap/octomap/blob/devel/octomap/src/simple_example.cpp

### 如何使用 octomap_server #### 安装 octomap_server 要安装 `octomap_server`,可以通过 ROS 的包管理器进行操作。通常情况下,可以运行以下命令来安装官方发布的版本[^2]: ```bash sudo apt-get install ros-$ROS_DISTRO-octomap-server ``` 如果需要从源码编译,则需克隆仓库至工作空间并执行 Catkin 编译流程。具体路径可参考 `/octomap_mapping_ws/src/octomap_mapping/octomap_server/src` 中的内容[^1]。 --- #### 启动 octomap_server 并发布地图 启动 `octomap_server` 需要在 ROS 环境下配置参数文件以及订阅传感器数据(如激光雷达或深度相机的数据流)。以下是基本的启动方式: 1. **创建 launch 文件** 创建一个 `.launch` 文件用于加载必要的参数和节点。例如: ```xml <launch> <!-- 加载参数 --> <param name="frame_id" value="map"/> <param name="resolution" value="0.05"/> <!-- 运行 octomap_server 节点 --> <node pkg="octomap_server" type="octomap_server_node" name="octomap_server"> <remap from="cloud_in" to="/camera/depth/points"/> <param name="sensor_model/max_range" value="5.0"/> </node> <!-- 发布 OctoMap 地图 --> <node pkg="octomap_server" type="octomap_saver" name="octomap_saver" output="screen"> <rosparam command="load" file="$(find your_package)/config/simulation.yaml"/> </node> </launch> ``` 2. **运行 Launch 文件** 执行以下命令以启动 `octomap_server` 和相关依赖项: ```bash roslaunch your_package octomap.launch ``` 3. **验证功能** 构建完成后,可通过 Rviz 查看生成的地图。在 Rviz 中添加显示类型为 `Octomap`,并将主题设置为 `/octomap_binary` 或 `/projected_map` 来观察三维占用栅格地图的效果。 --- #### 核心实现原理 通过阅读 GitHub 上的源码可知,`octomap::OccupancyOcTreeBase` 类负责存储概率占据信息,而 `octomap::OcTreeBase` 则提供了基础的操作接口[^3]。这些类共同实现了八叉树结构的核心逻辑,包括节点分裂、合并及查询等功能。 对于更高级的应用场景,开发者可以直接调用 C++ API 将深度图像转换成 OctoMap 数据结构[^4]。例如,在自定义程序中初始化八叉树对象并更新其状态: ```cpp #include <octomap/octomap.h> #include <pcl_conversions/pcl_conversions.h> void processPointCloud(const sensor_msgs::PointCloud2ConstPtr& cloud_msg) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::fromROSMsg(*cloud_msg, *cloud); // 初始化八叉树 double resolution = 0.05; octomap::OccTree* tree = new octomap::OccTree(resolution); // 插入点云数据 for (const auto& point : cloud->points) { if (!std::isnan(point.x)) { // 排除无效点 tree->updateNode(octomap::point3d(point.x, point.y, point.z), true); } } // 更新树的状态 tree->updateInnerOccupancy(); } ``` 上述代码展示了如何基于 PCL 库处理点云消息,并将其插入到 OctoMap 结构中的过程。 --- #### 常见问题排查 - 如果无法正常接收点云输入,请确认传感器驱动已正确配置。 - 若地图未按预期渲染,可能是因为分辨率参数不合理或者最大探测距离超出范围所致。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值