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 |