Robot joystick steering behavior

I built a Budget Robotics (http://www.budgetrobotics.com/) Rigel robot (nice kit) that is being used as a software development platform for a
future project - a remote controlled lawnmower. I am using the joysticks on a Sony Playstation controller for the steering.
The problem is when the joystick is centered to the right, the robot will turn hard right going forward but if you pull slightly back on the joystick the robot abruptly reverses. Is this common behavior for electric wheelchairs, etc?
I was thinking of having to come back to center with the joystick before being allowed to change direction. Any thoughts?
TIA Randy Haas
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
What interface are you using between the Playstation controller and the servos? It sounds like you need to adjust the software on the interface to provide more of a ramping about center. That is, you want more of the control distance within the 50-100 microsecounds around center (1500 us). Modified servos do not have linear speed ramps.
(A wheelchair motor, with the appropriate PID motor driver, would, but they are also made to have slow accelleration. You don't want grampa doing wheelies, after all!)
-- Gordon Author: Constructing Robot Bases, Robot Builder's Sourcebook, Robot Builder's Bonanza
Randy Haas wrote:

Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
I am using a Basic Atom with a Atom Bot board.
Randy Haas

Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
Randy Haas wrote:

Then what I might suggest is to write a small "exercize" program without the joystick control. Have your program go through a repeated set of moves. In your program you might add a routine for slowing the motors (by choosing values nearest to 1500 us), and have it move back and forth in this state as well.
When the platform is behaving the way you think it should you can write or modify the joystick interface portion to match the joystick motions to what you know the motors are capable of doing.
-- Gordon Author: Constructing Robot Bases, Robot Builder's Sourcebook, Robot Builder's Bonanza
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, Jul 20, 2004 at 05:53:43AM -0700, Randy Haas wrote:

Great stuff!

I suspect the problem is your algorithm for setting the motor speeds based on joystick position. How do you do it?
My rover (http://www.bdmicro.com/rover/) has a remote interface and can also be controlled by the Playstation controller. Basically I map the joystick position into left and right motor speeds. I found the most intuitive way to do this was to use trig. If x is the left-to-right joystick reading, and y is the top-to-bottom joystick reading, I calculate the left and right motor speeds as follows:
speed = sqrt(x*x + y*y); theta = atan2(y, x); /* take care to handle when x == 0 */ left = speed*(sin(theta) + cos(theta)); right = speed*(sin(theta) - cos(theta));
Then, just set the speed of the left and right motors appropriately as calculated (with your own scaling as needed, of course), changing them as the joystick changes position.
I do first clean up the x and y positions a little, making sure that when the joystick is centered, x and y are both zero, like this:
x = raw_x - 128; y = 127 - raw_y;
raw_x and raw_y are the numbers read directly from the PS II controller. The above shifts the so that the joystick at lower left gives an x,y of (-127, -127_ and upper right gives (128, 128), with (0,0) in the center like normal cartesion axis orientation.

The above formula gives very intuitive control over my rover. Stick forward moves the robot forward. Stick left or right rotates the robot in the direction of the stick. Stick backward and the robot goes backwards. Smooth transitions for all stick movement.
Hope this helps.
-Brian -- Brian Dean http://www.bdmicro.com/
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

I took a similar approach. I have a +- 15 degree deadspot on full forward and full reverse joystick position so the steering wouldn't be so twitchy - most of the time the lawnmower will be moving directly forward. Near the full right (and full left) position, I start to reverse that drive while the opposite drive is full speed - robot turns in its own length. This would be useful at the end of the lawnmower's path to make it easy to return. But the problem was the discontinuities at the full left and full right positions - just a little farther (359 degree or 181 degrees) and you would spin hard in the opposite direction.
What I did was to set a flag so thet once you were moving in a forward direction, you couldn't reverse until the joystick was centered (within a fudge factor). I set it up to give progressive steering (like you have) from full forward down to full right or full left. There I would start to reverse that drive to spin the robot harder and be complete by 315 degrees(225 degrees). Still have the discontinuity at 270 degrees but you don't need to get close to that position.
To reverse, you move the joystick near center to stop motion and then pull back (270 degrees). Then the joystick would only allow reverse direction with similar behavior (but mirrored about the x axis) as above.
I'll play with it some more, but it feels natural and the lawnmower won't need reverse much since it can spin around in it's own length.
Randy Haas
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Thu, Jul 22, 2004 at 02:20:29AM -0700, Randy Haas wrote:

Not sure if it applies completely in your case, but here's a more complete listing of my code that handles the joystick values and translates the result into motor speed and direction:
x = ps2_rjoyx() - 128; /* right joystick x position */ y = 127 - ps2_rjoyy(); /* right joystick y position */
mag = sqrt(x*x + y*y); /* magnitude of the overall speed */ if (x == 0) { /* don't divide by zero, handle this case seperately */      /* the joystick is either tilted up or down, there's no x component */ if (y >= 0) theta = PI/2.0; else theta = -PI/2.0; } else {      /* joystick has both an x and y component */ theta = atan2(y, x); }
l = mag*(sin(theta) + cos(theta)); /* left motor speed and direction */ r = mag*(sin(theta) - cos(theta)); /* right motor speed and direction */
Note the check above for when x == 0, and the sign of y. Maybe you are missing something like that? Also note the use of atan2() from the Standard C math library which properly determines the quadrant of the result. From the 'man' page description:
SYNOPSIS #include <math.h>
double atan2(double y, double x);
DESCRIPTION The atan2() function computes the principal value of the arc tangent of y/x, using the signs of both arguments to determine the quadrant of the return value.
There are no discontinuities in the control using the above equations.

You shouldn't need to do that. Try my code above, or its equivalent in your favorite language. The above is "C".

Got a web site, any photos?
Good luck!
-Brian
--
Brian Dean
http://www.bdmicro.com/
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

Polytechforum.com is a website by engineers for engineers. It is not affiliated with any of manufacturers or vendors discussed here. All logos and trade names are the property of their respective owners.