Forum Update - Announcement about May 10th, 2018 update and your password.

Next large robot

1141517192023

Comments

  • Glad to see you are able to move forward again.
    Jim
  • RS_Jim wrote: »
    Glad to see you are able to move forward again.
    Jim
    It's always better when you aren't banging your head on the table trying to figure out what direction to go next to get the program to do what you want! I'm looking forward to programming right now instead of avoiding it.

  • DiverBob wrote: »
    RS_Jim wrote: »
    Glad to see you are able to move forward again.
    Jim
    It's always better when you aren't banging your head on the table trying to figure out what direction to go next to get the program to do what you want! I'm looking forward to programming right now instead of avoiding it.
    Lol

  • Completed adding the PI code to the Tibia motor and it works fine except it tends to overshoot the desired position on long moves and then has to come back to the correct position. Debug output shows that the speed was greater than expected as the error decreased resulting in the overshoot and correction. I found and removed a bug in the speed control routine which seems to have corrected the worst of it. Still need to spend some time making various sized movements and review the debug output.

    With that success under my belt I decided to tackle using just integer math to calculate the slope of the line for motor position vs ADC values. This eliminated the F32 object and saved one cog for other purposes now! With this change I can get 1/10 degree movement changes on the femur and tibia with a corresponding change to the size of the dead band zone for these motors. Data entry via the terminal for moving the Tibia to 51.6 degrees is entered as $,1,2,516. The coxa movement doesn't get much of a boost from this change as there is only a ADC value change of 5.88 between each degree of movement and the dead band zone is set to +/-3. So although I can enter a request for a 1/10 degree movement, the best the coxa can respond to is about 1/2 degree movement (sometimes!).

    I also have had an issue where some extreme femur and tibia positions can cause mechanical binding due to the leg parallelogram design. Did some measurements and realized that all I had to do was check for a minimum angle of 25 degrees in one corner of the parallelogram. The code now accepts the requested angle change, validates it doesn't exceed the min or max angle for that motor, and then subtracts the femur angle from the tibia angle. If the absolute value is less than 25 degrees the input is rejected. It performs the same check for both femur and tibia movements. This method works because the femur and tibia angle movements are both based on the same plane, the tibia moves the top side of the parallelogram and the tibia moves the side.

    Next program code routine is to create an array to hold some Excel calculated IK values for each motor and have the leg loop through the array to see how closely the leg tip follows a straight line. This test will incorporate many of the elements of the code working together simultaneously for the first time. It will be a validation for the IK calculations, the accuracy of the motor positioning, and identify any other issues that might have been hidden from only dealing with a single axis at a time for coding and testing. I started down this route last night and identified an issue with the motor done flags which are preventing motor movement. It got too late to dive too deeply into that problem, the rest of the weekend will be used for that. I have a camera set up and hope to film some of the test results, I tend only to save the results that are successful, you don't want to see some of the unsuccessful tests! The leg has unexpectedly kicked me more than once or tried to knock itself off the test stand. Desperate lunges for the motor power switch are are a regular occurrence some nights.

    Bob
  • Completed correcting bugs in the code that have shown up so far. Set up the code to run all 3 motors together at the same time and ran a array of values calculated that should have moved the leg tip in a straight line. I saw a few issues with this, most importantly the leg tip didn't move in a straight line! It runs fairly straight for the first 6 inches and then starts to curve outward and upward toward the extreme positions. I believe there is a calibration issue here, went back and tested the movements and checked the input angle against the output angle. I'm seeing some differences, will have to graph the values to see if there is some non-linearity in the movement going on here. If it is consistent then I can code around it, the graphs should help there. So, today will be a calibration checking and testing day.

    Another issue identified was that all this time I've been streaming data from leg testing back to my monitor while running the individual motors. I found that when I turn off a motor code output to the screen, I get different movement from the motor. This is because of the inherent delay the trouble shooting feedback to the monitor is putting in to the code, this testing and adding a delay that mimics the time if the troubleshooting code is running.

    I also see that the motors run a different rates so they arrive a given location at different times. I will be using a counter to figure out the time differences and then the speed control routine can be used to adjust each motor to run such that the leg tip arrives at its destination at the same time.

    I taped videos for the IK and the PID routines used. Need to do some editing and will post those shortly. Hopefully I'll get the movement issues worked out soon and can show that also.
  • Thanks for the update Bob. It has been too long since we've seen pictures or videos. :-)
    Infernal Machine
  • DiverBobDiverBob Posts: 635
    edited August 2015 Vote Up0Vote Down
    Now to figure out how to post a You Tube video in this new format... It's still uploading so don't get into it for a bit yet, I only have a slow DSL internet connection out here! Edit: had to run the video upload overnight and forgot to push the publish button this morning. Should be good to go now!

    This is a basic explanation of PID controllers and how I implemented it in the robot. I have another video like this for the Inverse Kinematics used on the robot that I will edit and post next. The writing pad I'm using I found at Costco for $20, thought it might come in handy for times like this or just jotting down some ideas. One disadvantage is that you can't erase mistakes, you can only clear the whole slate. Otherwise, it helps when I just want to write a quick note of a value or reading. I was always looking for a scrap of paper for those times.

    I was able to re-calibrate the coxa and tibia movements and that improved the accuracy of the leg movement by a lot. (Still need to calibrate the femur...) The movement isn't as smooth as I would like (too jerky) but I will work on that part this week. I need to find some code in the OBEX that will allow me to time the motor movements in msec so I can adjust the speed of each motor to match the slowest moving motor. That should help in reducing the amount of jerking. Another option is instead of waiting for each motor to actually finish its move prior to sending the next motor commands, use a timer to send move commands. The leg moves are fairly small and once the motor has moved most of the way to its destination, send the next command. That could reduce the start and stop jerkiness I'm getting. This method does require that the typical motor speed for all three motors matches fairly well otherwise they will get out of sync quickly.
  • Video setting is Private, so we can't watch it untilyou change it to public in "edit video."
    "When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

    - Pablo Picasso
  • Here is the PID code for the femur motor. This doesn't show everything (stripped out the debug and master computer feedback code) but should be enough to get a feel for the layout I'm using now. Comments are welcome if you see anything that could be done better!
    pub Main 'only showing the femur slope calc. FemurMotorRun is called by the master computer with an angle value later
      'get ADC interval per degree of movement
      'calculate ADC value using slope of line, y=mx+b where m = y1-y0/x1-x0
      'take value and mul by 100 for integer math later
      'calculate intial leg position based on ADC value
      fSlope := (((femurMaxADC-femurMinADC)*100) / (femurMaxAngle-femurMinAngle))
      femurAngle := (femurMaxAngle*10)-(((femurMaxADC - femurADC) *1000) / fSlope)
    
    pub FemurmotorRun(newangle) | moveangle
    ' input ADC value via io and the motor moves to that angle
      'skip routine if disabled
      if FemurDisable == 0
        moveangle := ||(newangle - (FemurMinAngle * 10))
        'calculate ADC value for input angle, div by 1000 to convert to correct level
        FemurTarget := (FemurMinADC) + (FSlope * moveangle)/1000
        FemurAngle := newangle
        FemurDone := 1                                                        'start update
    
    pub FemurPID | error, speed, actualADC, oldADC, endspeed
      'PID motor controller routine for Femur
      'repeat process until inside of deadband
      'monitors FemurTarget value continuously, runs in its own cog
      repeat
        error := FemurADC - FemurTarget
        'allow for calibration and keep motor stopped when inside deadzone
        if ||(error < 3) AND femurCal == 0                                          
          speed := 1500
          dc.set(0, speed, 0)                                                       'stop motor
        endspeed := 0
        inc1 := 8
        'if FemurAngle = 0 then running calibration check
        repeat while (||error => 3) AND (femurDone == 1) 
          'Femurdone is 0 during movement, 1 when stopped
          error := FemurTarget - FemurADC
          'set speed based on size of error
          if (error => 3) AND (error =< 10)
            speed := scurvePWM1[8]
          if (error => 11) AND (error =< 20)  
            speed := FemurSetSpeed1(inc1, speed, 7)
          if (error => 21) AND (error =< 30)  
            speed := FemurSetSpeed1(inc1, speed, 6)
          elseif (error => 31) AND (error =< 40)  
            speed := FemurSetSpeed1(inc1, speed, 5)
          elseif (error => 41) AND (error =< 50)
            speed := FemurSetSpeed1(inc1, speed, 4)
          elseif (error => 51) AND (error =< 60)
            speed := FemurSetSpeed1(inc1, speed, 3)
          elseif (error => 61) AND (error =< 80)
            speed := FemurSetSpeed1(inc1, speed, 2)
          elseif (error => 81) AND (error =< 100)
            speed := FemurSetSpeed1(inc1, speed, 1)
          elseif error => 100
            'provide ramp, send increment value, current speed and final speed
            speed := FemurSetSpeed1(inc1, speed, 0)
         
          if (error =< -3) AND (error => -10)
            speed := scurvePWM2[8]
          if (error =< -11) AND (error => -20)  
            speed := FemurSetSpeed2(inc1, speed, 7)
          elseif (error =< -21) AND (error => -30)
            speed := FemurSetSpeed2(inc1, speed, 6)
          elseif (error =< -31) AND (error => -40)  
            speed := FemurSetSpeed2(inc1, speed, 5)
          elseif (error =< -41) AND (error => -50)
            speed := FemurSetSpeed2(inc1, speed, 4)
          elseif (error =< -51) AND (error => -60)
            speed := FemurSetSpeed2(inc1, speed, 3)
          elseif (error =< -61) AND (error => -80)
            speed := FemurSetSpeed2(inc1, speed, 2)
          elseif (error =< -81) AND (error => -100)
            speed := FemurSetSpeed2(inc1, speed, 1)
          elseif error =< -100
            speed := FemurSetSpeed2(inc1, speed, 0)
         
          if (error =< 3) AND (error => -3)                                            'stop if in deadzone
            speed := 1500
            dc.set(0, speed, 0)                                                       'stop motor
            FemurColor := off
            femurDone := 0
            quit
    
          'set variable speed code here using the speedcmd value (10-100)
          endspeed := SetFemurSpeed(speed)
          dc.set(0, endspeed, 0)                                                         'start motor at speed
         
          ActualADC := FemurADC
          if FemurCounter == 1                                                        'check if ADC not changing
            oldADC := ActualADC                                                       'reset check ADC value
          if FemurStopError(oldADC, ActualADC)                                        'error if ADC not changing
            speed := 1500
            dc.set(0, speed, 0)
            quit
    
    pub FemurSetSpeed1(count, currentspeed, newspeed)
      'sets speed variable with a ramp function
      if currentspeed <> scurvePWM1[newspeed]
        result := scurvePWM1[count]
        inc1 := count-1 #> newspeed
      else
        result := scurvePWM1[newspeed]
       
    pub FemurSetSpeed2(count, currentspeed, newspeed)
      'sets speed variable with a ramp function
      if currentspeed <> scurvePWM2[newspeed]
        result := scurvePWM2[count]
        inc1 := count-1 #> newspeed
      else
        result := scurvePWM2[newspeed]
    
    pub SetFemurSpeed(speed)
    ' modify speed based on input value speedcmd (5-100%)
      if speed > 1500                                                               'formula differs for each motor direction
        result := 1500 + (((speed - 1500) * speedcmd) / 100)
        result := result #> 1552                                                    'set minimum speed
      elseif speed < 1500
        result := 1500 - (((1500 - speed) * speedcmd) / 100)
        result := result <# 1448
          
    pub FemurStopError(iADC, aADC)
      FemurCounter := FemurCounter + 1                                                                    'count to 5
      if FemurCounter == 1                                                                     'at start get ADC value
        iADC := aADC
      if FemurCounter == 5                                                                     'max count 5
        FemurCounter := 0
        if iADC == aADC                                                             'error, ADC not changing
          Result := true
    
    dat
    femurMinAngle word 38
    femurMaxAngle word 136
    femurMinADC word 163
    femurMaxADC word 3700
    
    'SCurve value is PWM value
    scurvePWM1 word 1000,1014,1052,1108,1176,1250,1324,1392,1448 
    scurvePWM2 word 2000,1986,1948,1892,1824,1750,1676,1608,1552
    
    
  • DiverBobDiverBob Posts: 635
    edited September 2015 Vote Up0Vote Down
    I have been working on the robot, just not much to post lately. Here is a video showing the Inverse Kinematics layout and equations used for calculating motor movements. At this time I've only used the calculations in an Excel spreadsheet and entered them into the leg programming as an array that I can have the leg step through. That has helped me to verify that the formulas are correct by having the leg make the movements. Also this is the first time I've successfully had all 3 motors moving at the same time and in a coordinated fashion.
    Initial tests had considerable jerkiness to the movements, re-calibrating made a huge difference there. Unfortunately the calibration process took longer than expected as I slowly tweaked in the movement values. Unfortunately I didn't video any of that testing but I did video many of the subsequent tests. I have to complete my testing process and then compile the video, I'll talk more about that process once I get the video up. I had to upgrade from Adobe Premiere Elements 8 to 14 last night as version 8 was crashing on my new computer. Version 14 is much better and the rendering process only took a few minutes vs hours on my old computer.



    The current round of testing has been me directly feeding data from the terminal into the leg controller. Next step is to re-introduce the master computer as the data entry point and program in the IK equations in the master. Using an array to feed discrete values (I used a 15 value array based on 1 inch movements) means that the leg can have considerable jerkiness moving from one value to the next. With IK supplying the movement values every few milliseconds the size of the movement will be reduced considerably and in theory should mean smoother movement. My concern going into this next phase is that the size of the movement means a low error and the motors will always be moving a very slow speeds. However if the motors fall behind, the error increases, there could be some equilibrium reached. That's what the testing is for!
  • Bob,
    Would love to see the video but it is not showing up.
    Jim
  • PublisonPublison Posts: 10,183
    edited September 2015 Vote Up0Vote Down
    Jim,

    Try,

    www.youtube.com/watch?v=6EG6d95aN9E#t=91

    Infernal Machine
  • RS_Jim wrote: »
    Bob,
    Would love to see the video but it is not showing up.
    Jim

    This should take you directly to my YouTube video location:
    https://www.youtube.com/results?search_query=6EG6d95aN9E
  • Posted over in the Prop 1 forum, looking for another means of setting up the master to slave prop communications loop. I want to explore other communications methods before I lock myself into a specific one. This is another area I don't have any expertise in so calling out the big guns!
  • Got some answers over on the Prop 1 forum to try out. Unfortunately I'm on some pain meds for oral surgery on Thursday for an implant so when I tried to code last night I failed open, couldn't concentrate at all. So today will be a soldering day, that is repetitious and easy enough that I should be able to work my way through that. I have several more plug-in boards to attach servo connectors to so the leg sensors can be fed up to the computer level. I would like to try out putting another leg on and running 2 legs at least manually from the master computer but that will have to wait a few days.
  • Didn't do any programming this weekend but did finish soldering the connectors for the remaining 4 I/O boards. With that completed, I mounted 2 more legs and connected everything up to the RoboPi propeller leg controller boards. Here are some photos showing some of the things completed.

    IMG_5657.JPGIMG_5658.JPGIMG_5659.JPGIMG_5660.JPG

    1st photo is the computer deck with 4 slave computers installed and the board in the middle is the master computer. All the IO wiring is coming up into the computer deck via the slots in the base of the computer deck. The 2nd photo shows 2 of the 3 installed legs attached. Photo 3 shows the IO board and power input board, there is one of these for each leg. It makes adding and removing the leg much easier given the modular design approach I took with this robot. The 4th photo shows what the interior of the main body looks like with the wiring for 3 attached legs. I need to clean it up a bit just to make the wiring a bit more manageable and easier to locate any specific wire for troubleshooting purposes.

    Sometime this week I'll reconnect the master computer and set up a half duplex communications between the master and the slave boards. I also need to run the new legs and get them calibrated. Lots to do yet!

    Bob
    1824 x 1024 - 832K
    1385 x 993 - 457K
    1374 x 893 - 346K
    1824 x 1024 - 536K
  • Bob,

    Great to see some new pictures!

    Infernal Machine
  • Looks great Bob!
    www.mikronauts.com / E-mail: mikronauts _at_ gmail _dot_ com / @Mikronauts on Twitter
    RoboPi: The most advanced Robot controller for the Raspberry Pi (Propeller based)
  • Great pics! I continue to be amazed by your diligent and persistent progress in this fantastic long-term and very complex project. I get bored with some projects before my super glue sets up!
    "When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

    - Pablo Picasso
  • Spent some time programming the new IK equations into SPIN and not getting valid answers as an output on the terminal. The L1 value come out correct but the value, L is not right and all the remaining values are identical. The L calculation is a simple floating point subtraction of L1- coxalength. That is simple but I'm missing something basic here. Hopefully someone else can see what I'm missing. Here is a copy of the code and the output that I get from the code.
    ''**********************************************
    ''*  Master Controller v3                      *
    ''*  Author: Bob Sweeney                       *
    ''*  Start with clean slate - no radio control *
    ''**********************************************
    CON
      'System Clock
      _xinfreq = 5_000_000
      _clkmode = xtal1 + pll16x
      CR            = 13
      CLS           = 16
      Degrees       = (180.0/pi)
      Radians       = (pi / 180.0)
    '[BODY DIMENSIONS]  All units are in 1/10"
      CoxaLength    = 2.6        'Length of the Coxa [in]
      FemurLength   = 6.0        'Length of the Femur [in]
      TibiaLength   = 24.6       'Lenght of the Tibia [in]
    
    OBJ
      uarts  : "pcFullDuplexSerial4FC" '1 COG for 4 serial ports
      F      : "F32_1_6.spin"
      FS     : "FloatString"
      
    Var
      long coxaAngle, tibiaAngle, femurAngle
      long L1, L, C, IKb, IKb1, IKb2
    
    PUB StartProgram            
      F.start
      uarts.Init
      'uarts.AddPort(vm_port,vm_rx,vm_tx,vm_cts,vm_rts,UARTS#DEFAULTTHRESHOLD,UARTS#NOMODE,UARTS#BAUD9600)
      uarts.AddPort(1,31,30,UARTS#PINNOTUSED,UARTS#PINNOTUSED,UARTS#DEFAULTTHRESHOLD,UARTS#NOMODE,UARTS#BAUD115200)
      uarts.Start                                           'Start the ports
      pauseMSec(500)
      uarts.tx(1, CLS)
      Main  
     
    Pub Main   
      LegIK(1.0,24.0,10.0)
    
    PUB  LegIK (IKX, IKY, IKZ)
      '[LEG INVERSE KINEMATICS] Calculates the angles of the tibia and femur for the given position of the feet
    
      L1 := f.fsqr(f.fadd(f.fmul(IKz,IKz),f.fmul(IKx,IKx)))
    
      L := f.fsub(L1, coxaLength)
    
      C := f.fsqr(f.fadd(f.fmul(IKy,IKy),f.fmul(L,L)))
    
      IKb := f.acos(f.fdiv((f.fsub((f.fadd((f.fmul(FemurLength,FemurLength)),(f.fmul(C,C)))),(f.fmul(TibiaLength,TibiaLength)))),(f.fmul((f.fmul(2.0,Femurlength)),C))))  
      
      IKb2 := f.atan2(L,IKy)
    
      IKb1 := f.acos(f.fdiv((f.fsub((f.fadd((f.fmul(tibiaLength,tibiaLength)),(f.fmul(C,C)))),(f.fmul(femurLength,femurLength)))),(f.fmul((f.fmul(2.0,tibialength)),C))))  
      
      femurAngle := f.fmul(f.fadd(IKb,IKb2), Degrees)
    
      tibiaAngle := f.fmul(f.fsub(IKb2,IKb1), Degrees)
    
      coxaAngle := f.fmul(f.atan2(IKz,IKx), Degrees)  
    
      uarts.Str(1, String(13, "L1: "))
      uarts.Str(1, fs.FloatToString(L1))
      uarts.Str(1, String(13, "coxaLength: "))
      uarts.Str(1, fs.FloatToString(coxaLength))
      uarts.Str(1, String(13, "L: "))
      uarts.Dec(1, fs.FloatToString(L))
      uarts.Str(1, String(13, "C: "))
      uarts.Dec(1, fs.FloatToString(C))
      uarts.Str(1, String(13, "IKb: "))
      uarts.Dec(1, fs.FloatToString(IKb))
      uarts.Str(1, String(13, "IKb1: "))
      uarts.Dec(1, fs.FloatToString(IKb1))
      uarts.Str(1, String(13, "B2: "))
      uarts.Dec(1, fs.FloatToString(IKb2))
      uarts.Str(1, String(13, "femurAngle: "))
      uarts.Dec(1, fs.FloatToString(femurAngle))
      uarts.Str(1, String(13, "TibiaAngle: "))
      uarts.Dec(1, fs.FloatToString(tibiaAngle))
      uarts.Str(1, String(13, "CoxaAngle: "))
      uarts.Dec(1, fs.FloatToString(coxaAngle))
      uarts.Str(1, String(13))
    
    '--------------------------------------------------------------------  
    
    PUB pauseMSec(Duration)
    '' Pause execution in milliseconds.
    '' Duration = number of milliseconds to delay
      waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
    
    L1: 10.04988
    coxaLength: 2.6
    L: 8264
    C: 8264
    IKb: 8264
    IKb1: 8264
    B2: 8264
    femurAngle: 8264
    TibiaAngle: 8264
    CoxaAngle: 8264
    
  • Paul K.Paul K. Posts: 150
    edited October 2015 Vote Up0Vote Down
    You have two ways to fix the code
    uarts.Str(1, String(13, "L1: "))
      uarts.Str(1, fs.FloatToString(L1))
      uarts.Str(1, String(13, "coxaLength: "))
      uarts.Str(1, fs.FloatToString(coxaLength))
      uarts.Str(1, String(13, "L: "))
      uarts.Dec(1, f.ftrunc(L))
      uarts.Str(1, String(13, "C: "))
      uarts.Dec(1, f.ftrunc(C))
      uarts.Str(1, String(13, "IKb: "))
      uarts.Dec(1, f.ftrunc(IKb))
      uarts.Str(1, String(13, "IKb1: "))
      uarts.Dec(1, f.ftrunc(IKb1))
      uarts.Str(1, String(13, "B2: "))
      uarts.Dec(1, f.ftrunc(IKb2))
      uarts.Str(1, String(13, "femurAngle: "))
      uarts.Dec(1, f.ftrunc(femurAngle))
      uarts.Str(1, String(13, "TibiaAngle: "))
      uarts.Dec(1, f.ftrunc(tibiaAngle))
      uarts.Str(1, String(13, "CoxaAngle: "))
      uarts.Dec(1, f.ftrunc(coxaAngle))
      uarts.Str(1, String(13))
    

    This will trunc the value. You were sending a Dec via the uart but you were changing it to a float value. I think it was floating the float value and it exceed the size a decimal value can be. I'm not sure.

    or
    uarts.Str(1, String(13, "L1: "))
      uarts.Str(1, fs.FloatToString(L1))
      uarts.Str(1, String(13, "coxaLength: "))
      uarts.Str(1, fs.FloatToString(coxaLength))
      uarts.Str(1, String(13, "L: "))
      uarts.Str(1, fs.FloatToString(L))
      uarts.Str(1, String(13, "C: "))
      uarts.Str(1, fs.FloatToString(C))
      uarts.Str(1, String(13, "IKb: "))
      uarts.Str(1, fs.FloatToString(IKb))
      uarts.Str(1, String(13, "IKb1: "))
      uarts.Str(1, fs.FloatToString(IKb1))
      uarts.Str(1, String(13, "B2: "))
      uarts.Str(1, fs.FloatToString(IKb2))
      uarts.Str(1, String(13, "femurAngle: "))
      uarts.Str(1, fs.FloatToString(femurAngle))
      uarts.Str(1, String(13, "TibiaAngle: "))
      uarts.Str(1, fs.FloatToString(tibiaAngle))
      uarts.Str(1, String(13, "CoxaAngle: "))
      uarts.Str(1, fs.FloatToString(coxaAngle))
      uarts.Str(1, String(13))
    
    Just change the uarts.dec to uarts.Str

    Values look good.

    L1=10.0498
    CoxaLength =2.6
    L=7.449876
    C=25.12968
    IKb=1.362565
    IKb1=0.2409583
    B2=0.300981
    femurAngle=95.31416
    TibiaAngle=3.439.45
    CoxaAngle=84.2894
  • Thanks Paul, good catch! I should know better than to code late at night by now, should have caught that mistake much earlier. That's the danger in using Cut and Paste and not really reading the code.
    I put in the change and now I'm running through some test values and comparing it to my spreadsheet values. There are some coxa value differences that I'm not sure where they are coming from as this is just atan of the X and Z values.
    Added some basic code to start reading from the Q4 transmitter again, got good inputs from a gimbal and a pot, will use those values to send values to the IK routine and see how the angle outputs change. Decided to spend the rest of tonight studying GAIT generation. I'm using Paul K.'s example code for a starting point, it's not quite coming together in my head yet but I think I'm starting to get understand it. Once I start programming a simple tripod gait I'm sure a lot of it will become much clearer.
  • Hi Bob. Nice to see new pictures updating, it must be fantastic following a project lasted for 5 years, we are waiting to see the final show of your robot.
    PCB Assembly, www.syspcb.com
  • Coming up on finishing up 4 years on this one project. This is the longest I've ever spent on a single project and been able to stick with it. Unfortunately a change in my job position at work has greatly impacted my time available for working on the robot in the evenings for the last year, usually I don't get home until late or am too tired/brain dead to spend any time playing on the computer.

    The programming side has taken much longer than expected but it continues to progress slowly. I've spent a lot of time studying gait generation from several hexapod code sources and am close to being ready to code my own version. Hopefully I can get some quality time on the computer this weekend and test out some of the ideas that have been percolating. I'm only going to program in a simple tripod gait to start and see how that works. I'll video some of the experiments and come up with a compilation video, should be good for a laugh or two.

    I appreciate everyone who has followed me on this journey and all the advice that has been offered. It would have taken me a lot longer to get to this point without your input.
  • It's been a while since my last posting and don't have much to show for it. My boss has been on vacation so I've been filling in for him, haven't felt like programming once I get home. However, I've been coming up with my own gaiting engine on paper and am ready to start programming it. However I need to get the transmitter commands to the leg controller. The master computer is receiving the input but the link between the two props isn't working correctly. I did some troubleshooting this afternoon and was able to fix a couple of issues but no data is coming down to the leg controller. I will try again tomorrow and see if a night away from programming helps clear the air.
    I'm still planning on going to a half-duplex communications loop from the master to the leg controllers, didn't put that in place since I wanted to try out the gait software and I knew I had this communications working at one time. Just have to figure out what I changed since the last time had it working. I've got the camera ready to video the gait movement attempts once I get the comms figured out.

    Bob
  • I'm good for another 4 years, so...

    GO BOB GO!... :)

    Hardware is easy, Software, not so easy.
    keep up the good fun.


    -Tommy
  • Finally got some quality time with the robot and got the master to slave link working correctly, next I have to verify the slave to master link is correct. As this was all working several months ago and I hadn't changed that portion of the code, it took longer to troubleshoot than it would have taken to just re-write that code. I found my error along with a wiring problem (two problems together do a good job of masking each other...). This success got my enthusiasm up for the testing the link back to the master but the transmitter batteries both died on me so they are being recharged for the next round. I've laid out several tests that gradually build on each other until I'm confident the master is accurately sending the movement signals and the slave responses are being received. Then the leg motors will be cut into the testing and I should be able to video that part and get something out. I want to control the gait of a single leg from the transmitter, both direction and speed of the leg tip, before I try to start up and coordinate multiple legs. I don't want to be watching one leg and having another leg move unexpectedly and possibly damaging itself. Of course all of this testing will be done on a test stand before I let it stand by itself. I'm not planning on having to try to pick this robot up if it should fall over. I may need to rig a safety strap to an overhead joist in the basement just in case.

    Bob
  • Had to take some vacation from work so I am staying home and working on the robot among other stuff... Got the link working from the transmitter to master to slave computers and the slave to master feedback loop working correctly. Did several tests, moving each motor individually from the transmitter via the IK engine and making sure the leg was moving to the correct position. I also got the leg feedback loop to the master computer working correctly, this is used to identify when a motor has finished its movement and also control the RGB lights for each leg. I put together a short video of these 4 tests since I haven't posted any video for a while! I hope you enjoy it.


    I am using full duplex serial and a single 4 port serial object for leg control from the master computer to the slave computer. Each slave has its own dedicated RX and TX lines from the master computer. Another 4 port serial control will be added later as I add additional legs for testing. I may use another communications schema later, it depends on what kind of issues I encounter when I get several legs trying to talk to the master at the same time. However, I plan on working on the gait engine for the rest of the week.

    Bob
  • Bob,
    can you post a link to your video?
    Jim
  • DiverBobDiverBob Posts: 635
    edited November 2015 Vote Up0Vote Down
    "www.youtube.com/ watch?v=rGQ6kkrl46U"

    Every time I paste the link in, the system posts it as a direct link. I put some spaces in the link above and that seems to work.
Sign In or Register to comment.