00001 
00013 #include <pcl/point_types.h>
00014 #include <math.h>
00015 
00016 #include <ground_truth/field_provider.h>
00017 
00018 #define PCL_WHITE 1.0, 1.0, 1.0
00019 #define PCL_BLUE 0.0, 0.0, 1.0
00020 #define PCL_GREEN 0.0, 1.0, 0.0
00021 #define PCL_YELLOW 1.0, 1.0, 0.0 
00022 
00023 #define CV_WHITE cvScalar(255, 255, 255)
00024 #define CV_BLUE cvScalar(255, 0, 0)
00025 #define CV_YELLOW cvScalar(0, 255, 255)
00026 #define CV_GREEN cvScalar(0, 255, 0)
00027 #define CV_RED cvScalar(0, 0, 255)
00028 #define CV_BLACK cvScalar(0,0,0)
00029 
00030 namespace ground_truth {
00031 
00035   FieldProvider::FieldProvider(float x, float y, float z) {
00036 
00037     centerField = Eigen::Vector3f(x, y, z);
00038   
00039     groundPoints[YELLOW_BASE_TOP] = Eigen::Vector3f(FIELD_X / 2, -FIELD_Y / 2, 0);
00040     groundPoints[YELLOW_BASE_PENALTY_TOP] = Eigen::Vector3f(FIELD_X / 2, -PENALTY_Y / 2, 0);
00041     groundPoints[YELLOW_BASE_PENALTY_BOTTOM] = Eigen::Vector3f(FIELD_X / 2, PENALTY_Y / 2, 0);
00042     groundPoints[YELLOW_BASE_BOTTOM] = Eigen::Vector3f(FIELD_X / 2, FIELD_Y / 2, 0);
00043     groundPoints[YELLOW_PENALTY_TOP] = Eigen::Vector3f(FIELD_X / 2 - PENALTY_X, -PENALTY_Y / 2, 0);
00044     groundPoints[YELLOW_PENALTY_BOTTOM] = Eigen::Vector3f(FIELD_X / 2 - PENALTY_X, PENALTY_Y / 2, 0);
00045     groundPoints[YELLOW_PENALTY_CROSS] = Eigen::Vector3f(PENALTY_CROSS_X, 0, 0);
00046 
00047     groundPoints[MID_TOP] = Eigen::Vector3f(0, -FIELD_Y / 2, 0);
00048     groundPoints[MID_BOTTOM] = Eigen::Vector3f(0, FIELD_Y / 2, 0);
00049 
00050     groundPoints[BLUE_BASE_TOP] = Eigen::Vector3f(-FIELD_X / 2, -FIELD_Y / 2, 0);
00051     groundPoints[BLUE_BASE_PENALTY_TOP] = Eigen::Vector3f(-FIELD_X / 2, -PENALTY_Y / 2, 0);
00052     groundPoints[BLUE_BASE_PENALTY_BOTTOM] = Eigen::Vector3f(-FIELD_X / 2, PENALTY_Y / 2, 0);
00053     groundPoints[BLUE_BASE_BOTTOM] = Eigen::Vector3f(-FIELD_X / 2, FIELD_Y / 2, 0);
00054     groundPoints[BLUE_PENALTY_TOP] = Eigen::Vector3f(-FIELD_X / 2 + PENALTY_X, -PENALTY_Y / 2, 0);
00055     groundPoints[BLUE_PENALTY_BOTTOM] = Eigen::Vector3f(-FIELD_X / 2 + PENALTY_X, PENALTY_Y / 2, 0);
00056     groundPoints[BLUE_PENALTY_CROSS] = Eigen::Vector3f(-PENALTY_CROSS_X, 0, 0);
00057 
00058     groundPoints[YELLOW_GOALPOST_TOP] = Eigen::Vector3f(FIELD_X / 2, -GOAL_Y / 2, 0);
00059     groundPoints[YELLOW_GOALPOST_BOTTOM] = Eigen::Vector3f(FIELD_X / 2, GOAL_Y / 2, 0);
00060 
00061     groundPoints[BLUE_GOALPOST_TOP] = Eigen::Vector3f(-FIELD_X / 2, -GOAL_Y / 2, 0);
00062     groundPoints[BLUE_GOALPOST_BOTTOM] = Eigen::Vector3f(-FIELD_X / 2, GOAL_Y / 2, 0);
00063 
00064     groundPoints[MID_CIRCLE_TOP] = Eigen::Vector3f(0, -CIRCLE_RADIUS, 0);
00065     groundPoints[MID_CIRCLE_BOTTOM] = Eigen::Vector3f(0, CIRCLE_RADIUS, 0);
00066 
00067     highPoints[YELLOW_GOALPOST_TOP_HIGH] = Eigen::Vector3f(FIELD_X / 2, -GOAL_Y / 2, GOAL_HEIGHT);
00068     highPoints[YELLOW_GOALPOST_BOTTOM_HIGH] = Eigen::Vector3f(FIELD_X / 2, GOAL_Y / 2, GOAL_HEIGHT);
00069     highPoints[BLUE_GOALPOST_TOP_HIGH] = Eigen::Vector3f(-FIELD_X / 2, -GOAL_Y / 2, GOAL_HEIGHT);
00070     highPoints[BLUE_GOALPOST_BOTTOM_HIGH] = Eigen::Vector3f(-FIELD_X / 2, GOAL_Y / 2, GOAL_HEIGHT);
00071 
00072     
00073     for (int i = 0; i < NUM_GROUND_PLANE_POINTS; i++) {
00074       groundPoints[i] += centerField;
00075     }
00076 
00077   }
00078 
00079   
00080 
00084   void FieldProvider::draw2dLine(IplImage* image, const Eigen::Vector3f &ep1, const Eigen::Vector3f &ep2, const CvScalar &color, int width) {
00085     cv::Point2d ep2d1, ep2d2;
00086     convertCoordinates(ep2d1, image->height, image->width, ep1);
00087     convertCoordinates(ep2d2, image->height, image->width, ep2);
00088     cvLine(image, ep2d1, ep2d2, color, width);
00089   }
00090 
00094   void FieldProvider::draw2dCenterCircle(IplImage* image, const Eigen::Vector3f ¢erPt, const Eigen::Vector3f &circlePt, const CvScalar &color, int width) {
00095     cv::Point2d center, circle;
00096     convertCoordinates(center, image->height, image->width, centerPt);
00097     convertCoordinates(circle, image->height, image->width, circlePt);
00098     float radius = sqrtf(powf(center.x - circle.x, 2) + pow(center.y - circle.y, 2));
00099     cvCircle(image, center, radius, color, width);
00100   }
00101 
00105   void FieldProvider::draw2dCircle(IplImage * image, const Eigen::Vector3f &pt, int radius, const CvScalar &color, int width) {
00106     cv::Point2d pt2d;
00107     convertCoordinates(pt2d, image->height, image->width, pt);
00108     cvCircle(image, pt2d, radius, color, width);
00109   }
00110 
00114   void FieldProvider::convertCoordinates(cv::Point2d &pos2d, int height, int width, const Eigen::Vector3f &pos3d) {
00115     float xMul = width / GRASS_X;
00116     float yMul = height / GRASS_Y;
00117     pos2d.x = xMul * -(pos3d.x() - centerField.x()) + width / 2;
00118     pos2d.y = yMul * (pos3d.y() - centerField.y()) + height / 2;
00119   }
00120 
00124   void FieldProvider::get2dField(IplImage* image, int highlightPoint) {
00125 
00126     cvZero(image);
00127 
00128     for (int i = 0; i < image->width; i++) {
00129       for (int j = 0; j < image->height; j++) {
00130         ((uchar*)(image->imageData + image->widthStep*j))[i*3+1] = 64;
00131       }
00132     }
00133 
00134     draw2dLine(image, groundPoints[YELLOW_BASE_TOP], groundPoints[YELLOW_BASE_BOTTOM], CV_WHITE, 4);
00135     draw2dLine(image, groundPoints[YELLOW_BASE_PENALTY_TOP], groundPoints[YELLOW_PENALTY_TOP], CV_WHITE, 4);
00136     draw2dLine(image, groundPoints[YELLOW_BASE_PENALTY_BOTTOM], groundPoints[YELLOW_PENALTY_BOTTOM], CV_WHITE, 4);
00137     draw2dLine(image, groundPoints[YELLOW_PENALTY_TOP], groundPoints[YELLOW_PENALTY_BOTTOM], CV_WHITE, 4);
00138     draw2dCircle(image, groundPoints[YELLOW_PENALTY_CROSS], 3, CV_WHITE, -1);
00139 
00140     draw2dLine(image, groundPoints[BLUE_BASE_TOP], groundPoints[BLUE_BASE_BOTTOM], CV_WHITE, 4);
00141     draw2dLine(image, groundPoints[BLUE_BASE_PENALTY_TOP], groundPoints[BLUE_PENALTY_TOP], CV_WHITE, 4);
00142     draw2dLine(image, groundPoints[BLUE_BASE_PENALTY_BOTTOM], groundPoints[BLUE_PENALTY_BOTTOM], CV_WHITE, 4);
00143     draw2dLine(image, groundPoints[BLUE_PENALTY_TOP], groundPoints[BLUE_PENALTY_BOTTOM], CV_WHITE, 4);
00144     draw2dCircle(image, groundPoints[BLUE_PENALTY_CROSS], 3, CV_WHITE, -1);
00145     
00146     draw2dLine(image, groundPoints[BLUE_BASE_TOP], groundPoints[YELLOW_BASE_TOP], CV_WHITE, 4);
00147     draw2dLine(image, groundPoints[BLUE_BASE_BOTTOM], groundPoints[YELLOW_BASE_BOTTOM], CV_WHITE, 4);
00148 
00149     draw2dLine(image, groundPoints[MID_TOP], groundPoints[MID_BOTTOM], CV_WHITE, 4);
00150 
00151     draw2dCenterCircle(image, centerField, groundPoints[MID_CIRCLE_TOP], CV_WHITE, 4);
00152 
00153     draw2dLine(image, groundPoints[YELLOW_GOALPOST_TOP], groundPoints[YELLOW_GOALPOST_BOTTOM], CV_YELLOW, 8);
00154     draw2dLine(image, groundPoints[BLUE_GOALPOST_TOP], groundPoints[BLUE_GOALPOST_BOTTOM], CV_BLUE, 8);
00155 
00156     if (highlightPoint >= 0 && highlightPoint < NUM_GROUND_PLANE_POINTS) {
00157       draw2dCircle(image, groundPoints[highlightPoint], 5, CV_BLACK, -1);
00158     }
00159 
00160     
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170     
00171 
00172 
00173 
00174 
00175 
00176 
00177     
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196   }
00197 
00198   
00199 
00203   void FieldProvider::draw3dLine(pcl_visualization::PCLVisualizer &visualizer, const Eigen::Vector3f &ep1, const Eigen::Vector3f &ep2, double r, double g, double b, const std::string &name) {
00204     pcl::PointXYZ ep3d1(ep1.x(), ep1.y(), ep1.z());
00205     pcl::PointXYZ ep3d2(ep2.x(), ep2.y(), ep2.z());
00206     visualizer.addLine<pcl::PointXYZ, pcl::PointXYZ>(ep3d1, ep3d2, r, g, b, "__"+name+"__");
00207     visualizer.addSphere<pcl::PointXYZ>(ep3d1, 0.02, r, g, b, "__"+name+"_pt1"+"__");
00208     visualizer.addSphere<pcl::PointXYZ>(ep3d2, 0.02, r, g, b, "__"+name+"_pt2"+"__");
00209   }
00210 
00214   void FieldProvider::draw3dCenterCircle(pcl_visualization::PCLVisualizer &visualizer, const Eigen::Vector3f ¢erPt, const Eigen::Vector3f &circlePt, double r, double g, double b, const std::string &name) {
00215     if (centerPt.z() == 0) { 
00216       pcl::ModelCoefficients circleModel;
00217       circleModel.values.push_back(centerPt.x());
00218       circleModel.values.push_back(centerPt.y());
00219       circleModel.values.push_back((circlePt - centerPt).norm());
00220       visualizer.addCircle(circleModel, "__"+name+"__");
00221     }
00222   }
00223 
00227   void FieldProvider::get3dField(pcl_visualization::PCLVisualizer &visualizer) {
00228     
00229     draw3dLine(visualizer, groundPoints[YELLOW_BASE_TOP], groundPoints[YELLOW_BASE_BOTTOM], PCL_WHITE, "yellow_base");
00230     draw3dLine(visualizer, groundPoints[YELLOW_BASE_PENALTY_TOP], groundPoints[YELLOW_PENALTY_TOP], PCL_WHITE, "yellow_penalty_top");
00231     draw3dLine(visualizer, groundPoints[YELLOW_BASE_PENALTY_BOTTOM], groundPoints[YELLOW_PENALTY_BOTTOM], PCL_WHITE, "yellow_penalty_bottom");
00232     draw3dLine(visualizer, groundPoints[YELLOW_PENALTY_TOP], groundPoints[YELLOW_PENALTY_BOTTOM], PCL_WHITE, "yellow_penalty");
00233 
00234     pcl::PointXYZ yellowCross(groundPoints[YELLOW_PENALTY_CROSS].x(), groundPoints[YELLOW_PENALTY_CROSS].y(), groundPoints[YELLOW_PENALTY_CROSS].z());
00235     visualizer.addSphere<pcl::PointXYZ>(yellowCross, 0.02, PCL_WHITE, "yellowCross");
00236 
00237     draw3dLine(visualizer, groundPoints[BLUE_BASE_TOP], groundPoints[BLUE_BASE_BOTTOM], PCL_WHITE, "blue_base");
00238     draw3dLine(visualizer, groundPoints[BLUE_BASE_PENALTY_TOP], groundPoints[BLUE_PENALTY_TOP], PCL_WHITE, "blue_penalty_top");
00239     draw3dLine(visualizer, groundPoints[BLUE_BASE_PENALTY_BOTTOM], groundPoints[BLUE_PENALTY_BOTTOM], PCL_WHITE, "blue_penalty_bottom");
00240     draw3dLine(visualizer, groundPoints[BLUE_PENALTY_TOP], groundPoints[BLUE_PENALTY_BOTTOM], PCL_WHITE, "blue_penalty");
00241 
00242     pcl::PointXYZ blueCross(groundPoints[BLUE_PENALTY_CROSS].x(), groundPoints[BLUE_PENALTY_CROSS].y(), groundPoints[BLUE_PENALTY_CROSS].z());
00243     visualizer.addSphere<pcl::PointXYZ>(blueCross, 0.02, PCL_WHITE, "blueCross");
00244     
00245     draw3dLine(visualizer, groundPoints[BLUE_BASE_TOP], groundPoints[YELLOW_BASE_TOP], PCL_WHITE, "top_long");
00246     draw3dLine(visualizer, groundPoints[BLUE_BASE_BOTTOM], groundPoints[YELLOW_BASE_BOTTOM], PCL_WHITE, "bottom_long");
00247 
00248     draw3dLine(visualizer, groundPoints[MID_TOP], groundPoints[MID_BOTTOM], PCL_WHITE, "mid_short");
00249 
00250     draw3dCenterCircle(visualizer, centerField, groundPoints[MID_CIRCLE_TOP], PCL_WHITE, "center_circle");
00251 
00252     draw3dLine(visualizer, highPoints[YELLOW_GOALPOST_TOP_HIGH], highPoints[YELLOW_GOALPOST_BOTTOM_HIGH], PCL_YELLOW, "yellow_goal_high");
00253     draw3dLine(visualizer, highPoints[BLUE_GOALPOST_TOP_HIGH], highPoints[BLUE_GOALPOST_BOTTOM_HIGH], PCL_BLUE, "blue_goal_high");
00254     draw3dLine(visualizer, highPoints[YELLOW_GOALPOST_TOP_HIGH], groundPoints[YELLOW_GOALPOST_TOP], PCL_YELLOW, "yellow_goal_top");
00255     draw3dLine(visualizer, highPoints[BLUE_GOALPOST_TOP_HIGH], groundPoints[BLUE_GOALPOST_TOP], PCL_BLUE, "blue_goal_top");
00256     draw3dLine(visualizer, highPoints[YELLOW_GOALPOST_BOTTOM_HIGH], groundPoints[YELLOW_GOALPOST_BOTTOM], PCL_YELLOW, "yellow_goal_bottom");
00257     draw3dLine(visualizer, highPoints[BLUE_GOALPOST_BOTTOM_HIGH], groundPoints[BLUE_GOALPOST_BOTTOM], PCL_BLUE, "blue_goal_bottom");
00258 
00259   }
00260 
00261 }