31#include "../../../SensorBuildOpt.h"
32#if !SENSORLIB_EXCLUDE_BHI260_KLIO
36const char *SensorBHI260AP_Klio::errorMessages[9] = {
39 "Parameter out of range",
40 "Invalid pattern operation",
52 similarity_result_buf(nullptr),
53 similarity_idx_buf(nullptr),
54 learning_callback(nullptr),
55 learning_callback_user_data(nullptr),
56 recognition_callback(nullptr),
57 recognition_callback_user_data(nullptr),
58 errorCode(KLIO_DRIVER_ERROR_NONE),
59 k_state({0, 0, 0, 0}) {}
69 sensor->configure(BoschSensorID::KLIO, 0, 0);
70 sensor->removeResultEvent(BoschSensorID::KLIO, static_klio_callback);
71 sensor->configure(BoschSensorID::KLIO_LOG, 0, 0);
72 sensor->removeResultEvent(BoschSensorID::KLIO_LOG, static_klio_log_callback);
75 if (similarity_result_buf ) {
76 free(similarity_result_buf);
77 similarity_result_buf =
nullptr;
79 if (similarity_idx_buf ) {
80 free(similarity_idx_buf);
81 similarity_idx_buf =
nullptr;
88 if (similarity_result_buf && similarity_idx_buf && sensor) {
95 const uint8_t PARAM_BUF_LEN = 252;
96 uint8_t param_buf[PARAM_BUF_LEN];
97 uint16_t size =
sizeof(param_buf);
103 if (!
getParameter(KLIO_PARAM_ALGORITHM_VERSION, param_buf, &size)) {
109 count = sscanf((
char *)param_buf,
"%d.%d.%d", &major, &minor, &version);
112 if (major < 0 || minor < 0 || version < 0 || count != 3) {
117 SENSORLIB_LOG_D(
"Klio version %d.%d.%d - buf:%s", major, minor, version, param_buf);
120 uint16_t length =
sizeof(param_buf);
121 if (!
getParameter(KLIO_PARAM_RECOGNITION_MAX_PATTERNS, param_buf, &length)) {
124 max_patterns = *((uint16_t *) param_buf);
125 similarity_result_buf = (
float *)malloc(
sizeof(
float) * max_patterns);
126 if (!similarity_result_buf) {
130 similarity_idx_buf = (uint8_t *)malloc(
sizeof(uint8_t) * max_patterns);
131 if (!similarity_idx_buf) {
133 free(similarity_result_buf);
139 length =
sizeof(param_buf);
140 if (!
getParameter(KLIO_PARAM_PATTERN_BLOB_SIZE, param_buf, &length)) {
141 free(similarity_idx_buf);
142 free(similarity_result_buf);
145 max_pattern_size = *((uint16_t *) param_buf);
149 uint8_t ignore_insignificant_movement = 1;
151 setParameter(KLIO_PARAM_LEARNING_IGNORE_INSIG_MOVEMENT, &ignore_insignificant_movement,
152 sizeof(ignore_insignificant_movement));
155 sensor->onResultEvent(BoschSensorID::KLIO_LOG, static_klio_log_callback,
this);
157 return sensor->onResultEvent(BoschSensorID::KLIO, static_klio_callback,
this);
162 bhy2_klio_sensor_state_t sensor_state = {
163 .learning_enabled = learning_enable,
164 .learning_reset = learning_reset,
165 .recognition_enabled = recognition_enable,
166 .recognition_reset = recognition_reset
168 return KlioTemplate(bhy2_klio_set_state, &sensor_state);
174 bhy2_klio_sensor_state_t sensor_state;
179 bhy2_klio_get_state(&sensor_state, sensor->getDev());
189 return bhy2_klio_set_state(&sensor_state, sensor->getDev()) == BHY2_OK;
195 k_state.learning_enabled =
true;
201 if (!KlioTemplate(bhy2_klio_set_pattern_states, KLIO_PATTERN_STATE_ENABLE, pattern_ids, size)) {
206 k_state.learning_enabled =
false;
207 k_state.recognition_enabled =
true;
213 return KlioTemplate(bhy2_klio_read_pattern, 0, pattern, size);
221void SensorBHI260AP_Klio::static_klio_callback(uint8_t sensor_id,
const uint8_t *data, uint32_t size, uint64_t *
timestamp,
void *user_data)
224 self->klio_call_local(sensor_id, data, size,
timestamp, self);
227void SensorBHI260AP_Klio::klio_call_local(uint8_t sensor_id,
const uint8_t *data_ptr, uint32_t size, uint64_t *
timestamp,
void *user_data)
229 bhy2_klio_sensor_frame_t data;
233 memcpy(&data, data_ptr,
sizeof(data));
234 if (learning_callback) {
235 if (k_state.learning_enabled) {
237 data.learn.progress, data.learn.index, learning_callback_user_data);
240 if (recognition_callback && data.recognize.index != 0xFF) {
241 if (k_state.recognition_enabled) {
242 recognition_callback(data.recognize.index, data.recognize.count, recognition_callback_user_data);
247void SensorBHI260AP_Klio::static_klio_log_callback(uint8_t sensor_id,
const uint8_t *data, uint32_t size, uint64_t *
timestamp,
void *user_data)
250 self->klio_log_call_local(sensor_id, data, size,
timestamp, self);
253void SensorBHI260AP_Klio::klio_log_call_local(uint8_t sensor_id,
const uint8_t *data_ptr, uint32_t size, uint64_t *
timestamp,
void *user_data)
255 bhy2_klio_log_frame_t data;
256 memcpy(&data, data_ptr,
sizeof(data));
257 SENSORLIB_LOG_D(
"ax: %.9g, ay: %.9g, az: %.9g, gx: %.9g, gy: %.9g, gz: %.9g\n",
268 return KlioTemplate(bhy2_klio_get_parameter,
id, parameter_data, size);
273 return KlioTemplate(bhy2_klio_set_parameter,
id, parameter_data, size);
278 return KlioTemplate(bhy2_klio_write_pattern, idx, parameter_data, size);
283 for (uint8_t
i = 0;
i < count; ++
i) {
284 if (!KlioTemplate(bhy2_klio_write_pattern, ids[
i], parameter_data_array[
i], sizes[
i])) {
294 return KlioTemplate(bhy2_klio_set_pattern_states,
static_cast<bhy2_klio_pattern_state_t
>(operation), pattern_ids, size);
299 return KlioTemplate(bhy2_klio_set_pattern_states, KLIO_PATTERN_STATE_ENABLE, pattern_ids, size);
304 return KlioTemplate(bhy2_klio_read_pattern, idx, buffer, length);
313 return sensor->configure(BoschSensorID::KLIO, sample_rate, report_latency_ms);
322 sensor->configure(BoschSensorID::KLIO, 0, 0);
331 return sensor->configure(BoschSensorID::KLIO_LOG, sample_rate, report_latency_ms);
336 learning_callback = cb;
337 learning_callback_user_data = user_data;
342 recognition_callback = cb;
343 recognition_callback_user_data = user_data;
352 uint32_t klio_status;
353 int8_t rslt = bhy2_klio_read_reset_driver_status(&klio_status, sensor->getDev());
354 if (rslt != BHY2_OK) {
355 errorCode =
static_cast<KlioError>(klio_status);
358 errorCode =
static_cast<KlioError>(klio_status);
359 return errorCode != KLIO_DRIVER_ERROR_NONE;
369 if (errorCode <= 8) {
370 return errorMessages[errorCode];
372 return "Unknown error code";
376template<
typename Func,
typename... Args>
377bool SensorBHI260AP_Klio::KlioTemplate(Func func, Args &&... args)
383 int8_t rslt = func(std::forward<Args>(args)..., sensor->getDev());
384 if (rslt != BHY2_OK) {
385 SENSORLIB_LOG_E(
"Interface access error, %s", BoschSensorUtils::get_api_error(rslt));
#define SENSORLIB_LOG_E(...)
#define SENSORLIB_LOG_D(...)
bhy2_klio_driver_error_state_t KlioError
void(*)(LearningChangeReason reason, uint32_t progress, int learn_index, void *user_data) LearningCallback
void end()
End the interaction with the KLIO functionality of the BHI260AP sensor and release related resources.
bool getLearnPattern(uint8_t *pattern, uint16_t *size)
Retrieve the learned pattern from the sensor.
bool writeMultiplePatterns(const uint8_t *ids, const uint8_t **parameter_data_array, const uint16_t *sizes, uint8_t count)
Write multiple patterns to the KLIO sensor.
bhy2_klio_parameter_t KlioParameter
bool readPattern(uint8_t idx, uint8_t *buffer, uint16_t *length)
Read a pattern from the KLIO sensor.
void setLearningCallback(LearningCallback cb, void *user_data)
Set the callback function for the learning event.
bhy2_klio_sensor_state_t KlioState
void disable()
Disable the KLIO sensor.
bool setPattern(KlioPatternState operation, const uint8_t *pattern_ids, uint16_t size)
Set the state of patterns in the KLIO sensor.
KlioError getError() const
Get the error information of the KLIO sensor.
bool writePattern(uint8_t idx, const uint8_t *parameter_data, uint16_t size)
Write a pattern to the KLIO sensor.
void(*)(uint8_t pattern_id, float count, void *user_data) RecognitionCallback
KlioState getState()
Get the current state of the KLIO sensor.
bool logout(float sample_rate, uint32_t report_latency_ms)
Log out the KLIO sensor with specified sample rate and report latency.
bool begin()
Initialize the interaction with the KLIO functionality of the BHI260AP sensor.
bool enablePattern(const uint8_t *pattern_ids, uint16_t size)
Enable specified patterns in the KLIO sensor.
bool enable(float sample_rate, uint32_t report_latency_ms)
Enable the KLIO sensor with specified sample rate and report latency.
bool learning()
Start the learning function of the KLIO sensor.
bool setState(bool learning_enable, bool learning_reset, bool recognition_enable, bool recognition_reset)
Set the learning and recognition states of the KLIO sensor.
uint8_t getMaxPatterns()
Retrieve the maximum number of recognition patterns allowed.
const char * errorToString() const
Convert the error information to a string.
bool checkError()
Check if there is an error in the KLIO sensor.
bool recognition(const uint8_t *pattern_ids, size_t size)
Start the recognition function of the KLIO sensor for the specified pattern IDs.
bool getParameter(KlioParameter id, uint8_t *parameter_data, uint16_t *size)
Get a parameter from the KLIO sensor.
void setRecognitionCallback(RecognitionCallback cb, void *user_data)
Set the callback function for the recognition event.
bool setParameter(KlioParameter id, const void *parameter_data, uint16_t size)
Set a parameter of the KLIO sensor.
SensorBHI260AP_Klio(SensorBHI260AP &sensor)
Constructor to initialize the SensorBHI260AP_Klio object.
~SensorBHI260AP_Klio()
Destructor to release resources occupied by the SensorBHI260AP_Klio object.