monitor_server.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "nav_msgs/Odometry.h"                  // odom
00003 #include "opencv2/highgui/highgui.hpp"
00004 #include "opencv2/imgproc/imgproc.hpp"
00005 #include "sensor_msgs/image_encodings.h"
00006 #include "tf/transform_broadcaster.h"
00007 #include "cirkit_waypoint_navigator/TeleportAbsolute.h"
00008 
00009 #include <stdio.h>
00010 
00011 const static std::string PARAM_NAME_RATIO_PARAM = "/ratio";
00012 const static std::string MAP_PATH = "/map/";
00013 const static std::string PARAM_NAME_MAP_NAME = "/image";
00014 const static std::string PARAM_NAME_MAP_RESOLUTION = "/resolution";
00015 const static std::string PARAM_NAME_MAP_ORIGIN = "/origin";
00016 const static std::string MAP_WINDOW_NAME = "Map Monitor";
00017 const static int ROS_SPIN_RATE = 100;
00018 const static int CV_WAIT_KEY_RATE = 50;
00019 const static cv::Scalar RED = cv::Scalar(0, 0, 255);
00020 const static cv::Scalar GREEN = cv::Scalar(0, 128, 0);
00021 const static cv::Scalar BLUE = cv::Scalar(255, 0, 0);
00022 const static int ARROW_LENGTH = 10;
00023 
00024 // default
00025 const static std::string DEFAULT_MAP_NAME = "201510240538.pgm";
00026 const static double DEFAULT_MAP_RESOLUTION = 0.1;
00027 const static double DEFAULT_RESIZE_RATIO = 0.2;
00028 
00029 enum WAIT_KEY_MODE
00030 {
00031     CURR_POSITON,
00032     HISTORY_POSITION,
00033     QUIT
00034 };
00035 
00036 enum RESULT
00037 {
00038     OK,
00039     NG
00040 };
00041 
00042 enum MAP_COORD
00043 {
00044     INDEX_X,
00045     INDEX_Y,
00046     INDEX_Z
00047 };
00048 
00049 
00050 class RemoteMonitorServer
00051 {
00052 public:
00053     bool getRobotPose(cirkit_waypoint_navigator::TeleportAbsolute::Request  &req,
00054                       cirkit_waypoint_navigator::TeleportAbsolute::Response &res);
00055     bool getHumanPose(cirkit_waypoint_navigator::TeleportAbsolute::Request  &req,
00056                       cirkit_waypoint_navigator::TeleportAbsolute::Response &res);
00057 
00058     RemoteMonitorServer(const std::string i_image_path, const std::string i_name_space)
00059        : rate_(ROS_SPIN_RATE), state_(CURR_POSITON)
00060     {
00061         //ros::NodeHandle n("~");
00062         //rate_ = ROS_SPIN_RATE;
00063         map_origin_.clear();
00064         server_robot_pose_ = nh_.advertiseService<cirkit_waypoint_navigator::TeleportAbsolute::Request,
00065                 cirkit_waypoint_navigator::TeleportAbsolute::Response>
00066                 ("remote_monitor_robot_pose", boost::bind(&RemoteMonitorServer::getRobotPose, this, _1, _2));
00067         server_human_pose_ = nh_.advertiseService<cirkit_waypoint_navigator::TeleportAbsolute::Request,
00068                 cirkit_waypoint_navigator::TeleportAbsolute::Response>
00069                 ("remote_monitor_human_pose", boost::bind(&RemoteMonitorServer::getHumanPose, this, _1, _2));
00070 
00071         this->loadRosParam(i_image_path, i_name_space);
00072     }
00073 
00074     void drawRobotPoseOnMap(cirkit_waypoint_navigator::TeleportAbsolute::Request &req)
00075     {
00076         // only current point
00077         drawArrow(map_img_pos_curr_, req);
00078         // all pos history
00079         drawArrow(map_img_pos_hist_, req);
00080     }
00081 
00082     void drawArrow(cv::Mat &img, cirkit_waypoint_navigator::TeleportAbsolute::Request &req)
00083     {
00084         // only current pos
00085         map_img_ori_small_.copyTo(map_img_pos_curr_);
00086         //-- center of the robot on the map
00087         double x_map_center = (req.x - map_origin_[INDEX_X]) * resize_ratio_curr_ / map_resolution_;
00088         double y_map_center = map_img_pos_curr_.rows - (req.y - map_origin_[INDEX_Y]) / map_resolution_ * resize_ratio_curr_;
00089 
00090         int w = 10;
00091         int h = 15;
00092         int lineType = 8;
00093 
00095         cv::Point rook_points[1][4];
00096         double p1_x_ori = (x_map_center-w*0.5) + w*0.5;
00097         double p1_y_ori = (y_map_center-h*0.5) + 0.0;
00098         double p2_x_ori = (x_map_center-w*0.5) + 0;
00099         double p2_y_ori = (y_map_center-h*0.5) + h;
00100         double p3_x_ori = (x_map_center-w*0.5) + w*0.5;
00101         double p3_y_ori = (y_map_center-h*0.5) + h*0.7;
00102         double p4_x_ori = (x_map_center-w*0.5) + w;
00103         double p4_y_ori = (y_map_center-h*0.5) + h;
00104 
00105         double cos_rot = cos(-req.theta + M_PI*0.5);
00106         double sin_rot = sin(-req.theta + M_PI*0.5);
00107 
00108         double p1_x_rot = cos_rot*(p1_x_ori-x_map_center) - sin_rot*(p1_y_ori-y_map_center);
00109         double p1_y_rot = sin_rot*(p1_x_ori-x_map_center) + cos_rot*(p1_y_ori-y_map_center);
00110         double p2_x_rot = cos_rot*(p2_x_ori-x_map_center) - sin_rot*(p2_y_ori-y_map_center);
00111         double p2_y_rot = sin_rot*(p2_x_ori-x_map_center) + cos_rot*(p2_y_ori-y_map_center);
00112         double p3_x_rot = cos_rot*(p3_x_ori-x_map_center) - sin_rot*(p3_y_ori-y_map_center);
00113         double p3_y_rot = sin_rot*(p3_x_ori-x_map_center) + cos_rot*(p3_y_ori-y_map_center);
00114         double p4_x_rot = cos_rot*(p4_x_ori-x_map_center) - sin_rot*(p4_y_ori-y_map_center);
00115         double p4_y_rot = sin_rot*(p4_x_ori-x_map_center) + cos_rot*(p4_y_ori-y_map_center);
00116 
00117         p1_x_rot += x_map_center;
00118         p1_y_rot += y_map_center;
00119         p2_x_rot += x_map_center;
00120         p2_y_rot += y_map_center;
00121         p3_x_rot += x_map_center;
00122         p3_y_rot += y_map_center;
00123         p4_x_rot += x_map_center;
00124         p4_y_rot += y_map_center;
00125 
00126         rook_points[0][0] = cv::Point(p1_x_rot, p1_y_rot);
00127         rook_points[0][1] = cv::Point(p2_x_rot, p2_y_rot);
00128         rook_points[0][2] = cv::Point(p3_x_rot, p3_y_rot);
00129         rook_points[0][3] = cv::Point(p4_x_rot, p4_y_rot);
00130 
00131         const cv::Point* ppt[1] = { rook_points[0] };
00132         int npt[] = { 4 };
00133 
00134         cv::fillPoly( img, ppt, npt, 1, GREEN, lineType );
00135     }
00136 
00137     void drawHumanPoseOnMap(cirkit_waypoint_navigator::TeleportAbsolute::Request &req)
00138     {
00139         // only current pos
00140         map_img_ori_small_.copyTo(map_img_pos_curr_);
00141         //-- center of the robot on the map
00142         double x_map_center = (req.x - map_origin_[INDEX_X]) * resize_ratio_curr_ / map_resolution_;
00143         double y_map_center = map_img_pos_curr_.rows - (req.y - map_origin_[INDEX_Y]) / map_resolution_ * resize_ratio_curr_;
00144         point_curr_ = cv::Point(x_map_center, y_map_center);
00145 
00146         // only current point
00147         drawHuman(map_img_pos_curr_, point_curr_);
00148         // all pos history
00149         drawHuman(map_img_pos_hist_, point_curr_);
00150     }
00151 
00152     void drawHuman(cv::Mat &img, const cv::Point2f pos)
00153     {
00154         const double body_len = 18.0;
00155         const double arm_len = 12.0;
00156         const double leg_len = 14.0;
00157         cv::Point point_body = cv::Point(pos.x, pos.y + body_len);
00158         cv::Point point_chest = cv::Point(pos.x, pos.y + body_len * 0.7);
00159         cv::Point point_arm_r = cv::Point(pos.x + arm_len, pos.y + arm_len * 0.25);
00160         cv::Point point_arm_l = cv::Point(pos.x - arm_len, pos.y + arm_len * 0.25);
00161         cv::Point point_leg_r = cv::Point(pos.x + leg_len * 0.25, pos.y + body_len + leg_len);
00162         cv::Point point_leg_l = cv::Point(pos.x - leg_len * 0.25, pos.y + body_len + leg_len);
00163 
00164         //-- draw
00165         cv::circle(img, point_curr_, 7, RED, -1, CV_AA);
00166         cv::line(img, point_curr_, point_body, RED, 2);
00167         cv::line(img, point_chest, point_arm_r, RED, 2);
00168         cv::line(img, point_chest, point_arm_l, RED, 2);
00169         cv::line(img, point_body, point_leg_r, RED, 2);
00170         cv::line(img, point_body, point_leg_l, RED, 2);
00171     }
00172 
00173     int waitKeyJudge(const int i_key)
00174     {
00175         int ret = 0;
00176 
00177         // current pose
00178         if(i_key == 'c' || i_key == 'C')
00179         {
00180             ret = CURR_POSITON;
00181         }
00182         // history of pose
00183         else if(i_key == 'h' || i_key == 'H')
00184         {
00185             ret = HISTORY_POSITION;
00186         }
00187         // reset history
00188         else if(i_key == 'r' || i_key == 'R')
00189         {
00190             // reset
00191             map_img_ori_small_.copyTo(map_img_pos_hist_);
00192             // redraw current position
00193             drawArrow(map_img_pos_curr_, req_);
00194 
00195             // keep original state
00196             ret = state_;
00197         }
00198         // zoom
00199         else if(i_key == 'p' || i_key == 'P')
00200         {
00201             resize_ratio_prev_ = resize_ratio_curr_;
00202             resize_ratio_curr_ += 0.05;
00203             ret = state_;
00204 
00205             // resize
00206             // resize
00207             cv::resize(map_img_ori_, map_img_ori_small_, cv::Size(), resize_ratio_curr_, resize_ratio_curr_, cv::INTER_LINEAR);
00208             map_img_pos_curr_ = map_img_ori_small_.clone();
00209             map_img_pos_hist_ = map_img_ori_small_.clone();
00210 
00211             drawRobotPoseOnMap(req_);
00212         }
00213         // fade
00214         else if(i_key == 'm' || i_key == 'M')
00215         {
00216             resize_ratio_prev_ = resize_ratio_curr_;
00217             resize_ratio_curr_ -= 0.05;
00218             ret = state_;
00219 
00220             // resize
00221             cv::resize(map_img_ori_, map_img_ori_small_, cv::Size(), resize_ratio_curr_, resize_ratio_curr_, cv::INTER_LINEAR);
00222             map_img_pos_curr_ = map_img_ori_small_.clone();
00223             map_img_pos_hist_ = map_img_ori_small_.clone();
00224 
00225             drawRobotPoseOnMap(req_);
00226         }
00227         // 'Esc' or 'q'が押された場合に終了
00228         else if(i_key == 27 || i_key == 'q' || i_key == 'Q')
00229         {
00230             ret = QUIT;
00231         }
00232         else
00233         {
00234             // do nothing
00235             ret = true;
00236         }
00237 
00238         return ret;
00239     }
00240 
00241     void showMap()
00242     {
00243         // current pose
00244         if(state_ == CURR_POSITON)
00245         {
00246             cv::imshow(MAP_WINDOW_NAME, map_img_pos_curr_);
00247         }
00248         // history of pose
00249         else if(state_ == HISTORY_POSITION)
00250         {
00251             cv::imshow(MAP_WINDOW_NAME, map_img_pos_hist_);
00252         }
00253         else
00254         {
00255             cv::imshow(MAP_WINDOW_NAME, map_img_pos_curr_);
00256         }
00257     }
00258 
00259     void runMainLoop()
00260     {
00261       while(nh_.ok())
00262       {
00263           //cv::imshow(MAP_WINDOW_NAME, map_img_pos_curr_);
00264           int key = cv::waitKey(CV_WAIT_KEY_RATE);
00265           if(key >= 0)
00266               state_ = waitKeyJudge(key);
00267 
00268           if(state_ == QUIT)
00269               break;
00270           else
00271               showMap();
00272 
00273           ros::spinOnce();
00274           rate_.sleep();
00275       }
00276     }
00277 
00278     int loadMapImage()
00279     {
00280         map_img_ori_ = cv::imread(image_path_);
00281 
00282         if(map_img_ori_.rows == 0 || map_img_ori_.cols == 0)
00283         {
00284           ROS_ERROR("image path is %s was not found.", image_path_.c_str());
00285           return NG;
00286         }
00287 
00288         ROS_INFO("image %s was successfully loaded.", image_path_.c_str());
00289         // resize
00290         cv::resize(map_img_ori_, map_img_ori_small_, cv::Size(), resize_ratio_curr_, resize_ratio_curr_, cv::INTER_LINEAR);
00291         map_img_pos_curr_ = map_img_ori_small_.clone();
00292         map_img_pos_hist_ = map_img_ori_small_.clone();
00293     }
00294 
00295 private:
00296     void loadRosParam(const std::string i_image_path, const std::string i_name_space)
00297     {
00298         // map file name
00299         image_path_ = i_image_path + MAP_PATH;
00300         nh_.param<std::string>(i_name_space + PARAM_NAME_MAP_NAME, image_name_, DEFAULT_MAP_NAME);
00301         image_path_ += image_name_;
00302         ROS_INFO("image path is %s.", image_path_.c_str());
00303 
00304         // resize_ratio
00305         nh_.param(i_name_space + PARAM_NAME_RATIO_PARAM, resize_ratio_curr_, DEFAULT_RESIZE_RATIO);
00306         // resolution
00307         nh_.param(i_name_space + PARAM_NAME_MAP_RESOLUTION, map_resolution_, DEFAULT_MAP_RESOLUTION);
00308         // origin(array)
00309         XmlRpc::XmlRpcValue origin_list;
00310         nh_.getParam(i_name_space + PARAM_NAME_MAP_ORIGIN, origin_list);
00311         ROS_ASSERT(origin_list.getType() == XmlRpc::XmlRpcValue::TypeArray);
00312 
00313         for (int32_t i = 0; i < origin_list.size(); ++i)
00314         {
00315             ROS_ASSERT(origin_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00316             map_origin_.push_back(static_cast<double>(origin_list[i]));
00317         }
00318     }
00319 
00320 private:
00321     ros::NodeHandle nh_;
00322     ros::Rate rate_;
00323     ros::ServiceServer server_robot_pose_;
00324     ros::ServiceServer server_human_pose_;
00325     std::string image_path_;
00326     std::string image_name_;
00327     double resize_ratio_curr_;
00328     double resize_ratio_prev_;
00329     double map_resolution_;
00330     std::vector<double> map_origin_;
00331     cv::Point point_curr_;
00332     cv::Point point_tip_;
00333     // images
00334     cv::Mat map_img_ori_;
00335     cv::Mat map_img_ori_small_;
00336     cv::Mat map_img_pos_curr_;
00337     cv::Mat map_img_pos_hist_;
00338     // state
00339     cirkit_waypoint_navigator::TeleportAbsolute::Request req_;
00340     int state_;
00341 };
00342 
00343 
00344 bool RemoteMonitorServer::getRobotPose(cirkit_waypoint_navigator::TeleportAbsolute::Request  &req,
00345                                        cirkit_waypoint_navigator::TeleportAbsolute::Response &res)
00346 {
00347     ROS_INFO("RobotPose: [x] -> %6.2f, [y] -> %6.2f, [theta] -> %6.2f", req.x, req.y, req.theta);
00348 
00349     req_ = req;
00350     drawRobotPoseOnMap(req);
00351 
00352     return true;
00353 }
00354 
00355 bool RemoteMonitorServer::getHumanPose(cirkit_waypoint_navigator::TeleportAbsolute::Request  &req,
00356                                        cirkit_waypoint_navigator::TeleportAbsolute::Response &res)
00357 {
00358     ROS_INFO("HumanPose: [x] -> %6.2f, [y] -> %6.2f, [theta] -> %6.2f", req.x, req.y, req.theta);
00359 
00360     req_ = req;
00361     drawHumanPoseOnMap(req);
00362 
00363     return true;
00364 }
00365 
00366 int fillPolygonAndShow()
00367 {
00368     int w = 20;
00369     cv::Mat img = cv::Mat::zeros( w, w, CV_8UC3 );
00370     int lineType = 8;
00371 
00373     cv::Point rook_points[1][4];
00374     rook_points[0][0] = cv::Point(w*0.5, 0.0);
00375     rook_points[0][1] = cv::Point(0, w);
00376     rook_points[0][2] = cv::Point(w*0.5, w*0.7);
00377     rook_points[0][3] = cv::Point(w, w);
00378 
00379     const cv::Point* ppt[1] = { rook_points[0] };
00380     int npt[] = { 4 };
00381 
00382     cv::fillPoly( img, ppt, npt, 1, GREEN, lineType );
00383 
00384     cv::Point2f center(img.cols*0.5, img.rows*0.5);
00385     //const cv::Mat affine_matrix = cv::getRotationMatrix2D( center, angle, scale );
00386 
00387     cv::imshow("test", img);
00388     int key = cv::waitKey();
00389 
00390     if(key == 27 || key == 'q' || key == 'Q')
00391         return -1;
00392 }
00393 
00394 int humanDrawAndShow()
00395 {
00396 
00397     int w = 20;
00398     cv::Mat img = cv::Mat::zeros( w, w, CV_8UC3 );
00399     int lineType = 8;
00400 
00402     cv::Point rook_points[1][4];
00403     rook_points[0][0] = cv::Point(w*0.5, 0.0);
00404     rook_points[0][1] = cv::Point(0, w);
00405     rook_points[0][2] = cv::Point(w*0.5, w*0.7);
00406     rook_points[0][3] = cv::Point(w, w);
00407 
00408     const cv::Point* ppt[1] = { rook_points[0] };
00409     int npt[] = { 4 };
00410 
00411     cv::fillPoly( img, ppt, npt, 1, GREEN, lineType );
00412 
00413     cv::Point2f center(img.cols*0.5, img.rows*0.5);
00414     //const cv::Mat affine_matrix = cv::getRotationMatrix2D( center, angle, scale );
00415 
00416     cv::imshow("test", img);
00417     int key = cv::waitKey();
00418 
00419     if(key == 27 || key == 'q' || key == 'Q')
00420         return -1;
00421 }
00422 
00423 int main(int argc, char **argv)
00424 {
00425     /*
00426     if (fillPolygonAndShow() == -1)
00427         return -1;
00428         */
00429 
00430     ros::init(argc, argv, "remote_monitor_server");
00431 
00432     if(argc < 3)
00433     {
00434         ROS_ERROR("Short of arguments. map package path and namespace must be given.");
00435         ROS_ERROR("Aborting remote_monitor_server...");
00436         return -1;
00437     }
00438 
00439     std::string map_package_path = argv[1];
00440     std::string ns = argv[2];
00441     RemoteMonitorServer monitor_server(map_package_path, ns);
00442 
00443     if(monitor_server.loadMapImage() == NG)
00444     {
00445         ROS_ERROR("Aborting remote_monitor_server...");
00446         return -1;
00447     }
00448 
00449     monitor_server.runMainLoop();
00450 
00451     return 0;
00452 }


remote_monitor
Author(s): CIR-KIT
autogenerated on Thu Jun 6 2019 20:33:41