Questions on Phoenix code with RC individual leg control

Hiya.

So this is what Ive done,

 ;*************************************************************************************
   ;*** Individual leg control mode choose between 6 legs with 2-state button ***
   ;*************************************************************************************
   elseif LegMode
   	      	BalanceMode = 1
			GaitType = 2
   	     
   	     TestLeg = RRGaitLegNr
         TravelLengthX = (RCInput(1)-1500)/4.5   
         TravelLengthZ = (RCInput(0)-1500)/4.5
         TravelHeightY = (RCInput(3)-1500)/3
   
		serout S_OUT, i9600, "GaitPosX=", sdec GaitPosX," GaitPosY=", sdec GaitPosY," GaitPosZ=", sdec GaitPosZ, 13]

   
  ENDIF
 
return   

Ignore the travel lengthX’Y’Z channels which are assigned to the wrong channels of the remote… I’ll fix that later.

So with that serout command Ive noticed that the 3 angles max limits are -24 and +24 for GaitPosY,X,Z which is why Ive used 4.5/4.5/3 respectively where you had used 4/4/3 “I’m just experimenting with the values I used based off visually the problems Ive been experiencing.” I have some values to shoot for now less then 24 and no more then -24

I see your max and min values are not the same as the ones I see, due to adjusting the end points, what I believe I will do is adjust all of the end points so that max is 2000 and min is 1000 and centered is as close to 1500 as possible.

RCpwmMAX con 1850 <— your values
RCpwmMIN con 1150 <— your values

As for your comment of the Sbyte values getting larger then they should, I did not find this was the case but good call.

I’m looking at how you had used the max min commands and realize now why you had used that to avoid issues like this. I just want to avoid a large deadzone on the far reaches of each stick.

What I think I need to do on the transmitter is adjust all the End Points so that they all end at 1000 and 2000 'which is around 121%-123%
I had remembered a while back when I asked you why my phoenix was having issues and you explained the max and min thing a while ago, now I understand what was happening with the values so that makes sense to me.

So as for monitoring the Gait variables I had noticed that when any one of the 3 axis value gets larger then 24 they quickly become inverted from 24 to -24 which is what causes the leg to quickly jump into the opposite direction… I cant say exact but I’m going to take a guess at this and say it has to do with one of the trig values getting larger then they should. Id have to learn some of that again to give you a better idea, but since you understand the code more then me you would have a better idea of what is happening with the large values and why they happen to get inverted like that when that value is 25 and higher

Actually do you have any notes on what the max and min of all the variables are? so i can adjust my division values accordingly? the other option is to just not use endpoints and set them all to 100%

One other idea I was going to implement was when the individual leg is selected it simply taps twice or something, I think I can do this by just adding then subtracting 10 or so from one of the TravelLength variables that deals with up and down movement and then return to the other loop which deals with actually controlling the arm, and would only do this on a new leg selected.

other then having the ability for every leg to be controlled which you did in the modified remote code you sent me for reference, that’s what my goal is now.

Oh I almost forgot, I cant find in the 'Modified remote" version you had sent me what it is that keeps your leg stuck in 3d space when you switch from Mode3 to Mode2 “balance one leg mode”…

I notice that your balance one leg mode and BodyRotX’y’z are in the same mode where as mine are in different sub routines…is that why? is there anyway I can make the un modified code perform like the modified remote code when it comes to holding that leg in 3d space while switching from mode 3 "leg control’ to mode 2 “body rotation” ?? or am i stuck

–Aaron

Actually do you have any notes on what the max and min of all the variables are? I have found the limits of the travelLength variables being -24 and 24.

thanks again.

Edited … made a mistake.

Alllllllllllllrighty,

This is what I have so far


