DataValidatorGroup::DataValidatorGroup(unsigned siblings) : _first(nullptr), _last(nullptr), _curr_best(-1), _prev_best(-1), _first_failover_time(0), _toggle_count(0) { DataValidator *next = nullptr; DataValidator *prev = nullptr; for (unsigned i = 0; i < siblings; i++) { next = new DataValidator(); if (i == 0) { _first = next; } else { prev->setSibling(next); } prev = next; } _last = next; if (_first) { _timeout_interval_us = _first->get_timeout(); } }
float DataValidatorGroup::get_vibration_factor(uint64_t timestamp) { DataValidator *next = _first; float vibe = 0.0f; /* find the best RMS value of a non-timed out sensor */ while (next != nullptr) { if (next->confidence(timestamp) > 0.5f) { float *rms = next->rms(); for (unsigned j = 0; j < 3; j++) { if (rms[j] > vibe) { vibe = rms[j]; } } } next = next->sibling(); } return vibe; }
void DataValidatorGroup::set_equal_value_threshold(uint32_t threshold) { DataValidator *next = _first; while (next != nullptr) { next->set_equal_value_threshold(threshold); next = next->sibling(); } }
void DataValidatorGroup::set_timeout(uint32_t timeout_interval_us) { DataValidator *next = _first; while (next != nullptr) { next->set_timeout(timeout_interval_us); next = next->sibling(); } _timeout_interval_us = timeout_interval_us; }
void Sensors::print_status() { _voted_sensors_update.print_status(); PX4_INFO("Airspeed status:"); _airspeed_validator.print(); }
void DataValidatorGroup::put(unsigned index, uint64_t timestamp, float val[3], uint64_t error_count, int priority) { DataValidator *next = _first; unsigned i = 0; while (next != nullptr) { if (i == index) { next->put(timestamp, val, error_count, priority); break; } next = next->sibling(); i++; } }
uint32_t DataValidatorGroup::failover_state() { DataValidator *next = _first; unsigned i = 0; while (next != nullptr) { if (next->used() && (next->state() != DataValidator::ERROR_FLAG_NO_ERROR) && (i == (unsigned)_prev_best)) { return next->state(); } next = next->sibling(); i++; } return DataValidator::ERROR_FLAG_NO_ERROR; }
void Sensors::diff_pres_poll(struct sensor_combined_s &raw) { bool updated; orb_check(_diff_pres_sub, &updated); if (updated) { orb_copy(ORB_ID(differential_pressure), _diff_pres_sub, &_diff_pres); float air_temperature_celsius = (_diff_pres.temperature > -300.0f) ? _diff_pres.temperature : (raw.baro_temp_celcius - PCB_TEMP_ESTIMATE_DEG); _airspeed.timestamp = _diff_pres.timestamp; /* push data into validator */ _airspeed_validator.put(_airspeed.timestamp, _diff_pres.differential_pressure_raw_pa, _diff_pres.error_count, 100); #ifdef __PX4_POSIX _airspeed.confidence = 1.0f; #else _airspeed.confidence = _airspeed_validator.confidence(hrt_absolute_time()); #endif /* don't risk to feed negative airspeed into the system */ _airspeed.indicated_airspeed_m_s = math::max(0.0f, calc_indicated_airspeed(_diff_pres.differential_pressure_filtered_pa)); _airspeed.true_airspeed_m_s = math::max(0.0f, calc_true_airspeed(_diff_pres.differential_pressure_filtered_pa + _voted_sensors_update.baro_pressure() * 1e2f, _voted_sensors_update.baro_pressure() * 1e2f, air_temperature_celsius)); _airspeed.true_airspeed_unfiltered_m_s = math::max(0.0f, calc_true_airspeed(_diff_pres.differential_pressure_raw_pa + _voted_sensors_update.baro_pressure() * 1e2f, _voted_sensors_update.baro_pressure() * 1e2f, air_temperature_celsius)); _airspeed.air_temperature_celsius = air_temperature_celsius; _airspeed.differential_pressure_filtered_pa = _diff_pres.differential_pressure_filtered_pa; int instance; orb_publish_auto(ORB_ID(airspeed), &_airspeed_pub, &_airspeed, &instance, ORB_PRIO_DEFAULT); } }
void DataValidatorGroup::print() { /* print the group's state */ ECL_INFO("validator: best: %d, prev best: %d, failsafe: %s (%u events)", _curr_best, _prev_best, (_toggle_count > 0) ? "YES" : "NO", _toggle_count); DataValidator *next = _first; unsigned i = 0; while (next != nullptr) { if (next->used()) { uint32_t flags = next->state(); ECL_INFO("sensor #%u, prio: %d, state:%s%s%s%s%s%s", i, next->priority(), ((flags & DataValidator::ERROR_FLAG_NO_DATA) ? " OFF" : ""), ((flags & DataValidator::ERROR_FLAG_STALE_DATA) ? " STALE" : ""), ((flags & DataValidator::ERROR_FLAG_TIMEOUT) ? " TOUT" : ""), ((flags & DataValidator::ERROR_FLAG_HIGH_ERRCOUNT) ? " ECNT" : ""), ((flags & DataValidator::ERROR_FLAG_HIGH_ERRDENSITY) ? " EDNST" : ""), ((flags == DataValidator::ERROR_FLAG_NO_ERROR) ? " OK" : "")); next->print(); } next = next->sibling(); i++; } }
float DataValidatorGroup::get_vibration_offset(uint64_t timestamp, int axis) { DataValidator *next = _first; float vibe = -1.0f; /* find the best vibration value of a non-timed out sensor */ while (next != nullptr) { if (next->confidence(timestamp) > 0.5f) { float *vibration_offset = next->vibration_offset(); if (vibe < 0.0f || vibration_offset[axis] < vibe) { vibe = vibration_offset[axis]; } } next = next->sibling(); } return vibe; }
NewAccountDialog::NewAccountDialog( GuiFactory* factory ) : GeneralDialogBox(factory,factory->getLanguageManager(),factory->getGuiColorManager(),factory->getFontManager()) { setTitle("account.create"); setOkText("account.create"); addLabel("fields.required"); m_txtUsername = createTextField("username"); m_txtPassword = createTextField("password"); m_txtConfirmPassword = createTextField("confirm.password"); m_txtEmail = createTextField("email",DIALOG_TEXT_LONG); // m_txtConfirmEmail = createTextField("email.confirm",DIALOG_TEXT_LONG); //std::vector<std::string> items; //items.push_back("gender.male"); //items.push_back("gender.female"); //m_gender = createDropdown("gender.gender","gender.gender",items); //m_birthday = createDate("birthday"); //m_txtPassphrase = createTextField("security.phrase"); m_cbAge = createCheckBox(""); m_cbAge->setText(getFactory()->getLanguageManager()->getElementWithArg("over.age","13")); addLabel("fields.optional"); m_txtFirstName = createTextField("first.name"); m_txtLastName = createTextField("last.name"); DataValidator dv; m_txtFirstName->setMaxLength(25); m_txtLastName->setMaxLength(25); m_txtUsername->setMaxLength(dv.getMaxUsernameLength()); m_txtPassword->setIsPassword(true); m_txtPassword->setMaxLength(20); m_txtConfirmPassword->setIsPassword(true); m_txtConfirmPassword->setMaxLength(20); m_txtEmail->setMaxLength(35); //m_txtConfirmEmail->setMaxLength(35); }
bool NewAccountDialog::validateData() { std::vector<std::string> errors; DataValidator dv; std::stringstream ss; /* if(m_txtFirstName->getTextLength() < 3) { errors.push_back("firstname.validate"); } if(m_txtLastName->getTextLength() < 3) { errors.push_back("lastname.validate"); } */ if(m_txtUsername->getTextLength() < 3) { errors.push_back("username.validate"); } if(!dv.usernameIsValid(m_txtUsername->getText())) { errors.push_back("username.invalid.validate"); } if(!dv.isPasswordValid(m_txtPassword->getPassword())) { errors.push_back("password.validate"); } else if(m_txtPassword->getPassword() != m_txtConfirmPassword->getPassword()) { errors.push_back("account.password.mismatch"); } if(m_txtEmail->getTextLength() == 0) { errors.push_back("email.validate"); } else if(!dv.isEmailValid(m_txtEmail->getText())) { errors.push_back("email.invalid.validate"); } if(!m_cbAge->checked()) { errors.push_back("confirm.age"); } /* if(m_txtEmail->getText() != m_txtConfirmEmail->getText()) { errors.push_back("email.mismatch.validate"); } */ /* if(m_gender->getSelectedIndex() < 0) { errors.push_back("gender.validate"); } if(m_txtPassphrase->getTextLength() == 0) { errors.push_back("security.phrase.validate"); } bool anythingEmpty = false; for(int i = 0; i < m_birthday.size(); i++) { if(m_birthday[i]->getSelectedIndex() < 0) anythingEmpty = true; } */ /* if(anythingEmpty) { errors.push_back("birthday.validate"); } else { int month = m_birthday[0]->getSelectedIndex(); month++; ss.clear(); ss.str(""); ss << m_birthday[1]->getItemAt(m_birthday[1]->getSelectedIndex()); int day = 0; ss >> day; if(!dv.dateIsValid(2000,month,day)) { errors.push_back("birthday.invalid.validate"); } } */ std::string errorText; std::string bullet; bullet += 0xe2; bullet += 0x80; bullet += 0xa2; for(int i = 0; i < errors.size(); i++) { errorText += bullet; errorText += " "; errorText += getFactory()->getLanguageManager()->getElement(errors[i]); if(i + 1 < errors.size()) errorText += "\n\n"; } if(errorText.length() > 0) { DISPATCH_SCENE_EVENT (*it)->showMessageBox( getFactory()->getLanguageManager()->getElement("newaccount.validate"),errorText,MessageBox::MT_OK,this,1); } return errorText.length() == 0; }
float * DataValidatorGroup::get_best(uint64_t timestamp, int *index) { DataValidator *next = _first; // XXX This should eventually also include voting int pre_check_best = _curr_best; float pre_check_confidence = 1.0f; int pre_check_prio = -1; float max_confidence = -1.0f; int max_priority = -1000; int max_index = -1; DataValidator *best = nullptr; unsigned i = 0; while (next != nullptr) { float confidence = next->confidence(timestamp); if (static_cast<int>(i) == pre_check_best) { pre_check_prio = next->priority(); pre_check_confidence = confidence; } /* * Switch if: * 1) the confidence is higher and priority is equal or higher * 2) the confidence is no less than 1% different and the priority is higher */ if ((((max_confidence < MIN_REGULAR_CONFIDENCE) && (confidence >= MIN_REGULAR_CONFIDENCE)) || (confidence > max_confidence && (next->priority() >= max_priority)) || (fabsf(confidence - max_confidence) < 0.01f && (next->priority() > max_priority)) ) && (confidence > 0.0f)) { max_index = i; max_confidence = confidence; max_priority = next->priority(); best = next; } next = next->sibling(); i++; } /* the current best sensor is not matching the previous best sensor, * or the only sensor went bad */ if (max_index != _curr_best || ((max_confidence < FLT_EPSILON) && (_curr_best >= 0))) { bool true_failsafe = true; /* check whether the switch was a failsafe or preferring a higher priority sensor */ if (pre_check_prio != -1 && pre_check_prio < max_priority && fabsf(pre_check_confidence - max_confidence) < 0.1f) { /* this is not a failover */ true_failsafe = false; /* reset error flags, this is likely a hotplug sensor coming online late */ best->reset_state(); } /* if we're no initialized, initialize the bookkeeping but do not count a failsafe */ if (_curr_best < 0) { _prev_best = max_index; } else { /* we were initialized before, this is a real failsafe */ _prev_best = pre_check_best; if (true_failsafe) { _toggle_count++; /* if this is the first time, log when we failed */ if (_first_failover_time == 0) { _first_failover_time = timestamp; } } } /* for all cases we want to keep a record of the best index */ _curr_best = max_index; } *index = max_index; return (best) ? best->value() : nullptr; }