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 |
} |