;[RCInput] reads the input data from the RC-Remote and processes the
;data to the parameters.
RCInput1:
   
  ;Read input pulse lengths in the correct order that take shortest time
  PULSIN RCCh0, 0, RCInput(0)
  PULSIN RCCh2, 0, RCInput(2)
  PULSIN RCCh4, 0, RCInput(4)
  PULSIN RCCh5, 0, RCInput(5)
 
  PULSIN RCCh1, 0, RCInput(1)
  PULSIN RCCh3, 0, RCInput(3)
  PULSIN RCCh6, 0, RCInput(6)
 
 
   		WalkMode = False
   		MoveMode = False
   		LegMode = False
   		BalanceMode = False
   if RCInput(4) < 1100 then
      WalkMode = True
   elseif ((RCInput(4) > 1400) & (RCInput(4) < 1600))
      MoveMode = True
      else
      LegMode = True
   endif
   
   if RCInput(6) < 1500 then
      TwoStateSW = False
   	  else
      TwoStateSW = True
   endif
   
   If RCInput(6) > 1600 then
   		Whatleg = Whatleg + 1
		elseif Whatleg > 7
		Whatleg = 1
   endif
   		
   ;***********************************************************************************
   ;*** Walking mode, toogle between the different walking gait with 2-state button ***
   ;***********************************************************************************
   if WalkMode then
      if RCInput(5) < 1750 then 'Select BalanceMode with VR-pot at slower speed
         ;BalanceMode = TRUE
      else
         BalanceMode = FALSE
      endif
      if TwoStateSW then      'Toggle gait method:
         if GaitType < 7 then      'so far we have 8 gait methods
            GaitType = GaitType +1
            sound P9,[150\(800+(GaitType*100))]
         else
            GaitType = 0
            sound P9,[100\1900,150\2100]
         endif
         gosub GaitSelect
      endif
      	BodyPosY = (RCInput(2)-1000)/8
      	TravelLengthX = (RCInput(0)-1500)/4
        TravelLengthZ = (RCInput(1)-1500)/4
        TravelRotationY = (RCInput(3)-1500)/12
              
   ;***********************************************************************************
   ;*** Move mode, toogle between translating and rotating body with 2-state button ***
   ;***********************************************************************************
   elseif MoveMode
      if TwoStateSw then   'Toogle movement method
         if ToogleMovement then
            ToogleMovement = False
            sound P9,[100\800,150\1800]
         else
            ToogleMovement = True
            sound P9,[100\1800,150\800]
         endif
      endif
      if ToogleMovement then
         'Body translate:
           BodyPosX = -(RCInput(0)-1500)/10
           BodyPosZ = -(RCInput(1)-1500)/8
           BodyRotY = -(RCInput(3)-1500)/20
           BodyPosY = (RCInput(2)-1000)/8
        else
           'Body rotate:
           BodyRotX = -(RCInput(1)-1500)/20
           BodyRotY = -(RCInput(3)-1500)/20
           BodyRotZ = (RCInput(0)-1500)/20
           BodyPosY = (RCInput(2)-1000)/8
        endif   
   
   
   ;*************************************************************************************
   ;*** Individual leg control mode choose between 6 legs with 2-state button ***
   ;*************************************************************************************
   elseif LegMode
   		BalanceMode = 1
		GaitType = 2
   	   	If whatleg = 1 & TwoStateSW = True then
				Gosub LegTap
		Elseif whatleg = 1
				TestLeg = RFGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        ElseIf whatleg = 2 & TwoStateSW = True
				Gosub LegTap
        Elseif whatleg = 2	 	
   	     		TestLeg = RMGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        ElseIf whatleg = 3 & TwoStateSW = True
				Gosub LegTap
        Elseif whatleg = 3	 	
   	     		TestLeg = RRGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        ElseIf whatleg = 4 & TwoStateSW = True
				Gosub LegTap 		
        Elseif whatleg = 4	 	
   	     		TestLeg = LRGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        ElseIf whatleg = 5 & TwoStateSW = True
				Gosub LegTap
        Elseif whatleg = 5	 	
   	     		TestLeg = LMGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        ElseIf whatleg = 6 & TwoStateSW = True
				Gosub LegTap
        Elseif whatleg = 6	 	
   	     		TestLeg = LFGaitLegNr
         		TravelLengthX = (RCInput(1)-1500)/4   
         		TravelLengthZ = (RCInput(0)-1500)/4
         		TravelHeightY = (RCInput(3)-1500)/2
        Endif

		;serout S_OUT, i9600, "GaitPosX=", sdec GaitPosX," GaitPosY=", sdec GaitPosY," GaitPosZ=", sdec GaitPosZ, 13]
		;serout S_OUT, i9600, "Whatleg=", sdec Whatleg, 13]
   
  ENDIF
 
