【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(二)

文章目录

  • TASK系列解析文章
      • OptimizeByNLP
        • 1.get_nlp_info()定义问题规模
        • 2.get_bounds_info()定义约束边界约束
        • 3.get_starting_point()定义初值
        • 4.eval_f()求解目标函数
        • 5.eval_grad_f()求解梯度
        • 6.eval_g()求解约束函数
        • 7.eval_jac_g()求解约束雅可比矩阵
        • 8.eval_h()求解黑塞矩阵
        • 9. finalize_solution()
  • 参考

TASK系列解析文章

1.【Apollo学习笔记】——规划模块TASK之LANE_CHANGE_DECIDER
2.【Apollo学习笔记】——规划模块TASK之PATH_REUSE_DECIDER
3.【Apollo学习笔记】——规划模块TASK之PATH_BORROW_DECIDER
4.【Apollo学习笔记】——规划模块TASK之PATH_BOUNDS_DECIDER
5.【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_PATH_OPTIMIZER
6.【Apollo学习笔记】——规划模块TASK之PATH_ASSESSMENT_DECIDER
7.【Apollo学习笔记】——规划模块TASK之PATH_DECIDER
8.【Apollo学习笔记】——规划模块TASK之RULE_BASED_STOP_DECIDER
9.【Apollo学习笔记】——规划模块TASK之SPEED_BOUNDS_PRIORI_DECIDER&&SPEED_BOUNDS_FINAL_DECIDER
10.【Apollo学习笔记】——规划模块TASK之SPEED_HEURISTIC_OPTIMIZER
11.【Apollo学习笔记】——规划模块TASK之SPEED_DECIDER
12.【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_SPEED_OPTIMIZER
13.【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)
14.【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(二)

续接上文:【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)

OptimizeByNLP

这部分是具体的非线性规划代码实现。

在代码中首先可以看到构造了PiecewiseJerkSpeedNonlinearIpoptInterface这个类的对象。下面是该类构造函数中所含有的参数。

PiecewiseJerkSpeedNonlinearIpoptInterface::PiecewiseJerkSpeedNonlinearIpoptInterface(const double s_init, const double s_dot_init, const double s_ddot_init,const double delta_t, const int num_of_points, const double s_max,const double s_dot_max, const double s_ddot_min,const double s_ddot_max, const double s_dddot_min,const double s_dddot_max): curvature_curve_(0.0, 0.0, 0.0),v_bound_func_(0.0, 0.0, 0.0),s_init_(s_init),s_dot_init_(s_dot_init),s_ddot_init_(s_ddot_init),delta_t_(delta_t),num_of_points_(num_of_points),s_max_(s_max),s_dot_max_(s_dot_max),s_ddot_min_(-std::abs(s_ddot_min)),s_ddot_max_(s_ddot_max),s_dddot_min_(-std::abs(s_dddot_min)),s_dddot_max_(s_dddot_max),v_offset_(num_of_points),a_offset_(num_of_points * 2) {}

PiecewiseJerkSpeedNonlinearIpoptInterface继承自基类Ipopt::TNLP。为了利用IPOPT的接口TNLP求解问题,需要构建一个接口类来重写TNLP中求解问题所需要的一些函数,并完成对这些函数的实现。

IPOPT(Interior Point Optimizer)是一个用于大规模非线性优化的开源软件包。它可用于解决如下形式的非线性规划问题:
min ⁡ x ∈ R n f ( x ) s.t. g L ≤ g ( x ) ≤ g U x L ≤ x ≤ x U , x ∈ R n \begin{aligned} \min_{x\in\mathbb{R}^{n}}&& f(x) \\ \text{s.t.}&& g^{L}\leq g(x)\leq g^{U} \\ &&x^{L}\leq x\leq x^{U}, \\ &&x\in\mathbb{R}^{n} \end{aligned} xRnmins.t.f(x)gLg(x)gUxLxxU,xRn
g L {g^L} gL g U {g^U} gU是约束函数的上界和下界, x L {x^L} xL x U {x^U} xU是优化变量的上界和下界。

IPOPT的求解由以下几个函数构成:

1.get_nlp_info()定义问题规模

/** Method to return some info about the nlp */bool get_nlp_info(int &n, int &m, int &nnz_jac_g, int &nnz_h_lag,IndexStyleEnum &index_style) override;

• 优化变量数量:n
• 约束函数数量:m
• 雅可比矩阵非0项数量:nnz_jac_g
• 黑塞矩阵非0项数量:nnz_h_lag

2.get_bounds_info()定义约束边界约束

  /** Method to return the bounds for my problem */bool get_bounds_info(int n, double *x_l, double *x_u, int m, double *g_l,double *g_u) override;

• 自变量的下边界:x_l
• 自变量的上边界: x_u
• 约束函数下边界:g_l
• 约束函数的上边界:g_u

通过代码可知变量 x x x的边界约束(5n x 1)为:
x L = [ s i n i t s ( 1 ) − l o w e r ⋮ s ( n − 1 ) − l o w e r s ˙ i n i t 0 ⋮ 0 s ¨ i n i t s ¨ min ⁡ ⋮ s ¨ min ⁡ 0 ⋮ 0 0 ⋮ 0 ] , x U = [ s i n i t s ( 1 ) − u p p e r ⋮ s ( n − 1 ) − u p p e r s ˙ i n i t s ˙ max ⁡ ⋮ s ˙ max ⁡ s ¨ i n i t s ¨ max ⁡ ⋮ s ¨ max ⁡ inf ⁡ ⋮ inf ⁡ inf ⁡ ⋮ inf ⁡ ] {x^L} = \left[ {\begin{array}{ccccccccccccccc}{{s_{init}}}\\{{s_{(1) - lower}}}\\ \vdots \\{{s_{(n - 1) - lower}}}\\{{{\dot s}_{init}}}\\0\\ \vdots \\0\\{{{\ddot s}_{init}}}\\{{{\ddot s}_{\min }}}\\ \vdots \\{{{\ddot s}_{\min }}}\\0\\ \vdots \\0\\0\\ \vdots \\0\end{array}} \right],{x^U} = \left[ {\begin{array}{ccccccccccccccc}{{s_{init}}}\\{{s_{(1) - upper}}}\\ \vdots \\{{s_{(n - 1) - upper}}}\\{{{\dot s}_{init}}}\\{{{\dot s}_{\max }}}\\ \vdots \\{{{\dot s}_{\max }}}\\{{{\ddot s}_{init}}}\\{{{\ddot s}_{\max }}}\\ \vdots \\{{{\ddot s}_{\max }}}\\{\inf }\\ \vdots \\{\inf }\\{\inf }\\ \vdots \\{\inf }\end{array}} \right] xL= sinits(1)lowers(n1)lowers˙init00s¨inits¨mins¨min0000 ,xU= sinits(1)uppers(n1)uppers˙inits˙maxs˙maxs¨inits¨maxs¨maxinfinfinfinf

