Go to the documentation of this file.00001
00002 #include <std_msgs/String.h>
00003
00004 #include <cv_bridge/cv_bridge.h>
00005 #include <image_transport/image_transport.h>
00006 #include <sensor_msgs/image_encodings.h>
00007 #include <boost/date_time/posix_time/posix_time.hpp>
00008
00009 #include "ScavTaskColorShirt.h"
00010
00011
00012 #define INTMAX (32767)
00013 #define INTMIN (-32767)
00014 #define COLOR_RATIO (0.25)
00015 #define DISTANCE_TO_COLOR (200)
00016
00017
00018 #define SHIRT_HEIGHT_TOP (0.5)
00019 #define SHIRT_HEIGHT_BOTTOM (-0.5)
00020
00021 sensor_msgs::ImageConstPtr image;
00022
00023 std::string path_to_image;
00024
00025 Rgb baseline;
00026
00027 std::ostream& operator<<(std::ostream&stream, const Color& color) {
00028 if (color == BLUE)
00029 stream << "Blue";
00030 else if (color == YELLOW)
00031 stream << "Yellow";
00032 else if (color == RED)
00033 stream << "Red";
00034 else if (color == GREEN)
00035 stream << "Green";
00036 else if (color == ORANGE)
00037 stream << "Orange";
00038 return stream;
00039 }
00040
00041 void ScavTaskColorShirt::callback_image_saver(const sensor_msgs::ImageConstPtr& msg) {
00042 image = msg;
00043 }
00044
00045 void ScavTaskColorShirt::callback_human_detection(const PointCloud::ConstPtr& msg) {
00046
00047 int color_cnt = 0;
00048
00049 switch (color) {
00050 case RED: baseline = Rgb(255.0, 0.0, 0.0); break;
00051 case BLUE: baseline = Rgb(0.0, 0.0, 255.0); break;
00052 case GREEN: baseline = Rgb(0.0, 255.0, 0.0); break;
00053 case YELLOW: baseline = Rgb(255.0, 255.0, 0.0); break;
00054 case ORANGE: baseline = Rgb(191.0, 87.0, 0.0); break;
00055 }
00056
00057 float highest = -10000.0;
00058 float lowest = 10000.0;
00059
00060 BOOST_FOREACH (const pcl::PointXYZRGB& pt, msg->points) {
00061
00062
00063
00064
00065 highest = (highest > pt.y) ? highest : pt.y;
00066 lowest = (lowest < pt.y) ? lowest : pt.y;
00067 if (pt.y > SHIRT_HEIGHT_BOTTOM
00068 and pt.y < SHIRT_HEIGHT_TOP
00069 and this->getColorDistance( &pt, &baseline) < DISTANCE_TO_COLOR)
00070 {
00071 color_cnt++;
00072 }
00073 }
00074 ROS_INFO_STREAM("highest: " << highest << " lowest: " << lowest);
00075
00076 float ratio = (float) color_cnt / (float) msg->points.size();
00077
00078 ROS_INFO("ratio is %f", ratio);
00079
00080 if (ratio > COLOR_RATIO && ros::ok()) {
00081
00082 ROS_INFO_STREAM("person wearing " << color << " shirt detected");
00083
00084 boost::posix_time::ptime curr_time = boost::posix_time::second_clock::local_time();
00085
00086 std::string time_str = boost::posix_time::to_iso_extended_string(curr_time);
00087
00088 cv_bridge::CvImageConstPtr cv_ptr;
00089 cv_ptr = cv_bridge::toCvShare(image, sensor_msgs::image_encodings::BGR8);
00090
00091 if (false == boost::filesystem::is_directory(directory)) {
00092 boost::filesystem::path tmp_path(directory);
00093 boost::filesystem::create_directory(tmp_path);
00094 }
00095 path_to_image = directory + "color_shirt_" + time_str + ".PNG";
00096 cv::imwrite(path_to_image, cv_ptr->image);
00097
00098 ROS_INFO_STREAM("Finished saving picture: " << path_to_image);
00099
00100 task_completed = true;
00101 }
00102 }
00103
00104 ScavTaskColorShirt::ScavTaskColorShirt(ros::NodeHandle *nh, std::string dir, Color shirt_color) {
00105 this->nh = nh;
00106 directory = dir;
00107 color = shirt_color;
00108 task_description = "find a person wearing a color shirt: ";
00109 certificate = "";
00110
00111 std::string str;
00112 if (color == BLUE) str = "Blue";
00113 else if (color == YELLOW) str = "Yellow";
00114 else if (color == RED) str = "Red";
00115 else if (color == GREEN) str = "Green";
00116 else if (color == ORANGE) str = "Orange";
00117
00118 task_name = "Color shirt: " + str;
00119
00120 task_completed = false;
00121 std::ostringstream stream;
00122 stream << color;
00123 task_parameters.push_back(stream.str());
00124 }
00125
00126 void ScavTaskColorShirt::motionThread() {
00127
00128 std::string path_to_yaml;
00129
00130 if (false == nh->hasParam("path_to_search_points"))
00131 ROS_ERROR("path to yaml file of search points not set");
00132 ros::param::get("path_to_search_points", path_to_yaml);
00133
00134 search_planner_simple = new SearchPlannerSimple(nh);
00135
00136 int next_goal_index;
00137 while (ros::ok() and task_completed == false) {
00138 search_planner_simple->moveToNextDoor();
00139 }
00140 }
00141
00142 void ScavTaskColorShirt::visionThread() {
00143
00144 ros::Subscriber sub1 = nh->subscribe("/segbot_pcl_person_detector/human_clouds", 1,
00145 &ScavTaskColorShirt::callback_human_detection, this);
00146
00147 image_transport::ImageTransport it(*nh);
00148 image_transport::Subscriber sub = it.subscribe("/nav_kinect/rgb/image_raw", 1,
00149 &ScavTaskColorShirt::callback_image_saver, this);
00150
00151 ros::Rate rate(10);
00152
00153 while (ros::ok() and rate.sleep() and task_completed == false) {
00154 ros::spinOnce();
00155 }
00156 }
00157
00158 void ScavTaskColorShirt::executeTask(int timeout, TaskResult &result, std::string &record)
00159 {
00160
00161 boost::thread motion( &ScavTaskColorShirt::motionThread, this);
00162 boost::thread vision( &ScavTaskColorShirt::visionThread, this);
00163
00164 ros::Rate r(2);
00165 while (ros::ok() and r.sleep()) {
00166 if (task_completed) {
00167 search_planner_simple->cancelCurrentGoal();
00168 break;
00169 }
00170 }
00171
00172 motion.detach();
00173 vision.detach();
00174
00175 record = path_to_image;
00176 result = SUCCEEDED;
00177 }
00178
00179 void ScavTaskColorShirt::stopEarly() {
00180 task_completed = true;
00181 }