三次样条插值(附完整代码)

在这里插入图片描述
  给定 n + 1 n+1 n+1个点 ( t i , q i ) , i = 0 , 1 , . . . , n (t_i,q_i),i=0,1,...,n (ti,qi),i=0,1,...,n,求解 n n n段三次多项式 q k ( t ) q_k(t) qk(t),使得拼接而成的三次样条曲线 s ( t ) s(t) s(t)经过所有给定点,而且二阶连续。三次样条曲线 s ( t ) s(t) s(t)定义如下:
{ s ( t ) = { q k ( t ) , t ∈ [ t k , t k + 1 ] , k = 0 , 1 , . . . , n − 1 } q k ( t ) = a k 0 + a k 1 ( t − t k ) + a k 2 ( t − t k ) 2 + a k 3 ( t − t k ) 3 (1) \begin{cases} s(t) = \{q_k(t),t\in[t_k,t_{k+1}],k=0,1,...,n-1\} \\ q_k(t)=a_{k0}+a_{k1}(t-t_k)+a_{k2}(t-t_k)^2+a_{k3}(t-t_k)^3 \\ \tag 1 \end{cases} { s(t)={ qk(t),t[tk,tk+1],k=0,1,...,n1}qk(t)=ak0+ak1(ttk)+ak2(ttk)2+ak3(ttk)3(1)

  每一段三次多项式 q k ( t ) q_k(t) qk(t)需要确定 4 4 4个系数,因而未知数共 4 n 4n 4n个。三次样条曲线基本约束条件(1)位置约束,每一段三次多项式都必须经过两个点,有约束条件 2 n 2n 2n个;(2)速度约束,相邻两段三次多项式在连接处的速度相等,有约束条件 n − 1 n-1 n1个;(3)加速度约束,相邻两段三次多项式在连接处的加速度相等,有约束条件 n − 1 n-1 n1个。故还需两个给定约束( 4 n − 2 n − ( n − 1 ) − ( n − 1 ) = 2 4n-2n-(n-1)-(n-1)=2 4n2n(n1)(n1)=2),便可唯一确定三次样条曲线。这里讨论三种不同的给定约束:
  (1) 给定起始速度 v 0 v_0 v0与结束速度 v n v_n vn
  (2) 起始位置 q 0 q_0 q0与结束位置 q n q_n qn相等(数据需满足的特性,非约束条件),起始速度 v 0 v_0 v0与结束速度 v n v_n vn相等,起始加速度 a 0 a_0 a0与结束加速度 a n a_n an相等(周期三次样条)
  (3) 给定起始速度 v 0 v_0 v0、结束速度 v n v_n vn、起始加速度 a 0 a_0 a0、结束加速度 a n a_n an

一、给定起始速度 v 0 v_0 v0与结束速度 v n v_n vn

1、三次样条的系数通过速度计算

  三次样条曲线所有约束:
{ q k ( t k ) = q k , q k ( t k + 1 ) = q k + 1 , k = 0 , . . . , n − 1 q ˙ k ( t k + 1 ) = q ˙ k + 1 ( t k + 1 ) = v k + 1 , k = 0 , . . . , n − 2 q ¨ k ( t k + 1 ) = q ¨ k + 1 ( t k + 1 ) , k = 0 , . . . , n − 2 q ˙ 0 ( t 0 ) = v 0 , q ˙ n − 1 ( t n ) = v n (2) \begin{cases} q_k(t_k)=q_k ,q_k(t_{k+1})=q_{k+1} ,k=0,...,n-1 \\ \dot{q}_k(t_{k+1})=\dot{q}_{k+1}(t_{k+1})=v_{k+1},k=0,...,n-2 \\ \ddot{q}_k(t_{k+1})=\ddot{q}_{k+1}(t_{k+1}),k=0,...,n-2 \\ \dot{q}_0(t_0)=v_0,\dot{q}_{n-1}(t_n)=v_n \\ \tag 2 \end{cases} qk(tk)=qk,qk(tk+1)=qk+1,k=0,...,n1q˙k(tk+1)=q˙k+1(tk+1)=vk+1,k=0,...,n2q¨k(tk+1)=q¨k+1(tk+1),k=0,...,n2q˙0(t0)=v0,q˙n1(tn)=vn(2)
  若所有中间点速度 v k ( k = 1 , . . . , n − 1 ) v_k(k=1,...,n-1) vk(k=1,...,n1)都已知,根据位置与速度约束:
{ q k ( t k ) = a k 0 = q k q ˙ k ( t k ) = a k 1 = v k q k ( t k + 1 ) = a k 0 + a k 1 T k + a k 2 T k 2 + a k 3 T k 3 = q k + 1 q ˙ k ( t k + 1 ) = a k 1 + 2 a k 2 T k + 3 a k 3 T k 2 = v k + 1 (3) \begin{cases} q_k(t_k)=a_{k0}=q_k\\ \dot{q}_k(t_k)=a_{k1}=v_k \\ q_k(t_{k+1})=a_{k0}+a_{k1}T_k+a_{k2}T_k^2+a_{k3}T_k^3=q_{k+1}\\ \dot{q}_k(t_{k+1})=a_{k1}+2a_{k2}T_k+3a_{k3}T_k^2=v_{k+1}\\ \tag 3 \end{cases} qk(tk)=ak0=qkq˙k(tk)=ak1=vkqk(tk+1)=ak0+ak1Tk+ak2Tk2+ak3Tk3=qk+1q˙k(tk+1)=ak1+2ak2Tk+3ak3Tk2=vk+1(3)
  其中, T k = t k + 1 − t k T_k=t_{k+1}-t_k Tk=tk+1tk
  由式(3)可解得:
{ a k , 0 = q k a k , 1 = v k a k , 2 = [ 3 ( q k + 1 − q k ) / T k − 2 v k − v k + 1 ] / T k a k , 3 = [ 2 ( q k − q k + 1 ) / T k + v k + v k + 1 ] / T k 2 (4) \begin{cases} a_{k,0}=q_k\\ a_{k,1}=v_k\\ a_{k,2}=[3(q_{k+1}-q_k)/T_k-2v_k-v_{k+1}]/T_k\\ a_{k,3}=[2(q_k-q_{k+1})/T_k+v_k+v_{k+1}]/T_k^2\\ \tag 4 \end{cases} ak,0=qkak,1=vkak,2=[3(qk+1qk)/Tk2vkvk+1]/Tkak,3=[2(qkqk+1)/Tk+vk+vk+1]/Tk2(4)
  考虑加速度约束:
q ¨ k ( t k + 1 ) = 2 a k , 2 + 6 a k , 3 T k = 2 a k + 1 , 2 = q ¨ k + 1 ( t k + 1 ) (5) \ddot{q}_k(t_{k+1})=2a_{k,2}+6a_{k,3}T_k=2a_{k+1,2}=\ddot{q}_{k+1}(t_{k+1}) \tag 5 q¨k(tk+1)=2ak,2+6ak,3Tk=2ak+1,2=q¨k+1(tk+1)(5)
  将 a k , 2 , a k , 3 , a k + 1 , 2 a_{k,2},a_{k,3},a_{k+1,2} ak,2,ak,3,ak+1,2代入式(5)化简得:
T k + 1 v k + 2 ( T k + 1 + T k ) v k + 1 + T k v k + 2 = 3 [ T k 2 ( q k + 2 − q k + 1 ) + T k + 1 2 ( q k + 1 − q k ) ] / ( T k T k + 1 ) (6) \begin{aligned} &T_{k+1}v_k+2(T_{k+1}+T_k)v_{k+1}+ T_kv_{k+2} \\ &=3[T_k^2(q_{k+2}-q_{k+1}) + T_{k+1}^2(q_{k+1}-q_{k})]/(T_kT_{k+1}) \tag 6 \end{aligned} Tk+1vk+2(Tk+1+Tk)vk+1+Tkvk+2=3[Tk2(qk+2qk+1)+Tk+12(qk+1qk)]/(TkTk+1)(6)
  其中, k = 0 , 1 , . . . , n − 2 k=0,1,...,n-2 k=0,1,...,n2
  式(6)写成矩阵形式( v 0 , v n v_0,v_n v0,vn已知):
[ 2 ( T 0 + T 1 ) T 0 0 ⋯ 0 T 2 2 ( T 1 + T 2 ) T 1 0 ⋮ 0 ⋱ 0 ⋮ 0 T n − 2 2 ( T n − 3 + T n − 2 ) T n − 3 0 ⋯ 0 T n − 1 2 ( T n − 2 + T n − 1 ) ] [ v 1 v 2 ⋮ v n − 2 v n − 1 ] = [ 3 [ T 0 2 ( q 2 − q 1 ) + T 1 2 ( q 1 − q 0 ) ] / ( T 0 T 1 ) − T 1 v 0 3 [ T 1 2 ( q 3 − q 2 ) + T 2 2 ( q 2 − q 1 ) ] / ( T 1 T 2 ) ⋮ 3 [ T n − 3 2 ( q n − 1 − q n − 2 ) + T n − 2 2 ( q n − 2 − q n − 3 ) ] / ( T n − 3 T n − 2 ) 3 [ T n − 2 2 ( q n − q n − 1 ) + T n − 1 2 ( q n − 1 − q n − 2 ) ] / ( T n − 2 T n − 1 ) − T n − 2 v n ] (7) \left[ \begin{matrix} 2(T_0+T_1) & T_0 & 0 & \cdots & 0\\ T_2 & 2(T_1+T_2) & T_1 & 0 & \vdots \\ 0 & & \ddots & & 0 \\ \vdots &0 & T_{n-2} & 2(T_{n-3}+T_{n-2}) & T_{n-3} \\ 0 & \cdots & 0 & T_{n-1} & 2(T_{n-2}+T_{n-1}) \end{matrix} \right] \left[ \begin{matrix} v_1\\ v_2 \\ \vdots\\ v_{n-2}\\ v_{n-1} \\ \end{matrix} \right] \\ = \left[ \begin{matrix} 3[T_0^2(q_2-q_1) + T_1^2(q_1-q_0)]/(T_0T_1) - T_1v_0\\ 3[T_1^2(q_3-q_2) + T_2^2(q_2-q_1)]/(T_1T_2) \\ \vdots\\ 3[T_{n-3}^2(q_{n-1}-q_{n-2}) + T_{n-2}^2(q_{n-2}-q_{n-3})]/(T_{n-3}T_{n-2}) \\ 3[T_{n-2}^2(q_n-q_{n-1}) + T_{n-1}^2(q_{n-1}-q_{n-2})]/(T_{n-2}T_{n-1}) - T_{n-2}v_n \end{matrix} \right] \tag{7} 2(T0+T1)T200T02(T1+T2)00T1Tn2002(Tn3+Tn2)Tn100Tn32(Tn2+Tn1)v1v2vn2vn1=3[T02(q2q1)+T12(q1q0)]/(T0T1)T1v03[T12(q3q2)+T22(q2q1)]/(T1T2)3[Tn32(qn1qn2)+Tn22(qn2qn3)]/(Tn3Tn2)3[Tn22(qnqn1)+Tn12(qn1qn2)]/(Tn2Tn1)Tn2vn(7)
  式(7)为对角占优的三对角矩阵方程,可以利用Thomas algorithm或称“追赶法”快速且稳定地求解,而无需求解矩阵的逆。参考博文:三对角方程与循环三对角方程数值解(附完整代码)

clc;
clear;
close all;

t = [0, 5, 7, 8, 10, 15, 18]'; %递增时间序列
q = [3, -2, -5, 0, 6, 12, 8]';
v0 = 2; %起始速度
vn = -3; %结束速度
deltaT = 0.001; %插补周期

n = length(t); % n >= 4
T = diff(t);
a = zeros(n - 2, 1);
b = zeros(n - 2, 1);
c = zeros(n - 2, 1);
d = zeros(n - 2, 1);

for i = 2 : n - 2
    a(i) = T(i + 1);
end
for i = 1 : n - 2
    b(i) = 2.0 * (T(i) + T(i + 1));
end
for i = 1 : n - 3
    c(i) = T(i);
end

d(1) = 3.0 * (T(1)^2 * (q(3) - q(2)) + T(2)^2 * (q(2) - q(1))) / (T(1) * T(2)) - T(2) * v0;
for i = 2 : n - 3
   d(i) = 3.0 * (T(i)^2 * (q(i + 2) - q(i + 1)) + T(i + 1)^2 * (q(i + 1) - q(i))) / (T(i) * T(i + 1)); 
end
d(n - 2) = 3.0 * (T(n - 2)^2 * (q(n) - q(n - 1)) + T(n - 1)^2 * (q(n - 1) - q(n - 2))) / (T(n - 2) * T(n - 1)) - T(n - 2) * vn;

[v, sta] = solve_tridiagonal_matrix_equation(a, b, c, d, n - 2);
if sta == 0
    error('三对角矩阵方程求解出错!');
end
v = [v0; v; vn];

time = [];
pos = [];
vel = [];
acc = [];
time = [time; t(1)];
pos = [pos; q(1)];
vel = [vel; v0];
acc = [acc; 2.0 * (3.0 * (q(2) - q(1)) / T(1) - 2.0 * v(1) - v(2)) / T(1)];
for i = 1 : n - 1
    tt = (t(i) + deltaT : deltaT : t(i + 1))';
    b0 = q(i);
    b1 = v(i);
    b2 = (3.0 * (q(i + 1) - q(i)) / T(i) - 2.0 * v(i) - v(i + 1)) / T(i);
    b3 = (2.0 * (q(i) - q(i + 1)) / T(i) + v(i) + v(i + 1)) / T(i)^2;

    time = [time; tt];
    pos = [pos; b0 + (tt - t(i)) .* (b1 + (tt - t(i)) .* (b2 + b3 .* (tt - t(i))))];
    vel = [vel; b1 + (tt - t(i)) .* (2.0 * b2 + 3.0 * b3 .* (tt - t(i)))];
    acc = [acc; 2.0 * b2 + 6.0 * b3 .* (tt - t(i))];
end
if abs(time(end) - t(n)) > 1.0e-8
    b2 = (3.0 * (q(n) - q(n - 1)) / T(n - 1) - 2.0 * v(n - 1) - v(n)) / T(n - 1);
    b3 = (2.0 * (q(n - 1) - q(n)) / T(n - 1) + v(n - 1) + v(n)) / T(n - 1)^2;
    time = [time; t(n)];
    pos = [pos; q(n)];
    vel = [vel; vn];
    acc = [acc; 2.0 * b2 + 6.0 * b3 .* T(n - 1)];
end

figure(1)
subplot(3, 1, 1)
plot(time, pos);
hold on
plot(t, q, 'ro');
xlabel('t')
ylabel('pos')

subplot(3, 1, 2)
plot(time, vel);
hold on
plot([t(1), t(n)], [v0, vn], 'ro');
xlabel('t')
ylabel('vel')

subplot(3, 1, 3)
plot(time, acc);
xlabel('t')
ylabel('acc')

在这里插入图片描述

2、三次样条的系数通过加速度计算

  第 k k k段三次多项式的加速度:
q ¨ k ( t ) = [ ω k + 1 ( t − t k ) + ω k ( t k + 1 − t ) ] / T k (8) \ddot{q}_k(t)=[\omega_{k+1} (t-t_k)+\omega_{k} (t_{k+1}-t) ]/T_k \tag{8} q¨k(t)=[ωk+1(ttk)+ωk(tk+1t)]/Tk(8)
  其中, ω k \omega_{k} ωk t k t_k tk处对应的加速度, k = 0 , 1 , . . . , n k=0,1,...,n k=0,1,...,n
  对上式积分,得到速度:
q ˙ k ( t ) = ω k + 1 ( t − t k ) 2 / ( 2 T k ) + ω k ( t k + 1 − t ) 2 / ( 2 T k ) + ( q k + 1 − q k ) / T k − T k ( ω k + 1 − ω k ) / 6 (9) \dot{q}_k(t)=\omega_{k+1} (t-t_k)^2/(2T_k)+\omega_{k} (t_{k+1}-t)^2/(2T_k) \\ +(q_{k+1} -q_k)/T_k-T_k(\omega_{k+1}-\omega_{k})/6\tag{9} q˙k(t)=ωk+1(ttk)2/(2Tk)+ωk(tk+1t)2/(2Tk)+(qk+1qk)/TkTk(ωk+1ωk)/6(9)
   t k t_k tk处的速度与加速度约束:
{ q ˙ k − 1 ( t k ) = q ˙ k ( t k ) q ¨ k − 1 ( t k ) = q ¨ k ( t k ) = ω k (10) \begin{cases} \dot{q}_{k-1}(t_k)=\dot{q}_{k}(t_k)\\ \ddot{q}_{k-1}(t_k)=\ddot{q}_{k}(t_k)=\omega_{k}\\ \tag {10} \end{cases} { q˙k1(tk)=q˙k(tk)q¨k1(tk)=q¨k(tk)=ωk(10)
  由式(8)(9)(10)得:
( T k − 1 / T k ) ω k − 1 + [ 2 ( T k + T k − 1 ) / T k ] ω k + ω k + 1 = ( 6 / T k ) [ ( q k + 1 − q k ) / T k − ( q k − q k − 1 ) / T k − 1 ] , k = 1 , 2 , . . . , n − 1 (11) (T_{k-1}/T_k)\omega_{k-1} + [2(T_k + T_{k-1})/T_k]\omega_{k}+\omega_{k+1} \\ =(6/T_k) [(q_{k+1} -q_k)/T_k-(q_{k} -q_{k-1})/T_{k-1}],k=1,2,...,n-1 \tag{11} (Tk1/Tk)ωk1+[2(Tk+Tk1)/Tk]ωk+ωk+1=(6/Tk)[(qk+1qk)/Tk(qkqk1)/Tk1],k=1,2,...,n1(11)
  由 s ˙ ( t 0 ) = v 0 \dot{s}(t_0)=v_0 s˙(t0)=v0得:
T 0 2 ω 0 / 3 + T 0 2 ω 1 / 6 = q 1 − q 0 − T 0 v 0 (12) T_0^2\omega_0/3 + T_0^2\omega_1/6=q_1-q_0-T_0v_0 \tag{12} T02ω0/3+T02ω1/6=q1q0T0v0(12)
  由 s ˙ ( t n ) = v n \dot{s}(t_n)=v_n s˙(tn)=vn得:
T n − 1 2 ω n / 3 + T n − 1 2 ω n − 1 / 6 = q n − 1 − q n + T n − 1 v n (13) T_{n-1}^2\omega_n/3 + T_{n-1}^2\omega_{n-1}/6=q_{n-1}-q_n+T_{n-1}v_n \tag{13} Tn12ωn/3+Tn12ωn1/6=qn1qn+Tn1vn(13)
  将式(9)(12)(13)写成矩阵形式:
A ω = c (14) A\omega=c \tag{14} Aω=c(14)
  其中:
A = [ 2 T 0 T 0 0 ⋯ 0 T 0 2 ( T 0 + T 1 ) T 1 0 ⋮ 0 ⋱ 0 ⋮ 0 T n − 2 2 ( T n − 2 + T n − 1 ) T n − 1 0 ⋯ 0 T n − 1 2 T n − 1 ) ] (15) A=\left[ \begin{matrix} 2T_0 & T_0 & 0 & \cdots & 0\\ T_0 & 2(T_0+T_1) & T_1 & 0 & \vdots \\ 0 & & \ddots & & 0 \\ \vdots &0 & T_{n-2} & 2(T_{n-2}+T_{n-1}) & T_{n-1} \\ 0 & \cdots & 0 & T_{n-1} & 2T_{n-1}) \end{matrix} \right] \tag {15} A=2T0T000T02(T0+T1)00T1Tn2002(Tn2+Tn1)Tn100Tn12Tn1)(15)

c = [ 6 [ ( q 1 − q 0 ) / T 0 − v 0 ] 6 [ ( q 2 − q 1 ) / T 1 − ( q 1 − q 0 ) / T 0 ] ⋮ 6 [ ( q n − q n − 1 ) / T n − 1 − ( q n − 1 − q n − 2 ) / T n − 2 ] 6 [ v n − ( q n − q n − 1 ) / T n − 1 ] ] (16) c=\left[ \begin{matrix} 6[(q_1-q_0)/T_0 - v_0]\\ 6[(q_2-q_1)/T_1 -(q_1-q_0)/T_0]\\ \vdots \\ 6[(q_n-q_{n-1})/T_{n-1} -(q_{n-1}-q_{n-2})/T_{n-2}] \\ 6[v_n-(q_n-q_{n-1})/T_{n-1}]\\ \end{matrix} \right] \tag {16} c=6[(q1q0)/T0v0]6[(q2q1)/T1(q1q0)/T0]6[(qnqn1)/Tn1(qn1qn2)/Tn2]6[vn(qnqn1)/Tn1](16)
  求得 ω \omega ω,即可计算样条的系数:
{ a k 0 = q k a k 1 = ( q k + 1 − q k ) / T k − T k ( ω k + 1 + 2 ω k ) / 6 a k 2 = ω k / 2 a k 3 = ( ω k + 1 − ω k ) / ( 6 T k ) (17) \begin{cases} a_{k0}=q_k\\ a_{k1}=(q_{k+1}-q_k)/T_k-T_k(\omega_{k+1}+2\omega_{k})/6\\ a_{k2}=\omega_{k}/2\\ a_{k3}=(\omega_{k+1}-\omega_{k})/(6T_k)\\ \tag {17} \end{cases} ak0=qkak1=(qk+1qk)/TkTk(ωk+1+2ωk)/6ak2=ωk/2ak3=(ωk+1ωk)/(6Tk)(17)

clc;
clear;
close all;

t = [0, 5, 7, 8, 10, 15, 18]'; %递增时间序列
q = [3, -2, -5, 0, 6, 12, 8]';
v0 = 2; %起始速度
vn = -3; %结束速度
deltaT = 0.001; %插补周期

n = length(t); % n >= 4
T = diff(t);
a = zeros(n, 1);
b = zeros(n, 1);
c = zeros(n, 1);
d = zeros(n, 1);

for i = 1 : n - 1
    a(i + 1) = T(i);
end

b(1) = 2.0 * T(1);
for i = 2 : n - 1
    b(i) = 2.0 * (T(i - 1) + T(i));
end
b(n) = 2.0 * T(n - 1);

for i = 1 : n - 1
    c(i) = T(i);
end

d(1) = 6.0 * ((q(2) - q(1)) / T(1) - v0);
for i = 2 : n - 1
   d(i) = 6.0 * ((q(i + 1) - q(i)) / T(i) - (q(i) - q(i - 1)) / T(i - 1)); 
end
d(n) = 6.0 * (vn - (q(n) - q(n - 1)) / T(n - 1));

[w, sta] = solve_tridiagonal_matrix_equation(a, b, c, d, n);
if sta == 0
    error('三对角矩阵方程求解出错!');
end

time = [];
pos = [];
vel = [];
acc = [];
time = [time; t(1)];
pos = [pos; q(1)];
vel = [vel; v0];
acc = [acc; w(1)];
for i = 1 : n - 1
    tt = (t(i) + deltaT : deltaT : t(i + 1))';
    a0 = q(i);
    a1 = (q(i + 1) - q(i)) / T(i) - T(i) * (w(i + 1) + 2.0 * w(i)) / 6.0;
    a2 = 0.5 * w(i);
    a3 = (w(i + 1) - w(i)) / (6.0 * T(i));

    time = [time; tt];
    pos = [pos; a0 + (tt - t(i)) .* (a1 + (tt - t(i)) .* (a2 + a3 .* (tt - t(i))))];
    vel = [vel; a1 + (tt - t(i)) .* (2.0 * a2 + 3.0 * a3 .* (tt - t(i)))];
    acc = [acc; 2.0 * a2 + 6.0 * a3 .* (tt - t(i))];
end
if abs(time(end) - t(n)) > 1.0e-8
    time = [time; t(n)];
    pos = [pos; q(n)];
    vel = [vel; vn];
    acc = [acc; w(n)];
end

figure(1)
subplot(3, 1, 1)
plot(time, pos);
hold on
plot(t, q, 'ro');
xlabel('t')
ylabel('pos')

subplot(3, 1, 2)
plot(time, vel);
xlabel('t')
ylabel('vel')

subplot(3, 1, 3)
plot(time, acc);
xlabel('t')
ylabel('acc')

在这里插入图片描述

二、起始位置 q 0 q_0 q0与结束位置 q n q_n qn相等(数据需满足的特性,非约束条件),起始速度 v 0 v_0 v0与结束速度 v n v_n vn相等,起始加速度 a 0 a_0 a0与结束加速度 a n a_n an相等(周期三次样条)

  对于周期三次样条,起始速度 v 0 v_0 v0,结束速度 v n v_n vn,起始加速度 a 0 a_0 a0,结束加速度 a n a_n an不可以任意指定,需满足约束:
v 0 = q ˙ 0 ( t 0 ) = q ˙ n − 1 ( t n ) = v n (18) v_0=\dot{q}_0(t_0)=\dot{q}_{n-1}(t_n)=v_n \tag{18} v0=q˙0(t0)=q˙n1(tn)=vn(18)
q ¨ 0 ( t 0 ) = 2 a 0 , 2 = 2 a n − 1 , 2 + 6 a n − 1 , 3 T n − 1 = q ¨ n − 1 ( t n ) (19) \ddot{q}_0(t_0)=2a_{0,2}=2a_{n-1,2}+6a_{n-1,3}T_{n-1}=\ddot{q}_{n-1}(t_n) \tag{19} q¨0(t0)=2a0,2=2an1,2+6an1,3Tn1=q¨n1(tn)(19)

  结合式(4)(7)可得矩阵方程:
[ 2 ( T n − 1 + T 0 ) T n − 1 0 ⋯ 0 T 0 T 1 2 ( T 0 + T 1 ) T 0 0 ⋮ 0 0 ⋱ ⋮ ⋮ 0 T n − 2 2 ( T n − 3 + T n − 2 ) T n − 3 T n − 2 0 ⋯ 0 T n − 1 2 ( T n − 2 + T n − 1 ) ] [ v 0 v 1 v 2 ⋮ v n − 2 v n − 1 ] = [ 3 [ T n − 1 2 ( q 1 − q 0 ) + T 0 2 ( q n − 1 − q n − 2 ) ] / ( T n − 1 T 0 ) 3 [ T 0 2 ( q 2 − q 1 ) + T 1 2 ( q 1 − q 0 ) ] / ( T 0 T 1 ) 3 [ T 1 2 ( q 3 − q 2 ) + T 2 2 ( q 2 − q 1 ) ] / ( T 1 T 2 ) ⋮ 3 [ T n − 3 2 ( q n − 1 − q n − 2 ) + T n − 2 2 ( q n − 2 − q n − 3 ) ] / ( T n − 3 T n − 2 ) 3 [ T n − 2 2 ( q n − q n − 1 ) + T n − 1 2 ( q n − 1 − q n − 2 ) ] / ( T n − 2 T n − 1 ) ] (20) \left[ \begin{matrix} 2(T_{n-1}+T_0) & T_{n-1} & 0 & \cdots & 0 & T_0\\ T_1 & 2(T_0+T_1) & T_0 & 0 & \vdots & 0 \\ 0 & & \ddots & & & \vdots \\ \vdots &0 & & T_{n-2} & 2(T_{n-3}+T_{n-2}) & T_{n-3} \\ T_{n-2} & 0 & \cdots & 0 & T_{n-1} & 2(T_{n-2}+T_{n-1}) \end{matrix} \right] \left[ \begin{matrix} v_0\\ v_1 \\ v_2 \\ \vdots\\ v_{n-2}\\ v_{n-1} \\ \end{matrix} \right] \\ = \left[ \begin{matrix} 3[T_{n-1}^2(q_1-q_0) + T_0^2(q_{n-1}-q_{n-2})]/(T_{n-1}T_0)\\ 3[T_0^2(q_2-q_1) + T_1^2(q_1-q_0)]/(T_0T_1) \\ 3[T_1^2(q_3-q_2) + T_2^2(q_2-q_1)]/(T_1T_2) \\ \vdots\\ 3[T_{n-3}^2(q_{n-1}-q_{n-2}) + T_{n-2}^2(q_{n-2}-q_{n-3})]/(T_{n-3}T_{n-2}) \\ 3[T_{n-2}^2(q_n-q_{n-1}) + T_{n-1}^2(q_{n-1}-q_{n-2})]/(T_{n-2}T_{n-1}) \end{matrix} \right] \tag{20} 2(Tn1+T0)T10Tn2Tn12(T0+T1)000T00Tn2002(Tn3+Tn2)Tn1T00Tn32(Tn2+Tn1)v0v1v2vn2vn1=3[Tn12(q1q0)+T02(qn1qn2)]/(Tn1T0)3[T02(q2q1)+T12(q1q0)]/(T0T1)3[T12(q3q2)+T22(q2q1)]/(T1T2)3[Tn32(qn1qn2)+Tn22(qn2qn3)]/(Tn3Tn2)3[Tn22(qnqn1)+Tn12(qn1qn2)]/(Tn2Tn1)(20)
  式(20)为循环三对角矩阵方程,可以利用Sherman-Morrison 公式快速且稳定地求解,而无需求解矩阵的逆。参考博文:三对角方程与循环三对角方程数值解(附完整代码)

clc;
clear;
close all;

t = [0, 5, 7, 8, 10, 15, 18]'; %递增时间序列
q = [3, -2, -5, 0, 6, 12, 3]'; %首尾数据一致
deltaT = 0.001; %插补周期
forwardPeriodCount = 2;
backwardPeriodCount = 1;

n = length(t);
T = diff(t);
a = zeros(n - 1, 1);
b = zeros(n - 1, 1);
c = zeros(n - 1, 1);
d = zeros(n - 1, 1);

a(1 : n - 1) = T(1 : n - 1);

b(1) = 2.0 * (T(n - 1) + T(1));
for i = 2 : n - 1
    b(i) = 2.0 * (T(i - 1) + T(i));
end

c(1) = T(n - 1);
for i = 2 : n - 2
    c(i) = T(i - 1);
end
c(n - 1) = T(n - 2);

d(1) = 3.0 * (T(n - 1)^2 * (q(2) - q(1)) + T(1)^2 * (q(n) - q(n - 1))) / (T(n - 1) * T(1));
for i = 2 : n - 1
    d(i) = 3.0 * (T(i - 1)^2 * (q(i + 1) - q(i)) + T(i)^2 * (q(i) - q(i - 1))) / (T(i - 1) * T(i));
end

[v, sta] = solve_cyclic_tridiagonal_matrix_equation(a, b, c, d, n - 1);
if sta == 0
    error('循环三对角矩阵方程求解出错!');
end
v = [v; v(1)];

time = [];
pos = [];
vel = [];
acc = [];
time = [time; t(1)];
pos = [pos; q(1)];
vel = [vel; v(1)];
acc = [acc; 2.0 * (3.0 * (q(2) - q(1)) / T(1) - 2.0 * v(1) - v(2)) / T(1)];
for i = 1 : n - 1
    tt = (t(i) + deltaT : deltaT : t(i + 1))';
    a0 = q(i);
    a1 = v(i);
    a2 = (3.0 * (q(i + 1) - q(i)) / T(i) - 2.0 * v(i) - v(i + 1)) / T(i);
    a3 = (2.0 * (q(i) - q(i + 1)) / T(i) + v(i) + v(i + 1)) / T(i)^2;
    
    time = [time; tt];
    pos = [pos; a0 + (tt - t(i)) .* (a1 + (tt - t(i)) .* (a2 + a3 .* (tt - t(i))))];
    vel = [vel; a1 + (tt - t(i)) .* (2.0 * a2 + 3.0 * a3 .* (tt - t(i)))];
    acc = [acc; 2.0 * a2 + 6.0 * a3 .* (tt - t(i))];
end
if abs(time(end) - t(n)) > 1.0e-8
    a2 = (3.0 * (q(n) - q(n - 1)) / T(n - 1) - 2.0 * v(n - 1) - v(n)) / T(n - 1);
    a3 = (2.0 * (q(n - 1) - q(n)) / T(n - 1) + v(n - 1) + v(n)) / T(n - 1)^2;
    time = [time; t(n)];
    pos = [pos; q(n)];
    vel = [vel; v(n)];
    acc = [acc; 2.0 * a2 + 6.0 * a3 .* T(n - 1)];
end

period = time(end) - time(1);

figure(1)
subplot(3, 1, 1)
plot(time, pos, 'k');
hold on
plot(t, q, 'ko');
for i = 1 : forwardPeriodCount
    plot(time + i * period, pos, '--');
    plot(t + i * period, q, 'bo');
end
for i = 1 : backwardPeriodCount
    plot(time - i * period, pos, '--');
    plot(t - i * period, q, 'bo');
end
xlabel('t')
ylabel('pos')

subplot(3, 1, 2)
plot(time, vel, 'k');
hold on
for i = 1 : forwardPeriodCount
    plot(time + i * period, vel, '--');
end
for i = 1 : backwardPeriodCount
    plot(time - i * period, vel, '--');
end
xlabel('t')
ylabel('vel')

subplot(3, 1, 3)
plot(time, acc, 'k');
hold on
for i = 1 : forwardPeriodCount
    plot(time + i * period, acc, '--');
end
for i = 1 : backwardPeriodCount
    plot(time - i * period, acc, '--');
end
xlabel('t')
ylabel('acc')

在这里插入图片描述

三、给定起始速度 v 0 v_0 v0、结束速度 v n v_n vn、起始加速度 a 0 a_0 a0、结束加速度 a n a_n an

  对于三次样条,一般无法同时指定起始速度与加速度,结束速度与加速度。然而可以通过在第一段以及最后一段样条插入两个额外点以实现。假设样条插值有 n − 1 n-1 n1个点序列:
{ t = [ t 0 , t 2 , t 3 , . . . , t n − 3 , t n − 2 , t n ] T q = [ q 0 , q 2 , q 3 , . . . , q n − 3 , q n − 2 , q n ] T (21) \begin{cases} \pmb{t}=[t_0,t_2,t_3,...,t_{n-3},t_{n-2},t_{n}]^T\\ \pmb{q}=[q_0,q_2,q_3,...,q_{n-3},q_{n-2},q_{n}]^T\\ \tag {21} \end{cases} { ttt=[t0,t2,t3,...,tn3,tn2,tn]Tqqq=[q0,q2,q3,...,qn3,qn2,qn]T(21)
  在第一段以及最后一段样条插入两个额外点: ( t ‾ 1 , q ‾ 1 ) , ( t ‾ n − 1 , q ‾ n − 1 ) (\overline{t}_1,\overline{q}_1),(\overline{t}_{n-1},\overline{q}_{n-1}) (t1,q1),(tn1,qn1),不妨取其为相邻两个点的中点。新的点序列:
{ t = [ t 0 , t ‾ 1 , t 2 , t 3 , . . . , t n − 3 , t n − 2 , t ‾ n − 1 , t n ] T q = [ q 0 , q ‾ 1 , q 2 , q 3 , . . . , q n − 3 , q n − 2 , q ‾ n − 1 , q n ] T (22) \begin{cases} \pmb{t}=[t_0,\overline{t}_1,t_2,t_3,...,t_{n-3},t_{n-2},\overline{t}_{n-1},t_{n}]^T\\ \pmb{q}=[q_0,\overline{q}_1,q_2,q_3,...,q_{n-3},q_{n-2},\overline{q}_{n-1},q_{n}]^T\\ \tag {22} \end{cases} { ttt=[t0,t1,t2,t3,...,tn3,tn2,tn1,tn]Tqqq=[q0,q1,q2,q3,...,qn3,qn2,qn1,qn]T(22)
  根据式(12)(13)可得:
{ q 1 = q 0 + T 0 v 0 + T 0 2 a 0 / 3 + T 0 2 ω 1 / 6 q n − 1 = q n − T n − 1 v n + T n − 1 2 a n / 3 + T n − 1 2 ω n − 1 / 6 (23) \begin{cases} q_1=q_0+T_0v_0+T_0^2a_0/3+T_0^2\omega_1/6\\ q_{n-1}=q_n-T_{n-1}v_n+T_{n-1}^2a_n/3+T_{n-1}^2\omega_{n-1}/6\\ \tag {23} \end{cases} { q1=q0+T0v0+T02a0/3+T02ω1/6qn1=qnTn1vn+Tn12an/3+Tn12ωn1/6(23)
  根据式(15)(16)(23)可得矩阵方程:
A ω = c (24) A\omega=c\tag{24} Aω=c(24)
  其中,
A = [ 2 T 1 + T 0 ( 3 + T 0 / T 1 ) T 1 0 ⋯ 0 T 1 − T 0 2 / T 1 2 ( T 1 + T 2 ) T 2 ⋮ 0 T 2 2 ( T 2 + T 3 ) T 3 ⋮ ⋱ 0 ⋮ T n − 3 2 ( T n − 3 + T n − 2 ) T n − 2 − T n − 1 2 / T n − 2 0 ⋯ 0 T n − 2 2 T n − 2 + T n − 1 ( 3 + T n − 1 / T n − 2 ) ] (25) A=\left[ \begin{matrix} 2T_1+T_0(3+T_0/T_1) & T_1 & 0 & & \cdots & 0\\ T_1-T_0^2/T_1 & 2(T_1+T_2) & T_2 & & & \vdots \\ 0 & T_2 & 2(T_2+T_3) & T_3 & & \\ \vdots & & \ddots & & &0 \\ \vdots & & & T_{n-3} & 2(T_{n-3}+T_{n-2}) & T_{n-2}-T_{n-1}^2/T_{n-2} \\ 0 & & \cdots & 0 & T_{n-2} & 2T_{n-2}+T_{n-1}(3+T_{n-1}/T_{n-2})\\ \end{matrix} \right] \tag{25} A=2T1+T0(3+T0/T1)T1T02/T100T12(T1+T2)T20T22(T2+T3)T3Tn302(Tn3+Tn2)Tn200Tn2Tn12/Tn22Tn2+Tn1(3+Tn1/Tn2)(25)
c = [ 6 ( ( q 2 − q 0 ) / T 1 − v 0 ( 1 + T 0 / T 1 ) − a 0 ( 1 / 2 + T 0 / ( 3 T 1 ) ) T 0 ) 6 ( ( q 3 − q 2 ) / T 2 − ( q 2 − q 0 ) / T 1 + v 0 T 0 / T 1 + a 0 T 0 2 / ( 3 T 1 ) ) 6 ( ( q 4 − q 3 ) / T 3 − ( q 3 − q 2 ) / T 2 ) ⋮ 6 ( ( q n − 2 − q n − 3 ) / T n − 3 − ( q n − 3 − q n − 4 ) / T n − 4 ) 6 ( ( q n − q n − 2 ) / T n − 2 − ( q n − 2 − q n − 3 ) / T n − 3 − v n T n − 1 / T n − 2 + a n T n − 1 2 / ( 3 T n − 2 ) ) 6 ( ( q n − 2 − q n ) / T n − 2 + v n ( 1 + T n − 1 / T n − 2 ) − a n ( 1 / 2 + T n − 1 / ( 3 T n − 2 ) ) T n − 1 ) ] (26) c= \left[ \begin{matrix} 6((q_2-q_0)/T_1-v_0(1+T_0/T_1)-a_0(1/2+T_0/(3T_1))T_0)\\ 6((q_3-q_2)/T_2-(q_2-q_0)/T_1+v_0T_0/T_1+a_0T_0^2/(3T_1))\\ 6((q_4-q_3)/T_3-(q_3-q_2)/T_2)\\ \vdots\\ 6((q_{n-2}-q_{n-3})/T_{n-3}-(q_{n-3}-q_{n-4})/T_{n-4})\\ 6((q_n-q_{n-2})/T_{n-2}-(q_{n-2}-q_{n-3})/T_{n-3}-v_nT_{n-1}/T_{n-2}+a_nT_{n-1}^2/(3T_{n-2}))\\ 6((q_{n-2}-q_n)/T_{n-2}+v_n(1+T_{n-1}/T_{n-2})-a_n(1/2+T_{n-1}/(3T_{n-2}))T_{n-1})\\ \end{matrix} \right] \tag{26} c=6((q2q0)/T1v0(1+T0/T1)a0(1/2+T0/(3T1))T0)6((q3q2)/T2(q2q0)/T1+v0T0/T1+a0T02/(3T1))6((q4q3)/T3(q3q2)/T2)6((qn2qn3)/Tn3(qn3qn4)/Tn4)6((qnqn2)/Tn2(qn2qn3)/Tn3vnTn1/Tn2+anTn12/(3Tn2))6((qn2qn)/Tn2+vn(1+Tn1/Tn2)an(1/2+Tn1/(3Tn2))Tn1)(26)

clc;
clear;
close all;

t = [0, 5, 7, 8, 10, 15, 18]'; %递增时间序列
q = [3, -2, -5, 0, 6, 12, 8]';
v0 = 2; %起始速度
vn = -3; %结束速度
a0 = 0; %起始加速度
an = 0; %结束加速度
deltaT = 0.001; %插补周期

%前两个时间之间、后两个时间之间插入时间
n = length(t); % n >= 4
t2 = 0.5 * (t(1) + t(2));
t_n_1 = 0.5 * (t(n) + t(n - 1));
t = [t(1); t2; t(2 : n - 1); t_n_1; t(n)];
q = [q(1); 0.0; q(2 : n - 1); 0.0; q(n)];

n = n + 2;
T = diff(t);
a = zeros(n - 2, 1);
b = zeros(n - 2, 1);
c = zeros(n - 2, 1);
d = zeros(n - 2, 1);

a(2) = T(2) - T(1)^2 / T(2);
for i = 3 : n - 2
    a(i) = T(i);
end

b(1) = 2.0 * T(2) + T(1) * (3.0 + T(1) / T(2));
for i = 2 : n - 3
    b(i) = 2.0 * (T(i) + T(i + 1));
end
b(n - 2) = 2.0 * T(n - 2) + T(n - 1) * (3.0 + T(n - 1) / T(n - 2));

for i = 1 : n - 4
    c(i) = T(i + 1);
end
c(n - 3) = T(n - 2) - T(n - 1)^2 / T(n - 2);

d(1) = 6.0 * ((q(3) - q(1)) / T(2) - v0 * (1.0 + T(1) / T(2)) - a0 * (0.5 + T(1) / (3.0 * T(2))) * T(1));
d(2) = 6.0 * ((q(4) - q(3)) / T(3) - (q(3) - q(1)) / T(2) + v0 * T(1) / T(2) + a0 * T(1)^2 / (3.0 * T(2)));
for i = 3 : n - 4
    d(i) = 6.0 * ((q(i + 2) - q(i + 1)) / T(i + 1) - (q(i + 1) - q(i)) / T(i));
end
d(n - 3) = 6.0 * ((q(n) - q(n - 2)) / T(n - 2) - (q(n - 2) - q(n - 3)) / T(n - 3) - vn * T(n - 1) / T(n - 2) + an * T(n - 1)^2 / (3.0 * T(n - 2)));
d(n - 2) = 6.0 * ((q(n - 2) - q(n)) / T(n - 2) + vn * (1.0 + T(n - 1) / T(n - 2)) - an * (0.5 + T(n - 1) / (3.0 * T(n - 2))) * T(n - 1));

[w, sta] = solve_tridiagonal_matrix_equation(a, b, c, d, n - 2);
if sta == 0
    error('三对角矩阵方程求解出错!');
end

w = [a0; w; an];

q(2) = q(1) + T(1) * v0 + T(1)^2 * a0 / 3.0 + T(1)^2 * w(2) / 6.0;
q(n - 1) = q(n) - T(n - 1) * vn + T(n - 1)^2 * an / 3.0 + T(n - 1)^2 * w(n - 1) / 6.0;

time = [];
pos = [];
vel = [];
acc = [];
time = [time; t(1)];
pos = [pos; q(1)];
vel = [vel; v0];
acc = [acc; a0];
for i = 1 : n - 1
    tt = (t(i) + deltaT : deltaT : t(i + 1))';
    b0 = q(i);
    b1 = (q(i + 1) - q(i)) / T(i) - T(i) * (w(i + 1) + 2.0 * w(i)) / 6.0;
    b2 = 0.5 * w(i);
    b3 = (w(i + 1) - w(i)) / (6.0 * T(i));
    
    time = [time; tt];
    pos = [pos; b0 + (tt - t(i)) .* (b1 + (tt - t(i)) .* (b2 + b3 .* (tt - t(i))))];
    vel = [vel; b1 + (tt - t(i)) .* (2.0 * b2 + 3.0 * b3 .* (tt - t(i)))];
    acc = [acc; 2.0 * b2 + 6.0 * b3 .* (tt - t(i))];
end
if abs(time(end) - t(n)) > 1.0e-8
    time = [time; t(n)];
    pos = [pos; q(n)];
    vel = [vel; vn];
    acc = [acc; an];
end

figure(1)
subplot(3, 1, 1)
plot(time, pos);
hold on
plot(t([1, 3 : n - 2, n]), q([1, 3 : n - 2, n]), 'ro');
plot(t([2, n - 1]), q([2, n - 1]), 'bs');
xlabel('t')
ylabel('pos')

subplot(3, 1, 2)
plot(time, vel);
hold on
plot(t([1, n]), [v0, vn], 'ro');
xlabel('t')
ylabel('vel')

subplot(3, 1, 3)
plot(time, acc);
hold on
plot(t([1, n]), [a0, an], 'ro');
xlabel('t')
ylabel('acc')

在这里插入图片描述

四、参考文献

Trajectory Planning for Automatic Machines and Robots中章节:4.4 Cubic Splines

猜你喜欢

转载自blog.csdn.net/maple_2014/article/details/106932615
今日推荐