trajectory.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. //
  2. // Created by zx on 22-12-1.
  3. //
  4. //
  5. // Created by zx on 2020/9/9.
  6. //
  7. #include <iostream>
  8. #include "trajectory.h"
  9. Trajectory::Trajectory(){}
  10. Trajectory::Trajectory(const std::vector<Pose2d>& points)
  11. {
  12. m_pose_vector=points;
  13. }
  14. Pose2d& Trajectory::operator[](int index)
  15. {
  16. return m_pose_vector[index];
  17. }
  18. Trajectory& Trajectory::operator+(const Trajectory& other)
  19. {
  20. m_pose_vector.insert(m_pose_vector.end(),
  21. other.m_pose_vector.begin(),other.m_pose_vector.end());
  22. return *this;
  23. }
  24. void Trajectory::push_point(const Pose2d& point)
  25. {
  26. m_pose_vector.push_back(point);
  27. }
  28. /*
  29. * 根据梯度和方向计算角度,x轴正,逆时针为正
  30. */
  31. double gradient2theta(double gradient,bool direction)
  32. {
  33. //计算方向 在第几象限
  34. int Quadrant=1;
  35. if(gradient>0)
  36. {
  37. if(direction)
  38. Quadrant=1;
  39. else
  40. Quadrant=3;
  41. }
  42. else
  43. {
  44. if(direction)
  45. Quadrant=4;
  46. else
  47. Quadrant=2;
  48. }
  49. double angle=0;
  50. if(fabs(gradient)>=200.0)
  51. {
  52. angle=M_PI/2.0;
  53. }
  54. else
  55. {
  56. angle=atan(fabs(gradient));
  57. }
  58. // angle === (0,M_PI/2.0)
  59. if(Quadrant==1)
  60. {
  61. }
  62. if(Quadrant==2)
  63. {
  64. angle=M_PI-angle;
  65. }
  66. if(Quadrant==3)
  67. {
  68. angle+=M_PI;
  69. }
  70. if(Quadrant==4)
  71. {
  72. angle=-angle;
  73. }
  74. return angle;
  75. }
  76. double gen_axis_angle(const Pose2d& point1,const Pose2d& point2)
  77. {
  78. double delta_x=point2.x()-point1.x();
  79. double delta_y=point2.y()-point1.y();
  80. double gradient=0;
  81. if(delta_x==0)
  82. {
  83. if(delta_y>0)
  84. gradient=200;
  85. else if(delta_y<0)
  86. gradient=-200;
  87. else
  88. return 0;
  89. }
  90. else
  91. {
  92. gradient=delta_y/delta_x;
  93. }
  94. return gradient2theta(gradient,delta_x>=0);
  95. }
  96. /*
  97. * 计算曲线P 在(x1,x2)的线积分
  98. * 默认以 (x2-x1)/100 为步长
  99. */
  100. double integral_path(double x1,double x2,Eigen::MatrixXd P)
  101. {
  102. double a=P(0,0);
  103. double b=P(1,0);
  104. double c=P(2,0);
  105. double d=P(3,0);
  106. double delta=(x2-x1)/100.0;
  107. double t=x1;
  108. double integral=0.0;
  109. //循环条件为 t位于 x1和x2 之间
  110. while((x2-t)*(t-x1)>=0)
  111. {
  112. t+=delta;
  113. double graidient=3.0*a*pow(t,2.0)+2.0*b*t+c;
  114. integral+=sqrt(delta*delta+graidient*graidient);
  115. }
  116. return integral;
  117. }
  118. Trajectory Trajectory::create_trajectory(const Pose2d& start,const Pose2d& end,int point_count)
  119. {
  120. int extend_num=point_count/2;
  121. Trajectory trajectory;
  122. double angle =gen_axis_angle(start,end);
  123. Pose2d pose1=start.rotate(-angle);
  124. Pose2d pose2=end.rotate(-angle);
  125. double gradient1=pose1.gridient();
  126. double gradient2=pose2.gridient();
  127. //三阶多项式差值,生成 曲线
  128. double x0=pose1.x();
  129. double y0=pose1.y();
  130. double x1=pose2.x();
  131. double y1=pose2.y();
  132. Eigen::Matrix<double,4,4> A=Eigen::MatrixXd::Zero(4,4); //系数矩阵A
  133. Eigen::Matrix<double,4,1> B=Eigen::MatrixXd::Zero(4,1); //值矩阵B
  134. A(0,0)=pow(x0,3.0);
  135. A(0,1)=pow(x0,2.0);
  136. A(0,2)=x0;
  137. A(0,3)=1.0;
  138. A(1,0)=pow(x1,3.0);
  139. A(1,1)=pow(x1,2.0);
  140. A(1,2)=x1;
  141. A(1,3)=1.0;
  142. A(2,0)=3.0*pow(x0,2.0);
  143. A(2,1)=2.0*x0;
  144. A(2,2)=1.0;
  145. A(3,0)=3.0*pow(x1,2.0);
  146. A(3,1)=2.0*x1;
  147. A(3,2)=1.0;
  148. B(0,0)=y0;
  149. B(1,0)=y1;
  150. B(2,0)=gradient1;
  151. B(3,0)=gradient2;
  152. Eigen::MatrixXd P=A.inverse()*B;
  153. double a=P(0,0);
  154. double b=P(1,0);
  155. double c=P(2,0);
  156. double d=P(3,0);
  157. //步长
  158. double delta_x=(x1-x0)/float(point_count);
  159. //生成离散点,间距
  160. for(double x=x0-delta_x*extend_num;x<x1+delta_x*extend_num;x+=delta_x)
  161. {
  162. double y=a*pow(x,3.0)+b*pow(x,2.0)+c*x+d;
  163. double gradient=3.0*a*pow(x,2.0)+2.0*b*x+c;
  164. trajectory.push_point(Pose2d(x,y,gradient2theta(gradient)));
  165. }
  166. //将轨迹点反变换到原坐标系
  167. Trajectory trajectory_map;
  168. for(int i=0;i<trajectory.size();++i)
  169. {
  170. Pose2d point=trajectory[i];
  171. Pose2d new_point=point.rotate(angle);
  172. trajectory_map.push_point(new_point);
  173. }
  174. return trajectory_map;
  175. }
  176. Trajectory Trajectory::create_line_trajectory(const Pose2d& start,const Pose2d& end,float dt)
  177. {
  178. Trajectory trajectory;
  179. double angle =gen_axis_angle(start,end);
  180. trajectory.push_point(Pose2d(start.x(),start.y(),angle));
  181. int point_count=int(Pose2d::distance(start,end)/dt);
  182. //生成离散点,间距
  183. Pose2d diff=end-start;
  184. float solution_x=diff.x()/float(point_count);
  185. float solution_y=diff.y()/float(point_count);
  186. for(int i=1;i<point_count;++i)
  187. {
  188. double x=start.x()+i*solution_x;
  189. double y=start.y()+i*solution_y;
  190. //printf(" point x :%f y:%f\n",x,y);
  191. trajectory.push_point(Pose2d(x,y,angle));
  192. }
  193. trajectory.push_point(Pose2d(end.x(),end.y(),angle));
  194. return trajectory;
  195. }
  196. Trajectory Trajectory::path_smooth_slid(const std::vector<Pose2d>& path, int size)
  197. {
  198. //判断参数合理
  199. if(path.size() <= 2*size+1)
  200. return path;
  201. Trajectory smoothed_path;
  202. std::vector<float> smoothed_path_x;
  203. std::vector<float> smoothed_path_y;
  204. std::vector<float> smoothed_path_theta;
  205. //处理xy坐标
  206. for(auto i = 0; i < path.size(); ++i)
  207. {
  208. if(i >= size && i < path.size() - size)
  209. {
  210. float x_sum = 0.0, y_sum =0.0;
  211. for(auto j = i - size; j < i + size + 1; ++j)
  212. {
  213. x_sum += path[j].x();
  214. y_sum += path[j].y();
  215. }
  216. smoothed_path_x.push_back(x_sum/float(2.0*size+1));
  217. smoothed_path_y.push_back(y_sum/float(2.0*size+1));
  218. }
  219. else
  220. {
  221. smoothed_path_x.push_back(path[i].x());
  222. smoothed_path_y.push_back(path[i].y());
  223. }
  224. }
  225. //处理theta角度
  226. for(auto i = 0; i < path.size(); ++i)
  227. {
  228. if(i >= size - 1 && i < path.size() - size)
  229. {
  230. Pose2d point1 = Pose2d(smoothed_path_x[i],smoothed_path_y[i],0.0);
  231. Pose2d point2 = Pose2d(smoothed_path_x[i+1],smoothed_path_y[i+1],0.0);
  232. double angle = gen_axis_angle(point1,point2);
  233. smoothed_path_theta.push_back((float)angle);
  234. }
  235. else
  236. {
  237. smoothed_path_theta.push_back(path[i].theta());
  238. }
  239. }
  240. //构建平滑后的返回路径
  241. for (int i = 0; i < path.size(); ++i)
  242. {
  243. smoothed_path.push_point(Pose2d(smoothed_path_x[i], smoothed_path_y[i], smoothed_path_theta[i]));
  244. }
  245. return smoothed_path;
  246. }