Verify_result.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // Created by zx on 2020/1/10.
  3. //
  4. #include "Verify_result.h"
  5. #include <glog/logging.h>
  6. /*
  7. * 显示rotate rect
  8. */
  9. void display(cv::RotatedRect rect,cv::Scalar color)
  10. {
  11. return ;
  12. cv::Point2f points_src[4];
  13. rect.points(points_src);
  14. cv::Mat image=cv::Mat::zeros(1000,500,CV_8UC3);
  15. cv::RotatedRect t_rect=rect;
  16. t_rect.center=cv::Point2f(250,500);
  17. t_rect.size.width/=10.0;
  18. t_rect.size.height/=10.0;
  19. cv::Point2f points[4];
  20. t_rect.points(points);
  21. float min_x=10000,max_x=0;
  22. for(int i=0;i<4;++i)
  23. {
  24. if(points_src[i].x<min_x)
  25. min_x=points_src[i].x;
  26. if(points_src[i].x>max_x)
  27. max_x=points_src[i].x;
  28. cv::line(image, points[i%4],points[(i+1)%4],color,2);
  29. }
  30. char buf[255]={0};
  31. sprintf(buf,"(%.1f,%.1f)[%.1f,%.1f] c:%.1f",t_rect.size.height*10.0,t_rect.size.width*10.0,min_x,max_x,t_rect.angle);
  32. cv::putText(image,buf,cv::Point(10,50),1,1.0,color);
  33. cv::namedWindow("debug",0);
  34. cv::imshow("debug",image);
  35. cv::waitKey(0);
  36. }
  37. /*
  38. * 构造函数
  39. * parameter:硬件限制配置参数
  40. */
  41. Verify_result::Verify_result(Hardware_limit::Hardware_parameter parameter)
  42. {
  43. m_hardware_parameter=parameter;
  44. }
  45. /*
  46. * 检验硬件限制
  47. * rotate_rect:待检验的旋转矩形
  48. */
  49. Error_manager Verify_result::verify(cv::RotatedRect rotate_rect,float height,bool verify_vertex)
  50. {
  51. //-2300 3450
  52. cv::Point2f t_corners[4];
  53. rotate_rect.points(t_corners);
  54. //第一步,检验边界
  55. float corner_min_y=m_hardware_parameter.corner_min_y();
  56. float corner_max_y=m_hardware_parameter.corner_max_y();
  57. float center_minx=m_hardware_parameter.center_min_x();
  58. float center_maxx=m_hardware_parameter.center_max_x();
  59. float center_miny=m_hardware_parameter.center_min_y();
  60. float center_maxy=m_hardware_parameter.center_max_y();
  61. float center_x=rotate_rect.center.x;
  62. float center_y=rotate_rect.center.y;
  63. //左超界
  64. if(center_x<center_minx)
  65. {
  66. return Error_manager(HARDWARE_LIMIT_CENTER_X_LEFT,NORMAL,"left limit");
  67. }
  68. //右超界
  69. if(center_x>center_maxx)
  70. {
  71. return Error_manager(HARDWARE_LIMIT_CENTER_X_RIGHT,NORMAL,"right limit");
  72. }
  73. //前超界
  74. if(center_y>center_maxy)
  75. {
  76. return Error_manager(HARDWARE_LIMIT_CENTER_Y_TOP,NORMAL,"top limit");
  77. }
  78. for(int i=0;i<4;++i)
  79. {
  80. if(t_corners[i].y>corner_max_y)
  81. {
  82. return Error_manager(HARDWARE_LIMIT_CENTER_Y_TOP,NORMAL,"corner top limit");
  83. }
  84. }
  85. //后超界
  86. if(center_y<center_miny)
  87. {
  88. return Error_manager(HARDWARE_LIMIT_CENTER_Y_BOTTOM,NORMAL,"bottom limit");
  89. }
  90. for(int i=0;i<4;++i)
  91. {
  92. if(t_corners[i].y<corner_min_y)
  93. {
  94. return Error_manager(HARDWARE_LIMIT_CENTER_Y_BOTTOM,NORMAL,"corner bottom limit");
  95. }
  96. }
  97. //第二步,检验高度
  98. if(height>m_hardware_parameter.height())
  99. {
  100. char description[255]={0};
  101. sprintf(description,"locate height is out of range(%.2f),height:%.2f",m_hardware_parameter.height(),height);
  102. return Error_manager(HARDWARE_LIMIT_HEIGHT_OUT_RANGE,NORMAL,description);
  103. }
  104. //第三步,检验角度
  105. //计算角度到 0-180
  106. // 长边向量
  107. cv::Point2f vec;
  108. cv::Point2f vertice[4];
  109. rotate_rect.points(vertice);
  110. float len1 = pow(vertice[0].x - vertice[1].x, 2.0) + pow(vertice[0].y - vertice[1].y, 2.0);
  111. float len2 = pow(vertice[1].x - vertice[2].x, 2.0) + pow(vertice[1].y - vertice[2].y, 2.0);
  112. // 寻找长边,倾角为长边与x轴夹角
  113. if (len1 > len2)
  114. {
  115. vec.x = vertice[0].x - vertice[1].x;
  116. vec.y = vertice[0].y - vertice[1].y;
  117. }
  118. else
  119. {
  120. vec.x = vertice[1].x - vertice[2].x;
  121. vec.y = vertice[1].y - vertice[2].y;
  122. }
  123. float angle_x = 180.0 / M_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
  124. bool tb_theta_verify=false;
  125. for(int i=0;i<m_hardware_parameter.theta_range_size();++i)
  126. {
  127. Hardware_limit::Theta_range theta_range=m_hardware_parameter.theta_range(i);
  128. float min_theta=theta_range.min_theta();
  129. float max_theta=theta_range.max_theta();
  130. //角度检验, 根据plc限制
  131. if( angle_x>=min_theta&&angle_x<=max_theta)
  132. {
  133. tb_theta_verify = true;
  134. }
  135. }
  136. if(tb_theta_verify==false)
  137. {
  138. char description[255]={0};
  139. sprintf(description,"locate theta is out of range,theta:%.2f",angle_x);
  140. return Error_manager(HARDWARE_LIMIT_ANGLE_OUT_RANGE,NORMAL,description);
  141. }
  142. //是否检验顶点与栏杆的碰撞
  143. if(verify_vertex==false)
  144. {
  145. return SUCCESS;
  146. }
  147. //第二步,检验栏杆是否碰撞
  148. //创建栏杆
  149. const int railing_count=m_hardware_parameter.railing_parameter_size();
  150. if(railing_count==0)
  151. return SUCCESS;
  152. for(int i=0;i<railing_count;++i)
  153. {
  154. Hardware_limit::Railing railing_parameter=m_hardware_parameter.railing_parameter(i);
  155. Railing* tp_railing=new Railing(railing_parameter.pa(),railing_parameter.pb(),railing_parameter.pc(),
  156. railing_parameter.railing_width());
  157. if(tp_railing!=NULL)
  158. {
  159. Error_manager code;
  160. code=tp_railing->verify(rotate_rect);
  161. delete tp_railing;
  162. if(code!=SUCCESS)
  163. {
  164. return code;
  165. }
  166. }
  167. }
  168. return SUCCESS;
  169. }
  170. /*
  171. * 检验硬件限制
  172. * rotate_rect:待检验的旋转矩形
  173. * height:输入高度
  174. * terminal_id:终端编号,终端对应的左右栏杆号为: id,id+1
  175. */
  176. Error_manager Verify_result::verify(cv::RotatedRect rotate_rect,int terminal_id,int& code)
  177. {
  178. display(rotate_rect,cv::Scalar(0,255,0));
  179. cv::Point2f t_corners[4];
  180. rotate_rect.points(t_corners);
  181. code=0x000000;
  182. //第一步,检验边界
  183. float corner_min_y=m_hardware_parameter.corner_min_y();
  184. float corner_max_y=m_hardware_parameter.corner_max_y();
  185. float center_minx=m_hardware_parameter.center_min_x();
  186. float center_maxx=m_hardware_parameter.center_max_x();
  187. float center_miny=m_hardware_parameter.center_min_y();
  188. float center_maxy=m_hardware_parameter.center_max_y();
  189. float center_x=rotate_rect.center.x;
  190. float center_y=rotate_rect.center.y;
  191. // 后超界
  192. if(center_y<center_miny)
  193. {
  194. code|=LIMIT_BACK_ERROR;
  195. }
  196. for(int i=0;i<4;++i)
  197. {
  198. if(t_corners[i].y>corner_max_y)
  199. {
  200. code|=LIMIT_BACK_ERROR;
  201. }
  202. }
  203. //前超界
  204. if(center_y>center_maxy)
  205. {
  206. code|=LIMIT_FRONT_ERROR;
  207. }
  208. for(int i=0;i<4;++i)
  209. {
  210. if(t_corners[i].y>corner_max_y)
  211. {
  212. code|=LIMIT_FRONT_ERROR;
  213. }
  214. }
  215. ////第二步,根据id,检验左右栏杆
  216. int left_id=terminal_id;
  217. int right_id=terminal_id+1;
  218. if(left_id<m_hardware_parameter.railing_parameter_size()&&left_id>=0
  219. &&right_id<m_hardware_parameter.railing_parameter_size()&&right_id>=0)
  220. {
  221. Hardware_limit::Railing railing_left_parameter=m_hardware_parameter.railing_parameter(left_id);
  222. Railing* tp_left_railing=new Railing(railing_left_parameter.pa(),railing_left_parameter.pb(),railing_left_parameter.pc(),
  223. railing_left_parameter.railing_width());
  224. Hardware_limit::Railing railing_right_parameter=m_hardware_parameter.railing_parameter(right_id);
  225. Railing* tp_right_railing=new Railing(railing_right_parameter.pa(),railing_right_parameter.pb(),railing_right_parameter.pc(),
  226. railing_right_parameter.railing_width());
  227. if(tp_left_railing->verify(rotate_rect)!=SUCCESS)
  228. {
  229. code|=LIMIT_LEFT_ERROR;
  230. }
  231. if(tp_right_railing->verify(rotate_rect)!=SUCCESS)
  232. {
  233. code|=LIMIT_RIGHT_ERROR;
  234. }
  235. delete tp_left_railing;
  236. delete tp_right_railing;
  237. }
  238. // LOG(INFO)<<"verify end";
  239. if(code!=0x00000000)
  240. return ERROR;
  241. return SUCCESS;
  242. }