Set sonar angle to 5° degree
[ros_wild_thumper.git] / avr / motor_ctrl / main.c
index 805788f..5d65529 100644 (file)
  */
 
 
-#define TWI_ACK                TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
-#define TWI_RESET      TWCR &= ~((1 << TWSTO) | (1 << TWEN)); TWI_ACK
-#define TWI_NAK                TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
-
-#define KP 0.06
-#define KI 0.10
+#define KP 0.09
+#define KI 0.07
 #define KD 0.0
 #define PID_T 0.01
 // wheel diameter=12cm, encoder=48cpr, gear ratio=1:47
 // STEP_PER_M = 48*47/(d*pi)
-// Left real diameter: 0.12808
-#define STEP_PER_M_LEFT 5606.7
-// Right real diameter: 0.121
-#define STEP_PER_M_RIGHT 5934.8
+// Left real diameter: 0.12808, Right real diameter: 0.121
+#define STEP_PER_M 5770.8
+#define STEP_PER_M_LEFT (STEP_PER_M)
+#define STEP_PER_M_RIGHT (STEP_PER_M)
 #define WHEEL_DIST 0.39912 // Measured: 0.252
 #define PWM_BREAK INT16_MIN
+#define STALL_LIMIT 140000
+
+#define TWI_ACK   TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
+#define TWI_RESET TWCR &= ~((1 << TWSTO) | (1 << TWEN)); TWI_ACK
+#define TWI_NAK   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
+#define ENABLE_PWM_MOTOR1  TCCR1A |=  (1 << COM1A1)
+#define ENABLE_PWM_MOTOR2  TCCR1A |=  (1 << COM1B1)
+#define ENABLE_PWM_MOTOR3  TCCR2  |=  (1 << COM21);
+#define ENABLE_PWM_MOTOR4  TCCR0  |=  (1 << COM01);
+#define DISABLE_PWM_MOTOR1 TCCR1A &= ~(1 << COM1A1)
+#define DISABLE_PWM_MOTOR2 TCCR1A &= ~(1 << COM1B1)
+#define DISABLE_PWM_MOTOR3 TCCR2  &= ~(1 << COM21);
+#define DISABLE_PWM_MOTOR4 TCCR0  &= ~(1 << COM01);
+
 
 enum mode {
        MOTOR_MANUAL,
@@ -701,20 +711,24 @@ static void update_motor(void) {
                if (motor1 == 0) {
                        // stop
                        PORTC &= ~(1 << 3) & ~(1 << 2);
+                       DISABLE_PWM_MOTOR1;
                } else if (motor1 == PWM_BREAK) {
                        PORTC |= (1 << 3) | (1 << 2);
+                       ENABLE_PWM_MOTOR1;
                } else if ((!motor1_switch && motor1 > 0) || (motor1_switch && motor1 < 0)) {
                        // forward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 3);
                        tmp |=  (1 << 2);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR1;
                } else { // motor1 < 0
                        // backward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 2);
                        tmp |=  (1 << 3);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR1;
                }
 
                m1_old = motor1;
@@ -725,20 +739,24 @@ static void update_motor(void) {
                if (motor2 == 0) {
                        // stop
                        PORTC &= ~(1 << 5) & ~(1 << 4);
+                       DISABLE_PWM_MOTOR2;
                } else if (motor2 == PWM_BREAK) {
                        PORTC |= (1 << 5) | (1 << 4);
+                       ENABLE_PWM_MOTOR2;
                } else if ((!motor2_switch && motor2 > 0) || (motor2_switch && motor2 < 0)) {
                        // forward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 5);
                        tmp |=  (1 << 4);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR2;
                } else { // motor2 < 0
                        // backward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 4);
                        tmp |=  (1 << 5);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR2;
                }
 
                m2_old = motor2;
@@ -749,20 +767,24 @@ static void update_motor(void) {
                if (motor3 == 0) {
                        // stop
                        PORTC &= ~(1 << 7) & ~(1 << 6);
+                       DISABLE_PWM_MOTOR3;
                } else if (motor3 == PWM_BREAK) {
                        PORTC |= (1 << 7) | (1 << 6);
+                       ENABLE_PWM_MOTOR3;
                } else if ((!motor3_switch && motor3 > 0) || (motor3_switch && motor3 < 0)) {
                        // forward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 7);
                        tmp |=  (1 << 6);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR3;
                } else { // motor3 < 0
                        // backward
                        uint8_t tmp=PORTC;
                        tmp &= ~(1 << 6);
                        tmp |=  (1 << 7);
                        PORTC = tmp;
+                       ENABLE_PWM_MOTOR3;
                }
 
                m3_old = motor3;
@@ -773,20 +795,24 @@ static void update_motor(void) {
                if (motor4 == 0) {
                        // stop
                        PORTD &= ~(1 << 3) & ~(1 << 2);
+                       DISABLE_PWM_MOTOR4;
                } else if (motor4 == PWM_BREAK) {
                        PORTD |= (1 << 3) | (1 << 2);
+                       ENABLE_PWM_MOTOR4;
                } else if ((!motor4_switch && motor4 > 0) || (motor4_switch && motor4 < 0)) {
                        // forward
                        uint8_t tmp=PORTD;
                        tmp &= ~(1 << 3);
                        tmp |=  (1 << 2);
                        PORTD = tmp;
+                       ENABLE_PWM_MOTOR4;
                } else { // motor4 < 0
                        // backward
                        uint8_t tmp=PORTD;
                        tmp &= ~(1 << 2);
                        tmp |=  (1 << 3);
                        PORTD = tmp;
+                       ENABLE_PWM_MOTOR4;
                }
 
                m4_old = motor4;
@@ -874,26 +900,25 @@ static void update_pid(void) {
        static int32_t esum4=0;
 
        // protect motors from damage if stalling
-       if (labs(esum1) > 140000 && speed1 == 0) {
+       if (labs(esum1) > STALL_LIMIT && speed1 == 0) {
                motor1 = 0;
                motor1_mode = MOTOR_MANUAL;
                error_state |= (1<<4);
                esum1 = 0;
        }       
-       if (labs(esum2) > 140000 && speed2 == 0) {
+       if (labs(esum2) > STALL_LIMIT && speed2 == 0) {
                motor2 = 0;
                motor2_mode = MOTOR_MANUAL;
                error_state |= (1<<5);
                esum2 = 0;
        }       
-       if (labs(esum3) > 140000 && speed3 == 0) {
+       if (labs(esum3) > STALL_LIMIT && speed3 == 0) {
                motor3 = 0;
                motor3_mode = MOTOR_MANUAL;
                error_state |= (1<<6);
                esum3 = 0;
        }       
-       // protect motors from damage if stalling
-       if (labs(esum4) > 140000 && speed4 == 0) {
+       if (labs(esum4) > STALL_LIMIT && speed4 == 0) {
                motor4 = 0;
                motor4_mode = MOTOR_MANUAL;
                error_state |= (1<<7);
@@ -1019,9 +1044,12 @@ int main(void) {
        TWI_RESET;
 
        // Motor 1 & 2
-       // Timer 1: Fast PWM non-inverting mode, Top=255 => 15.625kHz
+       // Also used for PWM frequency TIMER1_FREQ (F_CPU/256)
+       // Timer 1: Fast PWM non-inverting mode, Top=255 => 19.531kHz
        // Prescaler=1
-       TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
+       //TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
+       // Avoid narrow spike on extreme pwm value 0 by not setting COM1*1
+       TCCR1A = (1 << WGM10);
        TCCR1B = (1 << WGM12) | (1 << CS10);
        OCR1A = 0;
        OCR1B = 0;
@@ -1029,13 +1057,17 @@ int main(void) {
        // Motor 3
        // Timer 2: Fast PWM non-inverting mode, Top=255
        // Prescaler=1
-       TCCR2 = (1 << WGM21) | (1 << WGM20) | (1 << COM21) | (1 << CS20);
+       //TCCR2 = (1 << WGM21) | (1 << WGM20) | (1 << COM21) | (1 << CS20);
+       // Avoid narrow spike on extreme pwm value 0 by not setting COM21
+       TCCR2 = (1 << WGM21) | (1 << WGM20) | (1 << CS20);
        OCR2 = 0;
 
        // Motor 4
        // Timer 0: Fast PWM non-inverting mode, Top=255
        // Prescaler=1
-       TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << COM01) | (1 << CS00);
+       //TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << COM01) | (1 << CS00);
+       // Avoid narrow spike on extreme pwm value 0 by not setting COM01
+       TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << CS00);
        OCR0 = 0;
 
        printf("\r\nStart\r\n");
@@ -1094,7 +1126,7 @@ int main(void) {
                        motor4_mode = MOTOR_PID;
                }
 
-               if (run_update >= 156) { // ~100Hz
+               if (run_update >= 195) { // TIMER1_FREQ/195 = ~100Hz
                        run_update=0;
 
                        update_pos();