InitPos bug?

Hi,
I have a problem with the generated program from PowerPod for my hexapod.

The problem occurs when I have one of these programs (i.e. for serial control or autonomus) on my BotBoardII. When the hexapod is turned on from off position it forces the legs in a HV postion less than 900 during the initializaition sequnce below.

InitPos serout SSC32,I8N1_38400,"#",RRHV,RRHV2,"P2100#",RRK,RRK2,"P1800#",MRHV,MRHV2,"P2100#",MRK,MRK2,"P1800#", | FRHV,FRHV2,"P2100#",FRK,FRK2,"P1800#",RLHV,RLHV2,"P900#",RLK,RLK2,"P1200#",MLHV,MLHV2,"P900#", | MLK,MLK2,"P1200#",FLHV,FLHV2,"P900#",FLK,FLK2,"P1200T1152",13]

The **HV,**HV2,“P900#” commands, which normaly runs fine, forces my servos to go below minimum position. This does not happend when the Hexapod is already on and I reprogram it.

Is there a solution for this?
can I just set the HV to 950 or will this ruin some init calculations?
Could it help to set the H3Init to ButtonA to be sure nothing is happening before i press the button, or does this screw up the Initiation?

I also have a question about the code:

if Initialized = 0 then Shunt

it does not seem to be doing anything, the program will go to Shunt even if Initialized = 1. Should it be a normal if, like this:

if Initialized = 0 then

Need some clarification here. What version of the SSC-32 do you have? I think there may have been an earlier version that would send servos to a limit if a group move (T or S modifier) was issued to a channel that was not previously enabled. Because the servo controller didn’t have a position stored for the servo it used the lower limit of 500. This has been fixed in later versions. Now if you send a group move to a servo that was not previously enabled it ignors the T or S modifier.

Also does it do this with the PS2 version loaded? I have not used these other version myself, but also have heard no other reports of this sort of problem. We normally have the Bot Board and SSC-32 on the same power switch. Do you have it connected differently than our tutorials illustrate?

The SSC-32 is version 2.
it sounds correct that the lower limit might be 500, how can i fix this?
I just tested the PS2 version, the same happens.
how dangerous is this for my servos?
The botboard II and the SSC-32 is on the same power switch.
I wil try to upload some pictures tonight of the connection.
PS2 is connected from 12-15 on BB and connection between SSC-32 and BB is on BB pin 8. It should all be connected as the tutorials.

This is not good for servos. But if a gear does not break it should survive. I have used this program personally and I have never seen the behavour you are describing.

Do you happen to have initial pulse position enabled in the SSC-32 registers section? If so disable it and see if things don’t improve.

Is it the calibration offset you mean? This is the calibration offset values from our last calibration.

;-------------Init SSC-32 with pulse offsets serout SSC32,I8N1_38400,"#", | RRHH,RRHH2,"po-100 #",RRHV,RRHV2,"po0 #",RRK,RRK2,"po3 #", | MRHH,MRHH2,"po-36 #",MRHV,MRHV2,"po0 #",MRK,MRK2,"po-43 #", | FRHH,FRHH2,"po-64 #",FRHV,FRHV2,"po-47 #",FRK,FRK2,"po5 #", | RLHH,RLHH2,"po-100 #",RLHV,RLHV2,"po-14 #",RLK,RLK2,"po45 #", | MLHH,MLHH2,"po-45 #",MLHV,MLHV2,"po-47 #",MLK,MLK2,"po-52 #", | FLHH,FLHH2,"po-53 #",FLHV,FLHV2,"po-9 #",FLK,FLK2,"po-57",13]

Some places we had to ajust quite alot…

Another thing. What exactly is the purpose of the H3Init? Is it to get a “startingpoint” for the following IK calculations?

Ok, first off there is no need to change anything in the PowerPod created program. Period. Hundreds of people have successfully built that robot using the provided instructions and the programs created by PowerPod with no modification whatsoever. It’s not that I don’t want to help you understand how the program works, it’s just that that’s not the problem.

I was asking you if you have made any changes to the registers in the SSC-32. This is done by using LynxTerm and clicking on Reg. If you have not done this then great. I just need to know…

I would recommend you go back to the tutorials and compare what they instruct you to do, and see if you missed something, or you can see any other type of problem. Take care to see if you changed anything as far as wiring goes. Observe the jumpers as well.

I can usually get an idea of what is going on pretty quickly. I’m still not 100% sure what your problem is. Can you try to describe it in more detail. Perhaps explain it in a way that would allow us to reproduce the problem here.

I have not used the LynxTerm program at all.
I have gone through the tutorials again and cannot find anything wrong
The PowerPod program was used to calibrate and create a autonomous, PS2 and a serial program.

The only difference I can see is on the powering. I used the middle power input instead of the lower(ref. SSC-32 picture). according to documentation this is no problem when the VS=VL and VS1=VS2 pins are installed. The red wire on SSC-32 which goes from the (-) is correct because I have used two 9V connectors againts each other for a easy disconnection of the wires without any tools (can upload a picture of this if it is confusing).

hexproj.blogspot.com/

(PIC1:SSC-32)

(PIC2:BBII)

Whats working as it should:
-gosub all1500 lines all the legs up with Hip Horizontal (HH) straight out from the body and a 90degree angle between HV and Kne(K)
-HV 2100 lifts the legs up to the 2100 position (->e.g. RR, FR, ML…)
-**HV 900 sets the legs down to 900 position
-**K and **HH also works perfectly

The problem:
-If the Hip Vertical (HV) legs is not in the most down position (equal to less than 900) when I power on the hexapod and it initiats the H3init sequence, it looks and sounds like it’s trying to get to the HV500 with the right side which you mentioned earlier.

-Another problem is that the walking sequnce from XSpeed and YSpeed has one leg or more moving in the opposite direction.
-the right side is not lifting its legs above 1500 pos but goes down toaprox. 900
-the right side does not go below 1500 but up to aprox. 2000
-right side leg seems abit of
-at XSpeed the MidRight (MR) leg is going the opposite way
-at YSpeed the FR and RR is going 135 degrees opposite of the rest

Your images didn’t come through.

The problems you are describing are because you probably built all the legs exactly the same, I.e. not three left and three right legs. :wink:

Edit: removed unnecessary questions…

Ok I see you added a link.

I may have confused the SSC-32 with the Bot Board in your comments.

Can you post some images of the entire robot? I think your only problem is having built all the same legs.

The first picture is of the top view the second is rear view.
Is there a size limit to the pictures i can add here?
I have now added the pictures to the blog.
hexproj.blogspot.com/

I got the hexapod used already built so I have just assumed that it was correct. I could not see that anything was wrong from the calibration.
It would be awsome if this is was the mistake :stuck_out_tongue:

Yep, that’s the problem. It was built with all left legs. The vertical servos need to all face forward. On your robot only the left legs have the vertical servos pointing forward.

See, no code changes, just mechanical ones. :smiley:

With a little wrenching you will have that baby walking in no time! 8)

So its the 3 *RHV servos that needs changing?
Not the knees and the Horizontal servos?

ALL of the vertical servos should point forward…

Look carefully at the image below. See the hardware that holds the servos into the brackets. They all face forward.

Hi, I still can not understand the purpose of some of the code, I hope you can help.

What exactly is the purpose of the H3Init?
Is it to get a calibration for the SSC-32 card to make the P2000# commands accurate?

And

The code:
if Initialized = 0 then Shunt
it does not seem to be doing anything, the program will go to Shunt even if Initialized = 1.

Thanks

i copied this from a earlier post, cannot remember where tho…

