PDA

View Full Version : mixing joy stick



Macgman2000
- 15th October 2008, 23:21
I have 2 pots that I am trying to mix at the TX side. The RX side drives standard hobby servos.

If the joy stick is viewed as 4 compass directions. Moving the stick north and south moves the 2 servos in unison the same amount same direction. But going E and W only moves one that corresponds to East and one that corresponds to West.

I have tried IF then conditional statements with dead bands to detect the proper mixing conditions but it seems to fall out of these conditions because of the sloppy nature of the pot/joy stick mechanics.

Does anyone have a cleaver way of finessing these issues?

Nick

skimask
- 16th October 2008, 02:42
What is this? A V-tail mixer? Spoilerons?
So, if your range is 0-999, the middle, say 400-600 from the stick is sloppy, and you need to assume that anything between 400 and 600 is actually 500, and need to 'linearize' the curve off of that 500 center some way leading back to the 'normal' values?
Jeeze...does that make any sense at all? :)

Macgman2000
- 16th October 2008, 03:03
I have only 8bit payload per pot. Actually its like flapperons,I am steering a tank. so to go right it mixes left and right motors in proportions, to steer from large arc to tight arc. To go straight it moves the left and right motor in tandum, same with reverse.

skimask
- 16th October 2008, 03:13
I have only 8bit payload per pot. Actually its like flapperons,I am steering a tank. so to go right it mixes left and right motors in proportions, to steer from large arc to tight arc. To go straight it moves the left and right motor in tandum, same with reverse.
Ok, tank-tread-erons... :)
I'll cook it over in the brain for awhile...
So then, values run from 0 to 255, 128 in the middle, say +/-16 for slop? 112-144 = no movement? Something along those lines?

EDIT: done cooking...

Without some better math (i.e. more bits at the input side), you'll lose some range at the output side of things (i.e. 0-223 vs. 0-255)...


inputvalue var byte
outputvalue var byte
deadband var byte
deadband = 32

if ( input > ( 128 + ( deadband / 2 ) ) ) or ( input < ( 128 - ( deadband / 2 ) ) ) then
output = 128 'set output to middle value
else
if input > ( 128 + ( deadband / 2 ) ) then
input = input - deadband
endif
endif

The total range is reduced to the max byte value (255) minus the total deadband (32 in this case) which equals 223, so 0=minimum, 223=maximum.
But that's just one way to do it...

Macgman2000
- 16th October 2008, 04:29
ok i understand the way you did it. I tried the following and it was iffy.


;ADCIN1 mydata1 ; X pot L/R
;ADCIN2 mydata2 ;y pot FW/REV
etc
.
if mydata1 > 120 and mydata1 < 130 then
mydata2 = mydata1
endif
here TX out the byte.

I am looking at the X pot to see if it has moved from center 120~130 if not then make Y the same as X so that left and right motor move in tandum going forward. If the X pot moves outside of the 120~130 range, then skip the conditional statement and load individual values for X and Y. the mechanical slop is so bad it is hard to find the deadband....I guess I need to do something mechanically to stabilize it....since I don't see how to improve it via code.

skimask
- 16th October 2008, 04:34
Ok, sure, now I smell what you're cooking... I was only shooting for a single channel, one X pot if you will.
Let me cook on that a bit more... I'm sure it can be done the same way, just have to sort out the deadband issue. Maybe start huge and working your way down until it seems comfortable...

skimask
- 16th October 2008, 04:43
lrinput var byte : frinput var byte : lroutput var byte : froutput var byte
loutput var byte : routput var byte : lrdeadband var byte : frdeadband var byte
lrdeadband = 32 : frdeadband = 32
lrmid var byte : lrmid = 128 - ( lrdeadband / 2 )
frmid var byte : frmid = 128 - ( frdeadband / 2 )
;adcin x
;adcin y

if ( lrinput > ( 128 + ( lrdeadband / 2 ) ) ) or ( lrinput < ( 128 - ( lrdeadband / 2 ) ) ) then
lroutput = lrmid 'set output to middle value
else
if lrinput > ( 128 + ( lrdeadband / 2 ) ) then
lroutput = lrinput - lrdeadband
endif
endif

if ( frinput > ( 128 + ( frdeadband / 2 ) ) ) or ( frinput < ( 128 - ( frdeadband / 2 ) ) ) then
froutput = frmid 'set output to middle value
else
if frinput > ( 128 + ( frdeadband / 2 ) ) then
froutput = frinput - frdeadband
endif
endif

After this bit o' code, left and right should have the deadband taken out, with (in this case) the mid-point of left/right being at 112, and the forward/reverse midpoint is also at 112.
Now you have to drive the H-bridge...
What do you have setup for that? Or do you have a separate controller for it or what?
Then you have to add in some code to find and/or remember the minimum and maximum values ever read for the pot's, sort of like a calibration routine for joysticks on a PC...blah blah blah...but I suppose you can keep adding tricks to the code until it gets unbearable...

Darrel Taylor
- 16th October 2008, 04:53
Never had a Tank before. But it sounded like an interesting way to spend the evening.

It might do it all. Or it might blow a loogie. :eek:

DeadBandX CON 10 ; center mechanical Dead Area
DeadBandY CON 5
JoyX VAR BYTE ; A/D values from joystick
JoyY VAR BYTE
TrimX VAR BYTE
TrimY VAR BYTE
Xcorr VAR WORD ; corrected values (x-128)
Ycorr VAR WORD ; puts center at 0,0
Left VAR WORD ; Left Tread
Right VAR WORD ; Right Tread
LeftDir VAR BIT ; Tread directions 1 = backwards
RightDir VAR BIT

