Code spitting out -16256?

Hey guys, here’s the deal. Our mechanum code has decided (between yesterday and a week ago) to start trying to send -16256 to the front left wheel, and 16608 to the rear left wheel, with both right wheels getting 0 (the slight differences in left values are due to joystick neutralizing issues). We really don’t remember changing anything that would cause this, and we’re totally stumped. the PWMs are still getting a reasonable output, but not the right output.

Theres a pic from the COM window attached

And here’s the code-


void Mechanum(void)
{

      signed double wFL, wFR, wRL, wRR, velocity, rotation, strafe, wMax;
    signed int difference, difference2, difference3, difference4;
    signed int prepwm01, prepwm02, prepwm03, prepwm04;
    static char pwm01_1, pwm02_1, pwm03_1, pwm04_1;

    /*velocity = (p1_y - 127);
    rotation = (p1_x - 127);
    strafe = (p2_x - 127);*/

    /*velocity = deadband(p1_y,127,15);
    rotation = deadband(p1_x,127,15);
    strafe = deadband(p2_x,127,15);*/
   
    velocity = ctbl[joysticklimit(p1_y)];
    rotation = (ctbl[joysticklimit(p1_x)] / 2);
    strafe = ctbl[joysticklimit(p2_x)];
   
    wFL = velocity - rotation - strafe;
    wFR = velocity + rotation + strafe;
    wRL = velocity - rotation + strafe;
    wRR = velocity + rotation - strafe;

   wMax = intMax(127, intABS(wFL));
   wMax = intMax(wMax, intABS(wFR));
   wMax = intMax(wMax, intABS(wRL));
   wMax = intMax(wMax, intABS(wRR));


    wFL = (wFL * 127 / wMax);
    wFR = (wFR * 127 / wMax);
    wRL = (wRL * 127 / wMax);
    wRR = (wRR * 127 / wMax);
    if (-127 > wFL || wFL > 127 || -127 > wFR || wFR > 127 || -127 > wRL || wRL > 127 || -127 > wRR || wRR > 127)
    {     
        printf("Received an unexpected number FL: %d FR: %d RL: %d RR: %d /n", wFL, wFR, wRL, wRR);
    }
else
    {
   

    prepwm01 = wFL + 127;
    prepwm02 = 127 - wFR;
    prepwm03 = wRL + 127;
    prepwm04 = 127 - wRR;   


//Trying to fix issues with sensitive joysticks (below)


/* if (prepwm01 < 132 || prepwm01 > 122)
{
prepwm01 = 127;
}
if (prepwm02 < 132) || prepwm02 > 122)
{
prepwm02 = 127;
}
if (prepwm03 < 132 || prepwm03 > 122)
{
prepwm03 = 127;
}
if (prepwm04 < 132 || prepwm04 > 122)
{
prepwm04 = 127;
} */


    pwm01 = prepwm01;
    pwm02 = prepwm02;
    pwm03 = prepwm03;
    pwm04 = prepwm04;

printf("PWMS- pwm01: %d , pwm02: %d , pwm03: %d , pwm04: %d \r 
", pwm01, pwm02, pwm03, pwm04);
printf("Wheels- FL: %d FR: %d RL: %d RR: %d \r 
", wFL, wFR, wRL, wRR);
printf("wMax: %d Port 1 Y: %d , Port 1 X: %d , Port 2 X: %d \r", wMax, p1_y, p1_x, p2_x);

    /*if (((intABS((char)pwm01 - pwm01_1)) > 0 ) || ((intABS((char)pwm02 - pwm02_1)) > 0 ) || ((intABS((char)pwm03 - pwm03_1)) > 0 ) || ((intABS((char)pwm04 - pwm04_1)) > 0 )) {
        printf(" pwm01: %d , pwm02: %d , pwm03: %d , pwm04: %d \r", pwm01, pwm02, pwm03, pwm04);
        printf(" Port 1 Y: %d , Port 1 X: %d , Port 2 X: %d \r", p1_y, p1_x, p2_x);
    }

    pwm01_1 = intABS(pwm01 - 127);
    pwm02_1 = intABS(pwm02 - 127);
    pwm03_1 = intABS(pwm03 - 127);
    pwm04_1 = intABS(pwm04 - 127);*/
}
}

The ctbl just adds a curve to the control, and switching to straight-out joystick driving (the first set of commented strafe = and rotation =) gives us pretty much the same results.

The wMax and intABS functions are-

int intMax(int x, int y)
{
    int max = x;
    if(y > max)
    {
           max = y;
    }
   return max;
}

int intABS(int i)
{
    if (i < 0)
        return -i;
    else
        return i;
}
int joysticklimit(int inp)
{
    if(inp < 127)
        {
            inp += 1;
            return inp;
        }
    else if (inp > 127)
        {
            inp -= 1;
            return inp;
        }
    else
        {
            return inp;
        }

Sorry if any of that was confusing, ask if you need clarification.
Thanks!

crap2.bmp (91.3 KB)


crap2.bmp (91.3 KB)

Your link for your COM window is for gmail?

Anyhow, your problem is almost certainly a typecast problem. I haven’t run through your code with a fine tooth comb, but these issues almost always trace back to typecast. Is your robot driving ok? In which case the issue is with printf.

Sorry about the link, I fixed it, the pic is now attached.

The robot is definitely not running okay, as two of the wheel are currently not doing anything (forgot which two, probably the left two), and the other two aren’t responding properly to joystick input.

That screenshot was actually from yesterday. Today we also had it print wMax and the joystick values, and both were insanely high (around 13k, if I remember correctly). After commenting off the entire mechanum code, and printing the joystick values outside the mechanum function, it gave us the correct values.

The other poster is right about there being casting issues. The sizes of doubles, ints, and chars are quite different, which can cause major problems with ranges.

A good starting point with this kind of code is to cast anything that is not of the same type as the lvalue (variable being assigned). This rule should also include any raw values such as the use of hard-coded in place numbers and #define constant numbers.

As far as the printf statement output, that does not represent the actual value in the least. The double type typically requires ‘%lf’ instead of ‘%d’ in a printf statement, but even then the RC cannot print floating point values, so you need to cast that value to a long and use ‘%ld’ to get a truncated value. You can always multiply the number by some power of 10 to see that number of decimal places.

That should be a good start.

Try changing

    prepwm01 = wFL + 127;
    prepwm02 = 127 - wFR;
    prepwm03 = wRL + 127;
    prepwm04 = 127 - wRR; 

to

    prepwm01 = (int)wFL + 127;
    prepwm02 = 127 - (int)wFR;
    prepwm03 = (int)wRL + 127;
    prepwm04 = 127 - (int)wRR; 

and

    pwm01 = prepwm01;
    pwm02 = prepwm02;
    pwm03 = prepwm03;
    pwm04 = prepwm04;

to

    pwm01 = (char)prepwm01;
    pwm02 = (char)prepwm02;
    pwm03 = (char)prepwm03;
    pwm04 = (char)prepwm04;

Also, I don’t see any reason all of the doubles at the top couldn’t be ints.
It doesn’t look like any of the possible values would be outside the range of an int and using floating points with the controller is never a good idea.
Unless you know what you’re doing, using floats and doubles usually lead to messed up numbers like what you’re getting.

Hope that helps.

We got rid of some things that were being used, switched to not using the table, and and made all the variables ints.

Updated code-

void Mechanum(void)
{
    signed int prepwm01, prepwm02, prepwm03, prepwm04, wFL, wFR, wRL, wRR, velocity, rotation, strafe, wMax;
    static char pwm01_1, pwm02_1, pwm03_1, pwm04_1; //will be used eventually

    velocity = (p1_y - 127);
    rotation = (p1_x - 127);
    strafe = (p2_x - 127);

printf("Velocity: %d  Rotation: %d  Strafe: %d \r 
", velocity, rotation, strafe);
   
    wFL = velocity - rotation - strafe;
    wFR = velocity + rotation + strafe;
    wRL = velocity - rotation + strafe;
    wRR = velocity + rotation - strafe;

printf("Wheels before wMax- FL: %d FR: %d RL: %d RR: %d \r 
", wFL, wFR, wRL, wRR);

   wMax = intMax(127, intABS(wFL));
   wMax = intMax(wMax, intABS(wFR));
   wMax = intMax(wMax, intABS(wRL));
   wMax = intMax(wMax, intABS(wRR));


    wFL = (wFL / wMax);
    wFR = (wFR * 127 / wMax);
    wRL = (wRL / wMax);
    wRR = (wRR * 127 / wMax);
  if (-127 > wFL || wFL > 127 || -127 > wFR || wFR > 127 || -127 > wRL || wRL > 127 || -127 > wRR || wRR > 127)
    {     
        printf("Received an unexpected number FL: %d FR: %d RL: %d RR: %d /n", wFL, wFR, wRL, wRR);
    }
else
    {

    prepwm01 = wFL + 127;
    prepwm02 = 127 - wFR;
    prepwm03 = wRL + 127;
    prepwm04 = 127 - wRR;   


    pwm01 = prepwm01;
    pwm02 = prepwm02;
    pwm03 = prepwm03;
    pwm04 = prepwm04;

printf("PWMS- pwm01: %d , pwm02: %d , pwm03: %d , pwm04: %d \r 
", pwm01, pwm02, pwm03, pwm04);
}
}

None of the other functions have changed.

We are currently receiving not quite so crappy numbers, but still aren’t getting the desired results (COM window attached).

We’ve found the problem to lie in-

    velocity = (p1_y - 127);
    rotation = (p1_x - 127);
    strafe = (p2_x - 127);

We’ve put some printf statements before and after these 3 lines, but the p1 and p2 variables are correct. For some reason the code is adding 129 to p1_x and p2_y and storing that into rotation and strafe instead of subtracting 127.

We can’t figure out where this is coming from. Any ideas?

Sorry we couldn’t try the last poster’s suggestion today- our lab lost its internet connection, and we forgot what it was. We’ll try that tomorrow.

craptacular.bmp (98.8 KB)


craptacular.bmp (98.8 KB)

p1_x, p1_y, and p2_x are of type unsigned char. If they are less than 127, your subtraction will wrap around (since negatives aren’t allowed) - i’m guessing your input is 126 (126 - 127 = -1, which is 255)

To fix it, you just need to typecast the inputs to ints:

    velocity = (((int)p1_y) - 127);
    rotation = (((int)p1_x) - 127);
    strafe = (((int)p2_x) - 127);

Thanks, that last suggestion fixed it!

Every thing is runnin smoothly now.