Putting robotics at your service™

Free shipping on orders over $200

PS2 analog sticks - Normalization of readings

Print view Share :
Previous topicNext topic

Page 2 of 3 [ 33 posts ]

1, 2, 3
User avatar
Guru ( offline )
Posts: 9258
Posted: 2010-06-09 15:10 
I am an experienced troubleshooter. I was merely trying to help you. Troubleshooting is in fact a process of elimination. You determine what the possible causes are. Define a test. Test something, and depending on the results you _may_ be able to eliminate a possible cause of the problem.

Your case involved a PS2 controller and code you wrote or modified. You state the program shows 127-255 from the joysticks. My test would have determined if it was the code or an electronic problem with the PS2 controller.

Do you see the value in knowing your PS2 controller is working properly before trying to locate a code problem that may not even exist?

I will get out. But I will also help if you want me to. I really do wish you well.

_________________
Jim Frye, the Robot Guy
http://www.lynxmotion.com
I've always tried to do my best...


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-09 21:09 
Robot Dude wrote:
I am an experienced troubleshooter. I was merely trying to help you. Troubleshooting is in fact a process of elimination. You determine what the possible causes are. Define a test. Test something, and depending on the results you _may_ be able to eliminate a possible cause of the problem.

I've been doing this right along, but I may have misunderstood your definition of "eliminating something" as meaning something unintended. I interpreted it as meaning physically eliminating something, where it could have meant eliminating a possible cause.

Robot Dude wrote:
Your case involved a PS2 controller and code you wrote or modified. You state the program shows 127-255 from the joysticks. My test would have determined if it was the code or an electronic problem with the PS2 controller.

I tried your test, but was unable to read any usable results from it. I could not see anything but a bunch of 255 values going by when I changed the sticks to different positions.

Robot Dude wrote:
Do you see the value in knowing your PS2 controller is working properly before trying to locate a code problem that may not even exist?

Oh, I definitely know the value in knowing the hardware is working good or not, and at present I don't have full confidence in my particular PS2 controller and cable combination.

I'll be ordering a brand new Lynxmotion PS2 Wireless Controller just like the one I have, so I can compare and have parts I can swap in and out so I can isolate the cause of this problem better. I'll test the entire new controller, receiver, and cable together before I do any swapping of parts, and I will mark everything before I do anything at all so I know what's original and what's new.

Right now, I don't really have a reference or additional experience with this to go by, so I can't point a definitive finger at the cause of the problem. I only know what appears to be the problem, which may or may not be the case. The actual cause of the problem remains to be isolated. This is my first real experience with any remote robot control, and I need to have a known good (as in I test it and it works in all respects) controller to test with.

I think it would be really cool to be able to control WALTER's four wheels using the analog sticks. I already have a tentative control scheme mapped out, and it will be quite interesting and I am sure unlike any remote control scheme you have seen to date if it works out. :D I'm also again seriously considering putting together a stock A4WD1 rover so I can run your stock control programs and get a better understanding of how they work. Rovers are much less expensive overall for me to play around with, and I really enjoy tinkering with them. :D

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 4888
Posted: 2010-06-09 22:13 
Hi again Dale,

As someone who has played around some with these for a bit, I would not necessarily use the word erratic for the stick values, but I do find that they do not have near the precision of some other things like a RC transmitter or our DIY remote control. I often only hit a few discrete values between the center location and full extents. For most of our projects like the brat or rovers this is sufficient. For some programs like rovers where you may want additional control sometimes we use another button/buttons to select a logical gear to help control the speed.

I agree with Jim that using the PS2 test program is a good start as it allows you to see the raw data from a simple program and allows you to see how the values change. If you were seeing all 255s, maybe you did not modify the program to work on P0-P3 (IE enable the built-in pull-up resistor). I modified a version of the program to do so. I also modified it to only output to the terminal if something actually changed. (I hate all of the endless scrolling of stuff as well)

If the values do not change properly then you can experiment changing pauses and the like. Sometimes if you query too fast, the Transmitter and receiver do not have enough time to talk to each other...

