-
Raphael Memmesheimer authoredRaphael Memmesheimer authored
OccupancyMap.h 11.68 KiB
#ifndef OCCUPANCYMAP_H
#define OCCUPANCYMAP_H
#include <vector>
#include <list>
#include <string>
#include <iostream>
#include <Eigen/Geometry>
#include "Math/Pose.h"
#include "Math/Point2D.h"
#include "Math/Box2D.h"
#include "nav_msgs/OccupancyGrid.h"
#include <tf/transform_listener.h>
#include <sensor_msgs/LaserScan.h>
class QImage;
using namespace std;
/**
* Structure to store the start and end point of each laser range in the current scan
* @param sensorPos position of the laser in the current scan (in base_link frame)
* @param endPos position of the end point of the laser frame in the current scan (in base_link frame)
* @param free indicates if the laser range hit an obstacle (false) or not (true)
*/
struct RangeMeasurement
{
geometry_msgs::Point sensorPos;
geometry_msgs::Point endPos;
bool free;
};
/**
* Used in struct MeasurePoint to specify if a measurement point is at the border of a scan segment
*/
enum BorderType
{
NoBorder,
LeftBorder,
RightBorder
};
/**
* Structure to store a measurement point for computeLaserScanProbability()
* @param hitPos Position of measured obstacle (robot coordinates)
* @param frontPos Position to check for NOT_KNOWN terrain
* This is needed to assure that front- and backside of obstacles can be distinguished
* @param border specifies if the measurement point is at the border of a scan segment
*/
struct MeasurePoint
{
Point2D hitPos;
Point2D frontPos;
BorderType borderType;
};
/**
* @class OccupancyMap
*
* @author Malte Knauf, Stephan Wirth, Susanne Maur (RX), David Gossow (RX), Susanne Thierfelder (R16)
*
* @brief This class holds and manages an occupancy map.
*
* An occupancy map is a map where free space and occupied space are marked. This map stores values
* for free and occupied space in an (2D-)unsigned char array. This array can be seen as a graylevel image.
* The darker a cell, the higher the probability that this cell is occupied by an obstacle.
* The size of the map and the size of one cell can be defined in the setup file with the values
* MAP_SIZE and MAP_CELL_SIZE. The origin of the coordinate system of the map is the center of the array.
* The x-axis is heading front, the y-axis points to the left (like the robot's coordinate system).
* The mapping data has to be inserted via the method insertLaserData().
*/
class OccupancyMap {
public:
static const int8_t INACCESSIBLE = 100;
static const int8_t OBSTACLE = 99;
static const int8_t OCCUPIED = 98;
static const int8_t UNKNOWN = 50;
static const int8_t NOT_SEEN_YET = -1;
static const int8_t FREE = 0;
/**
* The default constructor calls initMembers().
*/
OccupancyMap();
/**
* Constructor for a loaded map.
*/
OccupancyMap(float*& occupancyProbability, geometry_msgs::Pose origin, float resolution, int pixelSize, Box2D<int> exploredRegion);
/**
* Copy constructor, copies all members inclusive the arrays that lie behind the pointers.
* @param occupancyMap Source for copying
*/
OccupancyMap(const OccupancyMap& occupancyMap);
/**
* Method to init all members with default values from the configuration file. All arrays are initialized.
*/
void initMembers();
/**
* Assignment operator, copies all members (deep copy!)
* @param source Source to copy from
* @return Reference to copied OccupancyMap
*/
OccupancyMap& operator=(const OccupancyMap& source);
/**
* Deletes all dynamically allocated memory.
*/
~OccupancyMap();
/*
/**
* @return The resolution of the map in m.
*/
// int resolution() const;
geometry_msgs::Pose origin() const;
/**
* @return Width of the map.
*/
int width() const;
/**
* @return Height of the map.
*/
int height() const;
/**
* This method is used to reset all HighSensitive areas
*/
void resetHighSensitive();
/**
* @return Probability of pixel p being occupied.
*/
float getOccupancyProbability(Eigen::Vector2i p);
/**
* @brief This function inserts the data of a laserscan into the map.
*
* With the given data, start and end cells of a laser beam are computed and given to the
* method markLineFree().
* If the measurement is smaller than VALID_MAX_RANGE, markOccupied() is called for the endpoint.
* @param laserData The laser data msg.
*/
void insertLaserData( sensor_msgs::LaserScanConstPtr laserData );
void insertRanges( vector<RangeMeasurement> ranges );
/**
* @brief gives a list specially processed coordinates to be used for computeLaserScanProbability
*/
std::vector<MeasurePoint> getMeasurePoints( sensor_msgs::LaserScanConstPtr laserData );
/**
* This method computes a score that describes how good the given hypothesis matches with the map
* @param robotPose The pose of the robot
* @return The "fitting factor". The higher the factor, the better the fitting.
* This factor is NOT normalized, it is a positive float between 0 and FLOAT_MAX
*/
float computeScore( Pose robotPose, std::vector<MeasurePoint> measurePoints );
/**
* @return QImage of size m_PixelSize, m_PixelSize with values of m_OccupancyProbability scaled to 0-254
*/
QImage getProbabilityQImage(int trancparencyThreshold, bool showInaccessible) const;
//puma2::ColorImageRGB8* getUpdateImage( bool withMap=true ); TODO
/**
* Returns an "image" of the obstacles e.g. seen in the 3D scans
* @returns image with dark red dots in areas where the obstacles were seen
*/
//puma2::ColorImageRGB8* getObstacleImage ( ); TODO
/**
* Returns an "image" of occupancy probability image.
* @param[out] data vector containing occupancy probabilities. 0 = free, 100 = occupied, -1 = NOT_KNOWN
* @param[out] width Width of data array
* @param[out] height Height of data array
* @param[out] resolution Resolution of the map (m_Resolution)
*/
void getOccupancyProbabilityImage(vector<int8_t> &data, int& width, int& height, float &resolution);
/**
* This method marks free the position of the robot (according to its dimensions).
*/
void markRobotPositionFree();
/**
* @brief Computes the contrast of a single pixel.
* @param prob probability value (100=occupied, 50=NOT_KNOWN, 0=free) of a pixel.
* @return Contrast value from 0 (no contrast) to 1 (max. contrast) of this pixel
*/
double contrastFromProbability (int8_t prob);
/**
* @brief This method computes the sharpness of the occupancy grid
* @return Contrast value from 0 (no contrast) to 1 (max. contrast) of the map
*/
double evaluateByContrast();
/// GETTERS
Box2D<int> getExploredRegion() { return m_ExploredRegion; }
Box2D<int> getChangedRegion() { return m_ChangedRegion; }
/**
* Sets cells of this map to free or occupied according to maskMap
*/
void applyMasking(const nav_msgs::OccupancyGrid::ConstPtr &msg);
protected:
/**
* This method increments m_MeasurementCount for pixel p.
* @param p Pixel that has been measured.
*/
void incrementMeasurementCount(Eigen::Vector2i p);
/**
* This method increments the occupancy count int m_OccupancyCount for pixel p.
* @param p Occupied pixel.
*/
void incrementOccupancyCount(Eigen::Vector2i p);
/**
* This method increments m_MeasurementCount and if neccessary m_OccupancyCount for all pixels.
*/
void applyChanges();
void clearChanges();
/**
* This method scales the counts of all pixels down to the given value.
* @param maxCount Maximum value to which all counts are set.
*/
void scaleDownCounts(int maxCount);
/**
* This function paints a line from a start pixel to an end pixel.
* The computation is made with the Bresenham algorithm.
* @param data array on which the line shall be painted
* @param startPixel starting coordinates of the beam
* @param endPixel ending coordinates of the beam
* @param value The value with which the lines are marked.
*/
template<class DataT>
void drawLine(DataT* data, Eigen::Vector2i& startPixel, Eigen::Vector2i& endPixel, char value);
/**
* This method computes the values for m_OccupancyProbabilities from m_MeasurementCount and m_OccupancyCount.
*/
void computeOccupancyProbabilities();
/**
* This method sets all values of m_CurrentChanges to NO_CHANGE.
*/
void clearCurrentChanges();
/**
* This method resets all values of m_MinChangeX, m_MaxChangeX, m_MinChangeY and m_MaxChangeY.
* This means that no current changes are assumed.
*/
void resetChangedRegion();
/**
* This method updates the values of m_MinChangeX, m_MaxChangeX, m_MinChangeY and m_MaxChangeY to current changes.
* The area around the current robot pose will be included to the changed region.
* @param robotPose The current pose of the robot.
*/
void updateChangedRegion(Pose robotPose);
/**
* This method sets all values of m_MinChangeX, m_MaxChangeX, m_MinChangeY and m_MaxChangeY
* to initial values so that the complete map will be processed.
*/
void maximizeChangedRegion();
/**
* This method resets all values of m_ExploredX, m_MaxExploredX, m_MinExploredY and m_MaxExploredY.
*/
void resetExploredRegion();
/**
* Deletes all allocated members.
*/
void cleanUp();
/**
* Stores the size of one map pixel in m.
*/
float m_Resolution;
/**
* Stores the origin of the map
*/
geometry_msgs::Pose m_Origin;
/**
* Stores the width of the map in cell numbers.
*/
int m_PixelSize;
/**
* Stores the size of the map arrays, i.e. m_PixelSize * m_PixelSize
* for faster computation.
*/
unsigned m_ByteSize;
/**
* Array to store occupancy probability values.
* Values between 0 and 1.
*/
float* m_OccupancyProbability;
// Counts how often a pixel is hit by a measurement.
unsigned short* m_MeasurementCount;
// Counts how often a pixel is hit by a measurement that says the pixel is occupied.
unsigned short* m_OccupancyCount;
// Counts how often a cell is marked as inaccessible via markInaccessible()
unsigned char* m_InaccessibleCount;
// Used for setting flags for cells, that have been modified during the current update.
unsigned char* m_CurrentChanges;
// Used for high Sensitive areas
unsigned short* m_HighSensitive;
/**
* Store values from config files.
*/
// maximum valid range of one laser measurement
float m_LaserMaxRange;
//minimum valid range of one laser measurement
float m_LaserMinRange;
//minimum range classified as free in case of errorneous laser measurement
float m_FreeReadingDistance;
//enables checking to avoid matching front- and backside of an obstacle, e.g. wall
bool m_BacksideChecking;
//leaves a small border around obstacles unchanged when inserting a laser scan
bool m_ObstacleBorders;
//minimum distance in m between two samples for probability calculation
float m_MeasureSamplingStep;
//bool to reset high_sensitive Areas on the next iteration
bool m_reset_high;
//position of the laser scaner in base_link frame
geometry_msgs::Point m_LaserPos;
/**
* Defines a bounding box around the changes in the current map.
*/
Box2D<int> m_ChangedRegion;
/**
* Defines a bounding box around the area in the map, which is already explored.
*/
Box2D<int> m_ExploredRegion;
/**
* ros transform listener
*/
tf::TransformListener m_tfListener;
};
#endif