Shop OBEX P1 Docs P2 Docs Learn Events
Biped - work in progress build thread - Page 3 — Parallax Forums

Biped - work in progress build thread

13»

Comments

  • Spiral_72Spiral_72 Posts: 791
    edited 2011-10-30 12:46
    For everyone's information, I'm working with the Prop right now, so this will likely delay progress on my biped for a bit.

    I really think this can be done with the BS2, not only that, I would like to try it because I like pushing equipment to the limit, to do things it was not intended to do. SO, with that said, I'm not giving up the BS, but this is a perfect excuse to learn the Prop, learn something new and with the Prop it'll likely be a lot simpler for the final product if I ever get to add a torso of sorts, sensors, location sensors (probably not GPS) and assorted goodies. All this junk can be packed into a single uC rather than individual basic stamps.... y'know?

    Anyways, back to the Biped; I'm getting output from my Prop to blink an LED. I'm struggling through this Spin language, but I have learned a lot in a short time. I don't think servo control will take too long especially since I have Duane's working code to hack. I DO think memory management will take some time for me to learn, and I need that to make the biped walk.

    I need a name for this bot. I'm tired of typing "biped" :D

    Edit:
    Duane, now that I understand a little more, I'm going to try to run your Spin code again. It did not work before, but there were no compiler errors....... Due to ignorance, I didn't realize I had to include OBEX stuff :)
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-11-10 05:50
    Nov1011
    Progress is slow right now. I think I know enough about the Prop and Spin to start the actual control routine. Last night I sent each servo on the leg a 1.5ms center command, positioned the joint and locked the two together.
    Over the next week, I hope to install an EEPROM, translate my Basic control and interpolate routines into Spin and use the Servo32v7 object. I'll be using my trusty 4-cell NiMH pack for servo power.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-10 07:00
    Spiral_72,

    It would be good if your EEPROM were larger than 32K. With a 64K EEPROM, the Program could reside in the lower 32K of EEPROM and you could use the upper 32K for data storage. There's also a 128K EEPROM chip that works with the Prop.

    Can your 4-cell pack output enough current for all your servos?

    Duane
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-11-10 07:54
    Yessir, I either have a 64K or 128K EEPROM (actually several) for it. I don't remember which size. But yes, that's a great idea. The data table(s) could be stored in the EEPROM for read only. I hadn't considered that honestly.

    I use the NiMH pack on my airplanes. I know it'll drive five servos (2x ailerons, 1x rudder, 1x elevator, 1x throttle, and I'm crankin' em' all!) for 20min at a time for as many times as I can fly in a day without dropping below 4.8V. I'm kinda weird about over monitoring the battery level on a plane :) It'll easily supply a 4C or 4800ma surge and melt breadboards if given the chance.

    My first servo control program did not work..... at all.... it did absolutely nothing... so I need to figure out how the debug object works. I started over on a new program anyways. I didn't like how the first try laid out.

    I'll be using my current limiting supply to power the Prop during development. The 4-cell pack will ONLY drive the servos. That reminds me to order some more 3.3Vregs. I can't get the 3.3V pieces I ordered from Parallax with the Prop to work. I know that sounds dumb especially since it's only three leads, but the suckers don't work. I'm using an LM317 for the moment, hard wired (no pot) for 3.15V.



    Sub-post:
    Nov1111
    I wrote the very first working servo routine based on Duane's servo demo code last night. While this isn't a big achievement in itself, I did learn how to talk with the Servo32v7 object first hand. With the current setup (again like Duane's code) Cog0 performs all the calculations while another cog is solely responsible for sending the control signals to the six servos. I'm not proficient in Spin yet and nearly every command is first referenced with the Prop manual, but it is coming together.

    Duane, I would be weeks behind where I am now without your working code. Thank you.

    Sub-post:
    Nov1411
    Over the weekend I installed a 256kbit EEPROM and made sure that worked. It's kinda nice to cycle power and not have the program lost. I have plenty of extra room for data now, soon as I figure out how to use it.
    I worked on data tables, got them working and wrote a simple test program. The data table was LEDTIME byte 1, 2, 3, 4, 5. The program read the data one byte at a time and burned an LED for that duration in seconds. It worked, and I'm pleased.
    I lost Debug output from the Prop while editing and rewriting Duane's code for my own use. I need to figure out why it doesn't work next, cause' I'm gonna need it!
    At the moment I have several programs written to test different aspects of the whole. I need to compile all that junk into a single program at some point too.

    Sub-post:
    Nov1511
    The Prop program took it's first steps last night..... with the servo laying free in the table. The latest code runs through the setpoints one at a time. I do not have the interpolation programmed in Spin yet, but I hope to work on this later this week.
    Debug works finally, though it's outputting byte sized decimal numbers instead of word or long. Thanks to Duane for giving me the ASCII formatting codes, the debug screen looks more organized rather than text zipping by on the screen.
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-11-16 20:01
    Nov1611 (The first REAL post in a while)

    Alright, I have code that steps the hip through each of the six positions in my gait WITH interpolation!!!. I'm proud to admit, interpolation works in forward and reverse (positive and negative offsets)

    The program below is a bit of a mess. Duane may recognize several bits in here :) I have "real" mode, then two test modes. I comment out the relevant code for whatever mode I want to run. Make sense? I didn't expect it would... anyways:

    Six positions on one DOF in slow motion so I can see what's going on. The Prop sends debug information back to the computer for me to see.

    The code for people that might want to look, then attached if anyone would care to run it. An LED "Busy" indicator should be connected to P12, while the servo runs off P0
    DAT
            fileName        byte    "Prop Walker"           ' Display name on terminal window
            motiondat       word    1500,1350, 0            ' Position data for three DOF                                   
                            word    1490,1250, 0            ' Listed as HIP joint, KNEE joint and ANKLE joint
                            word    1390,1160, 0            ' Position numbers are direct pulse width data                                         
                            word    1650,1200, 0
                            word    1740,1410, 0
                            word    1700,1470, 0
                            word    1610,1370, 0
                            word    1500,1350, 0            ' Repeat first position set for endpoint on last                                   
    CON
      _Clkmode      = xtal1 + pll16x                        ' Set uC freq
      _Xinfreq      = 5_000_000                             ' State crystal freq                                                                    
      _DebugBaud    = 9600                                  ' Serial debug baud rate                                                                                                                         
    
      CE            = 11                                    ' CE: Clear to End of line     
      HM            =  1                                    ' HM: HoMe cursor       
      _Center       = 1500                                  ' Center position for standard                                                                  
      _SERVOpin     = 0                                     ' Servo pin
      _LEDpin       = 12                                    ' LED indicator pin  
    VAR
      long frameInterval, debugStack[100]
      word SservoPosition, EservoPosition, servoinc
      byte tableptr
    OBJ
      Debug : "Simple_Serial"
      Servo : "Servo32v7"
    PUB Setup | localIndex
      dira[_LEDpin]~~                                       ' Set LEDpin to output
      frameInterval := clkfreq / 50                         ' Frame interval = 50ms
    
      cognew(DebugLoop, @debugStack)                        ' starts a cog 6 left
      waitcnt(clkfreq / 20 + cnt)                           
    
      Servo.Start                                           ' starts a cog 5 left
       waitcnt(clkfreq / 20 + cnt)
    
    Mainloop
    PUB MainLoop | nextFrameTime, iteration, frame          ' This method is being executed in cog #0.
      outa[_LEDpin]~~                                       ' Turn on LED = indicate routine started                                                                 
      repeat
        repeat tableptr from 0 to 18 step 3
    
          Sservoposition := word[@motiondat][tableptr]      ' Read servo start position from the data table
          Eservoposition := word[@motiondat][tableptr+3]    ' Read servo end position from the data table
          servoinc := (Eservoposition - Sservoposition)/8   ' Get estimated servo increment for 16 iterations
          repeat iteration from 0 to 8
    '        nextFrameTime := cnt + frameInterval           ' Calculate and save current counter + 50ms
            !outa[_LEDpin]                                  ' Toggle LED to indicate work                                                                 
            repeat frame from 1 to 50                       ' FOR TESTING: Update servo, same position 50 times for slow motion
              Servo.Set(_SERVOPin, SservoPosition)          ' Request servo update
              waitcnt(clkfreq / 50 + cnt)                   ' Wait till 50ms increment - change back to nextFrameTime after testing
            Sservoposition += servoinc                      ' Add servo increment to servo position                
    
    
    
    PUB DebugLoop                                           ' We'll use a separate loop to send debug information
      Debug.init(31, 30, _DebugBaud)
      repeat
        Debug.str(string(HM, "Position index# ",CE))
        Dec(tableptr)
        Debug.str(string(13,"Servo start position: ",CE))
        Dec(Sservoposition)
        Debug.str(string(13,"Servo end position: ",CE))
        Dec(Eservoposition)
        Debug.str(string(13,"Servo increment: ",CE))
        Dec(servoinc)
        Debug.tx(CE)
          
    PUB Dec(value) | i, x                                   ' Print a decimal number
      x := value == NEGX                                    'Check for max negative
      if value < 0                                          
        value := ||(value+x)                                'If negative, make positive; adjust for max negative
        Debug.tx("-")                                       'and output sign
      i := 1_000_000_000                                    'Initialize divisor
      repeat 10                                             'Loop for 10 digits
        if value => i                                                               
          Debug.tx(value / i + "0" + x*(i == 1))            'If non-zero digit, output digit; adjust for max negative
          value //= i                                       'and digit from value
          result~~                                          'flag non-zero found
        elseif result or i == 1                             
          Debug.tx("0")                                     'If zero digit (or only digit) output it
        i /= 10                                             'Update divisor
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-17 14:27
    Spiral_72,

    It's good to see you making progress. Come on now, the Propeller is pretty cool isn't it?

    I've been learning to program AVRs so I can reprogram SparkFun's Nordic FOB. Ug, it has been painful.

    You mentioned wanting to read and write to EEPROM. Andy Lindsay (an all around nice guy) wrote a tutorial here.

    The code he uses doesn't release the I2C lines after using the EEPROM. This caused trouble when I wanted to use another object that also use the I2C lines (a RTC or Wii Nunchuck). I posted my solution to the conflict in post #5 of the turorial thread.

    I know you're not alone in not likely scrolling debug screens. I personally like to have access to the debug history that the scrolling allows. When I find an object that outputs nice pretty stationary data fields, one of the first things I do is to change the debug output so it scrolls. I like to be able to look back to see what the various parameters were before and after a change. I agree that the scrolling debug is not as pleasant to look at as a nice fixed display.

    I hope you keep the updates coming. Thanks for taking time to document the process. (I know posting details about a project can be very time consuming.)
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-11-30 11:39
    I'm not intentionally bumping the thread, but it's been two weeks since I've posted. I haven't given up, just been working a LOT on job related stuff.

    I worked on the code some. It's untested, but it should run three servos. I've also been working on some ideas for a new more accurate interpolation routine to end closer to the endpoint without overshooting and more fluid movement.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-30 13:32
    Spiral_72,

    Have tried playing with the ramping feature of the servo object? I think it's supposed to smooth things out.

    I think the original servo program I posted could be a lot sorter if I had used the ramping feature. I purposefully didn't use it so I could show one way of using an algorithm to control the servos.

    Let the rest of us know if there's something we can do to help.

    Thanks for the update.
  • AImanAIman Posts: 531
    edited 2011-11-30 21:59
    If you can still find the thread, I had posted some sketchs of a robotic hand I was working on. It may give you some insight into how to make joints work together.
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-12-01 13:14
    AIman wrote: »
    If you can still find the thread, I had posted some sketchs of a robotic hand I was working on. It may give you some insight into how to make joints work together.

    Oh yea! I remember that now! http://forums.parallax.com/showthread.php?108957-Robotic-Hand&p=902878#post902878
    I'd really like to build one myself.... maybe one day :)

    Duane,
    I haven't played with the servo ramp feature yet, but undoubtedly I need to. I haven't cinsidered it actually. I'll look into it. I might just replace the interpolate routine I've been working on ;)
  • Spiral_72Spiral_72 Posts: 791
    edited 2011-12-28 13:08
    The latest in several weeks: I made time (forsaking several items on my to do list BTW) to get back on this.

    I worked on the program last night and this morning, powered three micro servos through the control program, them plugged in the biped. The long story short is I made a stupid mistake on my data, so I've had to go back to the seven photos and recalculate joint angles..... but I'm proud to say one leg is making walking movements!!

    One leg is dead (not connected) for the moment, but with the other leg "Walking" I can hold the torso, tilt to adjust COG at the proper times and the live leg walks just fine :smile: I'm pleased with it so far. Unfortunately tonight is the last I'll be able to play for at least a week.

    Let's see what I can get done on the other leg, and I'll post new progress asap. I have a lot more programming to think about and it's become apparent I'll need a flexible toe.

    HOORAY!
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-01 20:09
    Jan1,12
    I rewrote my calculations and interpolation routines for less variable usage and more flexibility. The cool result is (besides flexibility) variable speed and much more fluid motion. The bot will walk in sloooooooow motion now :)

    I trying to find a way to efficiently include the other leg now. I guess I could hard code it in with a separate routine, however I want to set a tag or something instead.


    Jan2, 12
    I'm amazed (though it hasn't actually WALKED yet) how smooth and fluid the program / motion is. I have a constant to adjust the interpolation divisions / steps so set to eight divisions it's extremely fast, 16 is beautiful and 32 is sooooo slooooow. Set to 32 I noticed a glitch between each set of data points, however I'm pretty sure this is due to the fact the endpoint and the start point are the same between interpolations. Does that make sense? So I need to interpolate one set of data points < the endpoint rather than = endpoint.

    I finished modifying my program to control both legs last night. I hope to test it tonight. I'm not happy with the program layout, but I can work on that when it is proven to work.

    I'm using the Servo32v7 object. One leg is controlled under Zone1, pins 0-2 while the other is Zone 2, pins 8-10..... at least that's the plan.... if Servo32v7 works like I think it does.

    I think i'll need a flexible "Toe" for each foot. I've not found another biped that uses this idea, but I only have 3 DOF. I'm hoping the flexible member will take the place of the forward tilt ankle I don't have. Spring steel material looks to be very expensive, so I hope to try a strip of credit card or maybe use the spring from a tape measure. I hate the 3 DOF biped "Shuffle walk" I see a lot on others' robots so I'm trying my best to avoid that. Neither do I have the money or brain power to control eight - twelve DOF per leg.


    I need to post some pics and video I guess. No one wants to read all this stuff.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-04 17:29
    I present the first video and one of the first powered test. The ankles are not currently connected, however you can plainly see the motions programmed so far.

    Overall I'm happy with it. Before I go much farther I'll probably move my circuit to a smaller breadboard atop the legs with my NiMh pack with the cables tied out of the way.

    http://www.youtube.com/watch?v=iAz6yz5efXw&feature=youtu.be


    EDIT: I've attached the most recent code v8 here if anyone is interested. Actually v8 includes the powered ankle. The video was taken with v6a
  • lardomlardom Posts: 1,659
    edited 2012-01-04 21:09
    Spiral_72, you should at least study the propeller. I had serious doubts when I moved from the BS2 to the prop. After trying to program the propeller I posted my first forum question and then I got up from my computer. When I returned about fifteen minutes later, Mike Green had answered my question. It blew me away because I didn't realize how active this forum is. After that I didn't worry about getting stuck. PASM is another story but Spin is fairly easy.
    Oops! I wish I could delete this post. Your video comments say you used a propeller.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-05 05:56
    lardom wrote: »
    Spiral_72, you should at least study the propeller. I had serious doubts when I moved from the BS2 to the prop. After trying to program the propeller I posted my first forum question and then I got up from my computer. When I returned about fifteen minutes later, Mike Green had answered my question. It blew me away because I didn't realize how active this forum is. After that I didn't worry about getting stuck. PASM is another story but Spin is fairly easy.
    Oops! I wish I could delete this post. Your video comments say you used a propeller.

    HA! Thank you for watching the video. Yes sir, Duane is probably the one that brought me into this Prop realm. Before this I only used the BS.. This is my very first project with the Prop! Can you believe that? You are right though, SPIN is extremely easy to pick up.

    I added the powered ankle control last night after posting the video. I need to make a mechanical change though, so maybe I can get that done this weekend,
  • lardomlardom Posts: 1,659
    edited 2012-01-05 14:11
    I would like to see how your robot developes. It looks like you've done an excellent job so far.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-09 06:56
    lardom wrote: »
    I would like to see how your robot developes. It looks like you've done an excellent job so far.

    Thank you sir. I should have imagined this would be more difficult that it looks :)

    I got to work on the legs a bit over the weekend. The ankles are now powered. It took it's first unstable step!!!!!!!!! then a second "Step" much more unstable than the first, then hit the deck with a loud report.


    So at this point, it works barely. I'm not sure if I should proceed by modifying my data points for a canned walk routine or start getting the accelerometer working for dynamic balance. Both will be necessary I suppose. I suppose a working walk routine is necessary to start with dynamic balance so I'll continue with what I have. I need to take a video and analyze it frame by frame first though.
  • lardomlardom Posts: 1,659
    edited 2012-01-09 10:29
    You will solve the 'walk' puzzle and then you'll have to find a new challenge. For my own project I am thinking about keeping a video diary. The lessons I learn might be helpful to others. The Spin code I wrote for differential steering using unipolar steppers only needs minor tweaks. Now I have to get more power to the wheels.
    I would like to know how you made your own parts.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-09 13:57
    lardom wrote: »
    .................I would like to know how you made your own parts.

    Uh, HA! No you don't :smile: I used a scaled straight edge, precision pencil compass (from grade school), exact-o, pencil and a drill press with forstner bit and drills. I scrapped a few parts making mistakes, but it didn't take that long. The results look pretty nice though for what it is. I have about 4hrs in making the parts, then another 4hrs in assembly.


    I kinda had fun with the design work though. I used SolidWorks and made a whole motion study with load analysis on certain parts. Yea that was a little over-board, especially considering I used hot glue to bond everything, but I just had fun with it.

    I hope this will be a learning platform actually. Something I can add sensors to, work out code, visual recognition, AI.... uh, maybe not the last two things.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-18 12:22
    A poor status update, but an update nonetheless:

    It took THREE consecutive steps this past weeked!!!!! (Then crashed to the table)

    I've spent as much time as I could on this. I have a strange glitch in my interpolate function I can't seem to find the fix to. I spent most of last night working with the Servo32_Ramp_v2 function of the Servo32_v7 object. A long story short, it's working now. JohnnyMac offered his servo OBEX as an alternative. I'm going to try that asap.

    After working with the ramp function in Servo32_v7 till 12:40am, I laid in bed thinking about things... I "THINK" I know what's wrong with my routine.

    Regardless, one of the three routines should work soon. I'll move my circuit to a small breadboard with my new low power, low dropout Vregs atop the legs and give it a shot again.
    I need weight up top to help transfer the COG (the control board and battery) because as it is the ankle tilts, but lifts the leg instead of tilting the pair of legs. Maybe that makes sense?
    Besides, I run out'a servos wire pretty quick when this thing takes off for a stroll.... with it tethered to a separate control board. :)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-18 13:31
    If you post your code, I'll give it a look over to see if you glitch jumps out at me.
  • lardomlardom Posts: 1,659
    edited 2012-01-18 14:23
    Spiral_72, the more I consider what you're trying to do the more I'm impressed. It's not a quadruped. It has to balance!
    Your robotic toddler will perhaps seek one day to test its skills on uneven surfaces and...stairs. (You might have to add arms or at least pillows for that)
    All that I had to learn to get two steppers to do synchronized ramping seems minor. I stayed up late with a pencil and a calculator for days but I really like the intensity.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-18 14:59
    Duane: Alright, you asked for it!
    What's happening is the program and sets the servo to ServoStart then ramps to ServoEnd updating the ServoStart variable along the way. I interpolate 64 steps between each move. The move is very nice, smooth and fluid.

    Once the servo reaches ServoEnd by falling out of the repeat loop it updates with a new ServoStart and ServoEnd for the next frame of the step... This is where the glitch occurs. I've tried interpolating to 64 minus one, and 1 to 64 instead of 0 to 64. I dunno.

    I have an idea, but maybe I should keep it quiet until I get your opinion.

    The code is a bit messy. It's been changed a hundred times. Once it works I'll clean it up.


    Lardom:
    Thank you sir.... but it ain't working yet :) It is a lot more complicated than I had originally thought!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-18 15:28
    Spiral_72,

    A couple of things jump out at me. Both could be fixed by using longs instead of words for servo positions.

    I don't think negative numbers work the way you'd expect with words (or bytes). I make it a habit of always using longs whenever a number might interact mathematically with a negative number.

    The other circumstance when I like to use longs is with bit shifting or rotating. I don't remember the exact operations I was attempting, but I found my program behaved a lot better once I switched to longs.

    So an easy suggestion to implement is to use longs for your servo variables.
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-18 19:42
    Thank you Duane. I think I understand and I'll play around with that. I'm not sure how (because I've never used it) a negative long will add and subtract but I'll try it. Depending on my routine, longs should increase resolution too I think,

    The idea I had seems to have worked, though I never saw it on the debug screen. I guess serial communications are too slow or I don't have the debug set up properly. I even took a video of the debug and went through frame by frame.

    Regardless, what seems to be happening is my interpolate over or undershoots the endpoint by a very minimal amount. Near as I can tell, 5us at the most which is nothing. Maybe backlash in the servo exaggerated the trouble I don't know. Anyhoo, I fixed it by not updating the ServoStart position from the table between frames, rather I used the ServoPos from the last frame to start the new frame. It's smoooove now :) even though it makes for even more sloppy code.

    It's walking (sort of) and not doing anything unintended now. I'm working on the motion data itself now. I might need to add one frame so I have an odd number of frames for a center/standing frame. Right now I have an even number and it's throwing the RH off by half a step. Oops, I never thought of that before.

    Attached the v12 "Fixed" code.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-18 19:53
    Another thing I've wondered about is this line.
    nextFrameTime := frameInterval + cnt
    

    This might be causing your slight error.

    I'd suggest:
    nextFrameTime += frameInterval
    

    This will keep the small errors out. The Propeller manual talks about this in the waitcnt section.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-18 20:17
    I forgot to mention. The debug loop can't keep up with each servo frame so it doesn't try. It just displays the parameters of whatever frame the servos happen to be in with each loop. It should be possible to step through the program slowly to see the output of each frame by adding a flag the debug loop clears on each loop. There are several other ways of stepping through the program. If you do step through the program, you'd want to remove the waitcnt statement so the program doesn't lock up (as it waits for a time that has already passed).
  • Spiral_72Spiral_72 Posts: 791
    edited 2012-01-19 05:50
    Duane Degn wrote: »
    Another thing I've wondered about is this line.
    nextFrameTime := frameInterval + cnt
    

    This might be causing your slight error.

    I'd suggest:
    nextFrameTime += frameInterval
    

    This will keep the small errors out. The Propeller manual talks about this in the waitcnt section.

    Oh very nice catch! You are absolutely right.

    For the debug: That's a very good idea actually. I could disconnect the servos for the test and it wouldn't matter what the refresh rate was.
Sign In or Register to comment.