Shop OBEX P1 Docs P2 Docs Learn Events
joystick dampening math/ code — Parallax Forums

joystick dampening math/ code

OwenOwen Posts: 100
edited 2007-03-18 02:25 in General Discussion
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?

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-17 02:17
    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
  • OwenOwen Posts: 100
    edited 2007-03-17 02:31
    this is great! just what i have been looking for all day, Thank you!
  • SSteveSSteve Posts: 808
    edited 2007-03-17 03:29
    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

    links:
    My band's website
    Our album on the iTunes Music Store
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-17 05:33
    Steve,

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

    -Phil
  • OwenOwen Posts: 100
    edited 2007-03-17 20:31
    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)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-17 22:35
    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
  • OwenOwen Posts: 100
    edited 2007-03-17 23:12
    my code at the moment evaluates direction before using the smoothing code, so I think Requested_Position could stay positive.

    Owen
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-17 23:22
    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
  • OwenOwen Posts: 100
    edited 2007-03-17 23:58
    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 ChapT Chap Posts: 4,223
    edited 2007-03-18 00:01
    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)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-18 00:20
    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 ChapT Chap Posts: 4,223
    edited 2007-03-18 00:46
    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.
  • OwenOwen Posts: 100
    edited 2007-03-18 01:36
    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)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-03-18 02:25
    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
Sign In or Register to comment.