Converting Two joystick values into a vector

Hey everyone,

Our code takes in a vector (direction and magnitude) in order to move. This was implemented in order to simplify PID. We have been using a wheel and a joystick for our driver setup, but we are looking to switch to two joysticks.

Now to my main question. Is there any way to take the values of the left and right joysticks and turn them into a vector? I have seen ways to go from a vector to left and right motor power, but not the other way around.

Thanks.

Ben

Yes, there’s a way – here’s a hint: atan2 and the Pythagorean theorem.

Here’s a java example

public double getTheta(double x, double y){
        return com.sun.squawk.util.MathUtils.atan2(y, x);
    }
    
    public double getR(double x, double y){
        return Math.sqrt((x*x)+(y*y));
    }

Thanks all for the help, but I believe the wording of my question was a bit weird. It looks as though the examples you are giving are for x and y values (arcade drive). I was wondering about getting the x values from both joysticks (tank drive) and finding the vector components from that.

I may just interpreting your responses incorrectly, so tell me if I’m wrong.

Thanks again.

Ben

Maybe this will help.

You can take any continuous inputs from your joystick(s) and label then X and Y. Then use the info you’ve been given.

You can also think of this as a conversion from rectangular (cartesian) coordinate system and polar coordinate system. But you still need to define the X and Y, and that is independent of the conversion.

Greg McKaskle

Alright, let me get this straight.

You have a setup with two joysticks that are used in a tank drive set up, and from these two, you’d like to find the angle/magnitude.

This is a little trickier, as you first need to find the amount of turn (x), then you need the amount of going forward (y) from the two axes used in tank drive.
The speed of your turn is just the difference in the speeds of two sides of the robot, and the forward speed is the average of the two sticks.

Here’s some more java examples.

NOTE:See my later post for corrections!

 public double getTheta(double x, double y){
        return com.sun.squawk.util.MathUtils.atan2(y, x);
    }
    
    public double getR(double x, double y){
        return Math.sqrt((x*x)+(y*y));
    }
    
    public double getX(){
        return stick1.getY()-stick2.getY();
    }
    
    public double getY(){
        return (stick1.getY()+stick2.getY())/2;
    }

//you can get your values like this
double theta = getTheta(getX(), getY());
       double r = getR(getX(), getY());

When stick1 = 1 and stick2 = -1, your code gives r = 2 and theta = 0.

*





It really depends on what you are looking for. The getTheta method I posted doesn’t really do what you want.

This might

 public static double getTheta(double x, double y){
        double z = Math.atan2(y,x);
        double degrees = z * (180.0 / Math.PI); // convert to degrees
        degrees = (degrees > 0.0 ? degrees : (360.0 + degrees)); // correct discontinuity
        System.out.println(degrees+"t");
        return degrees;
    }

The problem is that the joysticks don’t give a robot an x and y component, they give a forward rate and turning rate components, which are different. I’m not really sure what you want.

Your post was linked to mine, with no quoting context provided. But I assume the pronoun “you” above refers not to me, but the OP, right?

I agree with you that the OP’s problem statement is not entirely clear.

public static double getTheta(double x, double y){
double z = Math.atan2(y,x);
double degrees = z * (180.0 / Math.PI); // convert to degrees
degrees = (degrees > 0.0 ? degrees : (360.0 + degrees)); // correct discontinuity
System.out.println(degrees+“t”);
return degrees;
}

Your code above gives the angle in degrees measured counter-clockwise from the positive X axis.

You can get the same result, without the need for conditional logic, with this computation:

180/pi*atan2(-y,-x) + 180

If however you want the angle in degrees measured clockwise from the positive Y axis, this will do that:

180/pi*atan2(-x,-y) + 180…(see below)

// RLaB version 2.1.05 Copyright (C) 1992-97 Ian Searle


x=0;  y=1;  180/pi*atan2(-x,-y)+180
        0  

x=1;  y=1;  180/pi*atan2(-x,-y)+180
       45  

x=1;  y=0;  180/pi*atan2(-x,-y)+180
       90  

x=1;  y=-1; 180/pi*atan2(-x,-y)+180
      135  

x=0;  y=-1; 180/pi*atan2(-x,-y)+180
      180  

x=-1; y=-1; 180/pi*atan2(-x,-y)+180
      225  

x=-1; y=0;  180/pi*atan2(-x,-y)+180
      270  

x=-1; y=1;  180/pi*atan2(-x,-y)+180
      315  

x=-0; y=1;  180/pi*atan2(-x,-y)+180
      360 

So the old drive system was controlled by two inputs, a wheel for direction and one axis of a joystick for magnitude. The old code used this to derive set values for the motors in your drive system. I don’t think you said, but if you’re using PID, I’m guessing this may be something like a swerve drive? This might also explain why you want to use a single vector to control things? In case it isn’t clear, it is hard to answer without a pretty detailed description. For example, was there a way to command the robot to turn in place? Really, it is helpful to know the drive system configuration and the operator inputs in some detail, along with how you want the new controls to work.

Now, you want to control this same drive system with a two-joystick tank-style operator interface. So you want to use two y-inputs (or whatever) to derive a single vector? How do you expect the controls to work?

Rather than try to answer based on this much speculation, it would be good to have confirmation or the specific details. I hope I didn’t confuse things and that this makes sense…

*Ben, are you still following this thread? If so, if you would respond to the last three posts 8, 9, 10 we might be able to offer you more help.

Hey guys, thanks for all the help, but I managed to skip converting the joysticks to a vector. I just bypass the PID and set the left and right motors to the values of the joysticks.