Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / mapping / odometry / odometry.c @ 872

History | View | Annotate | Download (1.81 KB)

1
#include "encoders.h"
2
#include <math.h>
3

    
4
//Odometry resolution, *64 microseconds.
5
#define ODOMETRY_CLK=80 
6

    
7
//Wheel = 2.613 in.  
8
//Circumference = 208.508133 mm
9
//Distance per encoder click (circumference / 1024)  = 203.621224 um.
10
//Robot width = 5.3745 in. = 136.5123 mm
11

    
12
#define ROBOT_WIDTH_MM=137    //mm
13
#define CLICK_DISTANCE_UM=204 //um
14

    
15
//Standard measures will be mm and us
16

    
17
int encoder_ltm1, encoder_rtm1;
18

    
19
int diff_x,diff_y;
20
double angle;
21

    
22
void odometry_init(){
23
        encoder_init();
24
        odometry_reset();
25

    
26
}
27

    
28
void odometry_reset(){
29
        diff_x = 0;
30
        diff_y = 0;
31
        angle = 0.0;
32
        
33
        //CTC Mode. CLK / 1024
34
        TCCR3A = 0; // (Fully disconnected)
35
        TCCR3B = _BV(WGM32) | _BV(CS32) | _BV(CS30); //CLK/1024 , CTC Mode.
36

    
37
        OCR3A = ODOMETRY_CLK;
38
}
39

    
40
void odometry_run(){
41
        int v_l, v_r;
42
        double omega;
43
        int encoder_left, encoder_right;        
44
        
45
        encoder_left = encoder_read(LEFT);        
46
        encoder_right = encoder_read(RIGHT);        
47
        
48
        v_l = (CLICK_DISTANCE_UM*(encoder_left - encoder_ltm1)) / (ODOMETRY_CLK * 64);  // um / us = m/s
49
        v_r = (CLICK_DISTANCE_UM*(encoder_right - encoder_rtm1)) / (ODOMETRY_CLK * 64); // same
50

    
51
        if(v_l == v_r){
52
                diff_x += v_l * cos(angle);
53
                diff_y += v_r * sin(angle);
54
                return;
55
        }
56
        
57
        //Relative to the center of the robot, the center of it's turn.
58
        turning_radius = ROBOT_WIDTH_MM * ((v_l + v_r) / (v_l - v_r)); //  = mm
59

    
60
        //TODO I think I may have gotten lazy on the angular momentum units before, hard to tell now.        
61
        if(v_r > v_l) //CCW positive.
62
                omega = ((double)(-v_r)) / (turning_radius + ROBOT_WIDTH_MM>>1);
63
        
64
        if(v_r > v_l) //CW negative.
65
                omega = ((double)(-v_l)) / (turning_radius - ROBOT_WIDTH_MM>>1);
66
        
67
        //Omega positive whenever t_r is negative, vica versa.
68
        vmag = -omega * turning_radius;
69

    
70
        angle += omega; // * the timer interval.
71
        diff_x += vmag * cos(angle);
72
        diff_y += vmag * sin(angle);
73
}
74

    
75
ISR(TIMER3_COMPA_vect){
76
        odometry_run();
77
}