Author Topic: How to map joystick movement to motor speeds  (Read 995 times)

0 Members and 1 Guest are viewing this topic.

Offline ali_asadzadehTopic starter

  • Super Contributor
  • ***
  • Posts: 1906
  • Country: ca
How to map joystick movement to motor speeds
« on: March 04, 2024, 11:55:44 am »
Hi
I have designed a robot that I'm developing an android app to control it, it has two motors, left and right, the joystick is a simple circle inside a bigger circle in the android app, like this image

photo-2024-03-04-15-04-27" border="0


So the joystick represents an analog joystic, I want to map this joystic movement to motor PWM and direction, so user can feel it's moving the motors to the correct direction.

the robot and it's left and right motors
photo-2024-03-04-15-01-35" border="0

I have done this, But it's not working correctly for me

suppose joystick returns a Radis and an angle, I have convert them to x and y by this sin formulas

x = radius*cos(angle);
y = radius*sin(angle);


leftSPeed = x + y;
rightSpeed =x -y;

//map motors  speeds to actual PWM values
Lpwm = abs(leftSPeed );
Rpwm = abs(rightSpeed);

if(leftSPeed >0)
 Ldirection=0;
else
 Ldirection = 1;

if(rightSpeed >0)
 Rdirection=0;
esle
 Rdirection=1;




But the robot does not move as expected, what's your
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline rxraine

  • Newbie
  • Posts: 3
  • Country: de
Re: How to map joystick movement to motor speeds
« Reply #1 on: March 04, 2024, 12:41:34 pm »
Sounds like the kind of thing people often want to do with RC tanks or boats that have two propellers but no rudder. This link might give you some ideas. Another option could be to throw hardware at the problem using something like this. Googling combinations of "rc", "tank", "joystick", "mixer", "arduino", etc. will give you more inspiration.  :)
 
The following users thanked this post: ali_asadzadeh

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3719
  • Country: us
Re: How to map joystick movement to motor speeds
« Reply #2 on: March 04, 2024, 02:36:20 pm »
You probably have the turning too sharp.  Consider what happens when the stick is at 45 degrees.  One wheel will  be stopped and the vehicle will turn in sharp circles around that wheel. That means about half the joystick range is dedicated to varying shades of "stationary" which is likely too much.   The overall steering sharpness of an algorithm like this also depends on the separation between the left and right wheels.  The closer they are together the smaller velocity difference is needed to trace out a given curve.

You also didn't say what the actual problem was, only that it doesn't move as expected.  To get real help you should probably explain both what you expected and what you observe.

 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How to map joystick movement to motor speeds
« Reply #3 on: March 04, 2024, 04:30:54 pm »
Let's say the "stick" deviation from its center point is (x,y), -1 ≤ x ≤ +1, -1 ≤ y ≤ +1.
We want y to correspond to the forward (>0) or backward (<0) velocity, relative to the maximum possible.
Similarly, we want x to correspond to the rotation (or direction change), relative to the maximum possible.
Let's say we use L and R for the relative angular velocities of the two motors, +1 being maximum speed forward, and -1 being maximum speed backwards.

In practice, the forward speed is the average of the two motors, and rotation is the difference of the two motors.  Scaled to the correct range, we have
    x = (L - R) / 2
    y = (L + R) / 2
which solved for L and R is
    L = y + x
    R = y - x

This means that at (x,y) = (0,+1), both motors are going full speed forward; at (1,0), left motor is going full speed forward and right motor full speed backwards, and so on.  At (0.5, 0.5), left motor is going half speed forward, and right motor is standstill.

Currently, your axes are swapped: x controls speed, and y turning.  Small logical error, big difference in the result!

The final issue is to ensure -1 ≤ L ≤ +1 and -1 ≤ R ≤ +1, by limiting the steering region in x,y.  It turns out it is a diamond, i.e. a square standing on its corner, because within one, |x| + |y| ≤ 1.

The simplest way to limit this within your steering disc or square, is to scale the values whenever they exceed the limits.  That is, you calculate
    c = abs(x) + abs(y)
and if c > 1, you do
    x = x / c
    y = y / c
otherwise you keep x and y as they are received from the analog stick.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How to map joystick movement to motor speeds
« Reply #4 on: March 04, 2024, 08:19:17 pm »
If you wanted to use the entire steering disc, you can "puff up" the steering diamond to a circular disc,  with a little bit of additional math.

Let's assume you have x and y such that -1 ≤ x ≤ +1, -1 ≤ y ≤ +1.

Then,
    rr = x*x + y*y;
    if (rr > 1.0) {
        c = 1.0 / (abs(x) + abs(y));
    } else
    if (rr > 0) {
        c = rr / (abs(x) + abs(y));
    } else {
        c = 0;
    }
    x *= c;
    y *= c;
    L = y + x;
    R = y - x;

