37 using vector_size_type = Vec3Vector::size_type;
39 vector_size_type minSize = 0;
40 vector_size_type maxSize = 0;
42 inline VectorSizes getMinMaxSetupDataSizes(TargetSetupData
const &d) {
45 auto sizes = {d.patterns.size(),
47 d.emissionDirections.size(),
48 d.baseMeasurementVariances.size(),
49 d.initialAutocalibrationErrors.size(),
52 std::tie(ret.minSize, ret.maxSize) = std::minmax(sizes);
56 enum class BeaconPatternStatus {
59 PatternContainsInvalidCharacter
61 inline BeaconPatternStatus
62 judgeBeaconPattern(std::string
const &pattern) {
64 if (pattern.empty()) {
65 return BeaconPatternStatus::PatternEmpty;
67 if (pattern.find_first_not_of(
".*") != std::string::npos) {
72 return BeaconPatternStatus::PatternContainsInvalidCharacter;
74 return BeaconPatternStatus::PatternOK;
76 class TargetDataChecker {
78 using size_type = Vec3Vector::size_type;
79 TargetDataChecker(TargetSetupData &data, TargetDataSummary &summary)
80 : d(data), m_summary(summary),
81 m_sizes(getMinMaxSetupDataSizes(data)) {}
85 void process(
bool silent) {
87 for (size_type i = 0; i < m_sizes.minSize; ++i) {
88 if (disabledBeacon(i)) {
89 d.patterns[i].clear();
92 if (0 == m_patternLength) {
95 m_patternLength = d.patterns[i].size();
97 OSVR_DEV_VERBOSE(
"Determined that patterns are "
102 bool gotError =
false;
103 checkPatternLength(i, gotError);
104 checkLocationValidity(i, gotError);
105 checkEmissionDirection(i, gotError);
106 checkMeasVariance(i, gotError);
107 checkAutocalib(i, gotError);
110 m_summary.validBeacons.push_back(wrapIndex(i));
115 for (size_type i = m_sizes.minSize; i < m_sizes.maxSize; ++i) {
120 bool gotError =
false;
122 i,
"Mismatched vectors: Beacon ID exists "
123 "in at least one vector, but not in all vectors.");
124 if (inRange(i, d.patterns,
"pattern")) {
125 if (disabledBeacon(i)) {
130 checkPatternLength(i, gotError);
133 if (inRange(i, d.locations,
"locations")) {
134 checkLocationValidity(i, gotError);
137 if (inRange(i, d.emissionDirections,
138 "emissionDirections")) {
139 checkEmissionDirection(i, gotError);
142 if (inRange(i, d.baseMeasurementVariances,
143 "baseMeasurementVariances")) {
144 checkMeasVariance(i, gotError);
147 auto gotInitialAutocalib =
148 inRange(i, d.initialAutocalibrationErrors,
149 "initialAutocalibrationErrors");
150 auto gotIsFixed = inRange(i, d.isFixed,
"isFixed");
151 if (gotInitialAutocalib && gotIsFixed) {
152 checkAutocalib(i, gotError);
162 bool disabledBeacon(size_type i) {
163 switch (judgeBeaconPattern(d.patterns[i])) {
164 case BeaconPatternStatus::PatternEmpty:
165 m_summary.disabledByEmptyPattern.push_back(wrapIndex(i));
167 case BeaconPatternStatus::PatternContainsInvalidCharacter:
172 m_summary.disabledByPattern.push_back(wrapIndex(i));
174 case BeaconPatternStatus::PatternOK:
179 void checkPatternLength(size_type i,
bool &gotError) {
181 if (d.patterns[i].size() != m_patternLength) {
183 recordError(i,
"Pattern was non-empty and all legal "
184 "characters, but length did not match.");
188 void checkLocationValidity(size_type i,
bool &gotError) {
192 recordError(i,
"Beacon location is still the bogus "
193 "'uninitialized' sentinel value.");
197 void checkEmissionDirection(size_type i,
bool &gotError) {
198 if (d.emissionDirections[i] == EmissionDirectionVec(0, 0, 0)) {
202 "Beacon emission direction is zero - uninitialized.");
207 void checkMeasVariance(size_type i,
bool &gotError) {
208 if (d.baseMeasurementVariances.size() <= i) {
209 d.baseMeasurementVariances.resize(i + 1, 1.);
211 if (d.baseMeasurementVariances[i] <= 0) {
214 i,
"Beacon base measurement variance is not positive.");
217 void checkAutocalib(size_type i,
bool &gotError) {
221 d.initialAutocalibrationErrors[i] = 0;
222 }
else if (d.initialAutocalibrationErrors[i] == 0.) {
224 recordError(i,
"Beacon initial autocalib error is zero, "
225 "but not marked as fixed (so autocalib "
226 "process noise would apply, etc.)");
227 }
else if (d.initialAutocalibrationErrors[i] < 0.) {
231 "Beacon initial autocalib error is negative.");
238 template <
typename T>
239 bool inRange(size_type i, T &vec, std::string
const &name) {
240 if (i < vec.size()) {
245 "Mismatched vectors: Beacon ID exists in at least "
246 "one vector, but not enough entries in the " +
251 template <
typename T>
void recordError(size_type i, T &&arg) {
252 m_summary.errors.emplace_back(wrapIndex(i),
253 std::forward<T>(arg));
256 static OneBasedBeaconId wrapIndex(size_type i) {
257 return makeOneBased(ZeroBasedBeaconId(i));
263 TargetDataSummary &m_summary;
264 std::size_t m_patternLength = 0;
265 VectorSizes
const m_sizes;
266 size_type m_minSize = 0;
267 size_type m_maxSize = 0;
272 auto zeroId = makeZeroBased(beacon);
273 if (!(zeroId.value() < patterns.size())) {
277 return (judgeBeaconPattern(patterns[zeroId.value()]) ==
278 BeaconPatternStatus::PatternOK);
282 if (!(beacon.value() < patterns.size())) {
288 patterns[beacon.value()].clear();
294 TargetDataChecker checker(*
this, ret);
295 checker.process(silent);
static LocationPoint getBogusLocation()
void markBeaconInactive(ZeroBasedBeaconId beacon)
bool isBeaconActive(OneBasedBeaconId beacon)
Is the beacon active?
Internal, configured header file for verbosity macros.