The bug of ARM CMSIS DSP library function Arm_sin_cos_f32
Wang Qiang
2016-05-10
I engaged in the development of power electronics products, using the STM32F4 series of CPUs, with floating-point operation, Park transformation or reverse transformation, the need to use the sin and cos, in order to facilitate the use of ARM_SIN_COS_F32 this function.
This article is original and cannot be reproduced without the author's permission.
1. Bug Discovery
The output current will suddenly appear a large negative current, has been on the PC through the C language simulation, there will be no error in the algorithm, the problem is fixed to the angle, because the angle is the feedback calculated, may be problematic, by printing but see the value of sin and cos is not in the range 1 to 1, the decision is Arm_sin_ Cos_f32 This function is not caused by angular anomalies, and the angle value is-720 degrees.
2. Source Code Analysis
After encountering the above problem, download the source code on the arm cmsis official website, find arm_sin_cos_f32 The source of this function is as follows:
void Arm_sin_cos_f32 (
float32_t Theta,
float32_t * Psinval,
float32_t * pcosval)
{
float32_t Fract, in; /* Temporary variables for input, output */
uint16_t Indexs, Indexc; /* Index variable */
float32_t F1, F2, D1, D2; /* Nearest OUTPUT values */
int32_t N;
float32_t Findex, Dn, Df, temp;
/* input x is in degrees */
/* Scale the input, divide-input by-cosine, for the Add 0.25 (PI/2) to read sine table */
in = Theta * 0.00277777777778f;
/* Calculation of floor value of input */
n = (int32_t) in;
/* Make negative values towards-infinity */
if (in < 0.0f)
{
n--;
}
/* Map input value to [0 1] */
in = in-(float32_t) n;
/* Calculation of index of the table */
Findex = (float32_t) fast_math_table_size * in;
Indexs = ((uint16_t) findex) & 0x1ff;
Indexc = (Indexs + (FAST_MATH_TABLE_SIZE/4)) & 0x1ff;
/* Fractional Value calculation */
Fract = Findex-(float32_t) Indexs;
/* Read nearest values of input value from the Cos & sin tables */
F1 = sintable_f32[indexc+0];
F2 = sintable_f32[indexc+1];
D1 =-sintable_f32[indexs+0];
D2 =-sintable_f32[indexs+1];
Dn = 0.0122718463030f; Delta between the points (fixed), in this case 2*pi/fast_math_table_size
Df = F2-F1; Delta between the values of the functions
temp = dn* (D1 + d2)-2*df;
temp = fract*temp + (3*DF-(D2 + 2*d1) *DN);
temp = fract*temp + d1*dn;
/* Calculation of cosine value */
*pcosval = fract*temp + F1;
/* Read nearest values of input value from the Cos & sin tables */
F1 = sintable_f32[indexs+0];
F2 = sintable_f32[indexs+1];
D1 = sintable_f32[indexc+0];
D2 = sintable_f32[indexc+1];
Df = F2-F1; Delta between the values of the functions
temp = dn* (D1 + d2)-2*df;
temp = fract*temp + (3*DF-(D2 + 2*d1) *DN);
temp = fract*temp + d1*dn;
/* Calculation of sine value */
*psinval = fract*temp + F1;
}
When theta =-720, in = 1, Findex = 512.0,indexs = 0,fract = 512.
The above function uses the method of linear interpolation, so the fract should be only 0 to 1, so the above bug is generated.
3. corresponding method
ARM_SIN_COS_F32 This function input range is 180 to 180, but the official web also wrote, if beyond this range, the function will automatically adjust back, so my code does not have a limit on the input range, compared to 720 degrees when the problem occurs, carefully analyze the code, If there is no problem between 180 and 180. The solution, then, is to limit the input to 180 to 180.
4. Summary
Authority is not necessarily authoritative.
The bug of ARM CMSIS DSP library function Arm_sin_cos_f32