ACos Table

Hi

In the Basic program created by the PowerPod software, what is the ;ACos table for? What does it do?

Nice moniker!

The Seawolf is an old WWII submarine. I’m partial to submarines, having been on one for about 5 years.

The ACos table provides the values the Arc Cosine would provide; a function that may not be provided in Atom Basic. It is also a much faster way then calculating with say, a Taylor series.

Alan KM6VV

boomer or fa?
:smiley:

(OT since OP question has been answered)

Hi Eddie,

Boomer! SSBN622 blue crew.

Alan KM6VV

Thanks :wink: Took it from an old ROV project I worked on couple of years ago.

Ok, so from what I understand it is a substitute for the standard arccos() function? But what does it do? Which calculations is it involved in?

I’m a total newbie to this and I’m trying to go through the generated code and understand it.

The ACOS function is not supported by Atom Basic, so the author supplied a look-up table.

In calculating the IK (Inverse Kinematics), or “desired movements” of the legs, simple trig is needed to solve triangles. the triangles are used to find the angles of the legs needed to move robots foot the required distance.

Alan KM6VV

Ok i think i understand. But in which part of the code are these calculations done? I have read about the SSC-32 card an how it controls the servos using commands like "#5 P1600 T1000 " to move a servo to a certain position. In the Basic code which I’m looking at there are similar instructions. (I’m looking at the code created for autonomous control)

serout SSC32,I8N1_38400,"#",MRHH,MRHH2,"P1800#",MRHV,MRHV2,"P1700#",MRK,MRK2,"P1700#",|MLHH,MLHH2,"P1200#",MLHV,MLHV2,"P1300#",MLK,MLK2,"P1300T288",13]

I assume this is just the way of writing the same type of instructions before sending it down to the SSC-32 card. But if this is the case, where does IK calculations come into the picture? Isn’t this just telleing the different servos in which angle they should move to?

Try searching your .BAS file for ACOS. You’ll find the table, and then something like this:

DCoord = SQR(XSpeed * XSpeed + YSpeed * YSpeed) TmpCos = XSpeed * 127 / DCoord gosub ACos DAngle = TmpAngle

The gosub calls the ACos sub routine. the subroutine works on the TmpCos variable, and returns an angle in DAngle.

The serout you listed is how we get a block of values out to three of the servos in this case, could be ALL of them. In your example the values are canned (1800, 1700, etc). In other places, variables are sent:

serout SSC32,I8N1_38400,"#",RRHH,RRHH2,"P",DEC HipH_Pulse(0),"#",RRHV,RRHV2,"P",DEC HipV_Pulse(0), |

In this snippet of code, three “RR” (right rear) servos (Hip Horz, Hip Vert, and Knee ) servos for right rear (0) leg.

These calculations and SSC32 write commands are common to ALL of the various hexapod programs.

More comments could probably be added to the BAS programs, but perhaps it’s a limitation of a software utility.

Alan KM6VV

Thanks for taking the time to describe that to me. I think I am beginning to understand how it works.

One can either build up ones own sequence and send it directly to the SSC-32 card. Telling it which angles to move the different servos. Or one can use some of the functions in the program to tell it to rotate, walk or similar and then the program will use the IK part to calculate the output ti the SSC-32 card for it to perform these actions. (am I getting close?)

What I have not figured out yet is how to use these walking and rotate functions etc. (I guess one have to use the Steering, XSpeed, YSpeed functions etc.)

I think you’re getting it. Yes, you can either send “canned” sequences to the SSC-32 (or it can store it’s own!), or you can generate them “on the fly” with IK calculations.

Yes, you input the motion you want into the Steering, XSpeed, YSpeed parameters, and then let the IK calculate the leg moves for you.

Alan KM6VV

Ok :slight_smile: Is there any tutorial or forum post or similar that explains how to use these parameters in the autonomous code? I have no idea how start using them.

And another thing…what is the difference between a sequence and a gait?

(Sorry for asking many trivial questions :stuck_out_tongue: )

Not much has been written about using the parameters in the autonomous mode. What I suggest is plugging in values that you might receive from the joystick. I recall that the program mentions the ranges for the parameters. Force a value, and see what happens! XSpeed will move you forward, YSpeed will move you sideways. If you have the PS2, you could “capture” the values that correspond to various joystick moves.

You might want to run in PS2 or COM mode for a while. There is a “PS2 simulator” program under the powerpod directory (on your computer) that will simulate a PS2. Use the debug command to echo out the three parameter values in response to PS2 commands (white rat).

Gait is the set of leg moves that cause motion. Sequence in this usage refers to a “canned” set of servo moves that also move the leg (or jaws, etc.).

We “generate” a gait, we “store” sequences.

Alan KM6VV

Thanks for all your help Alan. I’ll try to experiment a little taking basis in the PS2 code and see where it gets me.

I am also trying to strip away some of the unnecessary code from the generated autonomous code to make it a little simpler and easy to follow. Everthing that has to do with the Deck and LittleGrip as i don’t have that on my robot. I think I have taken away the most of it but I’m a little unceirtan about this part.