The test program also reads in 12 extra bytes of data that for the most part we never use. (it shows how much pressure is on each of the different buttons...). When we setup the mode value for 0x79 that gives us this additional information. Since most of my programs don't use this data, I sometimes simplify my PS2 init code such that it leaves it mode 0x73. It might be worthwhile to see if the controller has more precession if it knows it does not need to produce those extra 12 bytes of data. My C Library code for example defaults to mode 73

OK now if you are happy with those results, the next thing I would look at if I were you was the function Normalize. I understand what it is trying to do, which is to try scale the returned value such that whatever the actual center point maps to 127(or 128) and two ends map to 0 and 255. That is suppose the observed center location is at 132 instead of 128. Then you have 132 values on one side of the range and only 123 values on the other side....

Personally for your use, I think you could skip all of this and could easily simplify this and simply say if the joystick value is within the deadband units of center, set it to your logical center, else use it as is...

Got to go.

Kurt


Attachment:
File comment: Modified PS2 test program
test.bas [3.81 KiB]
Downloaded 59 times
User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-09 23:25 
kurte wrote:
As someone who has played around some with these for a bit, I would not necessarily use the word erratic for the stick values, but I do find that they do not have near the precision of some other things like a RC transmitter or our DIY remote control. I often only hit a few discrete values between the center location and full extents. For most of our projects like the brat or rovers this is sufficient. For some programs like rovers where you may want additional control sometimes we use another button/buttons to select a logical gear to help control the speed.

The "erratic" was a question only - I should change the topic name a bit. This is my first experience with the PS2 controller as a robot controller. To control WALTER the way I would like to will require three analog sticks - two for wheel control and one for the pan/tilt on the front. I could probably use the D-Pad for the pan/tilt though, but I have other plans for that. I really want a DIY remote, but am really unsure if I could pull off building one, at least not all of it.

kurte wrote:
I agree with Jim that using the PS2 test program is a good start as it allows you to see the raw data from a simple program and allows you to see how the values change. If you were seeing all 255s, maybe you did not modify the program to work on P0-P3 (IE enable the built-in pull-up resistor). I modified a version of the program to do so. I also modified it to only output to the terminal if something actually changed. (I hate all of the endless scrolling of stuff as well)

I did not modify it for P0 - P3 and to use the pull-up. I just made that change and reprogrammed it. Still not sure what I should be seeing and where, but I am seeing a lot of zeros now until I change something on the controller. I definitely don't like all the continuous scrolling - it really makes it impossible for me to see what I need to see and follow it properly. I will try your version.

kurte wrote:
If the values do not change properly then you can experiment changing pauses and the like. Sometimes if you query too fast, the Transmitter and receiver do not have enough time to talk to each other...

I see where timing is very important with all this.

kurte wrote:
The test program also reads in 12 extra bytes of data that for the most part we never use. (it shows how much pressure is on each of the different buttons...). When we setup the mode value for 0x79 that gives us this additional information. Since most of my programs don't use this data, I sometimes simplify my PS2 init code such that it leaves it mode 0x73. It might be worthwhile to see if the controller has more precession if it knows it does not need to produce those extra 12 bytes of data. My C Library code for example defaults to mode 73

I don't see any use for this additional data for my control purposes either.

kurte wrote:
Personally for your use, I think you could skip all of this and could easily simplify this and simply say if the joystick value is within the deadband units of center, set it to your logical center, else use it as is...

This is probably true. However, I still have not fully analyzed all of the code I took from the ps24wd1.bas program, and therefore don't understand a lot of it yet. I am not able to dig into analyzing code like I used to be able to do so it takes me much longer to gain the understanding I need.

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-09 23:48 
Kurte,

I like your version of the test program MUCH better! Now I can actually see what I need to see without all that scrolling making my eyes do things I would prefer they not do. :D Now I see that my analog sticks are returning values < 127, but that leads me to another question.

I have:
Code:
      serout S_OUT,i9600,["Remote, Left H: ",dec3 lhori\3,", Left V: ",dec3 lvert\3,", PanPos: ",sdec6 PanPos\6,", TiltPos: ",sdec6 TiltPos\6,", TestPos: ",sdec6 TestPos\6,13]

