footprint.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2014-2018, the neonavigation authors
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the copyright holder nor the names of its 
00014  *       contributors may be used to endorse or promote products derived from 
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #ifndef COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H
00031 #define COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H
00032 
00033 #include <ros/ros.h>
00034 
00035 #include <geometry_msgs/PolygonStamped.h>
00036 #include <nav_msgs/OccupancyGrid.h>
00037 #include <costmap_cspace_msgs/CSpace3D.h>
00038 #include <costmap_cspace_msgs/CSpace3DUpdate.h>
00039 
00040 #if ROS_DISTRO_indigo
00041 #include <XmlRpcValue.h>
00042 #else
00043 #include <xmlrpcpp/XmlRpcValue.h>
00044 #endif
00045 
00046 #include <costmap_cspace/costmap_3d_layer/base.h>
00047 #include <costmap_cspace/cspace3_cache.h>
00048 #include <costmap_cspace/polygon.h>
00049 
00050 namespace costmap_cspace
00051 {
00052 class Costmap3dLayerFootprint : public Costmap3dLayerBase
00053 {
00054 public:
00055   using Ptr = std::shared_ptr<Costmap3dLayerFootprint>;
00056 
00057 protected:
00058   float footprint_radius_;
00059   geometry_msgs::PolygonStamped footprint_;
00060   float linear_expand_;
00061   float linear_spread_;
00062   Polygon footprint_p_;
00063 
00064   CSpace3Cache cs_template_;
00065   int range_max_;
00066 
00067 public:
00068   Costmap3dLayerFootprint()
00069     : linear_expand_(0.0)
00070     , linear_spread_(0.0)
00071     , range_max_(0)
00072   {
00073   }
00074   void loadConfig(XmlRpc::XmlRpcValue config)
00075   {
00076     setExpansion(
00077         static_cast<double>(config["linear_expand"]),
00078         static_cast<double>(config["linear_spread"]));
00079     setFootprint(costmap_cspace::Polygon(config["footprint"]));
00080   }
00081   void setExpansion(
00082       const float linear_expand,
00083       const float linear_spread)
00084   {
00085     linear_expand_ = linear_expand;
00086     linear_spread_ = linear_spread;
00087 
00088     ROS_ASSERT(linear_expand >= 0.0);
00089     ROS_ASSERT(std::isfinite(linear_expand));
00090     ROS_ASSERT(linear_spread >= 0.0);
00091     ROS_ASSERT(std::isfinite(linear_spread));
00092   }
00093   void setFootprint(const Polygon footprint)
00094   {
00095     footprint_p_ = footprint;
00096     footprint_radius_ = footprint.radius();
00097     footprint_ = footprint.toMsg();
00098   }
00099   Polygon& getFootprint()
00100   {
00101     return footprint_p_;
00102   }
00103   const geometry_msgs::PolygonStamped& getFootprintMsg() const
00104   {
00105     return footprint_;
00106   }
00107   float getFootprintRadius() const
00108   {
00109     return footprint_radius_;
00110   }
00111   int getRangeMax() const
00112   {
00113     return range_max_;
00114   }
00115   const CSpace3Cache& getTemplate() const
00116   {
00117     return cs_template_;
00118   }
00119   void setMapMetaData(const costmap_cspace_msgs::MapMetaData3D& info)
00120   {
00121     ROS_ASSERT(footprint_p_.v.size() > 2);
00122 
00123     range_max_ =
00124         ceilf((footprint_radius_ + linear_expand_ + linear_spread_) / info.linear_resolution);
00125     cs_template_.reset(range_max_, range_max_, info.angle);
00126 
00127     // C-Space template
00128     for (size_t yaw = 0; yaw < info.angle; yaw++)
00129     {
00130       for (int y = -range_max_; y <= range_max_; y++)
00131       {
00132         for (int x = -range_max_; x <= range_max_; x++)
00133         {
00134           auto f = footprint_p_;
00135           f.move(x * info.linear_resolution,
00136                  y * info.linear_resolution,
00137                  yaw * info.angular_resolution);
00138           Vec p;
00139           p[0] = 0;
00140           p[1] = 0;
00141           if (f.inside(p))
00142           {
00143             cs_template_.e(x, y, yaw) = 100;
00144           }
00145           else
00146           {
00147             const float d = f.dist(p);
00148             if (d < linear_expand_)
00149             {
00150               cs_template_.e(x, y, yaw) = 100;
00151             }
00152             else if (d < linear_expand_ + linear_spread_)
00153             {
00154               cs_template_.e(x, y, yaw) = 100 - (d - linear_expand_) * 100 / linear_spread_;
00155             }
00156             else
00157             {
00158               cs_template_.e(x, y, yaw) = 0;
00159             }
00160           }
00161         }
00162       }
00163       if (footprint_radius_ == 0)
00164         cs_template_.e(0, 0, yaw) = 100;
00165     }
00166   }
00167 
00168 protected:
00169   bool updateChain(const bool output)
00170   {
00171     return false;
00172   }
00173   void updateCSpace(
00174       const nav_msgs::OccupancyGrid::ConstPtr& map,
00175       const UpdatedRegion& region)
00176   {
00177     if (root_)
00178       gemerateCSpace(map_, map, region);
00179     else
00180       gemerateCSpace(map_overlay_, map, region);
00181   }
00182   void gemerateCSpace(
00183       CSpace3DMsg::Ptr map,
00184       const nav_msgs::OccupancyGrid::ConstPtr& msg,
00185       const UpdatedRegion& region)
00186   {
00187     ROS_ASSERT(ang_grid_ > 0);
00188     const int ox =
00189         lroundf((msg->info.origin.position.x - map->info.origin.position.x) /
00190                 map->info.linear_resolution);
00191     const int oy =
00192         lroundf((msg->info.origin.position.y - map->info.origin.position.y) /
00193                 map->info.linear_resolution);
00194     // Clear travelable area in OVERWRITE mode
00195     if (overlay_mode_ == OVERWRITE && !root_)
00196     {
00197       for (size_t yaw = 0; yaw < map->info.angle; yaw++)
00198       {
00199         for (unsigned int i = 0; i < msg->data.size(); i++)
00200         {
00201           const auto& val = msg->data[i];
00202           if (val < 0)
00203             continue;
00204 
00205           const int x =
00206               lroundf((i % msg->info.width) * msg->info.resolution / map->info.linear_resolution);
00207           if (x < range_max_ || static_cast<int>(msg->info.width) - range_max_ <= x)
00208             continue;
00209           const int y =
00210               lroundf((i / msg->info.width) * msg->info.resolution / map->info.linear_resolution);
00211           if (y < range_max_ || static_cast<int>(msg->info.height) - range_max_ <= y)
00212             continue;
00213 
00214           const int res_up = ceilf(msg->info.resolution / map->info.linear_resolution);
00215           for (int yp = 0; yp < res_up; yp++)
00216           {
00217             for (int xp = 0; xp < res_up; xp++)
00218             {
00219               const int x2 = x + ox + xp;
00220               const int y2 = y + oy + yp;
00221               if (static_cast<unsigned int>(x2) >= map->info.width ||
00222                   static_cast<unsigned int>(y2) >= map->info.height)
00223                 continue;
00224 
00225               auto& m = map->getCost(x2, y2, yaw);
00226               m = 0;
00227             }
00228           }
00229         }
00230       }
00231     }
00232     // Get max
00233     for (size_t yaw = 0; yaw < map->info.angle; yaw++)
00234     {
00235       for (unsigned int i = 0; i < msg->data.size(); i++)
00236       {
00237         const int gx = lroundf((i % msg->info.width) * msg->info.resolution / map->info.linear_resolution) + ox;
00238         const int gy = lroundf((i / msg->info.width) * msg->info.resolution / map->info.linear_resolution) + oy;
00239         if ((unsigned int)gx >= map->info.width ||
00240             (unsigned int)gy >= map->info.height)
00241           continue;
00242 
00243         auto val = msg->data[i];
00244         if (val <= 0)
00245           continue;
00246 
00247         for (int y = -range_max_; y <= range_max_; y++)
00248         {
00249           for (int x = -range_max_; x <= range_max_; x++)
00250           {
00251             const int x2 = gx + x;
00252             const int y2 = gy + y;
00253             if (static_cast<unsigned int>(x2) >= map->info.width ||
00254                 static_cast<unsigned int>(y2) >= map->info.height)
00255               continue;
00256 
00257             auto& m = map->getCost(x2, y2, yaw);
00258             const auto c = cs_template_.e(x, y, yaw) * val / 100;
00259             if (m < c)
00260               m = c;
00261           }
00262         }
00263       }
00264     }
00265   }
00266 };
00267 }  // namespace costmap_cspace
00268 
00269 #endif  // COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H


costmap_cspace
Author(s): Atsushi Watanabe
autogenerated on Sat Jun 22 2019 20:07:13