3535#include < octocostmap/costmap_3d.h>
3636#include < octomap_server/octomap_server.h>
3737#include < boost/foreach.hpp>
38+ #include < pcl_ros/point_cloud.h>
39+ #include < pcl/point_types.h>
3840
3941namespace octocostmap {
4042 Costmap3D::Costmap3D (const std::string &name, tf::TransformListener &tfl):
41- name_ (name), tfl_(tfl), nh_(), priv_nh_(" ~/" + name_), octree_(0.5 ), map_frame_( " map " ) {
43+ name_ (name), map_frame_( " map " ), tfl_(tfl), nh_(), priv_nh_(" ~/" + name_), octree_(0.5 ) {
4244 octomap_sub_ = nh_.subscribe <octomap_server::OctomapBinary>(" octomap" , 1 , boost::bind (&Costmap3D::octomapCallback, this , _1));
45+ collision_volume_pub_ = nh_.advertise <pcl::PointCloud<pcl::PointXYZ> >(" collison_volume_cloud" , 1 );
4346 }
4447
4548 void Costmap3D::octomapCallback (const octomap_server::OctomapBinary::ConstPtr& map) {
@@ -52,45 +55,65 @@ namespace octocostmap {
5255 }
5356
5457 bool Costmap3D::checkRectangularPrismBase (const geometry_msgs::PointStamped &origin, double width, double height, double length, double resolution) {
55- std::vector<geometry_msgs::PointStamped> collision_pts;
56- geometry_msgs::PointStamped temp = origin;
58+ std::vector<tf::Point > collision_pts;
59+ tf::Stamped<tf::Point > temp_origin;
60+ tf::pointStampedMsgToTF (origin, temp_origin);
61+ tf::StampedTransform transform;
5762 double num_pts = width * height * length / (resolution * resolution * resolution);
58- collision_pts.reserve ( (size_t ) (num_pts + 1 ));
59- for (double dx = 0.0 ; dx < length; dx += resolution) {
60- for (double dy = 0.0 ; dy < width; dy += resolution) {
61- for (double dz = 0.0 ; dz < height; dz += resolution) {
62- temp.point .x = origin.point .x + dx;
63- temp.point .y = origin.point .y + dy;
64- temp.point .z = origin.point .z + dz;
65- collision_pts.push_back (temp);
63+ try {
64+ tfl_.lookupTransform (map_frame_, temp_origin.frame_id_ , temp_origin.stamp_ , transform);
65+ tf::Point origin_pt = transform * temp_origin;
66+ tf::Transform rotation_only (transform.getRotation ());
67+ tf::Vector3 x_vec = rotation_only * tf::Vector3 (length,0 ,0 );
68+ tf::Vector3 y_vec = rotation_only * tf::Vector3 (0 ,width,0 );
69+ tf::Vector3 z_vec = rotation_only * tf::Vector3 (0 ,0 ,height);
70+ tf::Point temp;
71+ collision_pts.reserve ( (size_t ) (num_pts + 1 ));
72+ double x_resolution = resolution/length;
73+ double y_resolution = resolution/width;
74+ double z_resolution = resolution/height;
75+ for (double dx = 0.0 ; dx <= 1.0 ; dx += x_resolution) {
76+ for (double dy = 0.0 ; dy <= 1.0 ; dy += y_resolution) {
77+ for (double dz = 0.0 ; dz <= 1.0 ; dz += z_resolution) {
78+ /* temp.setX(temp_origin.x() + dx);
79+ temp.setY(temp_origin.y() + dy);
80+ temp.setZ(temp_origin.z() + dz);
81+ */
82+ temp = origin_pt + dx*x_vec + dy*y_vec + dz*z_vec;
83+ collision_pts.push_back (temp);
84+ }
85+ }
86+ }
87+ if (collision_volume_pub_.getNumSubscribers () > 0 ) {
88+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
89+ cloud_ptr->header .frame_id = map_frame_;
90+ cloud_ptr->header .stamp = temp_origin.stamp_ ;
91+ BOOST_FOREACH ( tf::Point pt, collision_pts) {
92+ cloud_ptr->push_back (pcl::PointXYZ (pt.x (), pt.y (), pt.z ()));
6693 }
94+ collision_volume_pub_.publish (cloud_ptr);
6795 }
96+ return checkCollisionVolume (collision_pts);
97+ } catch (tf::TransformException ex) {
98+ ROS_ERROR (" %s" , ex.what ());
99+ // Err on the side of caution if we can't transform a point
100+ return true ;
68101 }
69- return checkCollisionVolume (collision_pts);
70102 }
71103
72- bool Costmap3D::checkCollisionVolume (const std::vector<geometry_msgs::PointStamped > &collision_volume) {
104+ bool Costmap3D::checkCollisionVolume (const std::vector<tf::Point > &collision_volume) {
73105 uint32_t num_points_checked = 0 ;
74106 bool retval = false ;
75- geometry_msgs::PointStamped temp;
76107 octomap::OcTreeNode *current_cell;
77108 octree_lock_.lock_shared ();
78- BOOST_FOREACH ( geometry_msgs::PointStamped pt, collision_volume) {
79- try {
80- tfl_.transformPoint (map_frame_, pt, temp);
81- current_cell = octree_.search (temp.point .x , temp.point .y , temp.point .z );
82- num_points_checked++;
83- if (current_cell) {
84- if (current_cell->isOccupied ()) {
85- retval = true ;
86- break ;
87- }
109+ BOOST_FOREACH ( tf::Point pt, collision_volume) {
110+ current_cell = octree_.search (pt.x (), pt.y (), pt.z ());
111+ num_points_checked++;
112+ if (current_cell) {
113+ if (current_cell->isOccupied ()) {
114+ retval = true ;
115+ break ;
88116 }
89- } catch (tf::TransformException ex) {
90- ROS_ERROR (" %s" , ex.what ());
91- // Err on the side of caution if we can't transform a point
92- retval = true ;
93- break ;
94117 }
95118 }
96119 octree_lock_.unlock_shared ();
0 commit comments