Go to the documentation of this file.00001
00013 #include "ros/ros.h"
00014 #include "sensor_msgs/LaserScan.h"
00015 #include "sensor_msgs/PointCloud.h"
00016 #include "open_door_detector/detect_open_door.h"
00017
00018 bool detect_door(open_door_detector::detect_open_door::Request &req,
00019 open_door_detector::detect_open_door::Response &res);
00020
00021 void laserCallback(const sensor_msgs::LaserScan::ConstPtr& scan_in);
00022
00023 const int DETECTION_THRESHOLD=25;
00024 const float WALL_DIST_THRESHOLD=0.2;
00025
00026
00027 sensor_msgs::LaserScan last_scan_in;
00028
00029 int main(int argc, char **argv)
00030 {
00031 ros::init(argc, argv, "detect_open_door");
00032 ros::NodeHandle n;
00033 ros::ServiceServer service = n.advertiseService("detect_open_door", detect_door);
00034 ROS_INFO("Ready to detect open door.");
00035 ros::Subscriber sub = n.subscribe("/scan",1000,laserCallback);
00036 ros::spin();
00037
00038 return 0;
00039 }
00040
00041
00042 bool detect_door(open_door_detector::detect_open_door::Request &req,
00043 open_door_detector::detect_open_door::Response &res)
00044 {
00045 if(req.aperture_angle <= 0) req.aperture_angle = 3;
00046
00047 int range_points = last_scan_in.ranges.size();
00048
00049 int range_start = range_points/2 - req.aperture_angle/(2*last_scan_in.angle_increment);
00050 if(range_start < 0) range_start = 0;
00051
00052 int range_end = range_points/2 + req.aperture_angle/(2*last_scan_in.angle_increment);
00053 if(range_end > range_points) range_end = range_points-1;
00054
00055 int door_start;
00056 int door_end;
00057 int n_short = 0;
00058 int n_long = 0;
00059 bool isDoor = false;
00060 float laser_dist;
00061 float door_width;
00062
00063
00064 for(int i=range_start; i<=range_end; i++){
00065 laser_dist = (req.wall_distance + WALL_DIST_THRESHOLD)/cos(last_scan_in.angle_min + i*last_scan_in.angle_increment);
00066 if(isDoor) {
00067 if(last_scan_in.ranges[i] <= laser_dist) {
00068 n_short++;
00069 } else {
00070 n_short = 0;
00071 }
00072 if(n_short > DETECTION_THRESHOLD) {
00073 door_end = i - DETECTION_THRESHOLD + 1;
00074 door_width = req.wall_distance*(tan(last_scan_in.angle_min+door_end*last_scan_in.angle_increment)
00075 -tan(last_scan_in.angle_min+door_start*last_scan_in.angle_increment));
00076 if(door_width <= req.min_door_width) {
00077 isDoor = false;
00078 door_start = 0;
00079 door_end = 0;
00080 n_short = 0;
00081 n_long = 0;
00082 } else {
00083 break;
00084 }
00085 }
00086 } else {
00087 if(last_scan_in.ranges[i] > laser_dist || last_scan_in.ranges[i] != last_scan_in.ranges[i]) {
00088 n_long++;
00089 } else {
00090 n_long = 0;
00091 }
00092 if(n_long > DETECTION_THRESHOLD) {
00093 isDoor = true;
00094 door_start = i - DETECTION_THRESHOLD + 1;
00095 door_end = range_end;
00096 }
00097 }
00098 }
00099
00100
00101
00102 if(isDoor) {
00103 res.door_pos.pose.position.x = req.wall_distance;
00104 float mid_door = (door_start + door_end)/2;
00105 float angle_mid_door = last_scan_in.angle_min + mid_door*last_scan_in.angle_increment;
00106 res.door_pos.pose.position.y=tan(angle_mid_door)*req.wall_distance;
00107 } else {
00108 res.door_pos.pose.position.x=0;
00109 res.door_pos.pose.position.y=0;
00110 }
00111 res.door_pos.pose.position.z=0;
00112 res.door_pos.pose.orientation.w=0;
00113 res.door_pos.pose.orientation.x=0;
00114 res.door_pos.pose.orientation.y=0;
00115 res.door_pos.pose.orientation.z=1;
00116
00117 res.door_pos.header.frame_id = "/camera_link";
00118 res.door_pos.header.stamp.now();
00119
00120 }
00121
00122 void laserCallback(const sensor_msgs::LaserScan::ConstPtr& scan_in)
00123 {
00124 last_scan_in = *scan_in;
00125 }