23 #include <nav_msgs/GetMap.h> 24 #include <nav_msgs/OccupancyGrid.h> 25 #include <nav_msgs/Path.h> 26 #include <nav_msgs/GetPlan.h> 27 #include <geometry_msgs/PoseStamped.h> 30 #include <boost/tuple/tuple.hpp> 49 return (firstIndexVector - sourceVector).squaredNorm() < (secondIndexVector - sourceVector).squaredNorm();
55 return firstIndexVector == secondIndexVector;
59 typedef std::vector<RayTracingIndex>
Ray;
70 nav_msgs::OccupancyGrid
mMap;
74 int8_t mCostTranslationTable[256];
76 MapHelper(
const std::string &mapTopicName =
"map",
const std::string &getPlanServiceName =
"move_base/make_plan") : mMapReceived(false), mCollisionThreshold(45) {
80 mCostTranslationTable[0] = 0;
81 mCostTranslationTable[253] = 99;
82 mCostTranslationTable[254] = 100;
83 mCostTranslationTable[255] = -1;
85 for (
int i = 1; i < 253; i++) {
86 mCostTranslationTable[i] = int8_t(1 + (97 * (i - 1)) / 251);
90 while(
ros::ok() && !mMapReceived) {
91 mDebugHelperPtr->write(std::stringstream() <<
"Waiting for map to arrive on topic '" << mapSubscriber.
getTopic() <<
"'",
98 mDebugHelperPtr->write(std::stringstream() <<
"waiting for service: " << getPlanServiceName,
DebugHelper::MAP);
100 mGetPlanServiceClient = mGlobalNodeHandle.
serviceClient<nav_msgs::GetPlan>(getPlanServiceName,
true);
102 mDebugHelperPtr->write(std::stringstream() <<
"Waiting for planning server to start on service '" 108 this->aggregateRaytracingMap();
117 mDebugHelperPtr->write(std::stringstream() <<
"Map resolution: " << mMap.info.resolution,
DebugHelper::MAP);
118 mDebugHelperPtr->write(std::stringstream() <<
"Map translation: " << this->getTranslation(),
DebugHelper::MAP);
119 mDebugHelperPtr->write(std::stringstream() <<
"Map orientation: " << this->getOrientation().
w() <<
", " 120 << this->getOrientation().
x() <<
", " 121 << this->getOrientation().
y() <<
", " 122 << this->getOrientation().
z(),
124 mDebugHelperPtr->write(std::stringstream() <<
"Map metric width: " << this->getMetricWidth(),
DebugHelper::MAP);
125 mDebugHelperPtr->write(std::stringstream() <<
"Map metric height: " << this->getMetricHeight(),
DebugHelper::MAP);
130 std::string name =
"global_costmap";
140 mGlobalNodeHandle.
getParam(
"/nbv/mMapsImagePath", path);
143 std::string costmapPath = path +
"/costmap.pgm";
144 mDebugHelperPtr->write(
"Outputting calculated costmap to " + costmapPath,
152 ROS_ERROR(
"Cannot aggregate raytracing map. Dimensions of map and costmap do not match!");
153 mDebugHelperPtr->write(std::stringstream() <<
"Map size: " << mMap.info.width <<
"x" << mMap.info.height,
DebugHelper::MAP);
158 mRaytracingMap.info = mMap.info;
159 mRaytracingMap.data.reserve(mMap.data.size());
160 for (
unsigned int y = 0;
y < mMap.info.height;
y++) {
161 for (
unsigned int x = 0;
x < mMap.info.width;
x++) {
162 unsigned int index =
y * mMap.info.width +
x;
163 int8_t mapOccupancyValue = mMap.data[index];
164 int8_t costmapOccupancyValue = mCostTranslationTable[mCostmap.
getCost(
x,
y)];
165 int8_t aggregatedOccupancyValue = mapOccupancyValue == -1 ? -1 : costmapOccupancyValue;
167 mRaytracingMap.data[index] = aggregatedOccupancyValue;
175 this->worldToMapCoordinates(position, mapX, mapY);
176 return this->getOccupancyValue(map, mapX, mapY);
181 this->worldToMapCoordinates(position, mapX, mapY);
182 return this->getOccupancyValue(costmap, mapX, mapY);
185 int8_t
getOccupancyValue(
const nav_msgs::OccupancyGrid &map,
const int32_t &mapX,
const int32_t &mapY) {
186 uint32_t width = map.info.width;
187 uint32_t height = map.info.height;
189 if (mapX < 0 || mapY < 0 || mapX >= (int32_t)width || mapY >= (int32_t)height) {
193 return map.data[mapX + mapY * width];
200 if (mapX < 0 || mapY < 0 || mapX >= (int32_t)width || mapY >= (int32_t)height) {
204 unsigned char cost = costmap.
getCost(mapX, mapY);
205 return mCostTranslationTable[cost];
210 return this->getOccupancyValue(mMap, position);
214 return this->getOccupancyValue(mMap, mapX, mapY);
219 return this->getOccupancyValue(mCostmap, position);
223 return this->getOccupancyValue(mCostmap, mapX, mapY);
228 return this->getOccupancyValue(mRaytracingMap, position);
232 return this->getOccupancyValue(mRaytracingMap, mapX, mapY);
237 bool retVal = this->doRaytracing(fromPoint, toPoint, ray);
246 int32_t fromMapX, fromMapY;
247 this->worldToMapCoordinates(fromPoint, fromMapX, fromMapY);
249 int32_t toMapX, toMapY;
250 this->worldToMapCoordinates(toPoint, toMapX, toMapY);
253 int32_t distanceX = toMapX - fromMapX;
254 int32_t distanceY = toMapY - fromMapY;
257 if (distanceX == 0 && distanceY == 0) {
258 int8_t occupancyValue = this->getRaytracingMapOccupancyValue(fromMapX, fromMapY);
259 return this->isOccupancyValueAcceptable(occupancyValue);
263 int32_t minX = std::min(fromMapX, toMapX);
264 int32_t maxX = std::max(fromMapX, toMapX);
265 int32_t minY = std::min(fromMapY, toMapY);
266 int32_t maxY = std::max(fromMapY, toMapY);
269 float resolution = mRaytracingMap.info.resolution;
272 int32_t signumX = distanceX < 0 ? - 1 : 1;
273 int32_t signumY = distanceY < 0 ? - 1 : 1;
276 SimpleVector2 diff = (toPoint - fromPoint).block<2, 1>(0, 0);
279 bool rayTracingSucceeded =
true;
282 for (int32_t offsetX = 0; offsetX <= abs(distanceX) + 1 && diff[0] != 0; offsetX += 1) {
283 double x = (fromMapX + signumX * offsetX) * resolution;
284 double t = (x - fromPoint[0]) / diff[0];
285 double y = fromPoint[1] + t * diff[1];
288 idx.
x = (int32_t) (x / resolution);
289 idx.
y = (int32_t) (y / resolution);
290 idx.
occupancy = this->getRaytracingMapOccupancyValue(idx.
x, idx.
y);
292 if (idx.
x < minX || idx.
x > maxX || idx.
y < minY || idx.
y > maxY) {
296 if (!this->isOccupancyValueAcceptable(idx.
occupancy)) {
297 rayTracingSucceeded =
false;
304 for (int32_t offsetY = 0; offsetY <= abs(distanceY) + 1 && diff[1] != 0; offsetY += 1) {
305 double y = (fromMapY + signumY * offsetY) * resolution;
306 double t = (y - fromPoint[1]) / diff[1];
307 double x = fromPoint[0] + t * diff[0];
310 idx.
x = (int32_t) (x / resolution);
311 idx.
y = (int32_t) (y / resolution);
312 idx.
occupancy = this->getRaytracingMapOccupancyValue(idx.
x, idx.
y);
314 if (idx.
x < minX || idx.
x > maxX || idx.
y < minY || idx.
y > maxY) {
318 if (!this->isOccupancyValueAcceptable(idx.
occupancy)) {
319 rayTracingSucceeded =
false;
331 ray.resize(std::distance(ray.begin(), endIterator));
333 return rayTracingSucceeded;
337 return mMap.info.width * mMap.info.resolution;
341 return mMap.info.height * mMap.info.resolution;
346 worldToMapCoordinates(position, continuousMapCoords);
349 x = (int32_t) floor(continuousMapCoords[0]);
350 y = (int32_t) floor(continuousMapCoords[1]);
356 SimpleMatrix3 rotationMatrix = orientation.toRotationMatrix();
359 result = (rotationMatrix.transpose() * position - translation) / mMap.info.resolution;
369 result = orientation.toRotationMatrix() * position * mMap.info.resolution + translation;
373 result = size * mMap.info.resolution;
377 result = size / mMap.info.resolution;
381 return SimpleVector3(mMap.info.origin.position.x, mMap.info.origin.position.y, mMap.info.origin.position.z);
389 return occupancyValue >= 0 && occupancyValue <= mCollisionThreshold;
393 mCollisionThreshold = thresholdValue;
397 return mCollisionThreshold;
401 return (goal - start).squaredNorm();
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
static SimpleQuaternion getSimpleQuaternion(const geometry_msgs::Pose &pose)
Eigen::Matrix< Precision, 2, 1 > SimpleVector2
void worldToMapCoordinates(const SimpleVector3 &position, SimpleVector3 &result)
costmap_2d::Costmap2D mCostmap
float getSquaredDistance(const SimpleVector3 &start, const SimpleVector3 &goal)
int8_t getOccupancyValue(const nav_msgs::OccupancyGrid &map, const int32_t &mapX, const int32_t &mapY)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int8_t mCollisionThreshold
bool isOccupancyValueAcceptable(const int8_t &occupancyValue)
void setCollisionThreshold(int8_t thresholdValue)
static boost::shared_ptr< DebugHelper > getInstance()
int8_t getCollisionThreshold()
int8_t getMapOccupancyValue(const int32_t &mapX, const int32_t &mapY)
ros::NodeHandle mGlobalNodeHandle
void mapToWorldCoordinates(const int32_t &x, const int32_t &y, SimpleVector3 &result)
Eigen::Matrix< Precision, 3, 1 > SimpleVector3
void mapToWorldCoordinates(const SimpleVector3 &position, SimpleVector3 &result)
void aggregateRaytracingMap()
int8_t getOccupancyValue(const nav_msgs::OccupancyGrid &map, const SimpleVector3 &position)
int8_t getRaytracingMapOccupancyValue(const int32_t &mapX, const int32_t &mapY)
bool doRaytracing(const SimpleVector3 &fromPoint, const SimpleVector3 &toPoint, Ray &ray)
boost::shared_ptr< MapHelper > MapHelperPtr
ros::ServiceClient mGetPlanServiceClient
std::vector< RayTracingIndex > Ray
int8_t getOccupancyValue(const costmap_2d::Costmap2D &costmap, const int32_t &mapX, const int32_t &mapY)
unsigned char getCost(unsigned int mx, unsigned int my) const
void mapToWorldSize(const double &size, double &result)
int8_t getCostmapOccupancyValue(const int32_t &mapX, const int32_t &mapY)
int8_t getMapOccupancyValue(const SimpleVector3 &position)
void worldToMapSize(const double &size, double &result)
bool saveMap(std::string file_name)
int8_t getRaytracingMapOccupancyValue(const SimpleVector3 &position)
nav_msgs::OccupancyGrid mMap
int8_t getCostmapOccupancyValue(const SimpleVector3 &position)
std::string getTopic() const
this namespace contains all generally usable classes.
unsigned int getSizeInCellsY() const
static bool equals(const RayTracingIndex &firstIndex, const RayTracingIndex &secondIndex)
bool doRaytracing(const SimpleVector3 &fromPoint, const SimpleVector3 &toPoint)
SimpleQuaternion getOrientation()
TFSIMD_FORCE_INLINE const tfScalar & z() const
void worldToMapCoordinates(const SimpleVector3 &position, int32_t &x, int32_t &y)
TFSIMD_FORCE_INLINE const tfScalar & w() const
MapHelper(const std::string &mapTopicName="map", const std::string &getPlanServiceName="move_base/make_plan")
static bool topologicalCompare(const RayTracingIndex &source, const RayTracingIndex &firstIndex, const RayTracingIndex &secondIndex)
unsigned int getSizeInCellsX() const
Eigen::Matrix< Precision, 3, 3 > SimpleMatrix3
bool getParam(const std::string &key, std::string &s) const
boost::shared_ptr< RayTracingIndex > RayTracingIndexPtr
void mapReceived(nav_msgs::OccupancyGrid map)
nav_msgs::OccupancyGrid mRaytracingMap
int8_t getOccupancyValue(const costmap_2d::Costmap2D &costmap, const SimpleVector3 &position)
ROSCPP_DECL void spinOnce()
DebugHelperPtr mDebugHelperPtr
SimpleVector3 getTranslation()
Eigen::Quaternion< Precision > SimpleQuaternion
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)