Joystick math assistance needed

Greets to all!
I am replacing a Logitech 3D Pro joystick (which was working fine with Game Control Plus) with a custom stick (actually an Navy joystick of amazing build-quality!). Prob is with GCP the stick returned values from -1 to 1 which I could convert as the Old code below.

For the Navy joystick, I’ve had to resort to reading the stick with an Arduino Micro and sending the data to Processing via Serial. The data is coming over just fine - but it is INTEGER (from the analog input) and currently is in a range of about 170 to 1000 - centering roughly at 300.

The data is being used in a radar display simulation (very simplistic) and I have 3 ‘bogies’ coming in at the ship and need their coordinates so I can display range and bearing. The joystick is used to mark a particular bogey as THE target.

So looking for ideas on how to do the math with integer data…

Old code:

  X = stick.getSlider("X").getValue();
  Y = stick.getSlider("Y").getValue();

  ajx = map(X, -1, 1, 0, width);
  ajy = map(Y, -1, 1, 0, height);

  JOYX = ajx;
  JOYY = ajy;
  // av = v >= 0 ? v * v : -v * v;    // From Quark on P Forum
  cartX = map(stick.getSlider("X").getValue(), -1, 1, -90, 90);
  cartY = map(stick.getSlider("Y").getValue(), -1, 1, 90, -90);
1 Like

That it is integer doesn’t matter.

Your old conversion was between -1-1 and 0-width.
Your new conversion is between 170-1000 and 0-width.

Old code:

ajx = map(X, -1, 1, 0, width);

New code:

ajx = map(X, 170, 1000, 0, width);

I’m not sure I understand the comment about “centering roughly at 300.” Do you mean that 170-300 is left and 300-1000 is right? That is very strange.

The pot on this joystick can turn 360 degrees so I’ve added a 1k resistor in series with one leg so it never goes to ground. Currently the input range from the Arduino analog pin runs from 170 to about 1000. I have centered the joystick while watching the output values change and it appears to be in the neighborhood of 250-300 when the stick is centered yet the ‘math center’ (max-min) comes out to be 415.

What I need to do is get values that i can get coming into Processing that will allow the creation of Cartesian coordinates. This is a radar simulation and the bow of the ship is 0 degrees (at the center of the screen, joystick centered), abeam right is 90, stern is 180, abeam left is 270, etc.

The joystick is moved to indicate the range and bearing of a bogey coming in to the ship. The x-y values of the joystick are converted to be "computer’ coordinates (x(0,0) upper left corner) for drawing the bogies and joystick cursors. I can then convert the xy of the cursor position to a CartCords and report distance and bearing. This was working perfectly with the Logitech Extreme 3D Pro joystick going thru GCP. It returned values from -1 to 1 and using the Processing map() function I got the CartCords.

Now with the current values coming in I can’t correct values from the map() function - even using the constrain() function after map.

I’m beginning to wonder if the pot on the joystick is non-linear. I’ve looked up it’s part number (circa 1980 or before) a and have found nothing.

Any ideas on this would be a great help!

i have a very un-electrical idea:
make the arduino_send
170 … 250 : -1
250 … 300 : 0
300 … 1023: 1
that turns it into a mouseWheel
and you do in processing
joystick += arduino_send * tune;

Sounds interesting - the original values were all pos/neg floating point fractional values from 0 to 1 - would this scheme provide all the fine points in between? Not sure if I understand! :slight_smile:

That is the question in a nutshell.

map and lerp are used for linear interpellation. You also could do piecewise linear in two part – one map for left of center, one map for right of center. But it sounds like you may actually want to map input to non-linear (curving) output.

One way to do that would be to adjust control factors to fit the non-linearity of your input

You will do that separately for x and y. If the non-linearity is the same for each, then the solutions for b and c are the same for each.

ajx = curvePoint(0, b1, c1, width, X);
ajy = curvePoint(0, b2, c2, height, Y);

The question is, what are b and c? Those will determine how “curved” your output is. In particular, it seems like you want a curve that 170=0, 300=width/2.0, and 1000=width

You could solve that mathematically or just make a little animated curve sketch and find the right point interactively by moving the control point around with the mouse.

This is a simple interactive demo of using curvePoint to create a simple 1D mapping that is non-linear.

/**
 * Non-linear mapping with curvePoint
 * 2019-03 Processing 3.4
 * This demonstrates a one-dimensional mapping, but can be made 2D
 * using curvePoint again to compute a y-axis with two y controls. 
 */
float x, y, steps;

void setup(){
  size(400,100);
  ellipseMode(CENTER);
  rectMode(CENTER);
}

void draw() {
  background(192);
  fill(255);
  float b = map(mouseX, 0, width, 0, width);
  float c = map(mouseY, 0, height, 0, width);
  line(0,height/2.0,width,height/2.0);

  // mark distribution of points
  int steps = 20;
  for (int i = 0; i <= steps; i++) {
    float t = i / float(steps);
    y = height/2.0;
    x = curvePoint(b, 0, width, c, t);
    ellipse(x, y, 6, 6);

    // display first control setting
    line(0, height/4.0, b, height/4.0);
    rect(b, height/4.0, 3, 30);

    // dislpay second control setting
    line(c, 3*height/4.0, width, 3*height/4.0);
    rect(c, 3*height/4.0, 3, 30);
  }
  if(frameCount%60==0){
    saveFrame("NonLinearMapping--screenshot.png");
  }
}

NonLinearMapping--screenshot

Jeremy - thanks for the code sample. I will build a sketch with it and see whats up.

=A.

Jeremy - have loaded your code to the Arduino and it DOES appear the pots on the Navy stick (3" dia wirewound!) are log. I then bread-boarded a Parallax joystick board and the response in Processing is as expected. With little stick center, my map() function now gets the cursors to center.

I would think the math to ‘linearize’ the log pots would be a bit hairy - so I’ll have to piggy-back some linear pots on the movement shaft. If I could have only gotten the Logitech Extreme to NOT go to center I would have been golden. I could remove the spring, but then it would way too floppy. But it was a sort of mechanical nightmare to get in and add some sort of drag to the plastic joints - i gave up and went on to use the Navy stick. Makes the display a tad more ‘authentic’ - but this pot prob adds yet more ‘joy’ to this…thing! :frowning:

More! Have been working with your code and getting to better understand it. I think my first run wasn’t done correctly. Now I see it drawing a straight line across the screen when using the non-linear pots. So - could use a little clarification:

I have a single value for X and a single value for Y - how do I mod your script to get the vertical element? Also


@jeremydouglass -

(From 'Joystick math assistance needed post)

More! Have been working with your code and getting to better understand it. I think my first run wasn’t done correctly. Now I see it drawing a straight line across the screen when using the non-linear pots. So - could use a little clarification:

I have a single value for X and a single value for Y - how do I mod your script to get the vertical element? Also it is wrapping around the screen - what vars controls the length of the line?