g ( x ) g(x) g(x)的边界约束([4(n-1)+3n] x 1)为:
g L = [ 0 ⋮ 0 s ′ ′ ′ min ⁡ ⋮ s ′ ′ ′ min ⁡ 0 ⋮ 0 0 ⋮ 0 − inf ⁡ ⋮ − inf ⁡ 0 ⋮ 0 − inf ⁡ ⋮ − inf ⁡ ] , g U = [ s ˙ max ⁡ ⋅ Δ t ⋮ s ˙ max ⁡ ⋅ Δ t s ′ ′ ′ max ⁡ ⋮ s ′ ′ ′ max ⁡ 0 ⋮ 0 0 ⋮ 0 0 ⋮ 0 inf ⁡ ⋮ inf ⁡ 0 ⋮ 0 ] {g^L} = \left[ {\begin{array}{ccccccccccccccc}0\\ \vdots \\0\\{{{s'''}_{\min }}}\\ \vdots \\{{{s'''}_{\min }}}\\0\\ \vdots \\0\\0\\ \vdots \\0\\{ - \inf }\\ \vdots \\{ - \inf }\\0\\ \vdots \\0\\{ - \inf }\\ \vdots \\{ - \inf }\end{array}} \right],{g^U} = \left[ {\begin{array}{ccccccccccccccc}{{{\dot s}_{\max }} \cdot \Delta t}\\ \vdots \\{{{\dot s}_{\max }} \cdot \Delta t}\\{{{s'''}_{\max }}}\\ \vdots \\{{{s'''}_{\max }}}\\0\\ \vdots \\0\\0\\ \vdots \\0\\0\\ \vdots \\0\\{\inf }\\ \vdots \\{\inf }\\0\\ \vdots \\0\end{array}} \right] gL= 00s′′′mins′′′min0000infinf00infinf ,gU= s˙maxΔts˙maxΔts′′′maxs′′′max000000infinf00

3.get_starting_point()定义初值

  /** Method to return the starting point for the algorithm */bool get_starting_point(int n, bool init_x, double *x, bool init_z,double *z_L, double *z_U, int m, bool init_lambda,double *lambda) override;

这部分在OptimizeByQP有具体介绍。
依据是否启动热启动warm-start,来确定是否将之前QP的结果作为NLP初始值。 X 0 {X_0} X0为5n x 1的向量。
X 0 = [ s Q P 0 ⋮ s Q P n − 1 s ˙ Q P 0 ⋮ s ˙ Q P n − 1 s ¨ Q P 0 ⋮ s ¨ Q P n − 1 0 ⋮ 0 0 ⋮ 0 ] {X_0} = \left[ {\begin{array}{ccccccccccccccc}{s_{QP}^0}\\ \vdots \\{s_{QP}^{n - 1}}\\{\dot s_{QP}^0}\\ \vdots \\{\dot s_{QP}^{n - 1}}\\{\ddot s_{QP}^0}\\ \vdots \\{\ddot s_{QP}^{n - 1}}\\0\\ \vdots \\0\\0\\ \vdots \\0\end{array}} \right] X0= sQP0sQPn1s˙QP0s˙QPn1s¨QP0s¨QPn10000

4.eval_f()求解目标函数

  /** Method to return the objective value */bool eval_f(int n, const double *x, bool new_x, double &obj_value) override;

