How to map joystick movement to motor speeds - Page 1
Forum section: electronics / general

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: March 04, 2024, 11:55:44 am
content: HiI 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 imageSo 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 motorsI have done this, But it's not working correctly for mesuppose joystick returns a Radis and an angle, I have convert them to x and y by this sin formulasx = radius*cos(angle);y = radius*sin(angle);leftSPeed = x + y;rightSpeed =x -y;//map motors speeds to actual PWM valuesLpwm = abs(leftSPeed );Rpwm = abs(rightSpeed);if(leftSPeed >0)Ldirection=0;elseLdirection = 1;if(rightSpeed >0)Rdirection=0;esleRdirection=1;But the robot does not move as expected, what's your

author: rxraine
author_rank: Newbie
timestamp: March 04, 2024, 12:41:34 pm
content: Sounds like the kind of thing people often want to do with RC tanks or boats that have two propellers but no rudder. Thislinkmight give you some ideas. Another option could be to throw hardware at the problem using something likethis. Googling combinations of "rc", "tank", "joystick", "mixer", "arduino", etc. will give you more inspiration.

author: ejeffrey
author_rank: Super Contributor
timestamp: March 04, 2024, 02:36:20 pm
content: 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: March 04, 2024, 04:30:54 pm
content: Let's say the "stick" deviation from its center point is (x,y), -1 ≤x≤ +1, -1 ≤y≤ +1.We wantyto correspond to the forward (>0) or backward (<0) velocity, relative to the maximum possible.Similarly, we wantxto correspond to the rotation (or direction change), relative to the maximum possible.Let's say we useLandRfor 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 havex= (L-R) / 2y= (L+R) / 2which solved forLandRisL=y+xR=y-xThis 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:xcontrols speed, andyturning. 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 inx,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 calculatec= abs(x) + abs(y)and ifc> 1, you dox=x/ cy=y/ cotherwise you keepxandyas they are received from the analog stick.

author: Nominal Animal
author_rank: Super Contributor
timestamp: March 04, 2024, 08:19:17 pm
content: 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 havexandysuch that -1 ≤x≤ +1, -1 ≤y≤ +1.Then,rr=x*x+y*y;if (rr> 1.0) {c= 1.0 / (abs(x) + abs(y));} elseif (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.Atx=0,y=1 (angle=90°,radius=1), both motors are turning forward at the maximum speed.Atx=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.Atx=0.5,y=0.5 (angle=45°,radius=0.7071), left motor is turning forward at 0.7071, and right motor is at standstill.Atx=0.6,y=0.6 (angle=45°,radius=0.8485), left motor is turning forward at 0.8485, and right motor is at standstill.Atx=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.Atx=1,y=0 (angle=0,radius=1), left motor is turning fully forward, right motor fully backwards.Atx=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 aty>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 velocityyand turning ratexdepend on the motor rotation ratesLandR.By the current definition, forward progress is theiraverage, which means that if one motor is standstill and other turns at full rate, the forward progressyis 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 forLandR, we getif (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.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: March 05, 2024, 09:57:54 am
content: Thanks guys for the feedback specially Nominal Animal for detailed feedback,QuoteI will try to Nominal Animal suggested function, and give updates on the results

author: Nominal Animal
author_rank: Super Contributor
timestamp: March 06, 2024, 08:00:42 pm
content: 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: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 thex,ycoordinates 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 betweenx,yandL,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.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 06, 2024, 09:19:33 pm
content: I personally hate touchscreen interfaces as a replacement for joysticks. Good luck.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: March 09, 2024, 11:54:16 am
content: 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