Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / behaviors / spline / server / encoders.c @ 1344

History | View | Annotate | Download (5.12 KB)

1 1238 ayeager
#include "encoders.h"
2
3
char encoder_buf_index;
4
5
unsigned int left_data, right_data;
6
7
unsigned int left_data_array[BUFFER_SIZE];
8
unsigned int right_data_array[BUFFER_SIZE];
9
int left_data_idx;
10
int right_data_idx;
11
12
int left_dx;
13
int right_dx;
14
long int timecount;
15
16
volatile short int data_ready;
17
18
void encoder_recv(unsigned int, unsigned int);
19
20
//Helper Function Prototypes
21
inline void left_data_array_put(unsigned short int value);
22
inline unsigned int left_data_array_top(void);
23
inline unsigned int left_data_array_prev(void);
24
inline unsigned int left_data_array_bottom(void);
25
26
inline void right_data_array_put(unsigned short int value);
27
inline unsigned int right_data_array_top(void);
28
inline unsigned int right_data_array_prev(void);
29
inline unsigned int right_data_array_bottom(void);
30
31
/**
32
 * @brief Returns the specified encoders value
33
 *
34
 * @param encoder this is the encoder that you want to read. Valid arguments
35
 *          are LEFT and RIGHT
36
 *
37
 * @return the value of the specified encoder
38
 **/
39
int encoder_read(char encoder){
40
41
        if(encoder==LEFT) return left_data;
42
        else if(encoder==RIGHT) return right_data;
43
        else return -1;
44
}
45
46
47
/**
48
* @brief Outputs encoder direction as FORWARD OR BACK
49
* A STUB! DO NOT use.
50
*
51
* @param encoder The encoder you want the direction of.
52
* Valid arguments are right and left.
53
*
54
* @return FORWARD or BACK (the constants)
55
*/
56
char encoder_direction(char encoder){
57
        return 0;
58
}
59
60
/**
61
 * Gets the total distance covered by the specified encoder (in encoder clicks)
62
 *
63
 * @param encoder the encoder that you want to read, use LEFT or RIGHT
64
 *
65
 * @return The distance covered by the specified encoder.
66
 **/
67
int encoder_get_dx(char encoder) {
68
69
        if(encoder==LEFT) return left_dx;
70
        else if(encoder==RIGHT) return right_dx;
71
        else return -1;
72
}
73
74
/**
75
 * Resets the distance accumulator for the specified
76
 *  encoder.
77
 *
78
 * @param encoder the encoder that you want to reset distance for
79
 **/
80
void encoder_rst_dx(char encoder) {
81
82
        if(encoder==LEFT) left_dx = 0;
83
        else if(encoder==RIGHT) right_dx = 0;
84
}
85
86
/**
87
* @brief Returns the number of encoder reads that have occurred.
88
*
89
* @return The time count.
90
*/
91
int encoder_get_tc(void) {
92
        return timecount;
93
}
94
95
/**
96
* @brief Resets the encoder read counter.
97
*/
98
void encoder_rst_tc(void) {
99
        timecount = 0;
100
}
101
102
103
/**
104
* @brief Returns the approximated instantaneous velocity of the robot
105
* in terms of encoder clicks.
106
*
107
* @param encoder RIGHT or LEFT - the wheel you want the velocity for.
108
*
109
* @return The instantaneous velocity for the given wheel.
110
*/
111
int encoder_get_v(char encoder){
112
        if (encoder == LEFT)
113
                return left_data_array_bottom() - left_data_array_top();
114
115
        if (encoder == RIGHT)
116
                return right_data_array_top() - right_data_array_bottom();
117
118
        return -1; /* TODO: velocity could be -1, use another value for error */
119
}
120
121
122
/**
123
* @brief Waits until n encoder reads have occurred.
124
* Counter is reset on functions exit.
125
*
126
* @param n
127
*/
128
void encoder_wait(int n){
129
        while(data_ready<n);
130
        data_ready=0;
131
}
132
133
134
//Full reads occur every 40 microseconds. This function should be called
135
//every 8 microseconds.
136
void encoder_recv(unsigned int left_data_buf, unsigned int right_data_buf){
137
        short int dx;
138
139
        left_data = left_data_buf;
140
        right_data = right_data_buf;
141
142
        /*Above 1023 is invalid data*/
143
        if(!(left_data > 1023)) {
144
                left_data_array_put(left_data);
145
146
                //Adjust left accumulator
147
                dx = - left_data + left_data_array_prev();
148
149
                if(left_data_array_prev()==0)  dx=0;
150
151
                if(dx > 512) left_dx += dx - 1023; //Underflow
152
                else if(dx < -512) left_dx += dx + 1023; //Overflow
153
                else left_dx += dx;
154
        }
155
156
        /*Above 1023 is invalid data*/
157
        if(!(right_data > 1023)) {
158
                right_data_array_put(right_data);
159
160
                //Adjust right accumulator
161
                dx = right_data - right_data_array_prev();
162
163
                if(right_data_array_prev()==0) dx=0;
164
165
                if(dx > 512) right_dx += dx - 1023; //underflow
166
                else if(dx < -512) right_dx += dx + 1023; //overflow
167
                else right_dx += dx;
168
        }
169
170
171
        //Increment timecount accumulator
172
        timecount++;
173
}
174
175
176
//Helper Functions
177
inline void left_data_array_put(unsigned short int value) {
178
        if(left_data_idx == BUFFER_SIZE-1)
179
                left_data_idx = 0;
180
        else
181
                left_data_idx++;
182
        left_data_array[left_data_idx] = value;
183
}
184
185
inline unsigned int left_data_array_top(void) {
186
        return left_data_array[left_data_idx];
187
}
188
189
inline unsigned int left_data_array_prev(void) {
190
        if(left_data_idx == 0)
191
                return left_data_array[BUFFER_SIZE-1];
192
        else
193
                return left_data_array[left_data_idx - 1];
194
}
195
196
inline unsigned int left_data_array_bottom(void) {
197
        if(left_data_idx == BUFFER_SIZE-1)
198
                return left_data_array[0];
199
        else
200
                return left_data_array[left_data_idx + 1];
201
}
202
203
inline void right_data_array_put(unsigned short int value) {
204
        if(right_data_idx == BUFFER_SIZE-1)
205
                right_data_idx = 0;
206
        else
207
                right_data_idx++;
208
        right_data_array[right_data_idx] = value;
209
}
210
211
inline unsigned int right_data_array_top(void) {
212
        return right_data_array[right_data_idx];
213
}
214
215
inline unsigned int right_data_array_prev(void) {
216
        if(right_data_idx == 0)
217
                return right_data_array[BUFFER_SIZE-1];
218
        else
219
                return right_data_array[right_data_idx - 1];
220
}
221
222
inline unsigned int right_data_array_bottom(void) {
223
        if(right_data_idx == BUFFER_SIZE-1)
224
                return right_data_array[0];
225
        else
226
                return right_data_array[right_data_idx + 1];
227
}