This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[C28x] acos() function in TMS320F28335



I hate to necro-post on a two year old thread,but I am noticing problems with the ACOS and F28335 also.  I am finding that on occasion the processor is returning 0 for the arc cosine (-1).  The result is repeatable, but the same code does not always produce the error.

In this particular case, I compute the phase angle between two vectors and take the acos() of the value to get the angle in radians.  In the code below, result will sometimes return 0 when the input vectors are 180 degrees apart.  I have broken the vAngle function into separate statements and verified that the input into the acos is indeed -1.  If I test for -1 +/- a small epsilon and make it -0.9999999 I get the correct result.  The problem appears to be caused by an input of exactly -1.0 (which is representable as a even power of 2 in floating point, while 0.9999 is not). 

As I indicated, it does not always happen.  One test case that does cause it to happen is to use an angle set of 6 and 186 degrees for the two vector inputs.  The vectors are simply a double[] with the cos and sin values of the angle in radians (i,e. the x,y components).

I have upgraded to code generation tools version 5.2.6 (April 2010) which apparently corrects some problems in math.h.  I did include the run time library in the project and I did include the proper header files (math.h).  I tried this in C and C++ and received the same result.  I have run this on a 6711 simulator and the code works perfectly.

The error can be duplicated easily with the following code: using a step size of 6.  Break when tcount = 92, then step and the next call to vAngle will produce an erroneous result (the inputs will be 6 and 186 degrees and the cos of the angle between them is -1).

 

float vDot(const float a[ ], const float b[ ] , const size_t n){
    float sum = 0;
     size_t i;
    for(i=0; i<n; ++i)
                  sum += a[i] * b[i];
         return sum;
}

float vNorm(const float a[ ], const size_t n){
         return sqrt(vDot(a, a, n));
}

float vAngle(const float a[ ], const float b[ ], const size_t n) {
    // cos theta = a dot b / |a| x |b|
    return acos (vDot(a,b,n) / (vNorm(a, n) * vNorm(b ,n) ));
}

//main code

void vector_test(void)
{
    const float pi=3.1415926535897932384626433832795;
    //const float halfpi = pi/2;
    const float twopi = 2*pi;
    int num_steps = 60; //Do each 6 degrees - fails right after tcount=92
    const float step = twopi / num_steps;
    int tcount = 0; //count the test number to reproduce failures
    float aVec[2] = {0,0};
    float bVec[2] = {0,0};
    
    float loop1, loop2;
    float result;
    float eresult;
    float error;
    float error_max = 0;
    int flag = 0;

    for (loop1 = 0; loop1 < twopi; loop1 += step)
    {
        aVec[0] = cos(loop1); //r=1 implied
        aVec[1] = sin(loop1);
        for (loop2 = 0; loop2 < twopi; loop2 += step)
        {
            bVec[0] = cos(loop2);
            bVec[1] = sin(loop2);
        //calculate the angle between them
        eresult = fabs((loop1 - loop2));
        //Make sure we have the smaller of the two angles
        if(eresult > pi)
            eresult = twopi - eresult; //take the smaller path
        result = vAngle(aVec, bVec, 2);
        error = fabs(result-eresult);
        if( error > error_max)
            error_max = error;

        if (error > .0005)
            {
            while(1)
                {
                flag = 1;
                }
            }
          tcount++;

        }    
    }
  
}