Recent Posts:
  • [Projects] SWIBR - Progress!
  • [Projects] SWIBR - Parts ordered!
  • [Projects] Iron Man - Update #8, More Negatives!
  • [Projects] Iron Man - Update #7, Negatives



  •  
     123456
    78910111213
    14151617181920
    21222324252627
    28

     






     
    [Projects] SWIBR - Progress!
    Ok, so my mouser and sparkfun orders came in! Got a lot of nice stuff. I started assembling the whole thing now although I'm still waiting on the geartrain to come in from Canadia.

    I assembled the H-bridge and it works great! Blue and Yellow LEDs show the output signal.



    I soldered up the gyro and accelerometer to their own breakout boards. Not too fun considering the pads are 0.5mm. But it can be done! Plus doing it myself saved me like $30 that SparkFun charges for their design.

    I have the basic code for the uC written for controlling the PITCH axis only. It uses 1D Kalman filtering and a PID Control loop. I won't be able to tune it until the robot is built but it's a good start.

    I based my code on the Kalman code published by Tom @ http://tom.pycke.be. The PID loop was written using Wikipedia as a reference.

    #define GYRO_PITCH  0
    #define ACEL_X      2
    #define ACEL_Z      3
    #define FILTERAMT  10
    
    struct Gyro1DKalman
    {
      float x_angle,x_bias;
      float P_00,P_01,P_10,P_11;	
      float Q_angle, Q_gyro;
      float R_angle;
    } filterPitch;
    
    float deltaTime, startTime, lastTime;
    
    int gyro_vals[FILTERAMT];
    int acelx_vals[FILTERAMT];
    int acelz_vals[FILTERAMT];
    int filterIndex = 0;
    
    float GYRO_PITCH_NEUTRAL = 773;
    float ACEL_X_NEUTRAL = 544;
    float ACEL_Z_NEUTRAL = 553;
    
    float calGyroPitch = 0, calAccelX = 0;
    float calCount = 0;
    
    float lastAngle = 0.0;
    float P = 0.0;
    float I = 0.0;
    float D = 0.0;
    
    // Initializing the struct
    void init_Gyro1DKalman(struct Gyro1DKalman *filterdata, float Q_angle, float Q_gyro, float R_angle)
    {
      filterdata->Q_angle = Q_angle;
      filterdata->Q_gyro  = Q_gyro;
      filterdata->R_angle = R_angle;
    }
    
    
    // Kalman predict
    void ars_predict(struct Gyro1DKalman *filterdata, const float dotAngle, const float dt)
    {
      filterdata->x_angle += dt * (dotAngle - filterdata->x_bias);
    
      filterdata->P_00 +=  - dt * (filterdata->P_10 + filterdata->P_01) + filterdata->Q_angle * dt;
      filterdata->P_01 +=  - dt * filterdata->P_11;
      filterdata->P_10 +=  - dt * filterdata->P_11;
      filterdata->P_11 +=  + filterdata->Q_gyro * dt;
    }
    
    
    // Kalman update
    float ars_update(struct Gyro1DKalman *filterdata, const float angle_m)
    {
      const float y = angle_m - filterdata->x_angle;
    
      const float S = filterdata->P_00 + filterdata->R_angle;
      const float K_0 = filterdata->P_00 / S;
      const float K_1 = filterdata->P_10 / S;
    	
      filterdata->x_angle +=  K_0 * y;
      filterdata->x_bias  +=  K_1 * y;
    	
      filterdata->P_00 -= K_0 * filterdata->P_00;
      filterdata->P_01 -= K_0 * filterdata->P_01;
      filterdata->P_10 -= K_1 * filterdata->P_00;
      filterdata->P_11 -= K_1 * filterdata->P_01;
    
      return filterdata->x_angle;
    }
    
    
    void setup()
    {
      analogReference(EXTERNAL);
      Serial.begin(9600);
      
      pinMode(3,OUTPUT);
      pinMode(5,OUTPUT);
      
      for(int i=0;i= FILTERAMT)
        filterIndex = 0;
        
      if(millis() - startTime < 5000)
      {
        // calibrating
        
        digitalWrite(13,HIGH);
        
        calAccelX += analogRead(ACEL_X);
        calGyroPitch += analogRead(GYRO_PITCH);
        calCount++;
        
        ACEL_X_NEUTRAL = calAccelX / calCount;
        GYRO_PITCH_NEUTRAL = calGyroPitch / calCount;
        
        digitalWrite(13,LOW);
        
        return;
      }
        
      if(deltaTime >= 20)
      {
        float gyro_avg = 0;
        for(int i=0;i windupGuard)
          I = windupGuard;
        if(I < -windupGuard)
          I = -windupGuard;
          
        float pid = P+I+D;
          
        if(pid > 255)
          pid = 255;
        if(pid < -255)
          pid = -255;
            
        Serial.print(pitchAngle);
        Serial.print(" | ");
        Serial.print(tmp * (180/PI));
        Serial.print(" | ");
        Serial.println(pid);
          
        if (abs(pitchAngle) < 60)
        {
          if(pid > 0)
          {
            digitalWrite(3,LOW);
            digitalWrite(5,LOW);
            analogWrite(3,pid);
          }
          else if(pid < 0)
          {
            digitalWrite(3,LOW);
            digitalWrite(5,LOW);
            analogWrite(5,-pid);
          } else {
            digitalWrite(3,LOW);
            digitalWrite(5,LOW);
          }
        } else
          I = 0;
            
        //Serial.print(pid);
        //Serial.print(" | ");
        //Serial.println(pitchAngle);
          
        lastAngle = pitchAngle;
          
        lastTime = millis();
      }
    }
    

    And here is a quick video of the controller in action!

    Posted on 2009-10-22 @ 21:31
     
    [Projects] SWIBR - Parts ordered!
    Soooo I placed the initial orders (and hopefully final ones) for the parts I think I'll need for SWIBR. Well, at least the ones I will buy on the interwebs.

    Parts purchased for the bot so far:

    Mouser:
    • 1x Board Mount Accelerometers 1.5G XYZ LEADS @ $10.77
    • 1x Gyroscopes Dual 0.83 mV deg/s LGA-16 @ $6.72
    • 20x Aluminum Electrolytic Capacitors - Leaded 100V 0.47uF 20% @ $0.04
    • 50x Aluminum Electrolytic Capacitors - Leaded 50volts 4.7uF @ $0.02
    • 33x Aluminum Electrolytic Capacitors - Leaded 10uF 100V @ $0.03
    • 20x Ceramic Disc Capacitors 0.01uF 50VDC @ $0.06
    • 1x Linear Regulators - Standard 3.3 V 500mA Fix Pos Voltage Regulator @ $0.68
    • 1x Crystals +/-20ppm 16MHZ FUNDAMENTAL @ $0.33
    • 20x Aluminum Electrolytic Capacitors - Leaded 16volts 100uF @ $0.03
    • 20x Ceramic Disc Capacitors C324 0.1uF 50volts 10% @ $0.15
    • 1x Ceramic Disc Capacitors 50V 22pF @ $0.06
    • 2x TIP102 Darlington Transistors NPN @ $0.46
    • 2x TIP107 Darlington Transistors PNP @ $0.44
    Mouser total: $27.35 + Shipping

    SparkFun:
    • 1x ATmega168 with Arduino Bootloader @ $4.95
    SparkFun total: $4.95 + Shipping

    Solarbotics:
    • 1x Regular Motor 2 @ $1.90
    • 1x GM9 + GMPW Combo @ $7.98
    Solarbotics total: $9.88 + Shipping

    So aside from all the other stuff I bought along with these purchases, and the materials I will need from local places (metal, etc), also excluding current components I have, I'm up to $42.18 so far. Not too bad.
    Posted on 2009-10-18 @ 16:47
     
    [Projects] Iron Man - Update #8, More Negatives!
    All the negatives are done now!

    Posted on 2009-10-12 @ 15:39
     
    [Projects] Iron Man - Update #7, Negatives
    Sooo the first negative mold is done of the rear of the helmet. For the record dishwashing liquid makes a pretty good mold release, but I still managed to tear the entire helmet portion up!

    Posted on 2009-10-11 @ 21:55
     
    [Projects] Iron Man - Update #6 (Video!)
    Latest update on the helmet, this time with a video...

    Posted on 2009-10-10 @ 19:00
     
    [Projects] Iron Man - Update #5
    Progress as of 20091010:

    Posted on 2009-10-10 @ 03:50
     
    [Projects] Iron Man - Update #4
    Progress as of 20091009:


    Posted on 2009-10-09 @ 03:50
     
    [Projects] Iron Man - Update #3
    Progress as of 20091007:


    Posted on 2009-10-07 @ 03:50
     
    [Projects] Iron Man - Update #2
    Progress as of 20091006:




    Posted on 2009-10-06 @ 03:50
     
    [Projects] Iron Man - Update #1
    Progress as of 20091005:

      
    Posted on 2009-10-05 @ 03:50