Matlab project1 phase 2&3 - Minimum Snap/Jerk and A* Algorithm <Experiment recording>

本文介绍了一种针对无人机的平滑轨迹规划方法,利用多项式拟合实现最小化加加速度或加加加速度的目标,确保无人机飞行稳定性和能耗效率。文章详细阐述了基于二次规划的解决方案,并探讨了路径连续性及约束条件。

Preface:This article is written for a nifty girl who I cherish.

在这里插入图片描述

(0)Minimum Snap/Jerk Trajectory Generation

(0.0)Theory

Handle problem

空间中有少量路径点,试图构建一条连续的路径,这条路径经过我们所给的少数路径点,使得无人机能够平滑地飞过这个路径

Method
  • 多项式有很好的特性,比如计算方便(可以用矩阵表示),可拟合高阶曲线,所以多项式拟合路径;
  • 考虑到路径可能很复杂,如果整个路径用一个多项式表示,那么就会使得拟合路径的多项式阶数很高,并且不能处理闭环路径;所以我们采用每个路径点之间用一个多项式拟合;
  • 并且为了使得拟合曲线满足函数的“不可一对多”,我们拟合的是一个参数方程,其自变量为时间
On drone

在无人机中,我们往往考虑要是得最小化加加速度(jerk)或者最小化加加加速度(snap)

  • 其中
  • 最小化速度(jerk)保证了无人机飞行路径最短
  • 最小化加加速度(jerk)保证了无人机飞行的稳定性(因为加加速度与无人机pitch,roll轴的角速度成真比)
  • 加加加速度(snap)保证了无人机的耗能最小(因为)
Problem defination

Target:最小化加加速度(jerk)或者加加加速度(snap)
Constraints:对初始结束位置速度加速度的约束,对位置点的约束,对连续的约束

这个可以转换为一个二次规划的问题,在Matlab中通过quadprog函数对其进行求解

quadprg:
x = q u a d p r o g ( H , f , A , b , A e q , b e q , l b , u b ) x = quadprog(H,f,A,b,Aeq,beq,lb,ub) x=quadprog(H,f,A,b,Aeq,beq,lb,ub)
其中:

可见目标优化函数需要写作二次型的形式,约束函数写作矩阵乘向量的形式

Problem sloving

Target:

对于5次多项式的轨迹,定义优化函数:
m i n ∫ 0 T ( p ( t ) ( 3 ) ) 2 d t = m i n ∑ i = 1 k ∫ t i − 1 t i ( p ( t ) ( 3 ) ) 2 d t = m i n ∑ i = 1 k ∫ t i − 1 t i ( [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] [ p i 0 p i 1 p i 2 p i 3 p i 4 p i 5 ] ) 2 d t = m i n ∑ i = 1 k ∫ t i − 1 t i ( [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] P i ) 2 d t = m i n ∑ i = 1 k ∫ t i − 1 t i ( [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] P i ) T ( [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] P i ) d t = m i n ∑ i = 1 k P i T ∫ t i − 1 t i [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] T [ 0 , 0 , 0 , 6 , 24 t , 60 t 2 ] d t P i = m i n ∑ i = 1 k P i T Q i P i min \int_0^T(p(t)^{(3)})^2dt \\ =min \sum_{i=1}^k \int_{t_{i-1}}^{t_i}(p(t)^{(3)})^2dt \\ =min \sum_{i=1}^k \int_{t_{i-1}}^{t_i} ([0,0,0,6,24t,60t^2] \left [\begin{array}{c} p_{i0} \\p_{i1} \\p_{i2} \\p_{i3} \\p_{i4} \\p_{i5} \end{array} \right])^2dt \\ =min \sum_{i=1}^k \int_{t_{i-1}}^{t_i} ([0,0,0,6,24t,60t^2]P_i)^2dt \\ =min \sum_{i=1}^k \int_{t_{i-1}}^{t_i} ([0,0,0,6,24t,60t^2]P_i)^T([0,0,0,6,24t,60t^2]P_i)dt \\ =min \sum_{i=1}^k P_i^T\int_{t_{i-1}}^{t_i} [0,0,0,6,24t,60t^2]^T[0,0,0,6,24t,60t^2]dtP_i \\ =min \sum_{i=1}^k P_i^TQ_iP_i min0T(p(t)(3))2dt=mini=1kti1ti(p(t)(3))2dt=mini=1kti1ti([0,0,0,6,24t,60t2]pi0pi1pi2pi3pi4pi5)2dt=mini=1kti1ti([0,0,0,6,24t,60t2]Pi)2dt=mini=1kti1ti([0,0,0,6,24t,60t2]Pi)T([0,0,0,6,24t,60t2]Pi)dt=mini=1kPiTti1ti[0,0,0,6,24t,60t2]T[0,0,0,6,24t,60t2]dtPi=mini=1kPiTQiPi
可见 Q i Q_i Qi是一个矩阵,那么要把所有 Q i Q_i Qi合并起来,又相互不参数干扰,就只有把所有矩阵用主角线把他们串起来:
( P 1 0 ⋯ 0 0 0 P 2 ⋯ 0 0 ⋮ ⋮ ⋱ 0 0 0 0 0 p k − 1 0 0 0 0 0 p k ) \begin{pmatrix} P_1 &0&\cdots&0&0 \\0&P_2&\cdots&0&0 \\\vdots&\vdots&\ddots&0&0 \\0&0&0&p_{k-1}&0 \\0&0&0&0&p_k \end{pmatrix} P10000P20000000pk100000pk

