Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 77534e6

Browse files
fix vl53l5cx + EdgeImpulse class
1 parent d2bf9e0 commit 77534e6

File tree

5 files changed

+243
-24
lines changed

5 files changed

+243
-24
lines changed

‎examples/VL53L5CX/VL53L5cxSimpleCapture/VL53L5cxSimpleCapture.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ void setup() {
1414
// turn on high speed communication
1515
tof8x8.highFreq();
1616

17-
// truncate readings further than 2m to 2m
17+
// truncate readings at 2 meters
1818
tof8x8.truncateAt(2000);
1919

2020
// you may optionally rescale to a given range
21-
//tof8x8.setRange(0, 255);
21+
tof8x8.scale(0, 1);
2222

2323
if (!tof8x8.begin())
2424
eloquent::abort(Serial, "vl53l5cx not found");

‎examples/VL53L5CX/VL53L5cxStreamCapture/VL53L5cxStreamCapture.ino

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <eloquent/modules/vl53l5cx/stream.h>
44

55
#define RESOLUTION 8*8
6-
#define NUM_FRAMES 10
6+
#define NUM_FRAMES 16
77

88

99
Eloquent::Modules::VL53L5CXStream<RESOLUTION, NUM_FRAMES> stream;
@@ -17,14 +17,14 @@ void setup() {
1717
// turn on high speed communication
1818
stream.highFreq();
1919

20-
// truncate readings further than 2m to 2m
20+
// truncate readings further than 2 meters
2121
stream.truncateAt(2000);
2222

2323
// you may optionally rescale to a given range
24-
//stream.setRange(0, 255);
24+
stream.setRange(0, 1);
2525

26-
// emit the "queue" event once every 2 frames
27-
stream.throttle(2);
26+
// emit the "queue" event once every 4 frames
27+
stream.throttle(4);
2828

2929
if (!stream.begin())
3030
eloquent::abort(Serial, "vl53l5cx not found");

‎src/eloquent/modules/VL53L5CX.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ namespace Eloquent {
118118
* @param i
119119
* @return
120120
*/
121-
uint16_t at(uint8_t i) {
121+
float at(uint8_t i) {
122122
if (!isOk())
123123
return 0;
124124

@@ -139,7 +139,7 @@ namespace Eloquent {
139139
* @param y
140140
* @return
141141
*/
142-
uint16_t at(uint8_t x, uint8_t y) {
142+
float at(uint8_t x, uint8_t y) {
143143
const uint8_t width = sqrt(_resolution);
144144

145145
return at(y * width + x);

‎src/eloquent/modules/vl53l5cx/stream.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ namespace Eloquent {
5050
* @param i
5151
* @return
5252
*/
53-
uint8_t at(size_t i) {
53+
float at(size_t i) {
5454
return features[i];
5555
}
5656

@@ -61,7 +61,7 @@ namespace Eloquent {
6161
* @param z
6262
* @return
6363
*/
64-
uint8_t at(uint8_t x, uint8_t y, size_t z) {
64+
float at(uint8_t x, uint8_t y, size_t z) {
6565
uint8_t width = sqrt(resolution);
6666

6767
return at(z * resolution + y * width + x);
@@ -72,18 +72,20 @@ namespace Eloquent {
7272
* @return
7373
*/
7474
bool queue() {
75-
size_t head = _counter % frames;
76-
7775
if (!read())
7876
return false;
7977

8078
shift();
8179
_counter += 1;
8280

83-
for (uint16_t i = 0, j = resolution * (frames - 1); i < resolution; i++, j++)
84-
features[j] = _data.distance_mm[i];
81+
for (uint16_t i = 0, j = resolution * (frames - 1); i < resolution; i++, j++) {
82+
features[j] = VL53L5CX::at(i);
83+
}
8584

86-
if (_counter % _throttle != 1)
85+
if (_counter < frames)
86+
return false;
87+
88+
if ((_counter % _throttle) != 1)
8789
return false;
8890

8991
return true;
@@ -100,7 +102,7 @@ namespace Eloquent {
100102
void printTo(Printer &printer, char delimiter = ',', char end = '\n') {
101103
printer.print(at(0));
102104

103-
for (uint8_t i = 1; i < resolution * frames; i++) {
105+
for (uint16_t i = 1; i < resolution * frames; i++) {
104106
printer.print(delimiter);
105107
printer.print(at(i));
106108
}
@@ -118,7 +120,10 @@ namespace Eloquent {
118120
* Shift data to the left by one frame
119121
*/
120122
void shift() {
121-
memcpy(features, features + resolution, resolution * (frames - 1));
123+
//memcpy(features, features + resolution, resolution * (frames - 1));
124+
125+
for (uint16_t i = 0; i < getLength(); i++)
126+
features[i] = features[i + resolution];
122127
}
123128
};
124129
}

‎src/eloquent/tinyml/edgeimpulse/impulse.h

Lines changed: 220 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,240 @@ namespace Eloquent {
1414
class Impulse {
1515
public:
1616

17+
/**
18+
* Constructor
19+
* @param debugOn
20+
*/
21+
Impulse(bool debugOn = false) :
22+
_errorCode(0),
23+
_debug(debugOn),
24+
_idx(-1),
25+
_maxAnomaly(1) {
26+
27+
}
28+
29+
/**
30+
* Check if everything is ok
31+
* @return
32+
*/
33+
bool isOk() {
34+
return _errorCode == 0;
35+
}
36+
1737
/**
1838
*
1939
* @param features
2040
* @return
2141
*/
22-
uint8_t predict(float *features) {
23-
return 0;
42+
int8_t predict(float *features) {
43+
_idx = -1;
44+
_errorCode = numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &_signal);
45+
46+
if (!isOk()) {
47+
return error("numpy::signal_from_buffer");
48+
}
49+
50+
_errorCode = run_classifier(&_signal, &_result, _debug);
51+
52+
if (!isOk()) {
53+
return error("run_classifier");
54+
}
55+
56+
#if EI_CLASSIFIER_HAS_ANOMALY == 1
57+
if (isAnomaly())
58+
return error("anomaly");
59+
#endif
60+
61+
// find argmax of scores
62+
_idx = 0;
63+
float proba = _result.classification[0].value;
64+
65+
for (size_t ix = 1; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
66+
float p = _result.classification[ix].value;
67+
68+
if (p > proba) {
69+
_idx = ix;
70+
proba = p;
71+
}
72+
73+
if (proba >= 0.5) {
74+
break;
75+
}
76+
}
77+
78+
return _idx;
2479
}
2580

81+
/**
82+
* Predict class label
83+
* @param features
84+
* @return
85+
*/
2686
String predictLabel(float *features) {
27-
predict(features);
28-
29-
return getLabel();
87+
return getLabelOf(predict(features));
3088
}
3189

90+
/**
91+
* Get label of current prediction
92+
* @return
93+
*/
3294
String getLabel() {
33-
return "";
95+
return getLabelOf(_idx);
96+
}
97+
98+
/**
99+
* Get probability of current prediction
100+
* @return
101+
*/
102+
float getProba() {
103+
return getProbaOf(_idx);
104+
}
105+
106+
/**
107+
* Get label of given class id
108+
* @param idx
109+
* @return
110+
*/
111+
String getLabelOf(int8_t idx) {
112+
if (idx < 0)
113+
return "";
114+
115+
if (idx >= EI_CLASSIFIER_LABEL_COUNT)
116+
return "OUT OF RANGE";
117+
118+
return _result.classification[idx].label;
34119
}
35120

121+
/**
122+
* Get probability of given class id
123+
* @param idx
124+
* @return
125+
*/
126+
float getProbaOf(int8_t idx) {
127+
if (idx < 0)
128+
return 0;
129+
130+
if (idx >= EI_CLASSIFIER_LABEL_COUNT)
131+
return 0;
132+
133+
return _result.classification[idx].value;
134+
}
135+
136+
/**
137+
* Get time spent on DSP
138+
* @return
139+
*/
140+
uint16_t getDspTiming() {
141+
return _result.timing.dsp;
142+
}
143+
144+
/**
145+
* Get time spent on classification
146+
* @return
147+
*/
148+
uint16_t getClassificationTiming() {
149+
return _result.timing.classification;
150+
}
151+
152+
/**
153+
* Debug classification result to given printer
154+
* @tparam Printer
155+
* @param printer
156+
*/
157+
template<class Printer>
158+
void printTo(Printer &printer) {
159+
printer.print("EdgeImpulse classification results\n");
160+
printer.print("----------------------------------\n");
161+
printer.print(" > Class scores\n");
162+
163+
for (uint8_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
164+
printer.print(" > ");
165+
printer.print(getLabelOf(i));
166+
printer.print(": ");
167+
printer.print(getProbaOf(i));
168+
printer.print("\n");
169+
}
170+
171+
#if EI_CLASSIFIER_HAS_ANOMALY == 1
172+
printer.print(" > Anomaly: ");
173+
printer.print(getAnomalyScore());
174+
printer.print("\n");
175+
#endif
176+
177+
printer.print(" > Timing\n");
178+
printer.print(" > DSP: ");
179+
printer.print(getDspTiming());
180+
printer.print(" ms\n");
181+
printer.print(" > Classification: ");
182+
printer.print(getClassificationTiming());
183+
printer.print(" ms\n");
184+
185+
#if EI_CLASSIFIER_HAS_ANOMALY == 1
186+
printer.print(" > Anomaly: ");
187+
printer.print(getAnomalyTiming());
188+
printer.print(" ms\n");
189+
#endif
190+
191+
printer.print(" > Error: ");
192+
printer.print(isOk() ? "OK" : _errorMessage);
193+
printer.print("(");
194+
printer.print(_errorCode);
195+
printer.print(")\n");
196+
}
197+
198+
#if EI_CLASSIFIER_HAS_ANOMALY == 1
199+
200+
/**
201+
* Set max allowed anomaly score
202+
*/
203+
void setMaxAnomalyScore(float score) {
204+
_maxAnomaly = score;
205+
}
206+
207+
/**
208+
* Check if current prediction is an anomaly
209+
*/
210+
bool isAnomaly() {
211+
return !isOk() || getAnomalyScore() > _maxAnomaly;
212+
}
213+
214+
/**
215+
* Get time spent on anomaly detection
216+
* @return
217+
*/
218+
uint16_t getAnomalyTiming() {
219+
return _result.timing.anomaly;
220+
}
221+
222+
/**
223+
* Get anomaly score
224+
* @return
225+
*/
226+
float getAnomalyScore() {
227+
return _result.anomaly;
228+
}
229+
#endif
230+
36231
protected:
232+
bool _debug;
233+
int _errorCode;
234+
float _maxAnomaly;
235+
String _errorMessage;
236+
signal_t _signal;
237+
ei_impulse_result_t _result;
238+
int8_t _idx;
239+
240+
241+
/**
242+
* Return error
243+
* @param errorMessage
244+
* @return
245+
*/
246+
int8_t error(const char *errorMessage) {
247+
_errorMessage = String(errorMessage);
248+
249+
return -1;
250+
}
37251
};
38252
}
39253
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /