Rose-Hulman Robotics Team

Changeset 506

Show
Ignore:
Timestamp:
05/27/09 00:35:35 (3 years ago)
Author:
auchtemm
Message:

some large changes to the code for PID. disabling needs to be handled in a cleaner way yet, as do serial timeouts.

Location:
trunk/electronics/avr/2008-mcc
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/electronics/avr/2008-mcc/main.m4

    r416 r506  
    9494 
    9595 
    96 void delay_ms(uint16_t t) { 
     96void delay_ms(uint16_t t) 
     97{ 
    9798        while (t--) _delay_ms(1); 
    9899} 
     100 
     101void calibrate() 
     102{ 
     103        pwm_set(0); 
     104        delay_ms(250); 
     105        pwm_set(255); 
     106        delay_ms(1000); 
     107        pwm_set(-255); 
     108        delay_ms(1000); 
     109        pwm_set(0); 
     110        delay_ms(5000); 
     111} 
     112 
    99113 
    100114int main() 
     
    109123 
    110124        pwm_init(); 
     125        pwm_set(0); 
     126 
     127        //while (1) 
     128        //      calibrate(); 
     129 
     130 
    111131//      spi_init(); 
    112132//      mcp_init(Loopback, msg_handler1); 
  • trunk/electronics/avr/2008-mcc/mkfile

    r369 r506  
    11<$RHRTELEC/avr/mkhdr 
    22 
    3 MCU_SPEED=20000000 
     3MCU_SPEED=20000000ULL 
    44TARG=pid 
    55OFILES=\ 
  • trunk/electronics/avr/2008-mcc/pid.m4

    r432 r506  
    3333int16_t set_point; 
    3434int16_t ticks; 
    35 int16_t distance; 
    3635uint8_t disabled; 
     36int8_t enc_inc; 
     37 
     38#define MAX_I_TERM (INT16_MAX-1) 
     39#define PWM_MAX 255 
    3740 
    3841/* All gains scaled by 128 */ 
     
    5053        int16_t error_sum; 
    5154        int16_t last_error; 
     55        int16_t max_error; 
     56        int16_t max_error_sum; 
    5257 
    5358} PID; 
     
    9499        PID.Ki = nKi; 
    95100        PID.Kd = nKd; 
     101        PID.max_error = INT16_MAX / (nKp + 1); 
     102        PID.max_error_sum = MAX_I_TERM / (nKi + 1); 
     103        PID.error_sum = 0; 
    96104} 
    97105 
     
    131139        PIN_INPUT(ENCA); 
    132140        PIN_INPUT(ENCB); 
    133         PIN_INPUT(KILL); 
    134          
     141        PIN_INPUT(ENCPOL); 
     142        PIN_INPUT(DISI); 
     143        PIN_OUTPUT(DIS); 
     144        PIN_SET(DIS); 
     145 
    135146        pid_disable(); 
    136         //pid_set_gain(190, 17, 120); 
     147 
     148        if (PIN_LEVEL(ENCPOL)) 
     149                enc_inc = 1; 
     150        else 
     151                enc_inc = -1; 
     152 
    137153        /* Interrupt on rising edge */ 
    138154        EICRA |= 0b00001100; 
    139155        EIMSK |= 0b00000010; 
    140156 
    141         PID.Kp = eeprom_read_word((uint16_t *)EAkp); 
    142         PID.Ki = eeprom_read_word((uint16_t *)EAki); 
    143         PID.Kd = eeprom_read_word((uint16_t *)EAkd); 
     157        pid_set_gain(eeprom_read_word((uint16_t *)EAkp), eeprom_read_word((uint16_t *)EAki), eeprom_read_word((uint16_t *)EAkd)); 
     158        PID.error_sum = 0; 
    144159 
    145160        /* Use Timer0 to trigger PID update 
     
    150165#if PIDUPDATE == PID50HZ  
    151166        TCCR0B = 0b00000101; 
    152         OCR0A = 194; 
     167        OCR0A = 194; // Actually, this is 100Hz 
    153168#elif PIDUPDATE == PID100HZ 
    154169        TCCR0B = 0b00000101; 
     
    160175} 
    161176 
     177 
    162178/* INT1 is encoder channel A  
    163179 * To enable interrupt on rising edge of INT1: 
     
    167183ISR(INT1_vect) 
    168184{ 
    169         cli(); 
    170185        if (PIN_LEVEL(ENCB)) 
    171                 enc_count++; 
     186                enc_count += enc_inc; 
    172187        else 
    173                 enc_count--; 
    174         sei(); 
    175 } 
     188                enc_count -= enc_inc; 
     189} 
     190 
    176191 
    177192/* PID update loop */ 
    178193ISR(TIMER0_COMPA_vect) 
    179194{ 
     195        int32_t rv, tmp; 
     196 
    180197        ticks = enc_count; 
    181         PID.error = set_point - enc_count; 
    182198        enc_count = 0; 
    183199 
    184         PID.p = PID.Kp * PID.error; 
    185  
    186         PID.error_sum += PID.error; 
     200        PID.error = set_point - ticks; 
     201 
     202        if (PID.error >= PID.max_error) 
     203                PID.p = INT16_MAX; 
     204        else if (PID.error < -PID.max_error) 
     205                PID.p = -INT16_MAX; 
     206        else 
     207                PID.p = PID.Kp * PID.error; 
     208 
     209 
     210        tmp = PID.error_sum + PID.error; 
     211        if (tmp >= PID.max_error_sum) 
     212                PID.error_sum = PID.max_error_sum; 
     213        else if (tmp < -PID.max_error_sum) 
     214                PID.error_sum = -PID.max_error_sum; 
     215        else  
     216                PID.error_sum = tmp; 
     217 
    187218        PID.i = PID.Ki * PID.error_sum; 
    188219 
    189220 
    190         PID.d = PID.Kd * (PID.error - PID.last_error); 
     221        PID.d = PID.Kd * (PID.last_error - PID.error); 
    191222        PID.last_error = PID.error; 
    192223 
    193224 
    194         if (PIN_LEVEL(KILL) == 0 || disabled) 
    195                 pwm_set(0); 
    196         else 
    197                 pwm_set((PID.p + PID.i + PID.d) >> 7); 
    198  
    199  
    200 } 
    201  
     225        rv = (PID.p + PID.i + PID.d) / 128; 
     226 
     227        if (rv >= PWM_MAX) 
     228                rv = PWM_MAX; 
     229        else if (rv < -PWM_MAX) 
     230                rv = -PWM_MAX; 
     231 
     232        pwm_set(rv); 
     233 
     234        if (PIN_LEVEL(DISI)) { 
     235                PIN_SET(DIS); 
     236        } else { 
     237                PID.error_sum = 0; 
     238                PIN_CLR(DIS); 
     239        } 
     240} 
     241 
  • trunk/electronics/avr/2008-mcc/pins.m4

    r383 r506  
    1414define(TXD, `DDRD, PORTD, PIND, PD1') 
    1515 
    16 define(KILL, `DDRD, PORTD, PIND, PD5') 
     16define(DISI, `DDRD, PORTD, PIND, PD7') 
     17define(DIS, `DDRB, PORTB, PINB, PB2') 
    1718 
     19define(ENCPOL, `DDRD, PORTD, PIND, PD5') 
  • trunk/electronics/avr/2008-mcc/pwm.m4

    r386 r506  
    1212void pwm_init() 
    1313{ 
    14         PIN_OUTPUT(PWM); 
    15  
    1614        /* f_pwm = f_clk/(2 * n * TOP) */ 
    17         TCCR1A = 0b10100000; 
     15        TCCR1A = 0b10000000; 
    1816        TCCR1B = 0b00010010; 
    1917 
    20         ICR1 = 10000; 
     18        ICR1 = 12500; 
    2119        pwm_set(0); 
     20        PIN_OUTPUT(PWM); 
    2221} 
    2322 
     
    2726 *  1500 = neutral 
    2827 *  2000 = full forward 
    29  *  sp should always be in the range [-256, 255] 
    3028 */ 
    3129void pwm_set(int16_t sp) 
    3230{ 
    33         if (sp >= 255) 
    34                 sp = 255; 
    35         else if (sp <= -256) 
    36                 sp = -256; 
     31        int16_t tmp; 
    3732 
    38         OCR1A = 1500 + (sp << 1); 
     33        tmp = sp * 2; 
     34        if (tmp > 512) 
     35                tmp = 512; 
     36        else if (tmp < -512) 
     37                tmp = -512; 
    3938         
     39        tmp += 1875; 
     40        OCR1A = tmp; 
    4041} 
    4142 
    4243int16_t pwm_get() 
    4344{ 
    44         return (OCR1A - 1500) >> 1; 
     45        return (OCR1A - 1875) / 2; 
    4546} 
    4647