Shouldn't this print out the proper values for the left stick? Maybe I am suffering from the fast scrolling thing with this also, and am missing what I need to be seeing.

I just had to forcefully kill Basic Micro Studio #30 again (after uninstalling and reinstalling it) while Jim's ps2test program was running on my Atom Pro and outputting to the serial console.

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 4888
Posted: 2010-06-10 00:00 
linuxguy wrote:
I have:
Code:
 serout S_OUT,i9600,["Remote, Left H: ",dec3 lhori\3,", Left V: ",dec3 lvert\3,", PanPos: ",sdec6 PanPos\6,", TiltPos: ",sdec6 TiltPos\6,", TestPos: ",sdec6 TestPos\6,13]

Shouldn't this print out the proper values for the left stick? Maybe I am suffering from the fast scrolling thing with this also, and am missing what I need to be seeing.

Yes and No. The other issue here is that by the time you get to this serout, your values have gone through your normalize function. So if something does not look right you don't know if it was the raw value or the normalize that screwed it.

You do have another serout in the Get_PS2_Data subroutine that is commented out that can give you this information:
Code:
'   serout S_OUT,i9600,[", Left H: ",dec3 lhori\3,", Left V: ",dec3 lvert\3,", Right H: ",dec3 rhori\3,", Right V: ",dec3 rvert\3,13]

Of course it will print lots of times unless you do the check to see if anything changed.

Kurt


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-10 00:04 
kurte wrote:
You do have another serout in the Get_PS2_Data subroutine that is commented out that can give you this information:
Code:
'   serout S_OUT,i9600,[", Left H: ",dec3 lhori\3,", Left V: ",dec3 lvert\3,", Right H: ",dec3 rhori\3,", Right V: ",dec3 rvert\3,13]