return   
;--------------------------------------------------------------------
LegTap
   	    			TravelLengthX = 20
					pause 50
					TravelLengthX = 0
					Pause 50
					TravelLengthX = 20
					Pause 50
					TravelLengthX = 0
Return

I’m really not sure why the little legs arnt tapping, Ive tried using RFPosX as an example and subtracting and or adding 30 to the number so when it exits that subtroutine its returned to its normal value that is set at initialization. for some reason it’s like not remembering the TwoStateSW position while trying to …

Another theory is, Im using RCInput(6) for 2 different things, the TwoStateSW variable which “Zenta” put in and the same RCInput(6) that I put in that modifies WhichLeg Nib variable…

So… “Whiskey Tango Foxtrot” I’m out of ideas at the moment…

Hi,

Thats because the LegTap sub dosen’t do anything… :wink:

Haha…

that would explain it…well’s then … how would one make it function? unless you have a better idea of how I should make a leg tap?

Thanks!

–Aaron

Instead of the pause 50 it have to move the leg (run one cycle).

DOH, now i know why it doesn’t do anything…
Back to the drawing board.

got any genius ideas how I can solve this?

… I’m running out of ideas to add to this thing :\

Only thing I can think of is make some sorta GP sequencer by simply hard setting the RFPosX,y,z on all legs… variables and then returning it to init positions… I think you did that in your modified version though

other then that… I;m outta ideas! I know its a horrible thing…

I’ve not done this either but I don’t think it should be difficult (the tapping function). One solution would be using a counter in the main loop that add for every cycle, then you can use this counter to know when to tap (lower or rise the leg). When you don’t do the tapping you must reset the counter.

ex.

[code]LegTap
IF ((Counter = 1) OR (Counter =3)) THEN
TravelHeightY = 20
ELSE
TravelHeightY = 0
ENDIF
IF Counter>3 THEN ;End the tapping
Counter = 0
ENDIF

Return [/code]

You probably have to experiment a bit. I’m not a programming expert either so there are probably better way to do it too. You have to figure out the rest of the code too, but I hope this gave you a little idea. :wink:
You also might want to alter the SSCTime speed or add an extra delay.

EDIT: By tapping I’m guessing you mean that the leg have to move up and down, therefore the change of TravelHeightY.

OOh, hey I would have figured that out eventually :slight_smile:

That makes sense though, After I looked at that subroutine that did nothing i wrote :slight_smile:, I saw how it needed to exit the main loop and return and then "do some stuff’ and come back into the routine.

Either way your code makes perfect sense “as it always does”

I have not modified SSCTime variable… was this the variable that was directly tied to the VRChannel6 pot on our transmitters?

InputTimeDelay = 128 - (ABS((RCInput(1)-1500)/4) MIN ABS(((RCInput(0)-1500)/4))) MIN ABS(((RCInput(3)-1500)/6)) + (128 -(RCInput(5)-910)/8) this was the only thing that links the SSCTime variable with the RCInput(5) VR Pot right?

I see that the only time the VRChannel6 pot is referenced "RCInput(5) is to simply modify SSCTime variable with the addition of depending on what gait is selected and balance mode is on or off… I think I have a solution to eliminate the VR channel 6 pot and simply get SSCTime variable from how far channels 1-4 sticks are pushed twords maximum “if you follow me”

although I’m not sure what to do with channel 6 when I remove it… turn the phoenix’s anger up?.. Actually maybe rather then use the VR pot map that to one of the unused switches A/b/D/G… an idea…

You know you should put your remote back to stock :\ there are quite a bit of programming options to select modes… “Just my opinion”

So how is SSCtime used? … i guess how was that number used for gait speed? does it have a maximum value? I wanted to see how fast I can get the phoenix to walk across the floor and it seems like the maximum speed happens to be the Tripod 4 step gait… I guess I wasn’t sure if there was a “faster method” for the phoenix to get from point A to point B… although the testing I was fiddling around with in the past with the ps2 code was that if I modified the ssctime or changed the “NomGaitSpeed” the phoenix was going so fast it would trip over its own feet!.

I’ll have to put SSCtime variable into a serout command and watch the value change, I’ll come up with an idea for how to eliminate VR pot6 and I’m guessing you had already done that since you used the 6 channel VR pot “I believe” to link all your FSxyz switches to… for the most part all it is is taking the abs value’s of all 4 gimble sticks subtracting 1500 and figuring out what to divide it by to get an ssctime based on any one of the 4 sticks… should be pretty straight forward… and I’m guessing plop this line of code into the RCInput subroutine should make it all happy…

