Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _cleaning_plan_alg_h_
00026 #define _cleaning_plan_alg_h_
00027
00028 #include <iri_clean_board/CleaningPlanConfig.h>
00029 #include "mutex.h"
00030
00031
00032 #include <ellipses_representation.h>
00033
00034
00035 #include <cv_bridge/cv_bridge.h>
00036 #include <sensor_msgs/image_encodings.h>
00037 #include <opencv2/imgproc/imgproc.hpp>
00038
00039
00040 #include <estirabot_msgs/PointsDistanceMsg.h>
00041 #include <estirabot_msgs/ArrayIndexes.h>
00042
00043
00044 #include <pcl/point_cloud.h>
00045 #include <pcl/io/pcd_io.h>
00046 #include <pcl/point_types.h>
00047 #include <pcl/common/common.h>
00048 #include <pcl_conversions/pcl_conversions.h>
00049
00050
00051 #include <tf/transform_datatypes.h>
00052 #include <Eigen/Core>
00053 #include <Eigen/Geometry>
00054
00055
00061 class CleaningPlanAlgorithm
00062 {
00063 protected:
00070 CMutex alg_mutex_;
00071
00072
00073 static const int IMAGE_WIDTH = 640;
00074 static const int IMAGE_HEIGHT = 480;
00075
00076
00077 uint32_t movements_offset;
00078 double small_objects_min, small_objects_max;
00079 bool two_arms_version;
00080 bool board_plan;
00081 bool rotate_hand;
00082 double pose_yaw;
00083 std::string camera_frame;
00084
00085
00086 double away_from_surface_distance;
00087
00088
00093 void movePoseAwayFromSurface(geometry_msgs::PoseStamped &pose, std::vector<float> plane_coeffs);
00094
00098 std::vector< cv::Point2f > getPointsSmallClean(cv::RotatedRect ellipse);
00099
00104 std::vector< cv::Point2f > getPointsLastSmallClean(cv::RotatedRect ellipse);
00105
00109 std::vector< cv::Point2f > getPointsStraightClean(cv::RotatedRect ellipse);
00110
00114 std::vector< cv::Point2f > getPointsCircularClean(cv::RotatedRect ellipse);
00115
00119 std::vector< cv::Point2f > getPointsGroupObjects(cv::RotatedRect ellipse);
00120
00124 std::vector< cv::Point2f > getPointsJoinGroups(std::vector<cv::RotatedRect> ellipses);
00125
00129 std::vector< cv::Point2f > getPointsPickUp(cv::RotatedRect ellipse);
00130
00136 std::vector< cv::Point2f > getNoPerceptionPoints(cv::Mat image);
00137
00148 std::vector< cv::Point2f > getPointsMoveToContainer(cv::RotatedRect& ellipse, int max_steps = 1);
00149
00150
00156 void posesFromImageCoordinates(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
00157 std::vector< cv::Point2f > img_coords,
00158 std::vector<float> plane_coeffs,
00159 double orientation_yaw,
00160 std::vector<geometry_msgs::PoseStamped> &poses,
00161 std::vector<iri_perception_msgs::ImagePoint> &poses_coords,
00162 uint8_t secondary_arm_movements,
00163 std::vector<uint8_t> &secondary_arm);
00164
00165
00171 geometry_msgs::Quaternion quaternionFrom3dVector(std::vector<float> plane_coefs, double new_yaw = 0);
00172
00173
00174
00175
00176 inline double getDistance(cv::Point2f p1, cv::Point2f p2)
00177 {
00178
00179 return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
00180 }
00181
00182 inline double getAngle2D (const Eigen::Vector2f &v1, const Eigen::Vector2f &v2)
00183 {
00184
00185 double rad = v1.dot (v2) / sqrt (v1.squaredNorm () * v2.squaredNorm ());
00186 if (rad < -1.0) rad = -1.0;
00187 if (rad > 1.0) rad = 1.0;
00188 double res = acos(rad);
00189
00190
00191
00192
00193
00194
00195
00196 if (res != res)
00197 res = 0;
00198
00199 return res;
00200 }
00201
00202 inline double getAngle2DwithAxisX (const cv::Point2f &v1, const cv::Point2f &v2)
00203 {
00204 Eigen::Vector2f ev;
00205 ev[0] = v2.x - v1.x;
00206 ev[1] = v2.y - v1.y;
00207
00208 if (ev[1] > 0)
00209 return -getAngle2D(Eigen::Vector2f(-1,0),ev);
00210 else
00211 return getAngle2D(Eigen::Vector2f(-1,0),ev);
00212 }
00213
00214
00215 inline double
00216 pointToPlaneDistance (const pcl::PointXYZ &p, const std::vector< float > &plane_coefficients)
00217 {
00218 return ( fabs (pointToPlaneDistanceSigned (p, plane_coefficients)) );
00219 }
00220
00221 inline double
00222 pointToPlaneDistanceSigned (const pcl::PointXYZ &p, const std::vector< float > &plane_coefficients)
00223 {
00224 return ( plane_coefficients[0] * p.x + plane_coefficients[1] * p.y + plane_coefficients[2] * p.z + plane_coefficients[3] );
00225 }
00226
00233 int32_t getNearestPoint(std::vector< cv::Point2f > points1, std::vector< cv::Point2f > points2);
00234
00235
00236 public:
00243 typedef iri_clean_board::CleaningPlanConfig Config;
00244
00251 Config config_;
00252
00261 CleaningPlanAlgorithm(void);
00262
00268 void lock(void) { alg_mutex_.enter(); };
00269
00275 void unlock(void) { alg_mutex_.exit(); };
00276
00284 bool try_enter(void) { return alg_mutex_.try_enter(); };
00285
00297 void config_update(Config& new_cfg, uint32_t level=0);
00298
00299
00300
00301
00308 ~CleaningPlanAlgorithm(void);
00309
00310
00326 bool getMovementFromAction(std::vector< estirabot_msgs::DirtyArea > dirty_areas,
00327 std::string action, estirabot_msgs::ArrayIndexes target_ellipses,
00328 EllipsesRepresentation& ellipses_rep,
00329 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
00330 std::vector<float> plane_coeffs,
00331 std::vector<geometry_msgs::PoseStamped> &poses,
00332 std::vector<iri_perception_msgs::ImagePoint> &poses_img_coords,
00333 std::vector<uint8_t> &secondary_arm);
00334
00342 void processedPosesFromImageCoordinates(EllipsesRepresentation& ellipses_rep,
00343 const pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
00344 const std::vector< cv::Point2f > img_coords,
00345 const std::vector<float> plane_coeffs,
00346 const uint8_t secondary_arm_movements,
00347 const double orientation_yaw,
00348 std::vector<geometry_msgs::PoseStamped> &poses,
00349 std::vector<iri_perception_msgs::ImagePoint> &poses_img_coords,
00350 std::vector<uint8_t> &secondary_arm);
00351 };
00352
00353 #endif