hope it helps.

  1. First of all we have the variables definition. Here we must concentrate on the fact that some variables are defined with special ranges of -127 to 127. We also must notice that the real dimensions from the Hex Legs are defined under the names of the variables HipV_HipH (distance from Horizontal shoulder Servo axis to Vertical shoulder Servo axis), FemurLength (distance from Vertical shoulder Servo axis to Knee servo axis) and TibiaLength (distance from the Knee servo axis to the end point of the leg). These real measures (you can check the distances in your Hexapods) are critical for the later transformations concerning IK.

  2. Second we can see the ARCCOS table. This table is scaled to 128 values comprising an angle of 90 degrees. We can see from the table that a cos x = 0 would mean a real angle of 90 degrees, and hence a value from the table of 64 (first position in the table or array). As the BASICATOM will process the angles like 7bits numbers, this is a good and fast approximation. On the other hand, a cos x = 1 would mean a real angle of 0 degrees and a value of 0 (in 7bits numbering for the microcontroller). We will later see that we make two real COS calculations with the BASIC ATOM.

  3. Later on the program we can see conventional initializations. I.e. we can see the offsets for the servos and also a call to the routine H3Init. This routine is particularly interesting because we are fixing the INITIAL positions for the tip ends of the legs. We are defining their real positions in the true space. We see following the assignments for each variable:
    XPos(Index) = HipV_HipH + Femur_Length
    YPos(Index) = - Tibia_Length
    ZPos(Index) = 0
    As it can be noticed, by the use of these variables we are defining the Axis Reference System in one particular point (i.e. in the axis of the Horizontal Shoulder or Hip Servo). If we place the Reference System there, we can see that the above variables are quite logical. We do this for the six legs, so we actually know the exact position (in each of the 6 individual reference systems) in the true space. There is something else to do so that everything here is right. We should call somewhere the routine All1500 so that the Hex gets to the position described by the above variables. I think this is done in the Shunt routine and (depending on the control selected for the self-generated program) on other places.

  4. Now that we have defined the initial position for the Hex and placed it into the right position, we have to face the movement. Depending on the type of control selected for our Hex, we will have increments in direction and distance which will be added to the actual legs position. These direction/distance increments can be given in different ways. I was checking the program self-generated with a PS2 controller. In this case, the angle given by the PS2 stick is calculated and later used for step calculations (or new position calculations of the leg tips). In other programs this method can vary. For the particular case of the PS2 controller, we can focus on the H3 label in the program (I omit the positions instructed to the Hex by means of the different buttons, etc… as this is out of the scope of the IK (they are direct commands to the SSC-32).

  5. From the H3 label we can see that XSpeed and YSpeed represent the coordinates of the Stick movement in the PS2 controller. From these two coordinates we use the well known Pythagoras Theorem to calculate the Hypotenuse of the triangle made. With this Hypotenuse, we can easily calculate the Tangent of the angle formed by the stick and hence, the angle which is desired for the movement of the HEX. The ARCOS table is used to calculate this angle with good approximated values (we do not need too much precision here and we improve the speed of the program by lowering the calculating time of the BASICATOM with trigonometric functions). The final angle is Dangle variable which we can think of like DistanceAngle (indicating the intended movement for the HEX). Right after this angle calculation we can see the distance of the movement (the mentioned Hypotenuse) intended by the variable DCoord. But in this case it is not used the exact distance of the hypotenuse always. We can see that the value of DCoord is limited and will only be chosen when its value is bellow that of (128 - ABS(Height) - ABS(TibiaAngle * 2)). I really do not fully understand this limitation, but I did not care to much about it as I was focused on the IK transformations.

  6. XPos2(Index) = -(DCoord * COS(DAngle + (Index * 43 + 21)) / 300) ; 43 => 60 degrees
    ZPos2(Index) = -(DCoord * SIN(DAngle + (Index * 43 + 21)) / 300) ; 43 => 60 degrees

Here is where we are starting to calculate the NEW positions for the 6 legs’ endpoints. This is denoted by the name of the variables (XPos2 and ZPos2). We may ask why the YPos2 is not calculated. In my opinion, YPos2 will be either UP or DOWN at fixed variables depending on the status of the leg (i.e. depending if the tripod belonging to that leg is UP or DOWN). Therefore, no new position calculation is needed here. The only variables affecting the new position are X and Z as the plane that they form is the one in which the movement (angle and distance) for the HEX is considered. Lets think about these two variables as the END position in this plane for each leg tip. Concerning the above mentioned variables, we can see the REAL Cos and Sin calculations in the program. The DCoord (Distance) is projected over each axis (X and Z) to calculate the new positions. The angle used is DAngle (calculated and explained before) + the index of this leg *43 (60 degrees) + 21. Ok, this is to be clarified. When we have the new positions calculated for each leg, we have to keep the axis reference system for each leg in the same direction (orientation), or otherwise opposite legs would move in a completely opposite pattern. Therefore we have to account for the 60 degrees of difference between each leg (round HEX) by means of the 43 value (7bits), but we are adding an additional angle of 30 degrees (21) which I do not fully understand. Finally we can see that the positions are scaled by dividing the result by 300 (this must be only to keep the movements controlled in a particular range, it can be studied by changing the figure and see what happens on real movements).

After all this, the program forwards us to the routines AorBDown and AorBUp. In these two routines we can see the calculations for the exact end positions of the leg tips in our HEX. Each routine takes care of a different (alternate) tripod. The calculations made there are just based on the addition of the intermediate values XPos2 and ZPos2 to the previous XPos and ZPos, accounting also for the YPos of the leg depending on the tripod (this can bee seen easily by tracking the variables LegupShift, Freeze and HeightShift.

  1. Now we have real positions for our legs (XPos, YPos, ZPos). We cannot move the legs to these new positions if we have not calculated previously the HipHorizontal Angle, HipVertical Angle and the Knee Angle. This is done after the label in the program: Distance and HipH_Angle with XZ. The calculations are easy. First of all the distance in the plane XZ is calculated by the hypotenuse of the triangle formed by the XPos and ZPos coordinates. From this information, we can calculate the HipHorizontal Angle. After the angle calculation, notice that the Distance value is corrected with the TibiaAngle variable for special 3DOF-C legs. The only meaning I find to the variable TibiaAngle is that it means the small increment in the X direction from its top left side to its bottom right side when placed vertically due to the curvature of the leg. This would be meaningful in my opinion at the time of making this correction.

  2. Following in the program we find the label Set Angle. After this label we can find the pending angle calculations. The first angle to be calculated is the HipVertical one. To calculate this angle we have to take two thinks into consideration. First is that we have to calculate the angle upon the basis that we have to make a triangle between the HipVertical Servo axis and the leg tip together with the FemurLength and TibiaLength. We can follow these steps:

a. Take the Distance (on plane XZ) and take out the HipH_HipV distance. There we have our new triangle whose hypotenuse is just the distance between the HipVertical Servo axis and the leg end tip. This hypotenuse is called in the program TmpSEW.
b. With the above information, we can use the Cosines Law (c2=a2+b2-2abcos(x)) to calculate the Knee Angle of the leg. We are calculating in the program cos(x) from the above mentioned equation. We call the ARCOS routine to calculate the Knee Angle.
c. Following we need to calculate the HipVertical angle. To calculate it, we have to calculate first the angle formed by the triangle described before on the cosines law. This is the TmpAngle. After this step, we calculated the other part of the angle by using the cosines law with the triangle formed by TmpSEW, TibiaLength and FemurLength. We have to add this last angle to TmpAngle to have the final HipVertical angle.

  1. Finally, we know the Three necessary angles for each leg and we only need to calculate the pulses to be sent to the servos. With these pulses we go to the last part of the program where the appropriate commands are sent to the SSC-32.

I hope this information is useful?

Yes, I think it helps for my the first question, the H3init has no effect on the commands that does not use inverse kinematics. If you wished to make a smal program with only direct commands like this:

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

You would not need the H3init, the acos or any of the kinematics code.

Correct?

but why use “then shunt”, when the next step is shunt anyway?

i beleive that is correct.

just a simple command line like the one here will work. using the If, Endif, and dualshock commands work well with instant move commands.

sorry if i have missed it or over looked it but, what is your projects intentions?


I just want to know the possibilities and to understand the code that I use completly.

The “if Initialized = 0 then Shunt” looks like it has no function and it is only used in the serial code. It is also located right in front of Shunt. Can the purpose be to call it up like a gosub and currently only there for demonstration?

i havent looked at the code you are refering too nor do i know what the “shunt” routine is…so you can PM me with it in full so i can look at it… but

if Initialized = 0 then Shunt looks to be calling up the “initialize” & “Shunt” sub-routines.