This maps the steering disc to the diamond (square standing on a corner), with any points outside the disc mapped to the closest point on the edge of the disc.
At x=0, y=1 (angle=90°, radius=1), both motors are turning forward at the maximum speed.
At x=0.25, y=0.75 (angle≃71.6°, radius≃0.7906), left motor is turning forward at 0.7906, and right motor at 0.3953.
At x=0.5, y=0.5 (angle=45°, radius=0.7071), left motor is turning forward at 0.7071, and right motor is at standstill.
At x=0.6, y=0.6 (angle=45°, radius=0.8485), left motor is turning forward at 0.8485, and right motor is at standstill.
At x=0.75, y=0.25 (angle≃18.4°, radius≃0.7906), left motor is turning forward at 0.7906, and right motor backward at 0.3953.
At x=1, y=0 (angle=0, radius=1), left motor is turning fully forward, right motor fully backwards.
At x=0.1, y=0.2 (angle≃63.4°, radius≃0.2236), left motor is turning forward at 0.2236, and right motor at 0.0745.



One could argue that at y>0 the vehicle should make some forward progress, i.e. that both motors turn forward then.
If so, all one needs to do, is to find out how the proper forward velocity y and turning rate x depend on the motor rotation rates L and R.
By the current definition, forward progress is their average, which means that if one motor is standstill and other turns at full rate, the forward progress y is half of maximum.

For example, we could decide that the forward speed is determined by the slower of the two motors, i.e.
    if (abs(L) < abs(R)) {
        y = L;
    } else {
        y = R;
    }
and rotation rate by the difference in the two motors,
    x = L - R;

Solving this for L and R, we get
    if (y >= 0) {
        if (x >= 0) {
            L = y + x;
            R = y;
        } else {
            L = y;
            R = y - x;
        }
    } else {
        if (x >= 0) {
            L = y - x;
            R = y;
        } else {
            L = y;
            R = y + x;
        }
    }

The steering region for this is the same diamond, or square standing on its corner, and the method to puff it up to a circular disc described earlier in this message should work for this, too.
« Last Edit: March 04, 2024, 08:26:44 pm by Nominal Animal »
 

Offline ali_asadzadehTopic starter

  • Super Contributor
  • ***
  • Posts: 1906
  • Country: ca
Re: How to map joystick movement to motor speeds
« Reply #5 on: March 05, 2024, 09:57:54 am »
Thanks guys for the feedback specially Nominal Animal for detailed feedback,

Quote


For example, we could decide that the forward speed is determined by the slower of the two motors, i.e.
    if (abs(L) < abs(R)) {
        y = L;
    } else {
        y = R;
    }
and rotation rate by the difference in the two motors,
    x = L - R;

Solving this for L and R, we get
    if (y >= 0) {
        if (x >= 0) {
            L = y + x;
            R = y;
        } else {
            L = y;
            R = y - x;
        }
    } else {
        if (x >= 0) {
            L = y - x;
            R = y;
        } else {
            L = y;
            R = y + x;
        }
    }


I will try to Nominal Animal suggested function, and give updates on the results


ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How to map joystick movement to motor speeds
« Reply #6 on: March 06, 2024, 08:00:42 pm »
If you have trouble defining what the relationship between the control stick position and motor speeds should be, start with a square with a grid of five points in each direction for each motor, and fill in the question marks (with motor speed -1.0 .. +1.0, +1 being full forward, 0 standstill, and -1 full backward):
Code: [Select]
            LEFT MOTOR                 RIGHT MOTOR
     -1.0 -0.5  0.0 +0.5 +1.0   -1.0 -0.5  0.0 +0.5 +1.0
+1.0        ?    ?    ?                ?    ?    ?
+0.5   ?    ?    ?    ?    ?      ?    ?    ?    ?    ?
 0.0   ?    ?    0    ?    ?      ?    ?    0    ?    ?
-0.5   ?    ?    ?    ?    ?      ?    ?    ?    ?    ?
-1.0        ?    ?    ?                ?    ?    ?
If you're limited to a circular disc, use the corresponding positions within the disc, and just note the x,y coordinates for each separately.  Approximative is fine; (-0.5,+0.866) or one quarter diameter in from left, at the upper curve of the disc, is close enough to (-0.5,+1.0) for this.

With this kind of a table, it is easy to derive the relationship between x,y and L,R.  I think the biggest hurdle is finding an intuitive/responsive pattern of motor rates corresponding to the values at question marks above.  What one assumes beforehand may not work best in practice.
I personally might even make a tiny simulator (static HTML+JavaScript, no network connection needed) to explore this.
« Last Edit: March 06, 2024, 08:02:55 pm by Nominal Animal »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14481
  • Country: fr
Re: How to map joystick movement to motor speeds
« Reply #7 on: March 06, 2024, 09:19:33 pm »
I personally hate touchscreen interfaces as a replacement for joysticks. Good luck.
 

Offline ali_asadzadehTopic starter

  • Super Contributor
  • ***
  • Posts: 1906
  • Country: ca
Re: How to map joystick movement to motor speeds
« Reply #8 on: March 09, 2024, 11:54:16 am »
Thanks for the feedback, For now I have replaced the single Joystick to two X and Y sliders, It's now working correctly, and I think I would stick to it for now
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf