00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <cob_map_accessibility_analysis/map_accessibility_analysis.h>
00019 #include <ros/ros.h>
00020
00021
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
00046 std::vector<std::vector<cv::Point> > area_contours;
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
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
00090 std::vector<std::vector<cv::Point> > area_contours;
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
00107 if (approach_path_accessibility_check == false
00108 || isApproachPositionAccessible(robot_location, cv::Point(u, v), area_contours) == true)
00109 {
00110
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
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 }