Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Joystick filtering gone horribly wrong...help! (http://www.chiefdelphi.com/forums/showthread.php?t=56211)

JBotAlan 27-03-2007 17:22

Joystick filtering gone horribly wrong...help!
 
Hey all,

I was asked to make the robot have a curved response in the drive motors, i.e. pushing the joysticks halfway gets you about quarter speed, but pushing them full gets you full speed. I was advised that this will make the drivers' jobs easier. However, it seems to be making my job more complicated...:p

I have a basic lookup table solution in place right now...but it doesn't work. Ideally, I want to be able to input a number of points on the curve (right now, I have 7) and have the code extrapolate the points in between. I would be able to tweak this curve, adjust the constants in code, recompile, and blast the code down again to have filtered joysticks.

Now, at this point in time, I am getting strange results. The code I have is trying to set outputs to values like 360-something or greater, and I can't figure out why (I know it's out of range. I know PWMs only go up to 254...). I am seeing this code get more and more complex, and I need some help implementing KISS in this situation.

Here's the code I've got right now:
Code:

unsigned char DRV_GetFilteredValue(unsigned char joystick)
{
        static const unsigned char lookup[] = {127,135,140,145,165,200,254};
        int temp_joystick = (((int)joystick-127)/21.1);
        printf("temp_joystick = %d\r\n",(int)temp_joystick);
        printf("joystick is %d\r\n", (int)joystick);
        if (temp_joystick >= 7) { temp_joystick = 6; }
        if ((joystick < 130) && (joystick > 124)) {
                return 127;
        } else if (temp_joystick < 0) {
                printf("lookup[temp_joystick] = %d, lookup[temp_joystick-1] = %d, output is %d\r\n", (int)lookup[temp_joystick], (int)lookup[temp_joystick-1], (int)((joystick - lookup[temp_joystick-1])*(lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1]);
                return ((joystick - lookup[temp_joystick-1])*(lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1];
        } else {
                temp_joystick = -temp_joystick;
                printf("lookup[temp_joystick] = %d, lookup[temp_joystick-1] = %d, output is %d\r\n", (int)lookup[temp_joystick], (int)lookup[temp_joystick-1], (int)254-((joystick - lookup[temp_joystick-1]) * (lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1]);
                return 254-((joystick - lookup[temp_joystick-1]) * (lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1];
        }
}

(If you can weed through that, you get a cookie)

You don't even have to look at that code. I just need something that I can put in place to filter the joysticks.

Thanks in advance for any help you can provide.

And I'm willing to throw out the code I've got; I just need *something* to work.

JBot

Bongle 27-03-2007 17:39

Re: Joystick filtering gone horribly wrong...help!
 
Code:

} else if (temp_joystick < 0) {
                printf("lookup[temp_joystick] = %d, lookup[temp_joystick-1] = %d, output is %d\r\n", (int)lookup[temp_joystick], (int)lookup[temp_joystick-1], (int)((joystick - lookup[temp_joystick-1])*(lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1]);
                return ((joystick - lookup[temp_joystick-1])*(lookup[temp_joystick] - lookup[temp_joystick-1]) / 21) + lookup[temp_joystick-1];

On this here, you access negative members of an array. The only time you will ever enter this code is when temp_joystick < 0, and then you use it to address your lookuptable.

That's one of a few issues. I'm coding up an integer version right now.

You need to have a power of two number of line points. They are assumed to be evenly spaced between 0 and 255.
Code:

#define BITS_FOR_LOOKUP 3 // we're using the most significant 3 bits of the joystick value

#include <iostream>
using namespace std;

unsigned char lookup[8] = {0,31,63,95,  126,158,190,221};

unsigned char joyFilter(unsigned char joyValue)
{
  unsigned char n = joyValue>>(8-BITS_FOR_LOOKUP);

  // n is between 0 and 7 for sure
  unsigned int last;
  unsigned  int next;
  unsigned  int howFarAlong = joyValue - (n<<(8-BITS_FOR_LOOKUP)); // finds out how along joyValue is between n and n+1
  unsigned  int maxFarAlong = (1<<(8-BITS_FOR_LOOKUP));
  unsigned  int invHowFarAlong = (maxFarAlong - howFarAlong);


  if(n+1 >= 8)
  {
      last = lookup[7];
      next = 256;
  }
  else
  {
      last = lookup[n];
      next = lookup[n+1];
  }

  return (invHowFarAlong*last)/maxFarAlong + (howFarAlong*next)/maxFarAlong ;


}


dpick1055 27-03-2007 18:25

Re: Joystick filtering gone horribly wrong...help!
 
Your actually making it more complicated then you need to with a lookup table. Using a squaring function and some if statements you can get the curved response you want. Here's the code I used on our robot this year.
Code:

        int linput;
        int rinput;
        int loutput;
        int routput;

                if (p1_y < 127)
                        {
                                linput = 127 - p1_y;
                                loutput = 127 - ((linput * linput) / 127);
                        }
                if (p1_y >= 127)
                        {
                                linput = p1_y - 127;
                                loutput = ((linput * linput) / 127) + 127;
                        }
               
                if (p2_y < 127)
                        {
                                rinput = 127 - p2_y;
                                routput = 127 - ((rinput * rinput) / 127);
                        }
                if (p2_y >= 127)
                        {
                                rinput = p2_y - 127;
                                routput = ((rinput * rinput) / 127) + 127;
                        }

                                        pwm15 = 254 - routput;
                                        pwm13 = loutput;


JBotAlan 27-03-2007 18:48

Re: Joystick filtering gone horribly wrong...help!
 
Quote:

Originally Posted by dpick1055 (Post 606146)
Your actually making it more complicated then you need to with a lookup table.

I was hoping someone else would find a simpler way of doing this. The lookup table was starting to get out of hand.

Thanks for your help; I will try this.

JBot

BTW, dpick, nice sig. You should get yourself a disable switch, though; you can react fast enough to kill the 'bot if bad things happen...;-)

dpick1055 27-03-2007 18:54

Re: Joystick filtering gone horribly wrong...help!
 
Thanks for the advice : ) We actually have one I just can't find it in the giant box of electrical stuff.

lukevanoort 27-03-2007 19:32

Re: Joystick filtering gone horribly wrong...help!
 
http://www.chiefdelphi.com/forums/showpost.php?p=547561&postcount=9 And, as an example of the 255 value tables I talked about, here is the 255 value table currently on our robot.
Code:

rom const unsigned char expotable[255] =
{
0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 24, 26, 28, 30, 32, 34,
36, 38, 40, 42, 44, 45, 47, 49, 50, 52, 53, 55, 56, 58, 59,
61, 62, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 76, 77, 78,
79, 80, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, 89, 90, 91,
92, 92, 93, 94, 95, 95, 96, 97, 97, 98, 98, 99, 100, 100,
101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106,
107, 107, 107, 108, 108, 109, 109, 109, 110, 110, 110, 111,
111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 114,
115, 115, 115, 115, 116, 116, 116, 116, 117, 117, 117, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 137, 137,
137, 138, 138, 138, 138, 139, 139, 139, 139, 140, 140, 140,
140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144,
144, 145, 145, 145, 146, 146, 147, 147, 147, 148, 148, 149,
149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155,
156, 156, 157, 157, 158, 159, 159, 160, 161, 162, 162, 163,
164, 165, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173,
174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187,
188, 189, 190, 192, 193, 195, 196, 198, 199, 201, 202, 204,
205, 207, 209, 210, 212, 214, 216, 218, 220, 222, 224, 226,
228, 230, 232, 234, 237, 239, 241, 244, 246, 249, 251, 254
};


bear24rw 27-03-2007 21:38

Re: Joystick filtering gone horribly wrong...help!
 
This is what Team 11 Came up with to put a curve on the joysticks..

Code:

int ramp_joystick(int value)
{
        if (value < 127 )
                return sqrt(127)*sqrt(value);

        if (value > 127 )
                return -sqrt(127)*sqrt(-value + 255) + 255;

        if (value == 127 )
                return 127;
}


whytheheckme 27-03-2007 21:58

Re: Joystick filtering gone horribly wrong...help!
 
Quote:

Originally Posted by lukevanoort (Post 606194)
http://www.chiefdelphi.com/forums/showpost.php?p=547561&postcount=9 And, as an example of the 255 value tables I talked about, here is the 255 value table currently on our robot.
Code:

rom const unsigned char expotable[255] =
{
0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 24, 26, 28, 30, 32, 34,
36, 38, 40, 42, 44, 45, 47, 49, 50, 52, 53, 55, 56, 58, 59,
61, 62, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 76, 77, 78,
79, 80, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, 89, 90, 91,
92, 92, 93, 94, 95, 95, 96, 97, 97, 98, 98, 99, 100, 100,
101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106,
107, 107, 107, 108, 108, 109, 109, 109, 110, 110, 110, 111,
111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 114,
115, 115, 115, 115, 116, 116, 116, 116, 117, 117, 117, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 137, 137,
137, 138, 138, 138, 138, 139, 139, 139, 139, 140, 140, 140,
140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144,
144, 145, 145, 145, 146, 146, 147, 147, 147, 148, 148, 149,
149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155,
156, 156, 157, 157, 158, 159, 159, 160, 161, 162, 162, 163,
164, 165, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173,
174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187,
188, 189, 190, 192, 193, 195, 196, 198, 199, 201, 202, 204,
205, 207, 209, 210, 212, 214, 216, 218, 220, 222, 224, 226,
228, 230, 232, 234, 237, 239, 241, 244, 246, 249, 251, 254
};


Our code looks very similar. We actually have 3 tables available to be loaded into ROM, depending on what kind of dampening we need (2nd order, 3rd order, 4th order)

Cool stuff.
Jacob

Tom Line 28-03-2007 08:52

Re: Joystick filtering gone horribly wrong...help!
 
We use excel. We use 3 points 0 127 to define one curve, and 3 points above 127 to define the 127 - 255 curve. Then you graph those points and have excel do a trendline and give you the equation.

Now you can just change your 3 datapoint values around and the trendline graph will automatically give you the new equation. You can either type the equation into excel and have it give you the values for a lookupt table (it becomes a simple copy/paste) or you can multiply the equation by 10, 100, or 1000 to remove the floats and simply use the equations with integer math in your program.

Once you have the excel spreadsheet set up, it takes about 30 seconds to change the curves then update your program.


All times are GMT -5. The time now is 09:08.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi