forked from zacsketches/Filter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFilter.h
More file actions
137 lines (110 loc) · 3.9 KB
/
Copy pathFilter.h
File metadata and controls
137 lines (110 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* I'd like to have a library I can call for basic filtering operations.
*
* Most sensors in small scale robotics are noisy. For example as a
* mobile robot approaches a wall, an atached ulrasonic sensor should
* give readings in cm similar to the list below
*
* 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ...bump!
*
* but all too often the data will come back like this
*
* 11, 10, 6, 8, 7, 3, 5, 4, 1, 2, 1, ..bump!
*
* By filtering the raw data, via a moving average or other more
* specialized filter we can use the noisy data as an input to our
* filter and then the processed data will give us a better linear
* output. This linear output still doesn't match the exact distance
* to the wall, but it is a much closer approximation than the noisy
* data and provides a better set of data for the robot to make
* control decisions from.
*
* Since this filter library is designed to support Arduino applications
* I'm limiting it to only work on integer data. I might add templating
* for arbitrary numeric types, but most Arduino users don't know how
* to instantiate a templated class, so it might not every get used.
*
*/
#ifndef FILTER_h
#define FILTER_h
// Uncomment the line below to run as an Arduino library from
// the Arduino IDE, and comment out the COMPILE directive below
// for command line testing
#define COMPILE_FOR_ARDUINO
// Uncomment the lines below to compile the Dev_test main()
// Also comment out the Arduino lines above
// #define COMPILE_FOR_CMD_LINE_TEST
#ifdef COMPILE_FOR_ARDUINO
#include "Arduino.h"
#endif
#ifdef COMPILE_FOR_CMD_LINE_TEST
#include <cstdio> //for access to NULL
#include <iostream> //for debug access to cout
#endif
//*******************************************************************
//* Node and FIFO_list
//* Filters use a linked list data structure to hold their historical
//* values.
//*******************************************************************
// declaring a list node structure
struct Node {
int data; // data field
Node* next; // link field
};
// declare the list header structure
struct FIFO_list {
int cnt;
Node* head;
Node* tail;
//constructor
FIFO_list(): cnt(0), head(NULL), tail(NULL) {}
//destructor
~FIFO_list();
// len returns the number of elements in L
int len( ) { return cnt; }
// add elt to the end of L
void append(int elem);
void inline remove_node(Node* p);
//return sum of elements
int sum();
//add the new data to the FIFO List, pushing out oldest data
void add(int new_data);
#ifdef COMPILE_FOR_CMD_LINE_TEST
//show the elements
void print();
#endif
};
//*******************************************************************
//* MOVING AVERAGE
//*******************************************************************
class Moving_average{
int len; //length of historical data to smooth.
//For example, to average the last three data points
//plus the current data, len would be 4.
int his; //length of historical data to store. If len is 4
//then his is 3.
FIFO_list data; //points to first data element
int ca; //current average
public:
//CONSTRUCTOR
//default data for the history is optional, but recommended
//when filtering write positions for servos. I like to use the
//servo default position (usually 90) as the default data
//for this filter
Moving_average(int length, int default_data=0);
const int length() { return len;}
/*
TODO Consider adding the set_length function below to allow
users to change the length of filtered data. I don't need
this function now, so I'm leaving it for future work should
a need arise.
*/
//void set_length(const int length);
//get and set the current average
int current() {return ca;}
void set_current(const int val) {ca = val;}
//add a new data point and return the filtered result. filter() also
//sets current
int filter(int new_data);
};
#endif