Main:
ADCIN 0, JoyX ; get Joystick values
ADCIN 1, JoyY
ADCIN 2, TrimX ; Joystick Center trims
ADCIN 3, TrimY ; set to 128 if not used

Xcorr = JoyX - 128 + (TrimX >> 3) - 16 ; adjust center position to 0
Ycorr = JoyY - 128 + (TrimY >> 3) - 16
IF ABS(Xcorr) < DeadBandX THEN Xcorr = 0 ; center deadband
IF ABS(Ycorr) < DeadBandY THEN Ycorr = 0

Left = Ycorr + Xcorr ; Mix Tread speeds
Right = Ycorr - Xcorr

LeftDir = Left.15 ; Tread Direction
RightDir = Right.15 ; 1 = backwards

Left = ABS(Left) ; make values positive
Right = ABS(Right)

if Left > 127 then Left = 127 ; Clamp max outputs
if Right > 127 then Right = 127

; Drive motors here
; LeftDir indicates the direction of the Left tread
; Left is the Speed of the motor 0 - 127
; Same for Right Track
GOTO Main

skimask
- 16th October 2008, 11:48
Never had a Tank before. But it sounded like an interesting way to spend the evening.
It might do it all. Or it might blow a loogie. :eek:
What!?! You live in CA. and never had a tank? :D
Slick bit of code...not nearly enough colons in there, but slick nonetheless... I'm hanging on to it for future use.

Darrel Taylor
- 20th October 2008, 21:37
Here ya go ski. Is this better ... :D
:::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
:DeadBandX CON 10 ; center mechanical Dead Area :
:DeadBandY CON 5 :
:JoyX VAR BYTE ; A/D values from joystick :
:JoyY VAR BYTE :
:TrimX VAR BYTE :
:TrimY VAR BYTE :
:Xcorr VAR WORD ; corrected values (x-128) :
:Ycorr VAR WORD ; puts center at 0,0 :
:Left VAR WORD ; Left Track :
:Right VAR WORD ; Right Track :
:LeftDir VAR BIT ; Tread directions 1 = backwards :
:RightDir VAR BIT :
: :
:::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
:Main: :
: ADCIN 0, JoyX ; get Joystick values :
: ADCIN 1, JoyY :
: ADCIN 2, TrimX ; Joystick Center trims :
: ADCIN 3, TrimY ; set to 128 if not used :
: :
: Xcorr = JoyX - 128 + (TrimX >> 3) - 16 ; adjust center position to 0:
: Ycorr = JoyY - 128 + (TrimY >> 3) - 16 :
: IF ABS(Xcorr) < DeadBandX THEN Xcorr = 0 ; center deadband :
: IF ABS(Ycorr) < DeadBandY THEN Ycorr = 0 ; :
: :
: Left = Ycorr + Xcorr ; Mix Tread speeds :
: Right = Ycorr - Xcorr :
: :
: LeftDir = Left.15 ; Tread Direction :
: RightDir = Right.15 ; 1 = backwards :
: :
: Left = ABS(Left) ; make values positive :
: Right = ABS(Right) :
: :
: if Left > 127 then Left = 127 ; Clamp max outputs :
: if Right > 127 then Right = 127 ; :
: :
: ; Drive motors here :
: ; LeftDir indicates the direction of the Left tread :
: ; Left is the Speed of the motor 0 - 127 :
: ; Same for Right Track :
:GOTO Main :
:::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
Still compiles.

skimask
- 21st October 2008, 00:09
dx con 10:dy con 5:jx var byte:jy var byte:tx var byte:ty var byte:xc var word:yc var word:lt var word:rt var word:ld var bit:rd var bit
main: adcin 0,jx:adcin 1,jy:adcin 2,tx:adcin 3,ty:xcr=jx-128+(tx>>3)-16:yc=jy-128+(ty>>3)-16:IF ABS(Xc) < dx THEN Xc = 0
IF ABS(Ycorr) < dy THEN Ycorr = 0
lt=yc+xc:rt=yc-xc:ld=lt.15:rd=rt.15:lt=abs(lt):rt=abs(rt):if Lt > 127 then Lt = 127
if Rt > 127 then Rt = 127
GOTO Main
That's what I'm talkin' 'bout...

Darrel Taylor
- 21st October 2008, 00:57
Eeeeuuuwww ...

Cleanup on Isle #2

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2403" />

skimask
- 21st October 2008, 01:36
Eeeeuuuwww ...
Cleanup on Isle #2
To quote somebody else...
Maybe you want a:

Cleaup on Aisle #2 :D

Darrel Taylor
- 21st October 2008, 01:47
No, I think you have your own little Island there.

The Colon Isle.

Population 1.

skimask
- 21st October 2008, 02:01
No, I think you have your own little Island there.
The Colon Isle.
Population 1.
This Isle has been Colon-ized! :D
Oh, and population 2.5 (got one that's just over half-way done cookin' in the oven)

Darrel Taylor
- 21st October 2008, 02:24
This Isle has been Colon-ized! :D
http://www.pbpgroup.com/files/ROFL.gif Good one!


Oh, and population 2.5 (got one that's just over half-way done cookin' in the oven)
That makes it a "semi-colon" ...
So it's commented out. :D
-0.5

skimask
- 21st October 2008, 03:22
http://www.pbpgroup.com/files/ROFL.gif Good one!
That makes it a "semi-colon" ...
So it's commented out. :D
-0.5
Well, it's my Isle...2 big hills, a valley, bushes, and a cavern not well tread upon... :)

Andy Wood
- 21st October 2008, 04:46
Eeeeuuuwww ...

Cleanup on Isle #2

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2403" />

Is this anything like colon cleansing???.......