-
Notifications
You must be signed in to change notification settings - Fork 0
/
Prototype_FINAL_Ver.ino
162 lines (115 loc) · 3.06 KB
/
Prototype_FINAL_Ver.ino
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "encoder_functions.h"
#include "motor_functions.h"
#include "joystick_functions.h"
#include "pid_functions.h"
#define ANGLE_OFFSET 0
#define BTN_PIN 2
#define N 10
#define ALPHA 0.25
float angle_lim[2] = {90, 165};
void sense();
void process();
void actuate();
float iir_filter(float actual, float last_est, float alpha);
float rolling_avg_filter(float actual, float *last_ests, int n);
float setpoint = 0;
float input = 0;
bool done = false;
unsigned long long duration = 5000;
unsigned long long start_time = 0;
unsigned long long last_time = 0;
unsigned long long time = 0;
unsigned long long refresh_time = 0;
unsigned long long refresh_period = 4000;
float dt = 0;
float raw_angle = 0;
float last_angle = 0;
float angle = 0;
float last_speeds[N] = {0};
float speed = 0;
int joystick_x = 0;
int joystick_y = 0;
bool joystick_btn = 0;
bool btn_pressed = false;
float err = 0;
float last_err = 0;
float err_dot = 0;
void setup() {
Serial.begin(9600);
motor_init();
spi_init();
joystick_init();
pinMode(BTN_PIN, INPUT_PULLUP);
for (int i = 0; i < 20; i++) {
sense();
process();
delay(30);
}
done = false;
Serial.printf("Current angle: %f\n", angle);
Serial.println("Test Begin");
for (int i = 0; i < 3; i++) {
sense();
process();
delay(30);
}
done = false;
enable();
start_time = millis();
}
void loop() {
sense();
process();
actuate();
Serial.print(joystick_x);
Serial.print(' ');
Serial.print(input);
Serial.print(' ');
Serial.println(get_angle());
delay(20);
}
void sense() {
float measurement = get_angle();
bool btn_read = digitalRead(BTN_PIN);
int joystick_data[3] = {0};
measure_joystick(joystick_data);
if (measurement)
raw_angle = measurement;
btn_pressed = !btn_read;
joystick_x = -joystick_data[0];
joystick_y = joystick_data[1];
joystick_btn = !joystick_data[2];
last_time = time;
time = millis();
}
void process() {
last_angle = angle;
angle = iir_filter(raw_angle - ANGLE_OFFSET, last_angle, ALPHA);
long long DT = time - last_time;
dt = (float)DT / 1000;
float raw_speed = (angle - last_angle) / dt;
for (int i = 0; i < N - 1; i++)
last_speeds[i] = last_speeds[i + 1];
last_speeds[N - 1] = speed;
speed = rolling_avg_filter(raw_speed, last_speeds, N);
int max_input = 255;
input = mapFloat(joystick_x, -515, 515, -max_input, max_input);
input = constrain(input, -max_input, max_input);
if (angle >= angle_lim[1] && input >= 0)
input = 0;
else if (angle <= angle_lim[0] && input <= 0)
input = 0;
}
void actuate() {
set_speed(input);
}
float iir_filter(float actual, float last_est, float alpha) {
return alpha * actual + (1 - alpha) * last_est;
}
float rolling_avg_filter(float actual, float *last_ests, int n) {
float est = actual;
for (int i = 0; i < n; i++)
est += last_ests[i];
est /= n;
return est;
}