Yes, I know. However, I am just printing the same data for the left stick as that is. :)

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-10 10:46 
I've been working on this some this morning, and it's giving me a headache (literally). :( :( I am going to need to leave it be for now. :( I just can't seem to get my head around the normalization stuff with the analog sticks and converting the readings to something that works for HSERVO (-12000 to +12000).

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 4888
Posted: 2010-06-10 11:25 
Good morning Dale,

This is why I suggested to simplify. Get rid of the calls to Normalize. I don't currently have a pan/tilt setup, but my MechBrat (modified from James code...) does use the joystick to turn the turret and changes the angle of the hip to allow you to aim the guns, which is more or less the same idea... Taking a look at it, it looks like i need to modify it to work with the new IDES. I have edited part of it. But for one direction the code looks like:
Code:
IF (ABS(DualShock(3)-128) > TravelDeadZone) THEN
   ; We also only process this if the turret servo is idle
   if HservoIDLE(Turret)then
      TurretAngle = HservoPos(Turret) + ((Dualshock(3) - 128)*4)
      IF TurretAngle > 12000 THEN
         TurretAngle = 12000
      ELSEIF TurretAngle < -12000
         TurretAngle = -12000
      ENDIF
      hservo [Turret\TurretAngle\100]
   endif
ENDIF

You can reduce the number of lines of code here by using the min/max functions on the original calculation. Obviously you would need to replace variable names and the like. Ie change DualShock(3) to lhori, TravelDeadZone to DeadBand, Turret to PanServo... You may wish to play with the timing of the move, etc.

Kurt


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-11 10:03 
kurte wrote:
This is why I suggested to simplify. Get rid of the calls to Normalize. I don't currently have a pan/tilt setup, but my MechBrat (modified from James code...) does use the joystick to turn the turret and changes the angle of the hip to allow you to aim the guns, which is more or less the same idea... Taking a look at it, it looks like i need to modify it to work with the new IDES. I have edited part of it. But for one direction the code looks like:
Code:
IF (ABS(DualShock(3)-128) > TravelDeadZone) THEN
   ; We also only process this if the turret servo is idle
   if HservoIDLE(Turret)then
      TurretAngle = HservoPos(Turret) + ((Dualshock(3) - 128)*4)
      IF TurretAngle > 12000 THEN
         TurretAngle = 12000
      ELSEIF TurretAngle < -12000
         TurretAngle = -12000
      ENDIF
      hservo [Turret\TurretAngle\100]
   endif
ENDIF

I'm back to working on this, now that my head isn't hurting. I can either get half range with stick self centering properly, OR full range and the stick does NOT center properly.

Here is the code in question:
Code:
   ' SET LINEARIZED JOYSTICK DISPLACEMENT BASED ON JOYSTICK CENTER POSITION
'   gosub Normalize [lhori, lhori_null], lhori
'   gosub Normalize [lvert, lvert_null], lvert
'   gosub Normalize [rhori, rhori_null], rhori
'   gosub Normalize [rvert, rvert_null], rvert

   lhori_s = lhori - 127
   lvert_s = lvert - 127
   rhori_s = rhori - 127
   rvert_s = rvert - 127

   ' Main processing
   if Autonomous then
      ' Autonomous control
      gosub Steering [CurrRFAngle, CurrLFAngle, CurrRRAngle, CurrLRAngle, MoveSpeed]
   else
      ' Remote control
      PanPos = (lhori_s * 100)  MAX 12000 MIN -12000
      TiltPos = (lvert_s * 100)  MAX 12000 MIN -12000
      
      hservo [PanServo\PanPos\MoveSpeed, TiltServo\TiltPos\MoveSpeed]

      serout S_OUT,i9600,["Remote, Left Hr: ",sdec4 lhori\4,", Left Vr: ",sdec4 lvert\4,", Right Hr: ",sdec4 rhori\4,", Right Vr: ",sdec4 rvert\4,13]
      serout S_OUT,i9600,["Remote, Left Hs: ",sdec4 lhori_s\4,", Left Vs: ",sdec4 lvert_s\4,", Right Hs: ",sdec4 rhori_s\4,", Right Vs: ",sdec4 rvert_s\4,", PanPos: ",sdec6 PanPos\6,", TiltPos: ",sdec6 TiltPos\6,13,13]
   endif

This code gives me full stick range, but the stick doesn't self center properly when I release it.

Below is the new Normalize subroutine (not currently being called):
Code:
Value var byte
Null var byte
Normalize [Value, Null]
   if Value < (Null - DeadBand) then
      Value = ((127 * Value) / (Null - DeadBand)) MAX 127
   elseif Value > (Null + DeadBand)
      Value = ((127 * (Value - Null)) / ((255 - DeadBand - Null) + 127)) MAX 255
   else
      Value = 127
   endif

   return Value

kurte wrote:
You can reduce the number of lines of code here by using the min/max functions on the original calculation. Obviously you would need to replace variable names and the like. Ie change DualShock(3) to lhori, TravelDeadZone to DeadBand, Turret to PanServo... You may wish to play with the timing of the move, etc.

I have not worked with this yet, but am going to try it out next. I've attached my complete code, which gives me full range on the stick, but does not self center properly.

8-Dale


Attachment:
File comment: All my current code.
walter.bas [10.06 KiB]
Downloaded 59 times

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..
User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-12 10:27 
I don't think I am actually seeing the zero values (-5 to + 5) that I am looking for to center the sticks. I'll try widening the range and see what happens.

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-12 12:41 
The PS2 controller sends 0 when centered, which would be -127 to get a +/- range (stick reading - 127). This is not cool, because it means there are two positions the controller sends a 0 reading - true stick position 0 and centered stick 0. I'm using Kurte's version of a test program.

Can somebody please confirm that this is or is not true?

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Expert ( offline )
Posts: 628
Posted: 2010-06-12 15:52 
That isn't true. The analog sticks return a value from 0 to 255. IIRC this is a 2s complement signed byte. There is only one position you will get 0. That is at center. However I've seen several different brands of PS2 controller that don't go back to 0 when the sticks are released. I've seen them as far off as +-5 when the sticks are released. Also there is a large dead zone on some sticks so you will get 0 for a significant movement of the sticks at the center area(eg as much as a millimeter).

_________________
Basicmicro


User avatar
Guru ( offline )
Posts: 2956
Posted: 2010-06-12 22:43 
Acidtech wrote:
That isn't true. The analog sticks return a value from 0 to 255.

With this range, how can 0 be center? Wouldn't 0 be all the way in one direction and 255 be all the way the other direction?

Acidtech wrote:
IIRC this is a 2s complement signed byte.

I never really did get 2's complement, so maybe this is my problem. I've been treating the stick readings as raw regular (not complemented in any way) binary bytes.

8-Dale

_________________
I can usually handle complexity. It's the [b][i]simple[/i][/b] things that always confound me..
Check out my [url=http://www.hybotics.me]blog[/url] now!
Open your mind, Read, Learn, Think, Apply..


User avatar
Guru ( offline )
Posts: 4888
Posted: 2010-06-13 09:53 
linuxguy wrote:
Acidtech wrote:
That isn't true. The analog sticks return a value from 0 to 255.

With this range, how can 0 be center? Wouldn't 0 be all the way in one direction and 255 be all the way the other direction?

Exactly. The center point is somewhere near 127 or 128. That is why when you look through programs that use the PS2, they often have the code that looks like:
Code:
IF (ABS(DualShock(3)-128) > TravelDeadZone) THEN

They are testing to see if the joystick is outside the center point by some slop factor. My current program has the TravelDeadZone set to 4. As Nathan mentioned some have a very large dead zone.

Acidtech wrote:
However I've seen several different brands of PS2 controller that don't go back to 0 when the sticks are released. I've seen them as far off as +-5 when the sticks are released.

I have seen this as well. Actually with the Sony wired one I had the worst results, It never appeared to return the same zero point twice and sometimes was off by as much as 8...

linuxguy wrote:
Acidtech wrote:
IIRC this is a 2s complement signed byte.

I never really did get 2's complement, so maybe this is my problem. I've been treating the stick readings as raw regular (not complemented in any way) binary bytes.

I am not sure it is a 2s compliment signed value as well. That is in Two's complement the hex value 80 which is 128 as a signed value would be -128 and hex 0xff in a signed byte would be the value -1. If you look at the Wikipedia entry for signed numbers: http://en.wikipedia.org/wiki/Signed_num ... sentations The PS2 values are more like Excess-N values... What we are typically trying to do is find out what side from center we are and by how much. First things choose what you think the center is: Some use 127 others choose 128, does not matter much other than which direction will have one extra value.

So for example if you look at some of the code I am currently using to test the roboclaw (borrowed from code that Xan did earlier), you will see the following:
Code:
      IF ABS(Dualshock(5) - 128) > DeadZone THEN ;Left Stick L/R
         LStickY = (Dualshock(5) - 128) ;Wheels
      ELSE
         LStickY=0      
      ENDIF
   
      IF ABS(Dualshock(6) - 128) > DeadZone THEN ;Left Stick U/D
         LStickX = -(Dualshock(6) - 127) ;Wheels
      ELSE
         LStickX=0
      ENDIF

I show the code for two different axis as sometimes the + or - the stick returns may not be logically the + or - that we wish to use. Note: LStickX and LstickY are defined as SBYTE.

So from the above the different values returned from the PS2 should map like:
Code:
   DS(value)      LStickX      LStickY
   124-132      0      0
   0      -128      127
   1      -127      126
   123      -5      4
   133      5      -6
   254      126      -127
   255      127      -128      

From doing the above, I do see a problem some may run into if they are not careful. That is if instead the code was:
Code:
      IF ABS(Dualshock(5) - 127) > DeadZone THEN ;Left Stick L/R
         LStickY = (Dualshock(5) - 127) ;Wheels
      ELSE
         LStickY=0      
      ENDIF

You could run into problems. Why? because if the value from the dual shock is 255 (0x80), we would find we are trying to assign:
LSticky = 255-127 = 128 but the value +128 is not a valid number in a signed byte, it will actually read as: -128

Kurt


1, 2, 3

All times are UTC - 5 hours [ DST ]. It is currently 2014-08-01 07:51
Feedback Form
Feedback Form