blob: 17c8ce4517c0d1fd9dd367614800a60914b943f0 [file] [log] [blame]
/*
* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gesture_predictor.hpp"
#include "constants.hpp"
namespace {
/* State for the averaging algorithm we're using. */
float prediction_history[kGestureCount][kPredictionHistoryLength] = {};
int prediction_history_index = 0;
int prediction_suppression_count = 0;
} /* namespace */
/* Return the result of the last prediction
* 0: wing("W"), 1: ring("O"), 2: slope("angle"), 3: unknown
*/
int PredictGesture(float *output)
{
/* Record the latest predictions in our rolling history buffer. */
for (int i = 0; i < kGestureCount; ++i) {
prediction_history[i][prediction_history_index] = output[i];
}
/* Figure out which slot to put the next predictions into. */
++prediction_history_index;
if (prediction_history_index >= kPredictionHistoryLength) {
prediction_history_index = 0;
}
/* Average the last n predictions for each gesture, and find which has the
* highest score.
*/
int max_predict_index = -1;
float max_predict_score = 0.0f;
for (int i = 0; i < kGestureCount; i++) {
float prediction_sum = 0.0f;
for (int j = 0; j < kPredictionHistoryLength; ++j) {
prediction_sum += prediction_history[i][j];
}
const float prediction_average = prediction_sum / kPredictionHistoryLength;
if ((max_predict_index == -1) || (prediction_average > max_predict_score)) {
max_predict_index = i;
max_predict_score = prediction_average;
}
}
/* If there's been a recent prediction, don't trigger a new one too soon. */
if (prediction_suppression_count > 0) {
--prediction_suppression_count;
}
/* If we're predicting no gesture, or the average score is too low, or there's
* been a gesture recognised too recently, return no gesture.
*/
if ((max_predict_index == kNoGesture) ||
(max_predict_score < kDetectionThreshold) ||
(prediction_suppression_count > 0)) {
return kNoGesture;
} else {
/* Reset the suppression counter so we don't come up with another prediction
* too soon.
*/
prediction_suppression_count = kPredictionSuppressionDuration;
return max_predict_index;
}
}