tutrcos
読み取り中…
検索中…
一致する文字列を見つけられません
bno055.hpp
[詳解]
1#pragma once
2
3#include <array>
4#include <cmath>
5#include <cstdint>
6
7#include "tutrcos/core.hpp"
9
10namespace tutrcos {
11namespace module {
12
47class BNO055 {
48public:
49 BNO055(peripheral::UART &uart, uint32_t timeout = 500) : uart_{uart} {}
50
51 bool init(uint32_t timeout) {
52 uint32_t start = core::Kernel::get_ticks();
53 while (core::Kernel::get_ticks() - start < timeout) {
54 uint8_t data = 0x00;
55 if (!write_reg(0x3D, &data, 1)) {
56 continue;
57 }
58 data = 0x04;
59 if (!write_reg(0x3B, &data, 1)) {
60 continue;
61 }
62 data = 0x08;
63 if (!write_reg(0x3D, &data, 1)) {
64 continue;
65 }
66 return true;
67 }
68 return false;
69 }
70
71 bool update() {
72 std::array<int16_t, 4> data;
73 if (!read_reg(0x1A, reinterpret_cast<uint8_t *>(data.data()), 6)) {
74 return false;
75 }
76 euler_x_orig_ = data[0] / 900.0f;
77 euler_y_orig_ = data[1] / 900.0f;
78 euler_z_orig_ = data[2] / 900.0f;
79
80 euler_x_ = normalize_angle(euler_x_orig_ - euler_x_offset_);
81 euler_y_ = normalize_angle(euler_y_orig_ - euler_y_offset_);
82 euler_z_ = normalize_angle(euler_z_orig_ - euler_z_offset_);
83
84 if (!read_reg(0x20, reinterpret_cast<uint8_t *>(data.data()), 8)) {
85 return false;
86 }
87 quat_w_orig_ = data[0] / 16384.0f;
88 quat_x_orig_ = data[1] / 16384.0f;
89 quat_y_orig_ = data[2] / 16384.0f;
90 quat_z_orig_ = data[3] / 16384.0f;
91
92 quat_w_ = quat_w_orig_ * quat_w_offset_ - quat_x_orig_ * quat_x_offset_ -
93 quat_y_orig_ * quat_y_offset_ - quat_z_orig_ * quat_z_offset_;
94 quat_x_ = quat_w_orig_ * quat_x_offset_ + quat_x_orig_ * quat_w_offset_ +
95 quat_y_orig_ * quat_z_offset_ - quat_z_orig_ * quat_y_offset_;
96 quat_y_ = quat_w_orig_ * quat_y_offset_ - quat_x_orig_ * quat_z_offset_ +
97 quat_y_orig_ * quat_w_offset_ + quat_z_orig_ * quat_x_offset_;
98 quat_z_ = quat_w_orig_ * quat_z_offset_ + quat_x_orig_ * quat_y_offset_ -
99 quat_y_orig_ * quat_x_offset_ + quat_z_orig_ * quat_w_offset_;
100 return true;
101 }
102
103 void reset_euler() {
104 euler_x_offset_ = euler_x_orig_;
105 euler_y_offset_ = euler_y_orig_;
106 euler_z_offset_ = euler_z_orig_;
107 }
108
109 void reset_quat() {
110 quat_w_offset_ = -quat_w_orig_;
111 quat_x_offset_ = quat_x_orig_;
112 quat_y_offset_ = quat_y_orig_;
113 quat_z_offset_ = quat_z_orig_;
114 }
115
116 float get_euler_x() { return euler_x_; }
117
118 float get_euler_y() { return euler_y_; }
119
120 float get_euler_z() { return euler_z_; }
121
122 float get_quat_w() { return quat_w_; }
123
124 float get_quat_x() { return quat_x_; }
125
126 float get_quat_y() { return quat_y_; }
127
128 float get_quat_z() { return quat_z_; }
129
130private:
131 peripheral::UART &uart_;
132
133 float euler_x_orig_ = 0;
134 float euler_y_orig_ = 0;
135 float euler_z_orig_ = 0;
136
137 float euler_x_offset_ = 0;
138 float euler_y_offset_ = 0;
139 float euler_z_offset_ = 0;
140
141 float euler_x_ = 0;
142 float euler_y_ = 0;
143 float euler_z_ = 0;
144
145 float quat_w_orig_ = 1;
146 float quat_x_orig_ = 0;
147 float quat_y_orig_ = 0;
148 float quat_z_orig_ = 0;
149
150 float quat_w_offset_ = -1;
151 float quat_x_offset_ = 0;
152 float quat_y_offset_ = 0;
153 float quat_z_offset_ = 0;
154
155 float quat_w_ = 1;
156 float quat_x_ = 0;
157 float quat_y_ = 0;
158 float quat_z_ = 0;
159
160 bool write_reg(uint8_t addr, uint8_t *data, uint8_t size) {
161 std::array<uint8_t, 4> buf{0xAA, 0x00, addr, size};
162 uart_.flush();
163 if (!uart_.transmit(buf.data(), 4, 5)) {
164 return false;
165 }
166 if (!uart_.transmit(data, size, 5)) {
167 return false;
168 }
169 if (!uart_.receive(buf.data(), 2, 5)) {
170 return false;
171 }
172 return buf[0] == 0xEE && buf[1] == 0x01;
173 }
174
175 bool read_reg(uint8_t addr, uint8_t *data, uint8_t size) {
176 std::array<uint8_t, 4> buf{0xAA, 0x01, addr, size};
177 uart_.flush();
178 if (!uart_.transmit(buf.data(), 4, 5)) {
179 return false;
180 }
181 if (!uart_.receive(buf.data(), 2, 5)) {
182 return false;
183 }
184 if (buf[0] != 0xBB || buf[1] != size) {
185 return false;
186 }
187 return uart_.receive(data, size, 5);
188 }
189
190 float normalize_angle(float angle) {
191 float res = fmod(angle, 2.0f * M_PI);
192 if (res < 0) {
193 return res + 2.0f * M_PI;
194 }
195 return res;
196 }
197};
198
199} // namespace module
200} // namespace tutrcos
static uint32_t get_ticks()
Definition kernel.hpp:14
Definition bno055.hpp:47
float get_euler_y()
Definition bno055.hpp:118
float get_euler_x()
Definition bno055.hpp:116
float get_quat_z()
Definition bno055.hpp:128
bool init(uint32_t timeout)
Definition bno055.hpp:51
bool update()
Definition bno055.hpp:71
void reset_euler()
Definition bno055.hpp:103
float get_quat_x()
Definition bno055.hpp:124
float get_quat_y()
Definition bno055.hpp:126
BNO055(peripheral::UART &uart, uint32_t timeout=500)
Definition bno055.hpp:49
float get_quat_w()
Definition bno055.hpp:122
float get_euler_z()
Definition bno055.hpp:120
void reset_quat()
Definition bno055.hpp:109
Definition uart.hpp:51
bool receive(uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:85
bool transmit(const uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:69
void flush()
Definition uart.hpp:101
Definition kernel.hpp:7