8 const sensor_msgs::CameraInfoConstPtr& info_msg) {
15 double angle_min, angle_max, vertical_fov;
21 fieldOfView(angle_min, angle_max, cx, 0, cx, cy, cx, depth_msg->height -1);
22 vertical_fov = angle_max - angle_min;
37 ROS_ERROR(
"Parameter used_depth_height is higher than height of image.");
45 findCliffInDepthImage<uint16_t>(depth_msg);
48 findCliffInDepthImage<float>(depth_msg);
52 ss <<
"Depth image has unsupported encoding: " << depth_msg->encoding;
53 throw std::runtime_error(ss.str());
58 if (rmin >= 0 && rmin < rmax) {
63 ROS_ERROR(
"Incorrect value of range minimal parameter. Set default value: 0.");
65 if (rmax >= 0 && rmin < rmax) {
70 ROS_ERROR(
"Incorrect value of range maximum parameter. Set default value: 10.");
80 ROS_ERROR(
"Incorrect value of sensor mount height parameter. Set default value: 0.");
85 if (angle < 90 && angle > -90) {
90 ROS_ERROR(
"Incorrect value of sensor tilt angle parameter. Set default value: 0.");
100 ROS_ERROR(
"Incorrect value of used depth height parameter. Set default value: 100.");
105 if (size > 0 && (size % 2 == 0)) {
110 ROS_ERROR(
"Incorrect value of block size. Set default value: 8.");
120 ROS_ERROR(
"Incorrect value of block points threshold parameter. Set default value: 1.");
130 ROS_ERROR(
"Incorrect value depth image row step parameter. Set default value: 1.");
140 ROS_ERROR(
"Incorrect value depth image column step parameter. Set default value: 1.");
150 ROS_ERROR(
"Incorrect value of ground margin parameter. Set default value: 0.");
155 return sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
159 double dot = ray1.x*ray2.x + ray1.y*ray2.y + ray1.z*ray2.z;
164 double xc,
double yc,
double x2,
double y2) {
165 cv::Point2d raw_pixel_left(x1, y1);
169 cv::Point2d raw_pixel_right(x2, y2);
173 cv::Point2d raw_pixel_center(xc, yc);
189 for(
unsigned i = 0; i < img_height; i++) {
203 for (
unsigned i = 0; i < img_height; i++) {
225 for (
unsigned i = 0; i < img_height; i++) {
235 enum Point { Row, Col, Depth };
237 const T* data =
reinterpret_cast<const T*
>(&depth_msg->data[0]);
238 const unsigned row_size = depth_msg->width;
243 ROS_ERROR(
"Block size should be even number. Value will be decreased by one.");
247 const unsigned block_cols_nr = img_width /
block_size_;
253 ROS_ERROR(
"Block points threshold is too big. Maximum admissible value will be set.");
261 std::vector<std::vector<int> > stairs_points;
264 std::vector<int> px_nr;
265 px_nr.resize(block_size_ * block_size_);
268 const unsigned c = block_size_ / 2;
269 std::vector<unsigned> center_points(4);
270 center_points[0] = c * block_size_ + c-1;
271 center_points[1] = c * block_size_ + c;
272 center_points[2] = (c-1) * block_size_ + c-1;
273 center_points[3] = (c-1)*block_size_ + c ;
276 for (
unsigned bj = 0; bj < block_rows_nr; ++bj) {
278 for (
unsigned bi = 0; bi < block_cols_nr; ++bi) {
281 unsigned block_cnt = 0;
282 std::fill(px_nr.begin(), px_nr.end(), -1);
289 unsigned row = (img_height - 1 ) - (bj * block_size_+ j);
290 unsigned col = bi * block_size_ + i;
291 ROS_ASSERT(row < img_height && col < img_width);
295 if (
typeid(T) ==
typeid(uint16_t)) {
296 unsigned depth_raw_mm =
static_cast<unsigned>(data[row_size * row + col]);
297 d =
static_cast<float>(depth_raw_mm) / 1000.0;
299 else if (
typeid(T) ==
typeid(float)) {
300 d =
static_cast<float>(data[row_size * row + col]);
305 tpoints[block_cnt][Row] = row;
306 tpoints[block_cnt][Col] = col;
307 tpoints[block_cnt][Depth] = d;
308 px_nr[j * block_size_ + i] = block_cnt;
317 if (px_nr[center_points[0]] > 0) {
318 stairs_points.push_back(tpoints[px_nr[center_points[0]]]);
320 else if (px_nr[center_points[1]] > 0) {
321 stairs_points.push_back(tpoints[px_nr[center_points[1]]]);
323 else if (px_nr[center_points[2]] > 0) {
324 stairs_points.push_back(tpoints[px_nr[center_points[2]]]);
326 else if (px_nr[center_points[3]] > 0) {
327 stairs_points.push_back(tpoints[px_nr[center_points[3]]]);
330 stairs_points.insert(stairs_points.end(), tpoints.begin(), tpoints.begin() + block_cnt);
336 std::vector<std::vector<int> >::iterator it;
337 geometry_msgs::Point32 pt;
351 for (it = stairs_points.begin(); it != stairs_points.end(); ++it) {
353 unsigned row = (*it)[Row];
367 new_depth_row[row_size * (*it)[Row] + (*it)[Col]] = 10000U;
373 template void CliffDetector::findCliffInDepthImage<uint16_t>(
const sensor_msgs::ImageConstPtr&);
374 template void CliffDetector::findCliffInDepthImage<float>(
const sensor_msgs::ImageConstPtr&);
void setDepthImgStepCol(const int step)
setDepthImgStepCol
cv::Size fullResolution() const
void detectCliff(const sensor_msgs::ImageConstPtr &depth_msg, const sensor_msgs::CameraInfoConstPtr &info_msg)
detectCliff detects descending stairs based on the information in a depth image
bool cam_model_update_
Determines if continuously cam model update required.
float range_min_
Stores the current minimum range to use.
depth_nav_msgs::Point32List stairs_points_msg_
sensor_msgs::Image new_depth_msg_
cv::Point3d projectPixelTo3dRay(const cv::Point2d &uv_rect) const
void setDepthImgStepRow(const int step)
setDepthImgStepRow
float range_max_
Stores the current maximum range to use.
bool depth_sensor_params_update
float ground_margin_
Margin for ground points feature detector (m)
void setUsedDepthHeight(const unsigned int height)
setUsedDepthHeight
image_geometry::PinholeCameraModel camera_model_
Class for managing sensor_msgs/CameraInfo messages.
unsigned int used_depth_height_
Used depth height from img bottom (px)
unsigned int block_points_thresh_
Threshold value of points in block to admit stairs.
void findCliffInDepthImage(const sensor_msgs::ImageConstPtr &depth_msg)
unsigned int block_size_
Square block (subimage) size (px).
void setSensorMountHeight(const float height)
setSensorMountHeight sets the height of sensor mount (in meters) from ground
bool fromCameraInfo(const sensor_msgs::CameraInfo &msg)
void setBlockSize(const int size)
setBlockSize sets size of square block (subimage) used in cliff detector
const std::string TYPE_32FC1
std::vector< unsigned int > dist_to_ground_
Calculated distances to ground for every row of depth image in mm.
float sensor_mount_height_
Height of sensor mount from ground.
const std::string TYPE_16UC1
bool publish_depth_enable_
Determines if depth should be republished.
void calcGroundDistancesForImgRows(double vertical_fov)
Calculates distances to ground for every row of depth image.
unsigned int depth_image_step_col_
Columns step in depth processing (px).
cv::Point2d rectifyPoint(const cv::Point2d &uv_raw) const
#define ROS_DEBUG_STREAM(args)
float sensor_tilt_angle_
Sensor tilt angle (degrees)
void fieldOfView(double &min, double &max, double x1, double y1, double xc, double yc, double x2, double y2)
unsigned int depth_image_step_row_
Rows step in depth processing (px).
void calcDeltaAngleForImgRows(double vertical_fov)
calcDeltaAngleForImgRows
void calcTiltCompensationFactorsForImgRows()
calcTiltCompensationFactorsForImgRows calculate factors used in tilt compensation ...
double angleBetweenRays(const cv::Point3d &ray1, const cv::Point3d &ray2) const
void setGroundMargin(const float margin)
setGroundMargin sets the floor margin (in meters)
void setBlockPointsThresh(const int thresh)
setBlockPointsThresh sets threshold value of pixels in block to set block as stairs ...
double lengthOfVector(const cv::Point3d &vec) const
lengthOfVector calculates length of 3D vector.
std::vector< double > tilt_compensation_factor_
Calculated sensor tilt compensation factors.
void setSensorTiltAngle(const float angle)
setSensorTiltAngle sets the sensor tilt angle (in degrees)
std::vector< double > delta_row_
void setRangeLimits(const float rmin, const float rmax)
setRangeLimits sets the minimum and maximum range of depth value from RGBD sensor.