| 78 | } |
| 79 | |
| 80 | int OsvrHdkLedIdentifier::getId(std::list<float> &brightnesses) const { |
| 81 | // If we don't have at least the required number of frames of data, we |
| 82 | // don't know anything. |
| 83 | if (brightnesses.size() < d_length) { |
| 84 | return -1; |
| 85 | } |
| 86 | |
| 87 | // We only care about the d_length most-recent levels. |
| 88 | truncateBrightnessListTo(brightnesses, d_length); |
| 89 | |
| 90 | // Compute the minimum and maximum brightness values. If |
| 91 | // they are too close to each other, we have a light rather |
| 92 | // than an LED. If not, compute a threshold to separate the |
| 93 | // 0's and 1's. |
| 94 | auto extrema = findMinMaxBrightness(brightnesses); |
| 95 | const auto minVal = extrema.first; |
| 96 | const auto maxVal = extrema.second; |
| 97 | static const double TODO_MIN_BRIGHTNESS_DIFF = 0.5; |
| 98 | if (maxVal - minVal <= TODO_MIN_BRIGHTNESS_DIFF) { |
| 99 | return -2; |
| 100 | } |
| 101 | const auto threshold = (minVal + maxVal) / 2; |
| 102 | |
| 103 | // Get a list of boolean values for 0's and 1's using |
| 104 | // the threshold computed above. |
| 105 | auto bits = getBitsUsingThreshold(brightnesses, threshold); |
| 106 | |
| 107 | // Search through the available patterns to see if the passed-in |
| 108 | // pattern matches any of them. If so, return that pattern. We |
| 109 | // need to check all potential rotations of the pattern, since we |
| 110 | // don't know when the code started. For the HDK, the codes are |
| 111 | // rotationally invariant. |
| 112 | |
| 113 | /// @todo feels like there should be a good algorithm for |
| 114 | /// rotation-invariant string matching besides brute-forcing it here. |
| 115 | /// -- rpavlik |
| 116 | for (size_t i = 0; i < d_patterns.size(); i++) { |
| 117 | for (size_t j = 0; j < bits.size(); j++) { |
| 118 | if (bits == d_patterns[i]) { |
| 119 | return static_cast<int>(i); |
| 120 | } |
| 121 | |
| 122 | // So long as we don't find the solution, this rotates |
| 123 | // back to the initial configuration after each inner loop. |
| 124 | std::list<bool>::iterator mid = bits.begin(); |
| 125 | std::rotate(bits.begin(), ++mid, bits.end()); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | // No pattern recognized and we should have recognized one, so return |
| 130 | // a low negative. We've used -2 so return -3. |
| 131 | return -3; |
| 132 | } |
| 133 | |
| 134 | } // End namespace vbtracker |
| 135 | } // End namespace osvr |
no test coverage detected