• 变量值:x
• 目标函数值:obj_val
m i n f = ∑ i = 0 n − 1 w s − r e f ( s i − s − r e f i ) 2 + w s ˙ − r e f ( s ˙ i − s ˙ − r e f ) 2 + w s ¨ s ¨ i 2 + ∑ i = 0 n − 2 w s ′ ′ ′ ( s ¨ i + 1 − s ¨ i Δ t ) 2 + ∑ i = 0 n − 1 w l a t _ a c c l a t _ a c c i 2 + w s o f t s _ s l a c k _ l o w e r i + w s o f t s _ s l a c k _ u p p e r i + w t a r g e t − s ( s n − 1 − s t a r g e t ) 2 + w t a r g e t − s ˙ ( s ˙ n − 1 − s ˙ t a r g e t ) 2 + w t a r g e t − s ¨ ( s ¨ n − 1 − s ¨ t a r g e t ) 2 \begin{aligned}minf=&\sum_{i=0}^{n-1}w_{s-ref}(s_i-s_-ref_i)^2+w_{\dot{s}-ref}(\dot{s}_i-\dot{s}_-ref)^2+w_{\ddot{s}}\ddot{s}_i^2+\sum_{i=0}^{n-2}w_{{s}^{'''}}(\frac{\ddot{s}_{i+1}-\ddot{s}_i}{\Delta t})^2\\&+\sum_{i=0}^{n-1}w_{lat\_acc}lat\_acc_i^2+w_{soft}s\_slack\_lower_i+w_{soft}s\_slack\_upper_i\\&+w_{target-s}(s_{n-1}-s_{target})^2+w_{target-\dot{s}}(\dot{s}_{n-1}-\dot{s}_{target})^2+w_{target-\ddot{s}}(\ddot{s}_{n-1}-\ddot{s}_{target})^2 \end{aligned} minf=i=0n1wsref(sisrefi)2+ws˙ref(s˙is˙ref)2+ws¨s¨i2+i=0n2ws′′′(Δts¨i+1s¨i)2+i=0n1wlat_acclat_acci2+wsofts_slack_loweri+wsofts_slack_upperi+wtargets(sn1starget)2+wtargets˙(s˙n1s˙target)2+wtargets¨(s¨n1s¨target)2

5.eval_grad_f()求解梯度

  /** Method to return the gradient of the objective */bool eval_grad_f(int n, const double *x, bool new_x, double *grad_f) override;

• 变量值:x
• 梯度值:grad_f

梯度的定义:
∇ x = d e f [ ∂ ∂ x 1 , ∂ ∂ x 2 , ⋯ , ∂ ∂ x ] T = ∂ ∂ x \nabla_x\overset{\mathrm{def}}{=}\left[\frac{\partial}{\partial x_1},\frac{\partial}{\partial x_2},\cdots,\frac{\partial}{\partial x}\right]^T=\frac{\partial}{\partial\boldsymbol{x}} x=def[x1,x2,,x]T=x

对目标函数求偏导,可得:
∂ f ∂ s = 2 ∑ i = 0 n − 1 w s − r e f ( s i − s − r e f i ) + ∑ i = 0 n − 1 2 w l a t _ a c c s ˙ i 4 κ κ ˙ + 2 w t a r g e t − s ( s n − 1 − s t a r g e t ) + 2 w t a r g e t − s ˙ ( s ˙ n − 1 − s ˙ t a r g e t ) + 2 w t a r g e t − s ¨ ( s ¨ n − 1 − s ¨ t a r g e t ) ∂ f ∂ s ˙ = 2 ∑ i = 0 n − 1 w s ˙ − r e f ( s ˙ i − s ˙ − r e f ) + ∑ i = 0 n − 1 4 w l a t _ a c c s ˙ i 3 κ 2 ∂ f ∂ s ¨ = 2 ∑ i = 0 n − 1 w s ¨ s ¨ i − 2 w s ′ ′ ′ 2 ( s ¨ 1 − s ¨ 0 ) Δ t 2 + ∑ i = 1 n − 2 2 w s ′ ′ ′ ( 2 s ¨ i − s ¨ i + 1 − s ¨ i − 1 ) Δ t 2 + 2 w s ′ ′ ′ 2 ( s ¨ n − 1 − s ¨ n − 2 ) Δ t 2 ∂ f ∂ s _ s l a c k _ l o w e r = n ⋅ w s o f t ∂ f ∂ s _ s l a c k _ u p p e r = n ⋅ w s o f t \begin{aligned} \frac{\partial f}{\partial s}=&2\sum_{i=0}^{n-1}w_{s-ref}(s_i-s_-ref_i)+\sum_{i=0}^{n-1}2w_{lat\_acc}{\dot s_i^4}{\kappa}{\dot\kappa}\\+&2w_{target-s}(s_{n-1}-s_{target})+2w_{target-\dot{s}}(\dot{s}_{n-1}-\dot{s}_{target})+2w_{target-\ddot{s}}(\ddot{s}_{n-1}-\ddot{s}_{target})\\ \frac{\partial f}{\partial \dot s}=&2\sum_{i=0}^{n-1}w_{\dot{s}-ref}(\dot{s}_i-\dot{s}_-ref)+\sum_{i=0}^{n-1}4w_{lat\_acc}{\dot s_i^3}{\kappa^2}\\ \frac{\partial f}{\partial \ddot s}=&2\sum_{i=0}^{n-1}w_{\ddot{s}}\ddot{s}_i-2w_{{s}^{'''}}{\frac{2(\ddot s_1-\ddot s_0)}{\Delta t^2}}+\sum_{i=1}^{n-2}2w_{{s}^{'''}}{\frac{(2\ddot s_i-\ddot s_{i+1}-\ddot s_{i-1})}{\Delta t^2}}+2w_{{s}^{'''}}{\frac{2(\ddot s_{n-1}-\ddot s_{n-2})}{\Delta t^2}}\\ \frac{\partial f}{\partial s\_slack\_lower}=&n \cdot w_{soft}\\ \frac{\partial f}{\partial s\_slack\_upper}=&n \cdot w_{soft} \end{aligned} sf=+s˙f=s¨f=s_slack_lowerf=s_slack_upperf=2i=0n1wsref(sisrefi)+i=0n12wlat_accs˙i4κκ˙2wtargets(sn1starget)+2wtargets˙(s˙n1s˙target)+2wtargets¨(s¨n1s¨target)2i=0n1ws˙ref(s˙is˙ref)+i=0n14wlat_accs˙i3κ22i=0n1ws¨s¨i2ws′′′Δt22(s¨1s¨0)+i=1n22ws′′′Δt2(2s¨is¨i+1s¨i1)+2ws′′′Δt22(s¨n1s¨n2)nwsoftnwsoft