[code]; 360° Deck Code
;Deck_Pulse = ((Deck_PulseMax - Deck_PulseMin) * DAngle) / 255 + Deck_PulseMin

	Steps = Steps + 1
	if Steps > NbSteps then
		Steps = 1
		FlipFlap = FlipFlap ^ 1
		NbSteps = GaitSpeed
	endif

	if LockLegs then
		if LeftStickMode > 0 then ;Body roll and pitch
			if (leftStickMode & 1) then
				Roll = Roll + (Steering - Roll) / StepFlag
				Steering = 0
			else
				Roll = 0
			endif

			if (leftStickMode & 2) then
				Pitch = Pitch + (Height - Pitch) / StepFlag
				Height = 0
			else
				Pitch = 0
			endif

			HeightShift(0) = Roll/10
			HeightShift(2) = HeightShift(0)
			HeightShift(3) = -HeightShift(0)
			HeightShift(5) = HeightShift(3)

			HeightShift(0) = ((HeightShift(0) + Pitch) max HeightLimit) min -HeightLimit
			HeightShift(3) = -HeightShift(0)
			HeightShift(2) = ((HeightShift(2) - Pitch) max HeightLimit) min -HeightLimit
			HeightShift(5) = -HeightShift(2)

			HeightShift(1) = HeightShift(0) + HeightShift(2)
			HeightShift(4) = HeightShift(3) + HeightShift(5)
		endif
		LittleGripOCPulse = ((LittleGripOCPulse + (Buttons2.bit3 * 50) - (Buttons2.bit2 * 50)) |
			min LGripOC_PulseMin) max LGripOC_PulseMax
		LittleGripLRPulse = ((LittleGripLRPulse + (Buttons2.bit1 * 50) - (Buttons2.bit0 * 50)) |
			min LGripLR_PulseMin) max LGripLR_PulseMax
		GaitSpeedTmp = StepFlag + 2
	else
		StepFlag = NbSteps - Steps + 1
	endif[/code]

Is this all this anly related to the Deck and LittleGrip or is some of it necessary for normal operations?

You can remove the LittleGrip code.

I’ve commented out a few more LittleGrip lines above. there will be more code later where the LittleGripLRPulse value is output to the SSC-32

"#",LGripOC,LGripOC2,"P",DEC LittleGripOCPulse,"#",LGripLR,LGripLR2,"P",DEC LittleGripLRPulse,"T200",13]

Don’t forget the associated variables declared at the start of the program.

Alan KM6VV

So what does the rest of the code do? I have been able to identify everything else in the genereated code for autonomous control exept for this part. I thought it was just related to LittleGrip and Deck.

[code]; 360° Deck Code
;remove ;Deck_Pulse = ((Deck_PulseMax - Deck_PulseMin) * DAngle) / 255 + Deck_PulseMin

  Steps = Steps + 1 
  if Steps > NbSteps then 
     Steps = 1 
     FlipFlap = FlipFlap ^ 1 
     NbSteps = GaitSpeed 
  endif 

  if LockLegs then 
     if LeftStickMode > 0 then ;Body roll and pitch 
        if (leftStickMode & 1) then 
           Roll = Roll + (Steering - Roll) / StepFlag 
           Steering = 0 
        else 
           Roll = 0 
        endif 

        if (leftStickMode & 2) then 
           Pitch = Pitch + (Height - Pitch) / StepFlag 
           Height = 0 
        else 
           Pitch = 0 
        endif 

        HeightShift(0) = Roll/10 
        HeightShift(2) = HeightShift(0) 
        HeightShift(3) = -HeightShift(0) 
        HeightShift(5) = HeightShift(3) 

        HeightShift(0) = ((HeightShift(0) + Pitch) max HeightLimit) min -HeightLimit 
        HeightShift(3) = -HeightShift(0) 
        HeightShift(2) = ((HeightShift(2) - Pitch) max HeightLimit) min -HeightLimit 
        HeightShift(5) = -HeightShift(2) 

        HeightShift(1) = HeightShift(0) + HeightShift(2) 
        HeightShift(4) = HeightShift(3) + HeightShift(5) 
     endif 

; LittleGripOCPulse = ((LittleGripOCPulse + (Buttons2.bit3 * 50) - (Buttons2.bit2 * 50)) |
; min LGripOC_PulseMin) max LGripOC_PulseMax
; LittleGripLRPulse = ((LittleGripLRPulse + (Buttons2.bit1 * 50) - (Buttons2.bit0 * 50)) |
; min LGripLR_PulseMin) max LGripLR_PulseMax

     GaitSpeedTmp = StepFlag + 2 
  else 
     StepFlag = NbSteps - Steps + 1 
  endif[/code]

If you think about the pan servos limitation of 180° of rotation and the robots round body can be pointed to walk in a 360° range.

The pan servo normally points in the direction of the walking for the front half of the round robot. Then it points the opposite direction when walking in the rear half of the bots range. This allows a sensor to be mounted on the front and back of the pan servo, and will alway be facing the direction it’s walking.

I believe the 360 part is if the pan servo was set up with a 1:2 gear increase it would have 360° range. This code allows the servo to rotate 180° (360° at the gear) for the full range of walking direction of the robot.

Oh man where’s the Tylenol… :open_mouth: