PDA

View Full Version : joystick dampening math/ code

Owen
03-17-2007, 09:06 AM
Anyone know of any math for dampening the effect of a joystick? I am building a project that precicely and remotly controls a motion picture camera using a playstation 2 controller and a propellar chip. at the moment the playstation controller is too sensitive and needs some way of dampening the Playstation joystick input. basicly I would like to have have an adjustable control dampening similar to the dampening an electric wheel chair might have. anyone done somthing like this before?

Phil Pilgrim (PhiPi)
03-17-2007, 09:17 AM
You can smooth the response by using a first-order IIR (infinte impulse response) filter, which is just a fancy way of saying "moving average". The formula is:

Actual_position := (Actual_position * Smooth + Requested_position * (100 - Smooth)) / 100

Requested_position is the input from the joystick. Actual_position is the number you use instead. Smooth ranges from 0 to 100 and represents the amount of smoothing. If Smooth is zero, no smoothing takes place. if Smooth is 100, no movement takes place. You'll find a happy medium somehwere in between.

Don't overdo the smoothing, though, as the person controlling things will have a tendency to overshoot the target. In any event, it will take some practice to get used to.

-Phil

Post Edited (Phil Pilgrim (PhiPi)) : 3/17/2007 2:23:09 AM GMT

Owen
03-17-2007, 09:31 AM
this is great! just what i have been looking for all day, Thank you!

SSteve
03-17-2007, 10:29 AM
Phil Pilgrim (PhiPi) said...
Actual_position := (Actual_position * Smooth + Requested_position * (100 - Smooth)) / 100

Is the "Actual_position" on the right side of the equation the previous Actual_position?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows

My band's website (http://www.theuniversalsteve.com)
Our album on the iTunes Music Store (http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=84780626&id=84781354)

Phil Pilgrim (PhiPi)
03-17-2007, 12:33 PM
Steve,

Yes. And I should have noted that it needs to be initialized to the Requested_position at the beginning of the program.

-Phil

Owen
03-18-2007, 03:31 AM
I tried the infinte impulse response equation and it works great untill I want to change direction, any ideas how change in direction could be incorperated?

Owen

Phil Pilgrim (PhiPi)
03-18-2007, 05:35 AM
Owen,

By "change direction" are you implying that Requested_position can take on negative values? If that's the case, some major code changes will be necessary.

-Phil

Owen
03-18-2007, 06:12 AM
my code at the moment evaluates direction before using the smoothing code, so I think Requested_Position could stay positive.

Owen

Phil Pilgrim (PhiPi)
03-18-2007, 06:22 AM
Could you post your code, please? For the smoothiing to work, the code has to be set up so that the variables are continuous from one side of zero velocity ot the other. If you have a separate variable that keeps track of direction, that will be a source of trouble without special handling.

-Phil

Owen
03-18-2007, 06:58 AM
here is the code for smoothing
when changeSpeed is called it is sent the current position of the joystick which is one byte 127 being the center of the joystick 0 and 255 being the all all the way foward or all the way back. the joystick is then remaped so that 0 is the center and 128 and 127 are the foward and back and direction can be determined. next the joystick is remaped to a scale that the stepper motor methode can handle ( sets the delay between steps) 255000 being stoped and 1 being the fastest step rate. then the speed is smoothed by the by the IIR equation before setting the output speed(spd). I know there is likely an eeasier way to do this but I do't have much programing experience yet. thanks for the help

Owen

PUB ChangeSpeed(speed) | smooth ' requested_speed 'requested_speed
smooth := 90

if speed => 121 and speed =< 133 'create joystick dead spot, not working
requested_speed := 255000
spd:= (spd * smooth + requested_speed * (100 - smooth))/100
return

if speed <121 'Determin direction of joystick
Dir:=1 ' set motor direction
requested_speed:= 255000 - ||((speed - 127) * 2001) ' rescale joystick so 0 is centered and scale for steper motor methode speed

spd:= (spd * smooth + requested_speed * (100 - smooth))/100 ' smooth speed changes

else

Dir:=0
requested_speed:= 255000 - ((speed - 128) * 2001)

spd:= (spd * smooth + requested_speed * (100 - smooth))/100

T Chap
03-18-2007, 07:01 AM
How are you driving the steppers? External driver(step/dir) or sequenced from the processor? You need two sets of smoothing code right? one going one direction, one going the other. ForwardSmooth and RevSmooth, same basic code copied over, just toggle Dir across the center position, and start the smoothing with numbers at the center.

Post Edited (originator) : 3/18/2007 12:19:26 AM GMT

Phil Pilgrim (PhiPi)
03-18-2007, 07:20 AM
I see a couple discontinuities: (speed - 127) should be (speed - 121), and (speed - 128) should be (speed - 133).

The variable requested_speed needs to be continuous at the edges of the deadzone. This will fix it so it is.

-Phil

T Chap
03-18-2007, 07:46 AM
Owen, I am developing a multi axis boom system, operated by nav keys on a GUI or handheld remote control for moving cameras. mics, etc. I found the steppers to be too noisey and caused too much vibration at really low speeds even at 1/16 microstepping. I started on a brushless DC servo system and am close to being done with it, the controls are PWM and DIR(braking as well), and with the exception of having to track the encoders and manage the PWM and error, the are very similar to operate. The result is precise movement, but much smoother and quieter control. I am doing something slightly different, in that I send a position, and the code tracks the position based on speed, accel, decel etc, but the effect is similar. With position instead of velocity/dir control, you can store sequences of preset positions, each with different speeds and accels.

Anyways, fascinating stuff, glad you posted as I have gained some useful info from Phils ideas.

Owen
03-18-2007, 08:36 AM
Phil said...
I see a couple discontinuities: (speed - 127) should be (speed - 121), and (speed - 128) should be (speed - 133).

The variable requested_speed needs to be continuous at the edges of the deadzone. This will fix it so it is.

-Phil

I gave this a try but all it did was slow the speed of my motors, my dead zone still doesn't work and smoothing doesn't work for changing directions. I guess I'm still a little confused because I used (speed -127) and (speed - 128) to remap the joystick so if I set them to (speed - 121) and (speed - 133) I'm just truncating the range of the joystick right?
thanks for the help, I'm slowly getting there
owen

Phil Pilgrim (PhiPi)
03-18-2007, 09:25 AM
Owen,

Okay, I see the problem. Dir is based on the instantaneous value of speed, whereas spd is smoothed. Both need to be based on smoothed values. I would compute requested_speed as a smoothed byte value from spd, forgetting about direction, but including any deadzone allowances you think are necessary. Then compute dir from requested_speed, along with a period variable for the steppers.

Strictly speaking period = k / speed, rather than k - speed, and you'll probably get better results if you follow this dictum. Of course speed can be zero, so you'll need to include a special case to avoid dividing by zero.

-Phil