matlab 中计算单个 Q i Q_i Qi函数可以是:

% n:polynormial order
% r:derivertive order, 1:minimum vel 2:minimum acc 3:minimum jerk 4:minimum snap
% t1:start timestamp for polynormial
% t2:end timestap for polynormial
function Q = computeQ(n,r,t1,t2)
syms x real;
a=x;
%generate simple polynormial like: x+x^2+x^3+x^4+x^5+x^6
for i=1:n
    a(end+1)=a(end)*x;
end
a=diff(a,r+1);
a1(x)=a'*a;
a2=int(a1(x),x);
Q=double(subs(a2,t2)-subs(a2,t1));

Equation Constraints:
在这里插入图片描述

有三类约束:

  • 起始点终点位置、速度、加速度约束
    位置约束:
    [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ 1 = x 0 [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ e = x e [1,t,t^2,t^3,t^4,t^5]\vec P_1=x_0 \\ [1,t,t^2,t^3,t^4,t^5]\vec P_e=x_e [1,t,t2,t3,t4,t5]P 1=x0[1,t,t2,t3,t4,t5]P e=xe
    速度约束:
    [ 0 , 1 , 2 t , 3 t 2 , 4 t 3 , 5 t 4 ] P ⃗ 1 = v 0 [ 0 , 1 , 2 t , 3 t 2 , 4 t 3 , 5 t 4 ] P ⃗ e = v e [0,1,2t,3t^2,4t^3,5t^4]\vec P_1=v_0 \\ [0,1,2t,3t^2,4t^3,5t^4]\vec P_e=v_e [0,1,2t,3t2,4t3,5t4]P 1=v0[0,1,2t,3t2,4t3,5t4]P e=ve
    加速度约束:
    [ 0 , 0 , 2 , 6 t , 12 t 2 , 20 t 3 ] P ⃗ 1 = a 0 [ 0 , 0 , 2 , 6 t , 12 t 2 , 20 t 3 ] P ⃗ e = a e [0,0,2,6t,12t^2,20t^3]\vec P_1=a_0 \\ [0,0,2,6t,12t^2,20t^3]\vec P_e=a_e [0,0,2,6t,12t2,20t3]P 1=a0[0,0,2,6t,12t2,20t3]P e=ae
    matlab先求多项式,再求导,代入 t t t值,列出矩阵与向量
    有六个方程
  • 中间点位置约束
    [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ n = x n [1,t,t^2,t^3,t^4,t^5]\vec P_n=x_n [1,t,t2,t3,t4,t5]P n=xn
    其中 n = 2 , 3 , 4... k − 2 , k − 1 n=2,3,4...k-2,k-1 n=2,3,4...k2,k1
    有k-2个方程
  • 中间点连续约束
    位置连续:
    [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ n − 1 = [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ n 即 : [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ n − 1 − [ 1 , t , t 2 , t 3 , t 4 , t 5 ] P ⃗ n = 0 即 : [ 1 , t , t 2 , t 3 , t 4 , t 5 , − 1 , − t , − t 2 , − t 3 , − t 4 , − t 5 ] [ P ⃗ n − 1 P ⃗ n ] = 0 [1,t,t^2,t^3,t^4,t^5]\vec P_{n-1}=[1,t,t^2,t^3,t^4,t^5]\vec P_n \\即: [1,t,t^2,t^3,t^4,t^5]\vec P_{n-1}-[1,t,t^2,t^3,t^4,t^5]\vec P_n=0 \\即:[1,t,t^2,t^3,t^4,t^5,-1,-t,-t^2,-t^3,-t^4,-t^5]\left [\begin{array}{c} \vec P_{n-1} \\ \vec P_n \end{array} \right]=0 [1,t,t2,t3,t4,t5]P n1=[1,t,t2,t3,t4,t5]P n[1,t,t2,t3,t4,t5]P n1[1,t,t2,t3,t4,t5]P n=0[1,t,t2,t3,t4,t5,1,t,t2,t3,t4,t5][P n1P n]=0
    同理速度连续:
    [ 0 , 1 , 2 t , 3 t 2 , 4 t 3 , 5 t 4 , − 0 , − 1 , − 2 t , − 3 t 2 , − 4 t 3 , − 5 t 4 ] [ P ⃗ n − 1 P ⃗ n ] = 0 [0,1,2t,3t^2,4t^3,5t^4,-0,-1,-2t,-3t^2,-4t^3,-5t^4]\left [\begin{array}{c} \vec P_{n-1} \\ \vec P_n \end{array} \right]=0 [0,1,2t,3t2,4t3,5t4,0,1,2t,3t2,4t3,5t4][P n1P n]=0
    同理加速度连续:
    [ 0 , 0 , 2 , 6 t , 12 t 2 , 20 t 3 , − 0 , − 0 , − 2 , − 6 t , − 12 t 2 , − 20 t 3 ] [ P ⃗ n − 1 P ⃗ n ] = 0 [0,0,2,6t,12t^2,20t^3,-0,-0,-2,-6t,-12t^2,-20t^3]\left [\begin{array}{c} \vec P_{n-1} \\ \vec P_n \end{array} \right]=0 [0,0,2,6t,12t2,20t3,0,0,2,6t,12t2,20t3][P n1P n]=0
    这里在matlab中就要注意排列约束的时候要按照顺序排列,这样才能保证中间点约束
    有(k-2)x3个方程
    综上:一共有(k-2)x4+6个约束方程

(0.1)codes

code

(1)A* algorithm

在这里插入图片描述

(1.0)Description

初始化

初始化Map矩阵,保存地图信息,1为障碍,0不是障碍
初始化gScore矩阵,保存分数信息,设置开始点为1,其余为无穷
初始化expanded矩阵,保存访问信息,设置全为0
初始化parents矩阵,用于保存节点的父节点信息,易于回溯
初始化queue矩阵,用于保存待访问节点,内部只有初始节点
while (queue不为空)
	从queue中取出g+h分数最小的节点p
	标记节点p于expanded为1
	把p节点从queue中删除
	找出p节点邻居节点中满足以下条件的节点ps:
		非障碍物,没有越界,没有被访问过
	将这些节点ps的父节点parents设置为p
	如果ps中含有终点,跳出while循环
如果终点没有父节点
	没有可达路径
如果终点有父节点
	从parents中向上不断寻找父节点,直到访问到开始节点,记录路径

(1.1)coding with matlab

  • 于matlab中数组中添加一个向量
queue(end+1,:)=map(1,:);
  • 于matlab中删除一个向量
queue(minIndex,:)=[];
  • matlab 反转一个向量
Optimal_path=flip(Optimal_path)

(1.2)codes

code

(2)More things

(2.0)Minimum polynomial degree

在这里插入图片描述
WHY?

(2.1)Polynomial Trajectories - corridor

  • Problems: 得到的路径可能会撞到障碍物,我们需要设置一定的可通行区域,保证无人机于区域内飞行
  • Methods: 在可行路径中添加采样点,设置不等式约束,保证采样点都满足不等式约束
    即:
    [ 1 , t , t 2 , t 3 , t 4 , t 5 ] p j < p ( j ) + r [1,t,t^2,t^3,t^4,t^5]p_{j}<p(j)+r [1,t,t2,t3,t4,t5]pj<p(j)+r
    [ − 1 , − t , − t 2 , − t 3 , − t 4 , − t 5 ] p j < − p ( j ) − r [-1,-t,-t^2,-t^3,-t^4,-t^5]p_{j}<-p(j)-r [1,t,t2,t3,t4,t5]pj<p(j)r
    p ( j ) p(j) p(j)为采样点的位置, p j p_{j} pj是采样点段的多项式参数,时间是到达该点的时间
    实际还有可行性检测(feasibility check),确保速度,加速度能够达到

(2.2)Polynomial Trajectories - divide time

  • Problems: 现有时间分配不合理,我们约束是每一维度的速度相同,但速度叠加后速度就不同了
  • Methods: 匀速分配,梯形分配

(2.3)Polynomial Trajectories - Closed form

  • Problems: 二次规划求解速度慢
  • methods: 闭式求解(只能有等式约束),只需要矩阵运算求解

(3)Reference

https://blog.youkuaiyun.com/q597967420/article/details/76099491

前馈控制音圈电机怎么simulink实现,由于使用正弦余弦x,y轴画图形,导致使用前馈v.a.j出现a,j初值异常,怎么修改这个前馈控制;被控模型 Ts = 1e-5; % 采样时间 (s) Bg = 0.16; % 磁场强度T Lq = 163.9; % 宏动线圈长度m M = 3; %宏动电机质量kg C = 0.3; % 导轨动摩擦系数 Rl = 4.2; %线圈回路电阻&Omega; La = 0.017; % 线圈回路电感H Kt = Bg * Lq; s = tf(&#39;s&#39;); num_plant_c = Bg*Lq; den_plant_c = [M*La, (C*La + M*Rl), (C*Rl + (Bg*Lq)^2), 0]; Plant_nominal_tf_c = minreal(tf(num_plant_c, den_plant_c)); 使用Discrete Derivative模块对轨迹r求导得出的a,j跳变,使用下面的function生成轨迹初值并不为零 function [pos, vel, acc, jerk] = y_heart_classic_zero_start(t, A, f) cycle_duration = 1/f; t_in_cycle = mod(t, cycle_duration); theta = 2 * pi * f * t_in_cycle; theta0 = 0; % 初始相位 initial_offset = A * (13*cos(theta0 - pi/2) - 5*cos(2*(theta0 - pi/2)) - 2*cos(3*(theta0 - pi/2)) - cos(4*(theta0 - pi/2))); pos = A * (13*cos(theta - pi/2) - 5*cos(2*(theta - pi/2)) - 2*cos(3*(theta - pi/2)) - cos(4*(theta - pi/2))) - initial_offset; vel = A * (-13*sin(theta - pi/2) + 10*sin(2*(theta - pi/2)) + 6*sin(3*(theta - pi/2)) + 4*sin(4*(theta - pi/2))) * (2 * pi * f); acc = A * (-13*cos(theta - pi/2) + 20*cos(2*(theta - pi/2)) + 18*cos(3*(theta - pi/2)) + 16*cos(4*(theta - pi/2))) * (2 * pi * f)^2; jerk = A * (13*sin(theta - pi/2) - 40*sin(2*(theta - pi/2)) - 54*sin(3*(theta - pi/2)) - 64*sin(4*(theta - pi/2))) * (2 * pi * f)^3; end
最新发布
10-10
#ifndef _BSPLINE_OPTIMIZER_H_ #define _BSPLINE_OPTIMIZER_H_ #include &lt;Eigen/Eigen&gt; #include &lt;plan_env/edt_environment.h&gt; #include &lt;ros/ros.h&gt; // Gradient and elasitc band optimization // Input: a signed distance field and a sequence of points // Output: the optimized sequence of points // The format of points: N x 3 matrix, each row is a point namespace tabv_planner { class BsplineOptimizer { public: static const int SMOOTHNESS; static const int DISTANCE; static const int FEASIBILITY; static const int ENDPOINT; static const int WAYPOINTS; static const int GROUND; static const int NORMAL_PHASE; BsplineOptimizer() {} ~BsplineOptimizer() {} /* main API */ void setEnvironment(const EDTEnvironment::Ptr&amp; env); void setParam(ros::NodeHandle&amp; nh); Eigen::MatrixXd BsplineOptimizeTraj(const Eigen::MatrixXd&amp; points, const double&amp; ts, const int&amp; cost_function, int max_num_id, int max_time_id); /* helper function */ // required inputs void setControlPoints(const Eigen::MatrixXd&amp; points); void setBsplineInterval(const double&amp; ts); void setCostFunction(const int&amp; cost_function); void setTerminateCond(const int&amp; max_num_id, const int&amp; max_time_id); void setMotionState(vector&lt;int&gt;&amp; motion_state_list); // optional inputs void setWaypoints(const vector&lt;Eigen::Vector3d&gt;&amp; waypts, const vector&lt;int&gt;&amp; waypt_idx); // N-2 constraints at most void optimize(); Eigen::MatrixXd getControlPoints(); vector&lt;Eigen::Vector3d&gt; matrixToVectors(const Eigen::MatrixXd&amp; ctrl_pts); private: EDTEnvironment::Ptr edt_environment_; // main input Eigen::MatrixXd control_points_; // B-spline control points, N x dim double bspline_interval_; // B-spline knot span Eigen::Vector3d end_pt_; // end of the trajectory int dim_; // dimension of the B-spline vector&lt;int&gt; motion_state_list_; // vector&lt;Eigen::Vector3d&gt; waypoints_; // waypts constraints vector&lt;int&gt; waypt_idx_; // waypts constraints index // int max_num_id_, max_time_id_; // stopping criteria int cost_function_; // used to determine objective function bool dynamic_; // moving obstacles ? double start_time_; // global time for moving obstacles /* optimization parameters */ int order_; // bspline degree double lambda1_; // jerk smoothness weight double lambda2_; // distance weight double lambda3_; // feasibility weight double lambda4_; // end point weight double lambda5_; // waypoints cost weight double lambda6_; // ground constraints // double dist0_; // safe distance double max_vel_, max_acc_; // dynamic limits double visib_min_; // threshold of visibility double wnl_; // double dlmin_; // // int algorithm1_; // optimization algorithms for quadratic cost int algorithm2_; // optimization algorithms for general cost int max_iteration_num_[4]; // stopping criteria that can be used double max_iteration_time_[4]; // stopping criteria that can be used /* intermediate variables */ /* buffer for gradient of cost function, to avoid repeated allocation and * release of memory */ vector&lt;Eigen::Vector3d&gt; g_q_; vector&lt;Eigen::Vector3d&gt; g_smoothness_; vector&lt;Eigen::Vector3d&gt; g_distance_; vector&lt;Eigen::Vector3d&gt; g_feasibility_; vector&lt;Eigen::Vector3d&gt; g_endpoint_; vector&lt;Eigen::Vector3d&gt; g_waypoints_; vector&lt;Eigen::Vector3d&gt; g_ground_; int variable_num_; // optimization variables int iter_num_; // iteration of the solver std::vector&lt;double&gt; best_variable_; // double min_cost_; // vector&lt;Eigen::Vector3d&gt; block_pts_; // blocking points to compute visibility /* cost function */ /* calculate each part of cost function with control points q as input */ static double costFunction(const std::vector&lt;double&gt;&amp; x, std::vector&lt;double&gt;&amp; grad, void* func_data); void combineCost(const std::vector&lt;double&gt;&amp; x, vector&lt;double&gt;&amp; grad, double&amp; cost); // q contains all control points void calcSmoothnessCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); void calcDistanceCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); void calcFeasibilityCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); void calcEndpointCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); void calcWaypointsCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); void calcGroundCost(const vector&lt;Eigen::Vector3d&gt;&amp; q, double&amp; cost, vector&lt;Eigen::Vector3d&gt;&amp; gradient); bool isQuadratic(); /* for benckmark evaluation only */ public: vector&lt;double&gt; vec_cost_; vector&lt;double&gt; vec_time_; ros::Time time_start_; void getCostCurve(vector&lt;double&gt;&amp; cost, vector&lt;double&gt;&amp; time) { cost = vec_cost_; time = vec_time_; } typedef unique_ptr&lt;BsplineOptimizer&gt; Ptr; EIGEN_MAKE_ALIGNED_OPERATOR_NEW }; } // namespace tabv_planner #endif 注释上述代码
09-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值