–Aaron

Actually looking at the code your using, you seem to handle GaitSpeed quite a bit differently lots of extra code to deal with that single variable…

Interesting…

Um Flippin Kay… Here’s what I have so far, Kinda got distracted by wanting to remove channel 6 “the SscTime Modifier channel” or VR pot.

SO I wasn’t sure how you dealt with the SSCTime in the code that you use “zenta” anyway Ive come up with a solution although I don’t know if some coder can come up with something a bit more efficient… somehow it seems like the AtomPro might spend too much time in the RCInput Subtroutine as it effects the walking of the gait…or so it looks like it does??.. anyway here it is

[code];[RCInput] reads the input data from the RC-Remote and processes the
;data to the parameters.
RCInput1:

;Read input pulse lengths in the correct order that take shortest time
PULSIN RCCh0, 0, RCInput(0)
PULSIN RCCh2, 0, RCInput(2)
PULSIN RCCh4, 0, RCInput(4)
PULSIN RCCh5, 0, RCInput(5)

PULSIN RCCh1, 0, RCInput(1)
PULSIN RCCh3, 0, RCInput(3)
PULSIN RCCh6, 0, RCInput(6)
;serout S_OUT, i9600, “SSCTime=”, sdec Ssctime, " “,“InputTimeDelay=”, sdec InputTimeDelay,” ",sdec RcInput(0), 13]

	WalkMode = False
	MoveMode = False
	LegMode = False
	BalanceMode = False

if RCInput(4) < 1100 then
WalkMode = True
elseif ((RCInput(4) > 1400) & (RCInput(4) < 1600))
MoveMode = True
else
LegMode = True
endif

if RCInput(6) < 1500 then
TwoStateSW = False
else
TwoStateSW = True
endif

If RCInput(6) > 1600 then
Whatleg = Whatleg + 1
elseif Whatleg > 7
Whatleg = 1
endif

If RcInput(0) > 1500 then
ChanVal0 = Abs((abs(RcInput(0)) - 1500) - 412)/2
else
ChanVal0 = Abs((abs(RcInput(0)) - 1500) + 412)/2
Endif

If RcInput(1) > 1500 then
ChanVal1 = Abs((abs(RcInput(1)) - 1500) - 412)/2
else
ChanVal1 = Abs((abs(RcInput(1)) - 1500) + 412)/2
Endif

If RcInput(3) > 1500 then
ChanVal3 = Abs((abs(RcInput(3)) - 1500) - 412)/2
else
ChanVal3 = Abs((abs(RcInput(3)) - 1500) + 412)/2
Endif

InputTimeDelay = ChanVal0 max ChanVal1 Max ChanVal3

;InputTimeDelay = Abs(RcInput(0)-1500) - 412
SSCTime = NomGaitSpeed + InputTimeDelay[/code]

OK so here is the rundown of how this code works

since InputTimeDelay is a variable max 255, which caused problems why I didn’t see it earlier when I was trying to make that variable 412 … that was funny… anyway…

when channel 1, 2, or 4 sticks are centered the value is 206 when the stick is pushed to its limit all the way up, down left or right, the value of the stick is 0

so each of the 3 if statements simply stores the value into ChanVal"1,2,4" which is only 0-206

then using the max command on all 3 variables it only returns the value if the lowest variable 'the one pushed to its limits"

then SSCTime is = to NomGaitSpeed + InputTimeDelay

Thus Channel 6 is eliminated… Hrms… any ideas what to use this for now? :slight_smile:

There has got to be a cleaner way of doing that? anyone have any ideas?

–Aaron

Or any ideas what to do with channel 6 I was actually tempted to change that so it raises and lowers the height of the phoenix rather then channel 4 which is the left up and down stick or throttle.

Hey everyone.

I know these sorta questions I ask can only really be answered by like a small group of people…

  1. people who have a pheonix
  2. people who change code on it
  3. people who possibly have RC remote
  4. people who want individual leg control

slim I know but i gotta ask!

I have been tinkering with the phoenix code quite a bit because I can really and I have some idea’s that id like to try and incorporate into my RC controlled cat mover

