Cordic算法可以利用简单的移位和加减来计算复杂的三角函数、双曲函数、对数、指数等。
Cordic算法核心思想有两点,通过已知的角度来逼近输入的角度(用移位来代替tanθ),已知角度的cosθ经过多次积累相乘趋于常数。具体原理如下。
根据坐标旋转公式
x2=x1cosθ-y1sinθ
y2=x1sinθ+y1cosθ
提取出cosθ
x2=cosθ(x1-y1tanθ)
y2=cosθ(y1+x1tanθ)
上式为一次旋转,那么通过已知的角度,来逼近输入的角度,就需要多次旋转,也就是该公式要迭代多次。
经过多次迭代后,cosθ会积累相乘并趋于一个常数
cos45°x cos26.5°x…xcos0.028°x cos0.014°≈0.60725941
1/0.60725941≈1.64676024187
将该常数定义为Kn
Kn=∏1/cosθi=
将tanθ用移位来代替,即
tanθ=2-i
x2= cosθ(x1-y12-i)
y2= cosθ(y1+x12-i)
θ=arctan(2-i)
利用反正切可以计算出已知的角度值,matlab代码如下。
clear; close all; clc;
for i=0:15
theta = rad2deg( atan(2^(-i)) );
fprintf('theta=%.9f\ttan=%.9f\n',theta,2^(-i))
end
xn=Kn(x0cosz0 – y0sinz0)
yn=Kn(y0cosz0 + x0sinz0)
zn=0
当x0=1/Kn,y0=0时,消掉了y0sinz0和y0cosz0,那么 n次迭代后,x0的1/Kn与Kn相乘为1,有:
Xn=cosz0
Yn=sinz0
Matlab代码如下
clear; close all; clc;
for i=0:15
theta = rad2deg( atan(2^(-i)) );
fprintf('i=%d \ttheta=%.9f\ttan=%.9f \tcos=%.9f \tsin=%.9f\n',i,theta,2^(-i),cosd(theta),sind(theta))
% fprintf('%.9f \t tan*2^16=%.0f\n',theta, (2^16) * theta)
end
n = 16;
kn = 1;
for i=0:n
kn = kn*sqrt(1+2^(-2*i));
end
fprintf('\nkn=%.9f\t1/kn=%.9f\t\n',kn,1/kn)
x = zeros(n+1);
y = zeros(n+1);
z = zeros(n+1);
x(1) = 1/kn;
z(1) = pi/6; %输入的角度
for i=1:n
if(z(i) >= 0)
s = 1;
else
s = -1;
end
x(i+1) = x(i) - s*y(i)*(2^(-(i-1)));
y(i+1) = y(i) + s*x(i)*(2^(-(i-1)));
z(i+1) = z(i) - s*atan(2^(-(i-1)));
end
cos_theta = x(17) %计算出cos
sin_theta = y(17) %计算出sin
theta = z(17) %zn趋于0
由以上已知角度可以看出计算的最大角度为45°+26.5°+ ... +0.028°+0.014°,最小角度为-45°-26.5°- ... -0.028°-0.014°,即计算范围为-89.8°~+89.8°。
如果计算的角度超出-89.8°~+89.8°,则需要利用三角函数的对称性来换算。
第一象限:Sin(θ)=Sinθ, Cos(θ)=Cosθ
第二象限:Sin(θ+90)=Cosθ, Cos(θ+90)=-Sinθ
第三象限:Sin(θ+180)=-Sinθ, Cos(θ+180)=-Cosθ
第四象限:Sin(θ+270)=-Cosθ, Cos(θ+270)=Sinθ
在QuestaSim中仿真结果如下: