Program Listing for File octomap_server.hpp
↰ Return to documentation for file (/tmp/ws/src/octomap_mapping/octomap_server/include/octomap_server/octomap_server.hpp
)
// Copyright 2010-2013, A. Hornung, University of Freiburg. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the Willow Garage nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#ifndef OCTOMAP_SERVER__OCTOMAP_SERVER_HPP_
#define OCTOMAP_SERVER__OCTOMAP_SERVER_HPP_
#include <octomap/octomap.h>
#include <octomap/OcTreeKey.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // pcl::SAC_SAMPLE_SIZE is protected since PCL 1.8.0 // NOLINT
#include <pcl/sample_consensus/model_types.h>
#pragma GCC diagnostic pop
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/passthrough.h>
#include "rclcpp/rclcpp.hpp"
#include "visualization_msgs/msg/marker_array.hpp"
#include "nav_msgs/msg/occupancy_grid.hpp"
#include "std_msgs/msg/color_rgba.hpp"
#include "sensor_msgs/msg/point_cloud2.hpp"
#include "std_srvs/srv/empty.hpp"
#include "pcl_conversions/pcl_conversions.h"
#include "pcl_ros/transforms.hpp"
#include "tf2_ros/buffer.h"
#include "tf2_ros/create_timer_ros.h"
#include "tf2_ros/message_filter.h"
#include "tf2_ros/transform_listener.h"
#include "message_filters/subscriber.h"
#include "octomap_msgs/msg/octomap.hpp"
#include "octomap_msgs/srv/get_octomap.hpp"
#include "octomap_msgs/srv/bounding_box_query.hpp"
#include "octomap_msgs/conversions.h"
#include "octomap_ros/conversions.hpp"
// switch color here - easier maintenance, only maintain OctomapServer.
// Two targets are defined in the cmake, octomap_server_color and octomap_server.
// One has this defined, and the other doesn't
// #define COLOR_OCTOMAP_SERVER
#ifdef COLOR_OCTOMAP_SERVER
#include <octomap/ColorOcTree.h>
#endif
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
namespace octomap_server
{
using nav_msgs::msg::MapMetaData;
using nav_msgs::msg::OccupancyGrid;
using octomap_msgs::msg::Octomap;
using sensor_msgs::msg::PointCloud2;
using std_msgs::msg::ColorRGBA;
using visualization_msgs::msg::MarkerArray;
class OctomapServer : public rclcpp::Node
{
public:
#ifdef COLOR_OCTOMAP_SERVER
using PCLPoint = pcl::PointXYZRGB;
using PCLPointCloud = pcl::PointCloud<pcl::PointXYZRGB>;
using OcTreeT = octomap::ColorOcTree;
#else
using PCLPoint = pcl::PointXYZ;
using PCLPointCloud = pcl::PointCloud<pcl::PointXYZ>;
using OcTreeT = octomap::OcTree;
#endif
using OctomapSrv = octomap_msgs::srv::GetOctomap;
using BBoxSrv = octomap_msgs::srv::BoundingBoxQuery;
using ResetSrv = std_srvs::srv::Empty;
explicit OctomapServer(const rclcpp::NodeOptions & node_options);
virtual bool onOctomapBinarySrv(
const std::shared_ptr<OctomapSrv::Request> req,
const std::shared_ptr<OctomapSrv::Response> res);
virtual bool onOctomapFullSrv(
const std::shared_ptr<OctomapSrv::Request> req,
const std::shared_ptr<OctomapSrv::Response> res);
bool clearBBoxSrv(
const std::shared_ptr<BBoxSrv::Request> req,
const std::shared_ptr<BBoxSrv::Response> resp);
bool resetSrv(
const std::shared_ptr<ResetSrv::Request> req,
const std::shared_ptr<ResetSrv::Response> resp);
virtual void insertCloudCallback(const PointCloud2::ConstSharedPtr cloud);
virtual bool openFile(const std::string & filename);
protected:
inline static void updateMinKey(const octomap::OcTreeKey & in, octomap::OcTreeKey & min)
{
for (size_t i = 0; i < 3; ++i) {
min[i] = std::min(in[i], min[i]);
}
}
inline static void updateMaxKey(const octomap::OcTreeKey & in, octomap::OcTreeKey & max)
{
for (size_t i = 0; i < 3; ++i) {
max[i] = std::max(in[i], max[i]);
}
}
inline bool isInUpdateBBX(const OcTreeT::iterator & it) const
{
// 2^(tree_depth-depth) voxels wide:
unsigned voxelWidth = (1 << (max_tree_depth_ - it.getDepth()));
octomap::OcTreeKey key = it.getIndexKey(); // lower corner of voxel
return key[0] + voxelWidth >= update_bbox_min_[0] &&
key[1] + voxelWidth >= update_bbox_min_[1] &&
key[0] <= update_bbox_max_[0] &&
key[1] <= update_bbox_max_[1];
}
OnSetParametersCallbackHandle::SharedPtr set_param_res_;
rcl_interfaces::msg::SetParametersResult onParameter(
const std::vector<rclcpp::Parameter> & parameters);
void publishBinaryOctoMap(const rclcpp::Time & rostime) const;
void publishFullOctoMap(const rclcpp::Time & rostime) const;
virtual void publishAll(const rclcpp::Time & rostime);
virtual void insertScan(
const tf2::Vector3 & sensor_origin, const PCLPointCloud & ground,
const PCLPointCloud & nonground);
void filterGroundPlane(
const PCLPointCloud & pc, PCLPointCloud & ground,
PCLPointCloud & nonground) const;
bool isSpeckleNode(const octomap::OcTreeKey & key) const;
virtual void handlePreNodeTraversal(const rclcpp::Time & rostime);
virtual void handleNode([[maybe_unused]] const OcTreeT::iterator & it) {}
virtual void handleNodeInBBX([[maybe_unused]] const OcTreeT::iterator & it) {}
virtual void handleOccupiedNode(const OcTreeT::iterator & it);
virtual void handleOccupiedNodeInBBX(const OcTreeT::iterator & it);
virtual void handleFreeNode(const OcTreeT::iterator & it);
virtual void handleFreeNodeInBBX(const OcTreeT::iterator & it);
virtual void handlePostNodeTraversal(const rclcpp::Time & rostime);
virtual void update2DMap(const OcTreeT::iterator & it, bool occupied);
inline size_t mapIdx(const int i, const int j) const
{
return gridmap_.info.width * j + i;
}
inline size_t mapIdx(const octomap::OcTreeKey & key) const
{
return mapIdx(
(key[0] - padded_min_key_[0]) / multires_2d_scale_,
(key[1] - padded_min_key_[1]) / multires_2d_scale_);
}
void adjustMapData(OccupancyGrid & map, const MapMetaData & old_map_info) const;
inline bool mapChanged(const MapMetaData & old_map_info, const MapMetaData & new_map_info)
{
return old_map_info.height != new_map_info.height ||
old_map_info.width != new_map_info.width ||
old_map_info.origin.position.x != new_map_info.origin.position.x ||
old_map_info.origin.position.y != new_map_info.origin.position.y;
}
static ColorRGBA heightMapColor(double h);
rclcpp::Publisher<MarkerArray>::SharedPtr marker_pub_;
rclcpp::Publisher<Octomap>::SharedPtr binary_map_pub_;
rclcpp::Publisher<Octomap>::SharedPtr full_map_pub_;
rclcpp::Publisher<PointCloud2>::SharedPtr point_cloud_pub_;
rclcpp::Publisher<OccupancyGrid>::SharedPtr map_pub_;
rclcpp::Publisher<MarkerArray>::SharedPtr fmarker_pub_;
message_filters::Subscriber<PointCloud2> point_cloud_sub_;
std::shared_ptr<tf2_ros::MessageFilter<PointCloud2>> tf_point_cloud_sub_;
rclcpp::Service<OctomapSrv>::SharedPtr octomap_binary_srv_;
rclcpp::Service<OctomapSrv>::SharedPtr octomap_full_srv_;
rclcpp::Service<BBoxSrv>::SharedPtr clear_bbox_srv_;
rclcpp::Service<ResetSrv>::SharedPtr reset_srv_;
std::shared_ptr<tf2_ros::Buffer> tf2_buffer_;
std::shared_ptr<tf2_ros::TransformListener> tf2_listener_;
std::unique_ptr<OcTreeT> octree_;
octomap::KeyRay key_ray_; // temp storage for ray casting
octomap::OcTreeKey update_bbox_min_;
octomap::OcTreeKey update_bbox_max_;
double max_range_;
std::string world_frame_id_; // the map frame
std::string base_frame_id_; // base of the robot for ground plane filtering
bool use_height_map_;
ColorRGBA color_;
ColorRGBA color_free_;
double color_factor_;
bool latched_topics_;
bool publish_free_space_;
double res_;
size_t tree_depth_;
size_t max_tree_depth_;
double point_cloud_min_x_;
double point_cloud_max_x_;
double point_cloud_min_y_;
double point_cloud_max_y_;
double point_cloud_min_z_;
double point_cloud_max_z_;
double occupancy_min_z_;
double occupancy_max_z_;
double min_x_size_;
double min_y_size_;
bool filter_speckles_;
bool filter_ground_plane_;
double ground_filter_distance_;
double ground_filter_angle_;
double ground_filter_plane_distance_;
bool compress_map_;
bool init_config_;
// downprojected 2D map:
bool incremental_2D_projection_;
OccupancyGrid gridmap_;
bool publish_2d_map_;
bool map_origin_changed;
octomap::OcTreeKey padded_min_key_;
unsigned multires_2d_scale_;
bool project_complete_map_;
bool use_colored_map_;
};
} // namespace octomap_server
#endif // OCTOMAP_SERVER__OCTOMAP_SERVER_HPP_