-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsensor.h
168 lines (134 loc) · 3.47 KB
/
sensor.h
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
163
164
165
166
167
168
#ifndef SENSOR_H
#define SENSOR_H
#define MPU_I2C_ADDR 0x68
#define GYRO_CONF_ADDR 27
#define ACCEL_CONF_ADDR 28
#define ACCEL_ADDR 59
#define GYRO_ADDR 67
#define PWR_ADDR 107
#define CALIBRATION_SAMPLES 100
#define CALIBRATION_SPACING_MS 10
#define GYRO_SCALE 250 / 32767.0f //131.0f
#define ACCEL_SCALE 4 / 32767.0f
#define SENSOR_TILT -11.3f
#define RADIANS PI/180.0f
#define DEGREES 180/PI
#define GYRO_CORRECTION_RATE 0.5f
#include <Wire.h>
#include <Arduino.h>
struct IVec3 {
short x;
short y;
short z;
void print();
};
struct Vec3 {
float x;
float y;
float z;
void print();
};
struct PYR {
float pitch;
float yaw;
float roll;
void print();
};
struct Quaternion {
float x;
float y;
float z;
float w;
void print();
Quaternion add(Quaternion b);
Quaternion subtract(Quaternion b);
inline Quaternion rotate(Vec3 axis, float theta) {
Quaternion b = fromAxisAngle(axis, theta);
return b.multiply(*this);
}
inline Quaternion multiply(Quaternion b) {
return Quaternion{
this->w*b.x + this->x*b.w + this->y*b.z - this->z*b.y,
this->w*b.y + this->y*b.w + this->z*b.x - this->x*b.z,
this->w*b.z + this->z*b.w + this->x*b.y - this->y*b.x,
this->w*b.w - this->x*b.x - this->y*b.y - this->z*b.z
};
}
inline Quaternion inverse() {
Quaternion retval = *this;
retval.x *= -1.0f;
retval.y *= -1.0f;
retval.z *= -1.0f;
return retval;
}
static inline Quaternion fromAxisAngle(Vec3 axis, float theta) {
float sine = sinf(theta/2.0f);
return Quaternion {
sine * axis.x,
sine * axis.y,
sine * axis.z,
cosf(theta/2.0f)
};
}
static inline Quaternion fromPYR(PYR p) {
float cp = cosf(p.pitch/2.0f);
float cy = cosf(p.yaw/2.0f);
float cr = cosf(p.roll/2.0f);
float sp = sinf(p.pitch/2.0f);
float sy = sinf(p.yaw/2.0f);
float sr = sinf(p.roll/2.0f);
return Quaternion {
cy*cp*sr - sy*sp*cr,
cy*sp*cr + sy*cp*sr,
sy*cp*cr - cy*sp*sr,
cy*cp*cr - sy*sp*sr
};
}
inline void normalize() {
float magnitude = sqrtf(this->x*this->x + this->y*this->y + this->z*this->z + this->w*this->w);
this->x /= magnitude;
this->y /= magnitude;
this->z /= magnitude;
this->w /= magnitude;
}
inline PYR toPYR() {
Quaternion q = *this;
PYR retval;
// roll (x-axis rotation)
float sinr_cosp = 2.0f * (q.w * q.x + q.y * q.z);
float cosr_cosp = 1.0f - 2.0f * (q.x * q.x + q.y * q.y);
retval.roll = std::atan2(sinr_cosp, cosr_cosp);
// pitch (y-axis rotation)
float sinp = std::sqrt(1.0f + 2.0f * (q.w * q.y - q.x * q.z));
float cosp = std::sqrt(1.0f - 2.0f * (q.w * q.y - q.x * q.z));
retval.pitch = 2.0f * std::atan2(sinp, cosp) - PI / 2.0f;
// yaw (z-axis rotation)
float siny_cosp = 2.0f * (q.w * q.z + q.x * q.y);
float cosy_cosp = 1.0f - 2.0f * (q.y * q.y + q.z * q.z);
retval.yaw = std::atan2(siny_cosp, cosy_cosp);
return retval;
}
};
struct FlightData {
FlightData();
Vec3 displacement;
PYR attitude;
PYR perceivedDown;//direction sensor believes is down
Vec3 gyroOffset;
Vec3 accelOffset;
Vec3 gyro;
Vec3 accel;
void calibrate();
Vec3 getAccel();
Vec3 getGyro();
Vec3 isolatedAccel();
PYR getAttitude();
void update(float dtime);
static PYR pyrFromAccel(Vec3 accel);
};
void initSensor();
int8_t readReg(int8_t reg);
void writeReg(int8_t reg, int8_t value);
IVec3 readRawGyro();
IVec3 readRawAccel();
#endif