Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
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 }
00268
00269 #endif // COSTMAP_CSPACE_COSTMAP_3D_LAYER_FOOTPRINT_H