所以,目标函数的梯度为
∂ f ∂ X = 2 ∑ i = 0 n − 1 w s − r e f ( s i − s − r e f i ) + 2 ∑ i = 0 n − 1 w s ˙ − r e f ( s ˙ i − s ˙ − r e f ) + 2 ∑ i = 0 n − 1 w s ¨ s ¨ i − 2 w s ′ ′ ′ 2 ( s ¨ 1 − s ¨ 0 ) Δ t 2 + ∑ i = 1 n − 2 2 w s ′ ′ ′ ( 2 s ¨ i − s ¨ i + 1 − s ¨ i − 1 ) Δ t 2 + 2 w s ′ ′ ′ 2 ( s ¨ n − 1 − s ¨ n − 2 ) Δ t 2 + ∑ i = 0 n − 1 2 w l a t _ a c c s ˙ i 4 κ κ ˙ + ∑ i = 0 n − 1 4 w l a t _ a c c s ˙ i 3 κ 2 + 2 w t a r g e t − s ( s n − 1 − s t a r g e t ) + 2 w t a r g e t − s ˙ ( s ˙ n − 1 − s ˙ t a r g e t ) + 2 w t a r g e t − s ¨ ( s ¨ n − 1 − s ¨ t a r g e t ) + 2 n ⋅ w s o f t \begin{aligned} \frac{\partial f}{\partial X}=&2\sum_{i=0}^{n-1}w_{s-ref}(s_i-s_-ref_i)+2\sum_{i=0}^{n-1}w_{\dot{s}-ref}(\dot{s}_i-\dot{s}_-ref)+2\sum_{i=0}^{n-1}w_{\ddot{s}}\ddot{s}_i\\ -&2w_{{s}^{'''}}{\frac{2(\ddot s_1-\ddot s_0)}{\Delta t^2}}+\sum_{i=1}^{n-2}2w_{{s}^{'''}}{\frac{(2\ddot s_i-\ddot s_{i+1}-\ddot s_{i-1})}{\Delta t^2}}+2w_{{s}^{'''}}{\frac{2(\ddot s_{n-1}-\ddot s_{n-2})}{\Delta t^2}}\\ +&\sum_{i=0}^{n-1}2w_{lat\_acc}{\dot s_i^4}{\kappa}{\dot\kappa}+\sum_{i=0}^{n-1}4w_{lat\_acc}{\dot s_i^3}{\kappa^2}\\ +&2w_{target-s}(s_{n-1}-s_{target})+2w_{target-\dot{s}}(\dot{s}_{n-1}-\dot{s}_{target})+2w_{target-\ddot{s}}(\ddot{s}_{n-1}-\ddot{s}_{target})\\ +&2n\cdot w_{soft} \end{aligned} Xf=+++2i=0n1wsref(sisrefi)+2i=0n1ws˙ref(s˙is˙ref)+2i=0n1ws¨s¨i2ws′′′Δt22(s¨1s¨0)+i=1n22ws′′′Δt2(2s¨is¨i+1s¨i1)+2ws′′′Δt22(s¨n1s¨n2)i=0n12wlat_accs˙i4κκ˙+i=0n14wlat_accs˙i3κ22wtargets(sn1starget)+2wtargets˙(s˙n1s˙target)+2wtargets¨(s¨n1s¨target)2nwsoft

6.eval_g()求解约束函数

  /** Method to return the constraint residuals */bool eval_g(int n, const double *x, bool new_x, int m, double *g) override;

• 变量值:x
• 约束函数值:g
g ( x ) = [ s 1 − s 0 ⋮ s n − 1 − s n − 2 s ¨ 1 − s ¨ 0 Δ t ⋮ s ¨ n − 1 − s ¨ n − 2 Δ t s 1 − ( s 0 + s ˙ 0 Δ t + 1 2 s ¨ 0 Δ t 2 + 1 6 ( s ¨ 1 − s ¨ 0 Δ t ) Δ t 3 ) ⋮ s n − 1 − ( s n − 2 + s ˙ n − 2 Δ t + 1 2 s ¨ n − 2 Δ t 2 + 1 6 ( s ¨ n − 1 − s ¨ n − 2 Δ t ) Δ t 3 ) s ˙ 1 − ( s ˙ 0 + s ¨ 0 Δ t + 1 2 ( s ¨ 1 − s ¨ 0 Δ t ) Δ t 2 ) ⋮ s ˙ n − 1 − ( s ˙ n − 2 + s ¨ n − 2 Δ t + 1 2 ( s ¨ n − 1 − s ¨ n − 2 Δ t ) Δ t 2 ) s ˙ 0 − s p e e d _ l i m i t ( s 0 ) ⋮ s ˙ n − 1 − s p e e d _ l i m i t ( s n − 1 ) s 0 − s _ s o f t _ l o w e r 0 + s _ s l a c k _ l o w e r ⋮ s n − 1 − s _ s o f t _ l o w e r n − 1 + s _ s l a c k _ l o w e r s 0 − s _ s o f t _ u p p e r 0 − s _ s l a c k _ u p p e r ⋮ s n − 1 − s _ s o f t _ u p p e r n − 1 − s _ s l a c k _ u p p e r ] g(x) = \left[ {\begin{array}{ccccccccccccccc}{{s_1} - {s_0}}\\ \vdots \\{{s_{n - 1}} - {s_{n - 2}}}\\{\frac{{{{\ddot s}_1} - {{\ddot s}_0}}}{{\Delta t}}}\\ \vdots \\{\frac{{{{\ddot s}_{n - 1}} - {{\ddot s}_{n - 2}}}}{{\Delta t}}}\\{{s_1} - ({s_0} + {{\dot s}_0}\Delta t{\rm{ + }}\frac{{\rm{1}}}{{\rm{2}}}{{\ddot s}_0}\Delta {t^{\rm{2}}}{\rm{ + }}\frac{{\rm{1}}}{{\rm{6}}}(\frac{{{{\ddot s}_1} - {{\ddot s}_0}}}{{\Delta t}})\Delta {t^{\rm{3}}})}\\ \vdots \\{{s_{n - 1}} - ({s_{n - 2}} + {{\dot s}_{n - 2}}\Delta t{\rm{ + }}\frac{{\rm{1}}}{{\rm{2}}}{{\ddot s}_{n - 2}}\Delta {t^{\rm{2}}}{\rm{ + }}\frac{{\rm{1}}}{{\rm{6}}}(\frac{{{{\ddot s}_{n - 1}} - {{\ddot s}_{n - 2}}}}{{\Delta t}})\Delta {t^{\rm{3}}})}\\{{{\dot s}_1} - ({{\dot s}_0} + {{\ddot s}_0}\Delta t + \frac{1}{2}(\frac{{{{\ddot s}_1} - {{\ddot s}_0}}}{{\Delta t}})\Delta {t^2})}\\ \vdots \\{{{\dot s}_{n - 1}} - ({{\dot s}_{n - 2}} + {{\ddot s}_{n - 2}}\Delta t + \frac{1}{2}(\frac{{{{\ddot s}_{n - 1}} - {{\ddot s}_{n - 2}}}}{{\Delta t}})\Delta {t^2})}\\{{{\dot s}_0} - speed\_limit({s_0})}\\ \vdots \\{{{\dot s}_{n - 1}} - speed\_limit({s_{n - 1}})}\\{{s_0} - s\_soft\_lowe{r_0} + s\_slack\_lower}\\ \vdots \\{{s_{n - 1}} - s\_soft\_lowe{r_{n - 1}} + s\_slack\_lower}\\{{s_0} - s\_soft\_uppe{r_0} - s\_slack\_upper}\\ \vdots \\{{s_{n - 1}} - s\_soft\_uppe{r_{n - 1}} - s\_slack\_upper}\end{array}} \right] g(x)= s1s0sn1sn2Δts¨1s¨0Δts¨n1s¨n2s1(s0+s˙0Δt+21s¨0Δt2+61(Δts¨1s¨0)Δt3)sn1(sn2+s˙n2Δt+21s¨n2Δt2+61(Δts¨n1s¨n2)Δt3)s˙1(s˙0+s¨0Δt+21(Δts¨1s¨0)Δt2)s˙n1(s˙n2+s¨n2Δt+21(Δts¨n1s¨n2)Δt2)s˙0speed_limit(s0)s˙n1speed_limit(sn1)s0s_soft_lower0+s_slack_lowersn1s_soft_lowern1+s_slack_lowers0s_soft_upper0s_slack_uppersn1s_soft_uppern1s_slack_upper

7.eval_jac_g()求解约束雅可比矩阵

  /** Method to return:*   1) The structure of the jacobian (if "values" is nullptr)*   2) The values of the jacobian (if "values" is not nullptr)*/bool eval_jac_g(int n, const double *x, bool new_x, int m, int nele_jac,int *iRow, int *jCol, double *values) override;

• 变量值:x
• 雅可比矩阵非0元素数量:nele_jac
• 雅可比矩阵值:values

f : R n → R n f:\mathbb{R}^n\to\mathbb{R}^n f:RnRn 是一个可微函数,则 f f f 在点 x = ( x 1 , x 2 , ⋯ , x n ) T \boldsymbol{x}=(x_1,x_2,\cdots,x_n)^T x=(x1,x2,,xn)T 处的雅可比矩阵为:

J = ( ∂ f 1 ∂ x 1 ∂ f 1 ∂ x 2 ⋯ ∂ f 1 ∂ x n ∂ f 2 ∂ x 1 ∂ f 2 ∂ x 2 ⋯ ∂ f 2 ∂ x n ⋮ ⋮ ⋱ ⋮ ∂ f n ∂ x 1 ∂ f n ∂ x 2 ⋯ ∂ f n ∂ x n ) \boldsymbol{J}=\begin{pmatrix} \frac{\partial f_1}{\partial x_1} & \frac{\partial f_1}{\partial x_2} & \cdots & \frac{\partial f_1}{\partial x_n} \\ \frac{\partial f_2}{\partial x_1} & \frac{\partial f_2}{\partial x_2} & \cdots & \frac{\partial f_2}{\partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial f_n}{\partial x_1} & \frac{\partial f_n}{\partial x_2} & \cdots & \frac{\partial f_n}{\partial x_n} \end{pmatrix} J= x1f1x1f2x1fnx2f1x2f2x2fnxnf1xnf2xnfn

其中, f i f_i fi 表示 f f f 的第 i i i 个分量函数, ∂ f i ∂ x j \frac{\partial f_i}{\partial x_j} xjfi 表示 f i f_i fi 对第 j j j 个自变量 x j x_j xj 的偏导数。

求解器通过稀疏矩阵来保存值。在这里插入图片描述在这里插入图片描述

稀疏矩阵的例子

由约束矩阵可知,共有7个类型的函数,分别求偏导可得:

  • 单调性约束: g 1 = s i + 1 − s i g_1=s_{i+1}-s_i g1=si+1si ∂ g 1 ∂ s i = − 1 , ∂ g 1 ∂ s i + 1 = 1 \frac{\partial g_1}{\partial s_i}=-1,\frac{\partial g_1}{\partial s_{i+1}}=1 sig1=1,si+1g1=1

  • 加加速度jerk约束: g 2 = s ¨ i + 1 − s ¨ i Δ t g_2 = \frac {\ddot s_{i+1}-\ddot s_i}{\Delta t} g2=Δts¨i+1s¨i ∂ g 2 ∂ s i = − 1 Δ t , ∂ g 2 ∂ s i + 1 = 1 Δ t \frac{\partial g_2}{\partial s_i}=-\frac{1}{\Delta t},\frac{\partial g_2}{\partial s_{i+1}}=\frac{1}{\Delta t} sig2=Δt1,si+1g2=Δt1

  • 位置等式约束: g 3 = s i + 1 − ( s i + s i ′ ∗ Δ t + 1 3 ∗ s i ′ ′ ∗ Δ t 2 + 1 6 ∗ s i + 1 ′ ′ ∗ Δ t 2 ) g_3=s_{i+1}-(s_i+s_i^{\prime}*\Delta t+\frac13*s_i^{\prime\prime}*\Delta t^2+\frac16*s_{i+1}^{\prime\prime}*\Delta t^2) g3=si+1(si+siΔt+31si′′Δt2+61si+1′′Δt2)
    ∂ g 3 ∂ s i = − 1 ∂ g 3 ∂ s i + 1 = 1 ∂ g 3 ∂ s ˙ i = − Δ t ∂ g 3 ∂ s ¨ i = − Δ t 2 3 ∂ g 3 ∂ s ¨ i + 1 = − Δ t 2 6 \begin{gathered} \begin{aligned}\frac{\partial g_3}{\partial s_i}=-1\end{aligned} \\ \frac{\partial g_3}{\partial s_{i+1}}=1 \\ \begin{aligned}\frac{\partial g_3}{\partial \dot s_i}&=-\Delta t\end{aligned} \\ \frac{\partial g_3}{\partial\ddot{s}_i}=-\frac{\Delta t^2}3 \\ \frac{\partial g_3}{\partial\ddot{s}_{i+1}}=-\frac{\Delta t^2}6 \end{gathered} sig3=1si+1g3=1s˙ig3=Δts¨ig3=3Δt2s¨i+1g3=6Δt2

  • 速度等式约束: g 4 = s i + 1 ′ − ( s i ′ + 1 2 ∗ s i ′ ′ ∗ Δ t + 1 2 ∗ s i + 1 ′ ′ ∗ Δ t ) g_4=s_{i+1}^{\prime}-(s_i^{\prime}+\frac12*s_i^{\prime\prime}*\Delta t+\frac12*s_{i+1}^{\prime\prime}*\Delta t) g4=si+1(si+21si′′Δt+21si+1′′Δt)
    ∂ g 4 ∂ s ˙ i = − 1 ∂ g 4 ∂ s ˙ i + 1 = 1 ∂ g 4 ∂ s ¨ i = − Δ t 2 ∂ g 4 ∂ s ¨ i + 1 = − Δ t 2 \begin{gathered} \frac{\partial g_4}{\partial\dot{s}_i}=-1 \\ \frac{\partial g_4}{\partial\dot{s}_{i+1}}=1 \\ \frac{\partial g_4}{\partial\ddot{s}_i}=-\frac{\Delta t}2 \\ \frac{\partial g_4}{\partial\ddot{s}_{i+1}}=-\frac{\Delta t}2 \end{gathered} s˙ig4=1s˙i+1g4=1s¨ig4=2Δts¨i+1g4=2Δt

  • 速度限制约束: g 5 = s ˙ i − s p e e d _ l i m i t ( s i ) g_5={{{\dot s}_i} - speed\_limit({s_i})} g5=s˙ispeed_limit(si)
    ∂ g 5 ∂ s ˙ i = 1 , ∂ g 5 ∂ s i = − d s p e e d _ l i m i t ( s i ) d s i \frac{\partial g_5}{\partial \dot s_i}=1,\frac{\partial g_5}{\partial s_{i}}=-\frac{d speed\_limit({s_i})}{ds_i} s˙ig5=1,sig5=dsidspeed_limit(si)

  • 软约束lower: g 6 = s i − s _ s o f t _ l o w e r i + s _ s l a c k _ l o w e r i g_6=s_i-s\_soft\_lower_i+s\_slack\_lower_i g6=sis_soft_loweri+s_slack_loweri
    ∂ g 6 ∂ s i = 1 , ∂ g 6 ∂ s _ s l a c k _ l o w e r i = 1 \frac{\partial g_6}{\partial s_i}=1,\frac{\partial g_6}{\partial s\_slack\_lower_i}=1 sig6=1,s_slack_lowerig6=1

  • 软约束upper: g 7 = s i − s _ s o f t _ u p p e r i − s _ s l a c k _ u p p e r i g_7=s_i-s\_soft\_upper_i-s\_slack\_upper_i g7=sis_soft_upperis_slack_upperi
    ∂ g 7 ∂ s i = 1 , ∂ g 7 ∂ s _ s l a c k _ u p p e r i = − 1 \frac{\partial g_7}{\partial s_i}=1,\frac{\partial g_7}{\partial s\_slack\_upper_i}=-1 sig7=1,s_slack_upperig7=1

雅可比矩阵(维度:[4(N-1)+3N]*5N)如下:
[ − 1 1 ⋱ ⋱ − 1 1 − 1 Δ t 1 Δ t ⋱ ⋱ − 1 Δ t 1 Δ t − 1 1 ⋱ ⋱ − 1 1 − Δ t ⋱ − Δ t − Δ t 2 3 − Δ t 2 6 ⋱ ⋱ − Δ t 2 3 − Δ t 2 6 − 1 1 ⋱ ⋱ − 1 1 − Δ t 2 − Δ t 2 ⋱ ⋱ − Δ t 2 − Δ t 2 − v _ f ( s i ) ′ ⋱ − v _ f ( s i ) ′ 1 ⋱ 1 1 ⋱ 1 1 ⋱ 1 1 ⋱ 1 − 1 ⋱ − 1 ] \left[ {\begin{array}{ccccccccccccccc}{\begin{array}{ccccccccccccccc}{ - 1}&1&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - 1}&1\end{array}}&{}&{}&{}&{}\\{}&{}&{\begin{array}{ccccccccccccccc}{ - \frac{1}{{\Delta t}}}&{\frac{1}{{\Delta t}}}&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - \frac{1}{{\Delta t}}}&{\frac{1}{{\Delta t}}}\end{array}}&{}&{}\\{\begin{array}{ccccccccccccccc}{ - 1}&1&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - 1}&1\end{array}}&{\begin{array}{ccccccccccccccc}{ - \Delta t}&{}&{}\\{}& \ddots &{}\\{}&{}&{ - \Delta t}\end{array}}&{\begin{array}{ccccccccccccccc}{ - \frac{{\Delta {t^2}}}{3}}&{ - \frac{{\Delta {t^2}}}{6}}&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - \frac{{\Delta {t^2}}}{3}}&{ - \frac{{\Delta {t^2}}}{6}}\end{array}}&{}&{}\\{}&{\begin{array}{ccccccccccccccc}{ - 1}&1&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - 1}&1\end{array}}&{\begin{array}{ccccccccccccccc}{ - \frac{{\Delta t}}{2}}&{ - \frac{{\Delta t}}{2}}&{}&{}\\{}& \ddots & \ddots &{}\\{}&{}&{ - \frac{{\Delta t}}{2}}&{ - \frac{{\Delta t}}{2}}\end{array}}&{}&{}\\{\begin{array}{ccccccccccccccc}{ - v\_f({s_i})'}&{}&{}\\{}& \ddots &{}\\{}&{}&{ - v\_f({s_i})'}\end{array}}&{\begin{array}{ccccccccccccccc}1&{}&{}\\{}& \ddots &{}\\{}&{}&1\end{array}}&{}&{}&{}\\{\begin{array}{ccccccccccccccc}1&{}&{}\\{}& \ddots &{}\\{}&{}&1\end{array}}&{}&{}&{\begin{array}{ccccccccccccccc}1&{}&{}\\{}& \ddots &{}\\{}&{}&1\end{array}}&{}\\{\begin{array}{ccccccccccccccc}1&{}&{}\\{}& \ddots &{}\\{}&{}&1\end{array}}&{}&{}&{}&{\begin{array}{ccccccccccccccc}{ - 1}&{}&{}\\{}& \ddots &{}\\{}&{}&{ - 1}\end{array}}\end{array}} \right] 11111111v_f(si)v_f(si)1111ΔtΔt111111Δt1Δt1Δt1Δt13Δt26Δt23Δt26Δt22Δt2Δt2Δt2Δt1111

8.eval_h()求解黑塞矩阵

  /** Method to return:*   1) The structure of the hessian of the lagrangian (if "values" is* nullptr) 2) The values of the hessian of the lagrangian (if "values" is not* nullptr)*/bool eval_h(int n, const double *x, bool new_x, double obj_factor, int m,const double *lambda, bool new_lambda, int nele_hess, int *iRow,int *jCol, double *values) override;

• 变量值:x
• 拉格朗日乘数:lambda
• 黑塞矩阵值:values
• 目标函数因数:obj_factor

黑塞矩阵的基本形式如下所示:

H = ( ∂ 2 f ∂ x 1 2 ∂ 2 f ∂ x 1 ∂ x 2 ⋯ ∂ 2 f ∂ x 1 ∂ x n ∂ 2 f ∂ x 2 ∂ x 1 ∂ 2 f ∂ x 2 2 ⋯ ∂ 2 f ∂ x 2 ∂ x n ⋮ ⋮ ⋱ ⋮ ∂ 2 f ∂ x n ∂ x 1 ∂ 2 f ∂ x n ∂ x 2 ⋯ ∂ 2 f ∂ x n 2 ) H = \begin{pmatrix} \frac{\partial^2 f}{\partial x_1^2} & \frac{\partial^2 f}{\partial x_1 \partial x_2} & \cdots & \frac{\partial^2 f}{\partial x_1 \partial x_n} \\ \frac{\partial^2 f}{\partial x_2 \partial x_1} & \frac{\partial^2 f}{\partial x_2^2} & \cdots & \frac{\partial^2 f}{\partial x_2 \partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial^2 f}{\partial x_n \partial x_1} & \frac{\partial^2 f}{\partial x_n \partial x_2} & \cdots & \frac{\partial^2 f}{\partial x_n^2} \end{pmatrix} H= x122fx2x12fxnx12fx1x22fx222fxnx22fx1xn2fx2xn2fxn22f

其中, f ( x ) f(\boldsymbol{x}) f(x) 是二次可微函数, ∂ 2 f ∂ x i ∂ x j \frac{\partial^2 f}{\partial x_i \partial x_j} xixj2f 表示 f ( x ) f(\boldsymbol{x}) f(x) x i x_i xi x j x_j xj 的二阶偏导数, H H H 表示黑塞矩阵。

目标函数的二阶偏导只有个别项是非0的:
∂ f ∂ s i 2 = 2 w s − r e f + 2 w l a t _ a c c [ s ˙ i 4 ⋅ ( κ ′ ( s i ) ) 2 + s ˙ i 4 ⋅ κ ( s i ) ⋅ κ ′ ′ ( s i ) ] + 2 w t a r g e t − s + 2 w t a r g e t − s ˙ + 2 w t a r g e t − s ¨ ∂ f ∂ s i ∂ s i ′ = 8 w l a t _ a c c s i ′ 3 ⋅ κ ( s i ) ⋅ κ ′ ( s i ) ∂ f ∂ s i ′ 2 = 12 w l a t _ a c c s i ′ 2 ⋅ κ 2 ( s i ) + 2 w s ˙ − r e f ∂ f ∂ s i ′ ′ 2 = 2 w a s i ′ 2 ⋅ κ 2 ( s i ) + 4 w j Δ t 2 + 2 w a ∂ f ∂ s i ′ ′ ∂ s i + 1 ′ ′ = − 2 w j Δ t 2 \begin{aligned} \frac{\partial f}{\partial s_i^2}&=2w_{s-ref}+2w_{lat\_acc}[ \dot s_i^4\cdot(\kappa^{\prime}(s_i))^2+\dot s_i^4\cdot \kappa(s_i)\cdot \kappa^{\prime\prime}(s_i)] \\&+2w_{target-s}+2w_{target-\dot s}+2w_{target-\ddot s}\\ \frac{\partial f}{\partial s_i \partial s_i^{\prime}}&=8w_{lat\_acc}{s_i^{\prime}}^3\cdot \kappa(s_i)\cdot \kappa^{\prime}(s_i) \\ \frac{\partial f}{\partial{s_i^{\prime}}^2}&=12w_{lat\_acc}{s_i^{\prime}}^2\cdot \kappa^2(s_i)+2w_{\dot s-ref} \\ \frac{\partial f}{\partial{s_i^{\prime\prime}}^2}&=2w_a{s_i^{\prime}}^2\cdot \kappa^2(s_i)+\frac{4w_j}{\Delta t^2}+2w_a \\ \frac{\partial f}{\partial s_i^{\prime\prime}\partial s_{i+1}^{\prime\prime}}&=-\frac{2w_j}{\Delta t^2}\end{aligned} si2fsisifsi2fsi′′2fsi′′si+1′′f=2wsref+2wlat_acc[s˙i4(κ(si))2+s˙i4κ(si)κ′′(si)]+2wtargets+2wtargets˙+2wtargets¨=8wlat_accsi3κ(si)κ(si)=12wlat_accsi2κ2(si)+2ws˙ref=2wasi2κ2(si)+Δt24wj+2wa=Δt22wj约束函数的二阶偏导数:
∂ g ∂ s i 2 = − s p e e d _ l i m i t ′ ′ ( s i ) \begin{aligned} &\frac{\partial g}{\partial{s_i}^2}=-speed\_limit^{\prime\prime}(s_i) \end{aligned} si2g=speed_limit′′(si)

9. finalize_solution()

  /** @name Solution Methods *//** This method is called when the algorithm is complete so the TNLP can* store/write the solution */void finalize_solution(Ipopt::SolverReturn status, int n, const double *x,const double *z_L, const double *z_U, int m,const double *g, const double *lambda,double obj_value, const Ipopt::IpoptData *ip_data,Ipopt::IpoptCalculatedQuantities *ip_cq) override;

目标函数取得最小值时的优化量:x
目标函数最小值:obj_value

最后再次回顾一下流程:

  • Input.输入部分包括PathData以及起始的TrajectoryPoint
  • Process.
    • Snaity Check. 这样可以确保speed_data不为空,并且speed Optimizer不会接收到空数据.
    • const auto problem_setups_status = SetUpStatesAndBounds(path_data, *speed_data); 初始化QP问题。若失败,则会清除speed_data中的数据。
    • const auto qp_smooth_status = OptimizeByQP(speed_data, &distance, &velocity, &acceleration); 求解QP问题,并获得distance\velocity\acceleration等数据。 若失败,则会清除speed_data中的数据。这部分用以计算非线性问题的初始解,对动态规划的结果进行二次规划平滑
    • const bool speed_limit_check_status = CheckSpeedLimitFeasibility();
      检查速度限制。接着或执行以下四个步骤:
      1)Smooth Path Curvature 2)SmoothSpeedLimit 3)Optimize By NLP 4)Record speed_constraint
    • 将 s/t/v/a/jerk等信息添加进 speed_data 并且补零防止fallback。
  • Output.输出SpeedData, 包括轨迹的s/t/v/a/jerk。

参考

[1] Planning Piecewise Jerk Nonlinear Speed Optimizer Introduction
[2] Planning 基于非线性规划的速度规划
[3] Apollo星火计划学习笔记——Apollo速度规划算法原理与实践
[4] Apollo规划控制学习笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

碎片笔记 | 大模型攻防简报

前言:与传统的AI攻防(后门攻击、对抗样本、投毒攻击等)不同,如今的大模型攻防涉及以下多个方面的内容: 目录 一、大模型的可信问题1.1 虚假内容生成1.2 隐私泄露 二、大模型的模型安全问题(传统AI攻防&…

交叉编译poco-1.9.2

目录 一、文件下载二、编译三、可能遇到的问题和解决方法3.1 error "Unknown Hardware Architecture."3.2 error Target architecture was not detected as supported by Double-Conversion一、文件下载 下载地址:poco-1.9.2 二、编译 解压目录后打开build/config/…

Mybatis-Genertor逆向工程

1、导入mybaties插件 <build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.2</version><dependencies><dependency>…

亲手实现:全方位解析SpringCloud Alibaba,这份全彩笔记送给你

SpringCloud Aliababa简介 大家好&#xff0c;这次我们来分享一个实用的开源项目—SpringCloud Alibaba。 SpringCloud是国内外微服务开发的首选框架&#xff0c;而SpringCloud Alibaba则是阿里巴巴为微服务架构而开发的组件&#xff0c;它支持SpringCloud原生组件&#xff0…

并联电容器交流耐压试验方法

对被试并联电容器两极进行充分放电。 检查电容器外观、 污秽等情况, 判断电容器是否满足试验要求状态。 用端接线将并联电容器两极短接连接湖北众拓高试工频耐压装置高压端, 外壳接地。 接线完成后经检查确认无误, 人员退出试验范围。 接入符合测试设备的工作电源&#xff0c;…

PHP8中获取并删除数组中第一个元素-PHP8知识详解

我在上一节关于数组的教程&#xff0c;讲的是在php8中获取并删除数组中最后一个元素&#xff0c;今天分享的是相反的&#xff1a;PHP8中获取并删除数组中第一个元素。 回顾一下昨天的知识&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;今天学习的是使用arr…

STM32--蓝牙

本文主要介绍基于STM32F103C8T6和蓝牙模块实现的交互控制 简介 蓝牙&#xff08;Bluetooth&#xff09;是一种用于无线通信的技术标准&#xff0c;允许设备在短距离内进行数据交换和通信。它是由爱立信&#xff08;Ericsson&#xff09;公司在1994年推出的&#xff0c;以取代…

软件架构之前后端分离架构服务器端高并发演进之路

软件架构之前后端分离架构&服务器端高并发演进之路 前后端分离架构从业务角度从质量属性从性能角度 服务器端关于不同并发量的演进之路1. 单体架构2. 第一次演进&#xff1a;应用服务器和数据库服务器分开部署3. 第二次演进&#xff1a;引入本地缓存和分部署缓存4. 第三次演…

Dajngo06_Template模板

Dajngo06_Template模板 6.1 Template模板概述 模板引擎是一种可以让开发者把服务端数据填充到html网页中完成渲染效果的技术 静态网页&#xff1a;页面上的数据都是写死的&#xff0c;万年不变 动态网页&#xff1a;页面上的数据是从后端动态获取的&#xff08;后端获取数据库…

车载网络扫盲

目录 车载以太网发展技术 车载网络通信架构与拓扑 车载网络的车载网关 车载网络通信协议 二层确定性以太网协议 二层车载网络扩展协议 三层安全加密协议 四层应用通信协议 车载网络通信架构的网络安全 车载以太网发展技术 车载网络技术包括车载影音娱乐和车载导航需要的MOST&am…

Java多线程篇(1)——深入分析synchronized

文章目录 synchronized原理概述锁升级 初始状态偏向锁偏向锁获取/重入偏向锁的撤销/重偏向和升级批量重偏向和批量偏向撤销偏向锁的释放 轻量级锁轻量级锁获取/重入轻量级锁膨胀轻量级锁释放 重量级锁重量级锁获取/重入重量级锁释放重量级锁的降级 其他锁粗化、锁消除调用hashc…

IDEA(2023)修改默认缓存目录

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;专栏系列&#xff1a;无 &#x1f33c…

OSCP系列靶场-Esay-Vegeta1保姆级

OSCP系列靶场-Esay-Vegeta1保姆级 目录 OSCP系列靶场-Esay-Vegeta1保姆级总结准备工作信息收集-端口扫描目标开放端口收集目标端口对应服务探测 信息收集-端口测试22-SSH端口的信息收集22-SSH端口版本信息与MSF利用22-SSH协议支持的登录方式22-SSH手动登录尝试(无)22-SSH弱口令…

二叉树顺序存储结构

目录 1.二叉树顺序存储结构 2.堆的概念及结构 3.堆的相关接口实现 3.1 堆的插入及向上调整算法 3.1.1 向上调整算法 3.1.2 堆的插入 3.2 堆的删除及向下调整算法 3.2.1 向下调整算法 3.2.2 堆的删除 3.3 其它接口和代码实现 4.建堆或数组调堆的两种方式及复杂度分析…

使用 Python 来创建一个基本的命令行密码管理器

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 密码管理器项目简介…

长亭雷池社区版本安装与使用

0x01 雷池介绍 一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术&#xff0c;作为反向代理接入&#xff0c;保护你的网站不受黑客攻击。核心检测能力由智能语义分析算法驱动&#xff0c;专为社区而生&#xff0c;不让黑客越雷池半步。 官方网址&…

【Linux】多线程互斥与同步

文章目录 一、线程互斥1. 线程互斥的引出2. 互斥量3. 互斥锁的实现原理 二、可重入和线程安全三、线程和互斥锁的封装1. 线程封装1. 互斥锁封装 四、死锁1. 死锁的概念2. 死锁的四个必要条件3. 避免死锁 五、线程同步1. 线程同步的理解2. 条件变量 一、线程互斥 1. 线程互斥的…

卷积网络:实现手写数字是识别50轮准确率97.3%

卷积网络&#xff1a;实现手写数字是识别50轮准确率 1 导入必备库2 torchvision内置了常用数据集和最常见的模型3 数据批量加载4 绘制样例5 创建模型7 设置是否使用GPU8 设置损失函数和优化器9 定义训练函数10 定义测试函数11 开始训练12 绘制损失曲线并保存13 绘制准确率曲线并…

机器人连续位姿同步插值轨迹规划—对数四元数、b样条曲线、c2连续位姿同步规划

简介&#xff1a;Smooth orientation planning is benefificial for the working performance and service life of industrial robots, keeping robots from violent impacts and shocks caused by discontinuous orientation planning. Nevertheless, the popular used quate…

学习记忆——方法篇——连锁拍照、情景故事和逻辑故事法

三大方法速记这些内容 1、连锁拍照法速记重要事件 2、情景故事速记速记购物信息 3、逻辑故事法速记客户档案 一、连锁拍照法速记重要事件 例&#xff1a;女朋友在出差之前嘱咐男朋友几件事 1、把房间收拾干净&#xff0c;最重要的是要把书架整理了&#xff0c;垃圾倒了 2、记…