trajectory.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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) const
  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 Trajectory::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. int point_count=int(Pose2d::distance(start,end)/dt);
  181. //生成离散点,间距
  182. Pose2d diff=end-start;
  183. float solution_x=diff.x()/float(point_count);
  184. float solution_y=diff.y()/float(point_count);
  185. for(int i=0;i<point_count;++i)
  186. {
  187. double x=start.x()+i*solution_x;
  188. double y=start.y()+i*solution_y;
  189. //printf(" point x :%f y:%f\n",x,y);
  190. trajectory.push_point(Pose2d(x,y,angle));
  191. }
  192. trajectory.push_point(Pose2d(end.x(),end.y(),angle));
  193. return trajectory;
  194. }