MorpHex, a sphere formed morphing hexapod

Since I have a level converter I’ll try it just to be sure.
What puzzle me is that the hserin timeout very quickly even with the 20000 (20 sec?!) timeout time.

The manual is in error (which was reported long ago and still not fixed :frowning: ) The timeout is like serin (.5 us)

Kurt

Ok, thanks for the heads up!

I just tried a level converter but that didn’t change it. I think I’ve to experiment more later…

Hi Kurt, Alan and others,

Finally, I’ve got some readings now. To make a long story short, there where some connection issues… (not my fault either :wink: ).

I’m trying to understand exactly how the hardware serial works:

  1. The serial readings get into a buffer. Like in this case when the IMU sends data continiously, and every serial stream is ended with a eol I think. Does the buffer get erased after a new serial stream from the IMU?
  2. hserin simply read the buffer, and clear it afterward?

The code that sends the data from the Arduino(IMU) send the data in this format: “!ANG:roll,pitch”:

[code]void printdata(void)
{
Serial.print("!");

  #if PRINT_EULER == 1
  Serial.print("ANG:");
  Serial.print(ToDeg(roll),0);//No decimal needed
  Serial.print(",");
  Serial.print(ToDeg(pitch),0);
  #endif

  Serial.println();    

}
[/code]
I assume the println(); returns a eol,(13)?
The Roll and Pitch vaule can be both positive and negative with a (-), so the length varies from 1 - 4 char (ex: 1 or -170). So the total length of the “package” is variable. I’m wondering if the values should be sent in a better way, maybe with a info about the length of pack? Or in another format like: “R:roll,P:pitch”.

Currently I’m using this code to read the buffer:

hserin 2,TimeOut,200000, [str RXstring\14]

Then I’m sending it to a terminal using hserout in same format just for testing:

!ANG:-26,-36 NG:-15,-39 !ANG:-13,-36 !ANG:-11,-32 !ANG:-10,-26 !ANG:-10,-21 !ANG:-12,-16 !AANG:-14,25 !ANG:-15,29 !ANG:-15,33 !ANG:-16,36 !ANG:-18,40 !ANG:-21,43 !ANG:-2-62,59
As you can see there are some strange results now and then. It isn’t caused by the IMU, because when I connect the IMU directly to a terminal the result are perfect.

I’m just wondering if some of you has any suggestion of how to make the result more accurate, I’m also thinking of how to actually get the Roll, Pitch values into a variable (in the BAP code) in a smart way?

Hi Zenta,
I will try to answer.

HSerial, both input and output go into their own 64 byte (if I remember correctly may be 32) circular queue/buffer (en.wikipedia.org/wiki/Circular_buffer). When a new byte comes in from the device an interrupt is generated and the interrupt code adds a byte into the queue. I don’t remember what they do if you overrun the buffer, typically either you replace the oldest character or you throw the new one away…

HSerout works the same way, that is when you output stuff, it is added to the queue and a hardware interrupt is setup, when the hardware is ready to send the next byte, it generates an interrupt, the interrupt code grabs the next byte in the queue and places it into the appropriate hardware register. If no more bytes to send it clears out the interrupt. If you try to send more characters than the buffer can hold, I believe this version will simply wait until there is room in the queue before continuing.

  1. Read does not clear it only grabs the number of bytes requested. If you wish to clear the buffer or the like you can use the hserstat command (which appears to not be in the current manual still :frowning: The command also allowed to clear buffers, ask if anything is in a buffer… You can also use HSERINNEXT to see if any characters are ready to be read. I use this in my phoenix extras to quickly see if there is any input from the USB…
    1A) If the IMU sends data quicker than you receive it, something will be lost.
  2. Answered in 1)

Assuming that your code is always reading the same thing, you might try:
hserin 2… [WAIT("!ANG:"), sdec sRoll, sDec sPitch]

Note: I have never tried the wait.

Your results look like you had data overruns. I had issues with the early XBEE Hserial code when I just had the transmitter sending continuous data, which is why I added hand shaking. If you are in control of what the IMU sends you can easily do the same. Also you could change the IMU to send the data in binary format and get away from worry about variable sizes. We can discuss options about this if you like.

For Handshaking, you have several options:
a) Use the RTS/CTS lines of the IMU - Like I do on the XBEE, to tell it I don’t want anything now. Helps with interrupts when you are trying to output things with serout…
b) They may already have a command, to say give me one now… Which you can use instead of continuous

Kurt

On AtomPro processors the buffers are 128bytes. Of you receive more than 128bytes without reading any out of the buffer you will over write the oldest bytes(eg circular queue style). When sending data if you send more than 128 bytes at a time the hserout command will wait until there is room in the buffer, other wise it just dumps the data in the buffer and lets the interrupt handler send the data as fast as it can.

Note that the WAIT modifier will wait indefinitely as long as some data is being received so a timeout doesn’t happen. Timeouts are lower level than modifiers so if any data is being received the timeouts will be reset and never timeout even if the data doesn’t match what the wait modifier is looking for.

Thanks for your very useful input Kurt and Nathan! :smiley:

Kurt, your suggestion about using the WAIT modifier worked just perfect!

main: hserin 2,TimeOut,200000,[WAIT("!ANG:"), sdec sRoll, sDec sPitch] pause 1 hserout 1,"Roll:", sdec sRoll, " Pitch:", sdec sPitch,13] pause 50 ;pause simulate phoenix code in process goto main
I did thought about testing the WAIT before but I had the impression the it would be a waste of time to use that modifier.
But after testing it the result seemed to work pretty fast.

This made me think: Does the WAIT modifier work differently for hserin than it does for serin? Or how exactly does the WAIT modifier work within the hserin? I imagine that the hserin simply read the buffer until it find the first match, correct? That should be a much faster process. So when using the WAIT within the serin the whole program halt until we have received the correct data.

I did just a very quick test with another program for comparing these two cases. The test was very simple, I measured how many lines I got in the terminal window using HSERIN with WAIT and the SERIN with WAIT within a time of 15 sec.
The result was pretty clear. With HSERIN/WAIT I got 279 lines and the SERIN/WAIT gave only 144 lines.

My next step is to connect the IMU to UART 1 on my ARC-32 based phoenix. To bad I can’t use terminal for debugging anymore. Maybe I’ve to hook up a LCD. Also, when using the UART 1 I need to set the jumpers on JP5 for every software uploads. I wish I had one more UART…

Oh, a last thing… I’m only using the RX on UART 1. Do we need both RX and TX to FTDI if we only want to send (TX) info to the terminal?

:laughing:

I just had to test it. And it worked fine!
Now I simply need a switch with C,NO,NC to select between FTDI and the IMU. :smiley:
For precaution I think its a smart thing to always turn of the power while doing that switch. Or is it?

Great to see the development of the morphex returning. although you are treading in areas im not sure i understand, its cool and interesting to see things are moving forward.

must get myself an ARC32.

anyway look forward to see it.
great work. :wink:

Hi,

Thanks Jonny, but not every thing is moving forward…
Well, the thing is that I’ve made a hard decision. I’m not ending the project, but there are some issues that has bothered me for a while.

Its just to heavy. At the end the total weight will be around 5 kg! :open_mouth: :blush: :imp:
… sigh … :unamused:
And that’s just to much for even the 5990’s and especially the 5645’s in sphere mode. It would probably walk ok like a hexapod though.
Another thing is the wires, a total of 36 (x3) servo wires gets a bit to crowded in the center of the body. For a project like this the RX-64/106 would work much better due to the elegant wire solution.

My decision is that I’m going to remove the upper set of legs (12 servos) and use all 12 5990’s for the femur and tibia’s on the lower set of legs. This mean that the upper part of MorpHex will be a solid half-sphere. I’ll also place both battery and electronics within the upper half-sphere. I’m also thinking of some fun stuff, like using one servo to lift and lower the upper half-sphere, that combined with the expanding body can be pretty cool. I hope.

It’s always sad when a project doesn’t come out like planned. I think this step is more realistic.

So, now I’ve to start tearing it apart again…

EDIT: I think I’ll still try to use the 5645’s on the tibia’s. That would also save me for some time. And I’ll have 6x5990 and 6x5645’s for another project…

Hey Zenta,

You always amaze me with your creations, however they end up turning out. It’s very interesting just watching your development process on everything! Keep on creating! :smiley:

8-Dale

Thanks Dale!

Since my last post I have rebuilt all legs and some of the wire work are done.
At the moment it only consist of 19 servos, like a normal hexapod + the inner body servo. As soon as I’ve mounted the electronics and done some work on the code I’ll do some testings.

I’ve got a cool idea of how to design the upper sphere section. If the testings go well I’ll start on that part.

I’ll keep you updated.

Hi, Zenta,

Sorry to hear that you had to change your design parameters for MorpHex. :frowning: BUT, in reaching for that star, you probably streched more envelopes in more directions than most of the rest of us will ever do :slight_smile: AND you still wind up with a very cool project that is completely viable in its modified form. :smiley:

Think of it this way: You didn’t fail. Your design concept was fine. The available technology in batteries, servos, weights and strengths of materials failed you. Leonardo da Vinci had a similar problem with his helicopter. :laughing:

Besides, you have affected the way the rest of us think in unexpected ways. I am an avid G-scale garden railroader. I have some animated amusement park rides (e.g. Ferris wheel, carousel). Your planetary gear central body and expanding leg mount design looks like the perfect basis for a whirling, Tilt-A-Wheel ride with teacups at the coxa mounts. So I plan to steal from you in about two months when I’m 72 and too old to move tons of earth and cement as I’m doing now. :laughing:

Between you and some of Innerbreed’s animatronix ideas, my train club will begin to think me strange. :smiling_imp: :stuck_out_tongue:

Thank you for sharing your wonderful ideas so often and in such detail.

Hi RoboTed,

Thanks for your nice comment about this project. Highly appreciated! :smiley:
Every time you get an idea of how a construction should work it happens to work perfect in your head. Especially late at night when I can’t sleep because I get this “brilliant” idea, next day when I’m sitting in my workshop the idea often fall to a failure due to other factors you didn’t thought of… :laughing:

Everything would be so much easier if we simply could adjust the force of gravity, so far that’s only possible in CG…

Feel free to “steal” any ideas, its good to know that some people find it interesting. :wink:

yes i know exactly what you mean. although i have a different way of doing it. if an idea comes to my head and im not at my desk, i usually sketch things down. the lads at work think im crazy as some of the things iv drawn make no sense to them. anyway, if i get an idea at night and i sketch it down. by the morning it makes no sense to me either. need a think bank to put all the ideas into there and then. :confused:

i used to say “Function over Form”. meaning the first initial idea you get might look great but my not function as intended. some changes need to be made in order get it to function properly. this might effect the form “look” of the idea.
Hence “Function over Form”.

or that’s my excuse when i make something that doesn’t look good. lol :wink:

Don’t you mean form over function?

Alan KM6VV

no, because in this case its the Functionality of the design, over takes the Form of the design.
Meaning in order to get it to Function properly, the look has had to take a step back slightly.

Hi,

Sorry for not updating this thread to often but I’ve done a lot of work on this project lately. Yesterday evening I managed to calibrate it and MorpHex walked for the first time. There are still a lot of work left on the code side though.

For those of you who are using the ARC-32 board I’ve some useful info about controlling different servos. I’ll provably update this thread too.

Shortly explained, different servos has different resolution or steps/deg.
In the Phoenix code I’m using different values for a standard 5645, 5990 and a 5645 programmed to full range. They all are different to the standard 200 steps per deg that are used for analog servos like the 645’s. Here are the constants I’m using:

StepsPerDegree645 con 200 StepsPerDegree5645 con 191 StepsPerDegree5645FR con 134 ;5645 at full range (FR) 180 deg. StepsPerDegree5990 con 181

At first I didn’t pay much attention to this part and the steps per degree was set to default 200, I then noticed that the 5990’s didn’t match at all when I started calibrating. I’m using some very large offset values for the 5990’s too and when I started checking the number I notice a very large aberration between the offset value and the actual angle.

Since all sections use the same sort of servo its rather easy to use the correct steps/deg constant in the servodriver:

[code]UpdateServoDriver:
;Update Right Legs
; BUGBUG : should we convert the offsets to their own table that has been pre multiplied?..
for LegIndex = 0 to 2
aswCoxaServo(LegIndex) = (-CoxaAngle1(LegIndex) * StepsPerDegree5645 ) / 10 + aServoOffsets(cCoxaPin(LegIndex)) ; Convert angle to HServo value
aswFemurServo(LegIndex) = (-FemurAngle1(LegIndex) * StepsPerDegree5990 ) / 10 + aServoOffsets(cFemurPin(LegIndex))
aswTibiaServo(LegIndex) = (-TibiaAngle1(LegIndex) * StepsPerDegree5645 ) / 10 + aServoOffsets(cTibiaPin(LegIndex))
next

;Update Left Legs
for LegIndex = 3 to 5
aswCoxaServo(LegIndex) = (CoxaAngle1(LegIndex) * StepsPerDegree5645 ) / 10 + aServoOffsets(cCoxaPin(LegIndex))
aswFemurServo(LegIndex) = (FemurAngle1(LegIndex) * StepsPerDegree5990 ) / 10 + aServoOffsets(cFemurPin(LegIndex))
aswTibiaServo(LegIndex) = (TibiaAngle1(LegIndex) * StepsPerDegree5645 ) / 10 + aServoOffsets(cTibiaPin(LegIndex))
next
aswInnerBodyServo = (GearAngle1 * StepsPerDegree5645FR ) / 10 + aServoOffsets(cInnerBodyServoPin) ;Morphex, assume GearAngle1 = 0 when its actually is 1800 deg
;
PrevSSCTime = SSCTime
return[/code]

I’ll keep you posted when i’ve done some more progress. :wink:

Hi,

Just wanted to inform you that I’ve implemented all the math and coding that is needed for doing body “morphing”. Its pretty awesome to watch the body expand or reduce in diameter. The body can adjust the diameter under any condition; standing, translating, rotating or walking.

Whenever I get time for it I’ll post a video or pics and more details on the math.

Awesome!