map_accessibility_analysis.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016  
00017 
00018 #include <cob_map_accessibility_analysis/map_accessibility_analysis.h>
00019 #include <ros/ros.h>
00020 
00021 //#define __DEBUG_DISPLAYS__
00022 
00023 MapAccessibilityAnalysis::MapAccessibilityAnalysis()
00024 {
00025 
00026 }
00027 
00028 MapAccessibilityAnalysis::~MapAccessibilityAnalysis()
00029 {
00030 
00031 }
00032 
00033 void MapAccessibilityAnalysis::inflateMap(const cv::Mat& original_map, cv::Mat& inflated_map, const int robot_radius_pixel)
00034 {
00035         cv::erode(original_map, inflated_map, cv::Mat(), cv::Point(-1, -1), robot_radius_pixel);
00036 }
00037 
00038 void MapAccessibilityAnalysis::checkPoses(const std::vector<cv::Point>& points_to_check, std::vector<bool>& accessibility_flags,
00039                 const cv::Mat& inflated_map, const bool approach_path_accessibility_check, const cv::Point& robot_location)
00040 {
00041 #ifdef __DEBUG_DISPLAYS__
00042         cv::Mat display_map = inflated_map.clone();
00043 #endif
00044 
00045         // find the individual connected areas
00046         std::vector<std::vector<cv::Point> > area_contours; // first index=contour index;  second index=point index within contour
00047         if (approach_path_accessibility_check == true)
00048         {
00049                 cv::Mat inflated_map_copy = inflated_map.clone();
00050                 cv::findContours(inflated_map_copy, area_contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
00051         }
00052 
00053         for (unsigned int i = 0; i < points_to_check.size(); ++i)
00054         {
00055                 const int u = points_to_check[i].x;
00056                 const int v = points_to_check[i].y;
00057                 ROS_INFO_STREAM("Checking accessibility of point (" << u << ", " << v << ")px.");
00058                 if (inflated_map.at<uchar>(v, u) != 0)
00059                 {
00060                         // check if robot can approach this position
00061                         if (approach_path_accessibility_check == false ||
00062                                         isApproachPositionAccessible(robot_location, cv::Point(u, v), area_contours) == true)
00063                                 accessibility_flags[i] = true;
00064                 }
00065 
00066 #ifdef __DEBUG_DISPLAYS__
00067                 if (accessibility_flags[i] == false)
00068                         cv::circle(display_map, cv::Point(u, v), 2, cv::Scalar(32), 10);
00069                 else
00070                         cv::circle(display_map, cv::Point(u, v), 2, cv::Scalar(192), 10);
00071 #endif
00072         }
00073 
00074 #ifdef __DEBUG_DISPLAYS__
00075         cv::imshow("points", display_map);
00076         cv::waitKey();
00077 #endif
00078 }
00079 
00080 
00081 void MapAccessibilityAnalysis::checkPerimeter(std::vector<Pose>& accessible_poses_on_perimeter,
00082                 const Pose& center, const double radius, const double rotational_sampling_step,
00083                 const cv::Mat& inflated_map, const bool approach_path_accessibility_check, const cv::Point& robot_location)
00084 {
00085 #ifdef __DEBUG_DISPLAYS__
00086         cv::Mat display_map = inflated_map.clone();
00087 #endif
00088 
00089         // find the individual connected areas
00090         std::vector<std::vector<cv::Point> > area_contours; // first index=contour index;  second index=point index within contour
00091         if (approach_path_accessibility_check == true)
00092         {
00093                 cv::Mat inflated_map_copy = inflated_map.clone();
00094                 cv::findContours(inflated_map_copy, area_contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
00095         }
00096 
00097         for (double angle = center.orientation; angle < center.orientation + 2 * CV_PI; angle += rotational_sampling_step)
00098         {
00099                 const double x = center.x + radius * cos(angle);
00100                 const double y = center.y + radius * sin(angle);
00101                 const int u = cvRound(x);
00102                 const int v = cvRound(y);
00103                 bool found_pose = false;
00104                 if (inflated_map.at<uchar>(v, u) != 0)
00105                 {
00106                         // check if robot can approach this position
00107                         if (approach_path_accessibility_check == false
00108                                         || isApproachPositionAccessible(robot_location, cv::Point(u, v), area_contours) == true)
00109                         {
00110                                 // add accessible point to results
00111                                 Pose pose;
00112                                 pose.x = x;
00113                                 pose.y = y;
00114                                 pose.orientation = angle + CV_PI;
00115                                 while (pose.orientation > 2 * CV_PI)
00116                                         pose.orientation -= 2 * CV_PI;
00117                                 while (pose.orientation < 0.)
00118                                         pose.orientation += 2 * CV_PI;
00119                                 accessible_poses_on_perimeter.push_back(pose);
00120                                 found_pose = true;
00121                         }
00122                 }
00123 #ifdef __DEBUG_DISPLAYS__
00124                 if (found_pose == true)
00125                         cv::circle(display_map, cv::Point(u, v), 2, cv::Scalar(192), 5);
00126                 else
00127                         cv::circle(display_map, cv::Point(u, v), 2, cv::Scalar(32), 5);
00128 #endif
00129         }
00130 
00131 #ifdef __DEBUG_DISPLAYS__
00132         cv::imshow("perimeter", display_map);
00133         cv::waitKey();
00134 #endif
00135 }
00136 
00137 
00138 bool MapAccessibilityAnalysis::isApproachPositionAccessible(const cv::Point& robotLocation,
00139                 const cv::Point& potentialApproachPose, std::vector<std::vector<cv::Point> > contours)
00140 {
00141         // check whether potentialApproachPose and robotLocation are in the same area (=same contour)
00142         int contourIndexRobot = -1;
00143         int contourIndexPotentialApproachPose = -1;
00144         for (unsigned int i = 0; i < contours.size(); i++)
00145         {
00146                 if (0 <= cv::pointPolygonTest(contours[i], potentialApproachPose, false))
00147                         contourIndexPotentialApproachPose = i;
00148                 if (0 <= cv::pointPolygonTest(contours[i], robotLocation, false))
00149                         contourIndexRobot = i;
00150         }
00151         ROS_DEBUG_STREAM("contourIndexPotentialApproachPose=" << contourIndexPotentialApproachPose
00152                                         << "  contourIndexRobot=" << contourIndexRobot);
00153         if (contourIndexRobot != contourIndexPotentialApproachPose ||
00154                         (contourIndexRobot == -1 && contourIndexPotentialApproachPose == -1))
00155                 return false;
00156 
00157         return true;
00158 }
00159 
00160 
00161 void MapAccessibilityAnalysis::computeClosestPointOnPolygon(const cv::Mat& map_with_polygon,
00162                 const Pose& pose_p, Pose& closest_point_on_polygon)
00163 {
00164         double closest_pixel_distance_squared = 1e10;
00165         for (int v = 0; v < map_with_polygon.rows; v++)
00166         {
00167                 for (int u = 0; u < map_with_polygon.cols; u++)
00168                 {
00169                         double dist_squared = 0.;
00170                         if (map_with_polygon.at<uchar>(v, u) == 128 &&
00171                                 (dist_squared = (pose_p.x - u) * (pose_p.x - u) + (pose_p.y - v) * (pose_p.y - v)) < closest_pixel_distance_squared)
00172                         {
00173                                 closest_pixel_distance_squared = dist_squared;
00174                                 closest_point_on_polygon.x = u;
00175                                 closest_point_on_polygon.y = v;
00176                         }
00177                 }
00178         }
00179 }


cob_map_accessibility_analysis
Author(s): Richard Bormann
autogenerated on Thu Jun 6 2019 21:01:20