I think this was brought up in the past about the global coordinates of the way Xan setup the RFPosx, y, z variables in relation to the phoenix body and the 6 main coxis joints and I have scratched my head a bit about a couple of things

Z axis can be + or - but it does not relate to z axis in normal coordinates IE up and down?

X axis is always positive for the left and right side of the bot

I would assume that the legs can be positioned on a xyz plane with the center of the phoenix being 0,0,0 and all legs would be positioned in relative 3d space based on where the center of the phoenix is… anyway moving on I believe I can still accomplish what I’m trying to do, everyone has there methods and I’m sure I’m missing why something was done one way and not another, feel free to chime in, I’m very curious about this.

Allright so, the way Zenta accomplished individual leg control, he had informed me on how to do this and I have implemented it into my RC Phoenix, and it does exactly that however I would like to “1-up” this idea and go for 2x legs to be controlled at the same time via RC I want to be able to walk up to a like cap from a water bottle on the floor and position the 2 front legs or rear legs “the phoenix has no idea what the front or back is SHE HAS NO HEAD DAMNIT!” anyway anyway… walk up to a cap and move both front legs close to each other and attempt to 2 leg grip a cap and pick it up… now it comes down to can the phoenix walk with only 4 legs?

An interesting subject… can a 6 legged robot walk with 4 legs?

I understand I will have to make a new gait I think Xan posted info on how to accomplish this… has anyone ever made their own walking gait?

The way Zenta showed me how to accomplish individual leg control modified some variables and later these variables got modified into new variables and those same variables were all duplicates of each other for each of the six legs… So I don’t believe I will be able to modify for instance TravelLengthX, Y, Z in order to do 2 leg control, in which case I most likely will have to modify RFPosX, Y, Z which are the initialization values that set’s each foot into 3d space when the phoenix is turned on.

which brings me to another point Xan had mentioned to me about not messing with these variables because in the ps2 code Xan does not modify these after INIT. Zenta uses these in his GP sequencer for pose’s and all, so I simply will have to duplicate this code

[code]ResetLegs

RFPosX = 53 ;Start positions of the Right Front leg
RFPosY = 25
RFPosZ = -91

RMPosX = 105 ;Start positions of the Right Middle leg
RMPosY = 25
RMPosZ = 0

RRPosX = 53 ;Start positions of the Right Rear leg
RRPosY = 25
RRPosZ = 91

LFPosX = 53 ;Start positions of the Left Front leg
LFPosY = 25
LFPosZ = -91

LMPosX = 105 ;Start positions of the Left Middle leg
LMPosY = 25
LMPosZ = 0

LRPosX = 53 ;Start positions of the Left Rear leg
LRPosY = 25
LRPosZ = 91

Return[/code]

and simply call it once when I have switched modes out 2 leg control mode to reset each leg value and do this once, and reset it anytime i enter and exit 2 leg mode

I’m pondering other ways to do this without duplicating code simply calling it at initialization or putting it into its own sub routine like above and put the gosub into an if statement of sorts… anyway not a big deal.

I guess the main question for the xan,zenta combo here :slight_smile: is if they have any ideas as to how I can accomplish this either using the TravelHeightX,Y,Z vairables or the RFPosX vairables or honestly can I add my own?

I’m much more of a fan of the RFPOS vairables as they are in mm and their values are much larger then thoes of TravelHeightX,Y,Z as the max and min values are +25 to -25 and it is kinda jerky as there is no movement when the value is between 2 numbers… I do not know what format the travelheight values are at…

So do I need to add my own position modifiers? or you guys think I could get away with simply modifying RFPOS variables? I know if I do this I will loose balance calculations while I’,m doing 2 leg control if i do it my way… as far as I know.

Honestly I would love to keep balance mode while I do this.

** A note to Zenta, I’m planning on using the vr channel 6 pot to control the distance between the RF and LF or the LR and RR legs.

anywho!
** Whoops I made a mistake, I actually will only be able to control the two legs in which the femur’s are on the outside and the tibia’s are on the inside of the phoenix… that way I can have the two tibia ends touch…

On the opposite side the femur’s are on the inside of the tibia’s this side , the ends of the tibia’s are not able to touch as the femur’s touch before the tibia’s do, so its just the opposite side will work.

–Aaron