Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (1.71 KB)

1 884 justin
#include "odometry.h"
2 723 justin
#include "encoders.h"
3 872 justin
#include <math.h>
4 884 justin
#include <avr/interrupt.h>
5
#include <dragonfly_lib.h>
6 723 justin
7 884 justin
int encoder_ltm1, encoder_rtm1;
8 724 justin
9 884 justin
int diff_x,diff_y;
10
float angle;
11 724 justin
12
13 884 justin
int odometry_dx(void){
14
        return diff_x;
15
}
16 724 justin
17 884 justin
int odometry_dy(void){
18
        return diff_y;
19
}
20 723 justin
21 884 justin
float odometry_angle(void){
22
        return angle;
23
}
24 723 justin
25 884 justin
void odometry_init(void){
26 723 justin
        encoder_init();
27
        odometry_reset();
28 890 justin
29
        //CTC Mode. CLK / 1024
30
        TCCR2 = 0; // (Fully disconnected)
31
        TCCR2 = _BV(WGM21) | _BV(CS22) | _BV(CS20); //CLK/1024 , CTC Mode.
32
33
        TIMSK |= _BV(OCIE2);
34
35
        OCR2 = ODOMETRY_CLK;
36 723 justin
}
37
38 884 justin
void odometry_reset(void){
39 723 justin
        diff_x = 0;
40
        diff_y = 0;
41 872 justin
        angle = 0.0;
42 723 justin
}
43
44 884 justin
void odometry_run(void){
45 872 justin
        int v_l, v_r;
46 884 justin
        float omega;
47 723 justin
        int encoder_left, encoder_right;
48 724 justin
49 723 justin
        encoder_left = encoder_read(LEFT);
50
        encoder_right = encoder_read(RIGHT);
51
52 872 justin
        v_l = (CLICK_DISTANCE_UM*(encoder_left - encoder_ltm1)) / (ODOMETRY_CLK * 64);  // um / us = m/s
53
        v_r = (CLICK_DISTANCE_UM*(encoder_right - encoder_rtm1)) / (ODOMETRY_CLK * 64); // same
54 724 justin
55 730 justin
        if(v_l == v_r){
56 724 justin
                diff_x += v_l * cos(angle);
57
                diff_y += v_r * sin(angle);
58 872 justin
                return;
59 724 justin
        }
60 723 justin
61
        //Relative to the center of the robot, the center of it's turn.
62 884 justin
        float turning_radius = ROBOT_WIDTH_MM * ((v_l + v_r) / (v_l - v_r)); //  = mm
63 724 justin
64 872 justin
        //TODO I think I may have gotten lazy on the angular momentum units before, hard to tell now.
65 723 justin
        if(v_r > v_l) //CCW positive.
66 884 justin
                omega = ((float)(-v_r)) / (turning_radius + (ROBOT_WIDTH_MM>>1));
67 723 justin
68 884 justin
        else //CW negative.
69
                omega = ((float)(-v_l)) / (turning_radius - (ROBOT_WIDTH_MM>>1));
70 723 justin
71
        //Omega positive whenever t_r is negative, vica versa.
72 884 justin
        float vmag = -omega * turning_radius;
73 723 justin
74
        angle += omega; // * the timer interval.
75 724 justin
        diff_x += vmag * cos(angle);
76
        diff_y += vmag * sin(angle);
77 723 justin
}
78
79 884 justin
ISR(TIMER2_COMP_vect){
80 723 justin
        odometry_run();
81
}
82 884 justin