void SideConfidenceProvider::updateBallConfidences(SideConfidence& sideConfidence) { // Check, if a mirrorcle has occured in the last frame if(sideConfidence.mirror) { confidenceBuffer.clear(); averageBallConfidence = UNKNOWN; sideConfidence.mirror = false; } // Special handling for certain game states: if(theGameInfo.state != STATE_PLAYING || theRobotInfo.penalty != PENALTY_NONE) { confidenceBuffer.clear(); averageBallConfidence = UNKNOWN; } // Save current local ball observation: if((theBallModel.timeWhenLastSeen == theFrameInfo.time && theFrameInfo.time != 0) && (theFieldDimensions.isInsideField(theRobotPose * theBallModel.estimate.position)) && (theBallModel.estimate.velocity.norm() <= maxBallVelocity) && (theRobotPose * theBallModel.estimate.position).norm() > centerBanZoneRadius) { lastBallObservation = theBallModel.estimate.position; timeOfLastBallObservation = theFrameInfo.time; } // Odometry update for buffered perception else if(theFrameInfo.getTimeSince(timeOfLastBallObservation) < ballBufferingInterval) { lastBallObservation = theOdometer.odometryOffset.inverse() * lastBallObservation; } // Add current confidence to buffer: if((theFrameInfo.getTimeSince(timeOfLastBallObservation) < ballBufferingInterval) && (theLocalizationTeamBall.isValid) && (theLocalizationTeamBall.position.norm() > centerBanZoneRadius) && (theLocalizationTeamBall.lastObservation > timeOfLastTeamBallObservation)) { SideConfidenceMeasurement scm; scm.ballConfidence = computeCurrentBallConfidence(); scm.timeStamp = timeOfLastBallObservation; confidenceBuffer.push_front(scm); timeOfLastBallObservation = 0; //For next confidence computation, a "fresh" observation is needed timeOfLastTeamBallObservation = theLocalizationTeamBall.lastObservation; } else { return; } // Check current buffer content for possible mirror situation if(!confidenceBuffer.full()) { return; } size_t mirrorCount(0); size_t okCount(0); for(const SideConfidenceMeasurement& confidence : confidenceBuffer) { switch(confidence.ballConfidence) { case MIRROR: ++mirrorCount; break; case OK: ++okCount; break; } } size_t unknownCount = confidenceBuffer.size() - mirrorCount - okCount; if((okCount == 0) && (mirrorCount > unknownCount)) averageBallConfidence = MIRROR; else if((okCount > unknownCount) && (mirrorCount == 0)) averageBallConfidence = OK; else averageBallConfidence = UNKNOWN; }
uint8_t StatusClient::read() { // Read the message type int32_t message_type; size_t bytes = _client.read((uint8_t *) &message_type, sizeof(message_type)); if (bytes < 1) { Serial1.println("Error reading message type"); return STATE_READ_ERROR; } // Decode message type as big-endian message_type = __REV(message_type); switch (message_type) { case MESSAGE_UPDATE: break; case MESSAGE_ERROR: Serial1.println("Upstream error"); return STATE_UPSTREAM_ERROR; default: Serial1.print("Unknown message type "); Serial1.print(message_type, HEX); Serial1.println(); return STATE_READ_ERROR; } // Read the message contents bytes = _client.read((uint8_t *) &_buffer, sizeof(NagiosStatus)); if (bytes < sizeof(_buffer)) { Serial1.println("Error reading message contents"); return STATE_READ_ERROR; } // Switch to little-endian values uint32_t *ptr = (uint32_t *) &_buffer; uint32_t *max_ptr = ptr + sizeof(NagiosStatus); for (; ptr < max_ptr; ++ptr) *ptr = __REV(*ptr); // Update the notification flags if (_buffer.critical_serial > _status.critical_serial) _notifications |= NOTIFICATION_CRITICAL; if (_buffer.warning_serial > _status.warning_serial) _notifications |= NOTIFICATION_WARNING; if (_buffer.ok_serial > _status.ok_serial) _notifications |= NOTIFICATION_OK; // Store the new status memcpy(&_status, &_buffer, sizeof(NagiosStatus)); // Debug logging Serial1.print("New status: "); Serial1.print(criticalCount()); Serial1.print(" "); Serial1.print(warningCount()); Serial1.print(" "); Serial1.print(okCount()); Serial1.print(", notifications: 0x"); Serial1.print(notifications(), HEX); Serial1.println(); return STATE_OK; }