Next large robot

1161718192022»

Comments

  • I didn't have to deal with that. There are a few sellers of these that have a warehouse in Oakland that they hold product in, and I live an hour from there in San Jose, so it was delivered with a lift-gate truck to my door as part of the $2500 price. I was expecting "75% completed kit" but it was pretty much plug & play. I've been happy with it.
  • I went and ordered the Boss Laser Cutter today. I ordered the LS1620 model but they upgraded me to the LS1630 model for the same price as the other unit. It seems they are phasing these out but haven't updated their website. They don't want to bring in any more of these so I agreed to take one. Now its a 2-4 week wait for delivery. In the meantime I have to figure out where to set this up in the basement and clear out a spot.

    Bob Sweeney
  • Unless you need to laser something bigger than 12" x 9", you can buy a 40W laser on ebay for $365, free shipping.

    A 100W laser can't cut any more materials that a 40W laser can. To laser all the plywood for my R/C airplane only takes an hour. I imagine then that a 100W laser would do it in 24 minutes. I did have to align the mirrors etc, but everything went smoothly.

    I hope for whatever you're spending, that at least it doesn't have stepper motors.
    I am the Master, and technology my slave.
  • The_Master wrote: »
    Unless you need to laser something bigger than 12" x 9", you can buy a 40W laser on ebay for $365, free shipping.

    A 100W laser can't cut any more materials that a 40W laser can. To laser all the plywood for my R/C airplane only takes an hour. I imagine then that a 100W laser would do it in 24 minutes. I did have to align the mirrors etc, but everything went smoothly.

    I hope for whatever you're spending, that at least it doesn't have stepper motors.
    This is a commercial laser and 100 watts may not cut/etch any more materials than a 40watt but it gives enough power to easily and quickly cut through fairly thick wood and plastics. I have several hobbies besides robotics that I plan on using the laser for making parts along with a few other side ventures I am exploring. It is probably over kill for what I will be using it for and expensive for hobby use but since you can't take it with you, might as well have fun along the way! Besides, think of all the new design robot bodies that can come out of this!

    I have been able to spend several hours working on coding the hexapod. I decided to experiment with the PID loop for the coxa by re-writing a new PID routine and making it even simpler. I got rid of the existing speed control code and only used the inherent ramping on the PID. Actually its a PI loop right now, I haven't added a derivative process yet. The proportional code was easy to integrate as it is simply the constant (kp) times the error (kp*error). I determined the kp value by simply incrementing it by 1 and then commanding a move. The larger the value the faster the leg moved until I got a value where the leg had significant overshoot. Then I backed the value back down to the previous value.

    The Integral portion is trickier but it improves the response rate as its output is added to the output of the Proportional code. The Integral value is based on the change in error over time, since the code time interval was essentially constant, I did not use any code to determine time. This simplifies the code to accumulating the error (errorsum = error + error sum) and then multiplying it by a constant (ki) (ki * errorsum). This value can grow pretty quickly so I put limits on its growth to prevent it going too far. Initial tuning of the Integral portion didn't go well as I was using integers for ki which cause the motor speed to accelerate much too rapidly and caused wide overshoots. That's when I figured out the ki value should be less than 1. Since I can't use floating point math (no cogs available to run the code), I set ki = 5 and then divided the integral result by 10. This produced a controllable leg movement that did not have any overshoot.

    A byproduct of this testing was that the encoder value at the end of one motor command now closely matched the last encoder value for the previous command. As I stated a few days ago I ran into issues where although the stop motor command was sent at the right time, the motor inertia caused enough additional movement that the leg would end up further away from the desired position.

    At this time I don't think I need to add the derivative portion of the control, I still have more testing to perform and I want to try a variety of integral constants to see what value gives the best response.
  • The re-write of the Coxa PID loop was successful so the Tibia and Femur loops were also updated using the new routine. This greatly simplified the movement routines, the troubleshooting text output is a significant part of the code now. With this last change I eliminated the 'S-curve' speed control as the PID now controls the motor speed. The ADC control was also removed, however I will need the ADC eventually for the leg impact sensors. Here is an example of the code used for the Coxa PID routine:
    pub CoxaPID | error, speed, actualADC, oldADC, endspeed, dir, currentAngle, kp, ki, errsum, output
      'PID motor controller routine for Coxa
      ' repeat until inside of deadband
      'monitors CoxaTarget value continuously
      repeat
        kp := 3                                                                       'tested to value 4 causes oscillations
        ki := 1
        CoxaColor := Green
        CoxaMagEncoder := CoxaEncoder
        error := CoxaMagEncoder - CoxaTarget                                               'error based on mag encoder, CoxaTarget is desired position
        'allow for calibration and keep motor stopped inside deadzone
        if ||error < 2 AND coxaCal == 0
          speed := 1500
          dc.set(2, speed, 0)                                                       'stop motor
        endspeed := 0
        ' if CoxaAngle = 0 then running calibration check
        repeat while (CoxaDone == 1) 
          CoxaMagEncoder := CoxaEncoder  
          error := CoxaTarget - CoxaMagEncoder                                              'error based on mag encoder
    
          errsum := error + errSum                                          'get Integral value, limit it to 500 (motor pwm stop =1500, so 
    1500-500 = 1000 and 1500+500 - 2000; the limit of HB-25 controller output
          if errsum > 500
            errsum := 500
          if errsum < -500
            errsum := -500
          output := (kp * error) + (ki * errSum)/10                                 'main PID output value - divide by 10 to use integral math
    
          if error > 0
            dir := 1
            speed := 1500 - (output)                                               'use output to determine motor speed - limit speed to max value
            if speed < 1100
              speed := 1100            
            CoxaColor := Blue
          else
            dir := 0
            speed := 1500 + ||(output)
            if speed > 1900
              speed  := 1900
            CoxaColor := Orange
    
          if (||error < 1)                                           'stop if in deadzone
            speed := 1500
            dc.set(2, speed, 0)                                                       'stop motor
            coxaColor := Green
            coxaDone := 0
            errSum := 0
            CoxaMagEncoder := CoxaEncoder  
            if CoxaTest == 1                                 'output text if in testing mode
              currentAngle := CoxaMaxAngle-(((CoxaMagEncoder - CoxaMaxMag) * 1000)/ cSlope)      'calc current angle for troubleshooting                              
              io.str(0,String(13, "Coxa Done - Stop, motor inside deadband: "))
              io.str(0,String("     Encoder: "))
              io.dec(0,CoxaMagEncoder)
              io.str(0,String("   -CoxaAngle: "))
              io.dec(0,currentAngle)
              io.tx(0, CR)
            quit
    
          'set variable speed code here using the speedcmd value (10-100)
          endspeed := SetCoxaSpeed(speed)
          dc.set(2, endspeed, 0)                                                     'start motor at speed
         
          CoxaMagEncoder := CoxaEncoder  
          if CoxaTest == 1
            currentAngle := CoxaMaxAngle-(((CoxaMagEncoder - CoxaMaxMag) * 1000)/ cSlope)      'calc current angle for troubleshooting                              
            io.str(0,String(13, "Coxa Angle: "))
            io.dec(0,currentAngle)                                    
            io.str(0,String("  -Encoder: "))
            io.dec(0,CoxaMagEncoder)                                    
            io.str(0,String( "  -CoxaTarget: "))
            io.dec(0,CoxaTarget)                                    
            io.str(0,String( "  -Error: "))
            io.dec(0,Error)                                    
            io.str(0,String( "  -Speed: "))
            io.dec(0,endspeed)
            io.str(0,String("  -dir: "))
            io.dec(0,dir)
            io.str(0,String("  -errsum: "))
            io.dec(0,errsum)
            io.str(0,String("  -ki: "))
            io.dec(0,ki)
          else
            pauseMSec(20)                                                       'required pause when not outputing debug info
     
          ActualADC := CoxaMagEncoder                                                     'based on encoder input
          if CoxaCounter == 1                                                        'check if encoder not changing
            oldADC := CoxaMagEncoder                                                      'reset check encoder value
          if CoxaStopError(oldADC, CoxaMagEncoder)                                        'error if encoder not changing
            speed := 1500
            dc.set(2, speed, 0)
            coxaColor := Red
            coxaDone := 0
            errSum := 0
            if CoxaTest == 1
              io.str(0,String(13, "Coxa Done 4 - Encoder value not changing: "))
              io.str(0,String("     Encoder: "))
              io.dec(0,CoxaMagEncoder)
              io.tx(0, CR)
            quit
        coxaColor := Green
    
    pub SetCoxaSpeed(speed)
    ' modify speed based on input value speedcmd (5-100%)
      if speed > 1500                                                               'formula differs for each motor direction
        result := 1500 + (((speed - 1500) * cSpeed) / 100)
        result := result #> 1552                                                    'set minimum speed
      elseif speed < 1500
        result := 1500 - (((1500 - speed) * cSpeed) / 100)
        result := result <# 1448
    
    pub CoxaStopError(iADC, aADC)
      CoxaCounter := CoxaCounter + 1                                                                    'count to 10
      result := false
      if CoxaCounter == 1                                                                     'at start get encoder value
        iADC := aADC
      if CoxaCounter == 10                                                                     'max count 10
        CoxaCounter := 0
        if iADC == aADC                                                             'error, encoder not changing
          Result := true
    
    I left in the code to set overall motor speed and determine if the motor is not moving.

    I am putting together a short video of the PID tuning process that I should be able to post shortly.

    The next step is to re-introduce the master computer into the mix and run the leg computer via commands from the master. Then I can visit the gait control algorithms again and start getting those working.

    Its slow but progress is still being made, thanks for joining me on this long, long journey!
  • Such a fun journey this has been! I book marked this thread at the very begining!
    Jim
  • I finally got Adobe Premier Elements to cooperate and was able to patch together a short video of the PID tuning process for the coxa motor. Hopefully there is enough information in there for you to see the process I used. Setting the PID variables is time consuming but the end result is worth it.

  • Got the laser cutter installed in the basement and took the first cuts today. It works great and I even was able to transfer CAD files to the laser software and cut out a cover for the Magnetic Encoder housing. It even fits! I see a lot of uses for this machine in the future.
  • Cool!
Sign In or Register to comment.