Tabla de contenido
Monitoreo de seguridad funcional
Análisis de la función CheckSafty
Análisis de la función RunOnce
Supervisión de la función de registro
Análisis de ubicación de informes de estado
Servicio de resumen de información de seguimiento
Supervisión de posición
el código
class LocalizationMonitor : public RecurrentRunner {
public:
LocalizationMonitor();
void RunOnce(const double current_time) override;
};
void LocalizationMonitor::RunOnce(const double current_time) {
auto manager = MonitorManager::Instance();
auto* component = apollo::common::util::FindOrNull(
*manager->GetStatus()->mutable_components(),
FLAGS_localization_component_name);
if (component == nullptr) {
// localization is not monitored in current mode, skip.
return;
}
static auto reader =
manager->CreateReader<LocalizationStatus>(FLAGS_localization_msf_status);
reader->Observe();
const auto status = reader->GetLatestObserved();
ComponentStatus* component_status = component->mutable_other_status();
component_status->clear_status();
if (status == nullptr) {
SummaryMonitor::EscalateStatus(ComponentStatus::ERROR,
"No LocalizationStatus received",
component_status);
return;
}
// Translate LocalizationStatus to ComponentStatus. Note that ERROR and FATAL
// will trigger safety mode in current settings.
switch (status->fusion_status()) {
case MeasureState::OK:
SummaryMonitor::EscalateStatus(ComponentStatus::OK, "", component_status);
break;
case MeasureState::WARNNING:
SummaryMonitor::EscalateStatus(
ComponentStatus::WARN,
absl::StrCat("WARNNING: ", status->state_message()),
component_status);
break;
case MeasureState::ERROR:
SummaryMonitor::EscalateStatus(
ComponentStatus::WARN,
absl::StrCat("ERROR: ", status->state_message()), component_status);
break;
case MeasureState::CRITICAL_ERROR:
SummaryMonitor::EscalateStatus(
ComponentStatus::ERROR,
absl::StrCat("CRITICAL_ERROR: ", status->state_message()),
component_status);
break;
case MeasureState::FATAL_ERROR:
SummaryMonitor::EscalateStatus(
ComponentStatus::FATAL,
absl::StrCat("FATAL_ERROR: ", status->state_message()),
component_status);
break;
default:
AFATAL << "Unknown fusion_status: " << status->fusion_status();
break;
}
}
analizar
- Determinar si el módulo de posicionamiento pertenece al módulo monitoreado
- Suscríbase a localization_msf_status, si no puede leerlo, informe una falla de nivel de ERROR
- Juzgue directamente la información de estado en el tema e informe la falla correspondiente de acuerdo con el estado
Observación
## Comprobar el estado de localización de MSF Proporcionamos una manera sencilla de comprobar el estado de localización de fusión, localización GNSS y lidar. Hay cuatro estados {NOT_VALID, NOT_STABLE, OK, VALID} para el estado de localización. Simplemente puede usar `rostopic echo /apollo/localization/msf_status` para verificar el estado de localización. Si fusion_status es VÁLIDO o correcto, la salida de la localización de msf es confiable.
Lo anterior es la lógica de juicio del estado de posicionamiento de apollo MSF, y todas las fallas anteriores son configuradas y emitidas por la parte de posicionamiento del módulo comercial.
La siguiente es la parte de detección de estado de modules/localization/rtk/rtk_localization.cc
void RTKLocalization::FillLocalizationStatusMsg(
const drivers::gnss::InsStat &status,
LocalizationStatus *localization_status) {
apollo::common::Header *header = localization_status->mutable_header();
double timestamp = apollo::cyber::Clock::NowInSeconds();
header->set_timestamp_sec(timestamp);
localization_status->set_measurement_time(status.header().timestamp_sec());
if (!status.has_pos_type()) {
localization_status->set_fusion_status(MeasureState::ERROR);
localization_status->set_state_message(
"Error: Current Localization Status Is Missing.");
return;
}
monitoreo de cámara
el código
class CameraMonitor : public RecurrentRunner {
public:
CameraMonitor();
void RunOnce(const double current_time) override;
private:
static void UpdateStatus(ComponentStatus* status);
};
void CameraMonitor::RunOnce(const double current_time) {
auto* manager = MonitorManager::Instance();
auto* component = apollo::common::util::FindOrNull(
*manager->GetStatus()->mutable_components(), FLAGS_camera_component_name);
if (component == nullptr) {
// camera is not monitored in current mode, skip.
return;
}
auto* status = component->mutable_other_status();
UpdateStatus(status);
}
analizar
Además de juzgar si la cámara está configurada como una configuración de monitoreo, la función central está en UpdateStatus
void CameraMonitor::UpdateStatus(ComponentStatus* status) {
status->clear_status();
std::string frame_id = "";
for (const auto& topic : camera_topic_set) {
const auto& reader_message_pair = CreateReaderAndLatestsMessage(topic);
const auto& reader = reader_message_pair.first;
const auto& message = reader_message_pair.second;
if (reader != nullptr && message != nullptr) {
if (frame_id.empty()) {
const auto& header = message->header();
if (header.has_frame_id()) {
frame_id = header.frame_id();
}
} else {
SummaryMonitor::EscalateStatus(
ComponentStatus::ERROR,
absl::StrCat("Only one camera is permitted"), status);
}
}
}
if (frame_id.empty()) {
SummaryMonitor::EscalateStatus(
ComponentStatus::ERROR, absl::StrCat("No camera is detected"), status);
} else {
SummaryMonitor::EscalateStatus(
ComponentStatus::OK, absl::StrCat("Detected one camera: ", frame_id),
status);
}
}
static const auto camera_topic_set = std::set<std::string>{
FLAGS_image_long_topic, FLAGS_camera_image_long_topic,
FLAGS_camera_image_short_topic, FLAGS_camera_front_6mm_topic,
FLAGS_camera_front_6mm_2_topic, FLAGS_camera_front_12mm_topic,
// Add more cameras here if you want to monitor.
};
- recibe las últimas noticias
- Obtenga el encabezado del mensaje, obtenga la identificación del marco, si hay dos conjuntos de identificación del marco, informe ERROR
absl::StrCat("Solo se permite una cámara"), status);
Si la identificación del marco está vacía, informe ERROR
ComponentStatus::ERROR, absl::StrCat("No se detecta ninguna cámara"), status);
Monitoreo de seguridad funcional
el código
// Check if we need to switch to safe mode, and then
// 1. Notify driver to take action.
// 2. Trigger Guardian if no proper action was taken.
class FunctionalSafetyMonitor : public RecurrentRunner {
public:
FunctionalSafetyMonitor();
void RunOnce(const double current_time);
private:
bool CheckSafety();
};
void FunctionalSafetyMonitor::RunOnce(const double current_time) {
auto* system_status = MonitorManager::Instance()->GetStatus();
// Everything looks good or has been handled properly.
if (CheckSafety()) {
system_status->clear_passenger_msg();
system_status->clear_safety_mode_trigger_time();
system_status->clear_require_emergency_stop();
return;
}
if (system_status->require_emergency_stop()) {
// EStop has already been triggered.
return;
}
// Newly entered safety mode.
system_status->set_passenger_msg("Error! Please disengage.");
if (!system_status->has_safety_mode_trigger_time()) {
system_status->set_safety_mode_trigger_time(current_time);
return;
}
// Trigger EStop if no action was taken in time.
if (system_status->safety_mode_trigger_time() +
FLAGS_safety_mode_seconds_before_estop <
current_time) {
system_status->set_require_emergency_stop(true);
}
}
analizar
Análisis de la función CheckSafty
bool FunctionalSafetyMonitor::CheckSafety() {
// We only check safety in self driving mode.
auto manager = MonitorManager::Instance();
if (!manager->IsInAutonomousMode()) {
return true;
}
// Check HMI modules status.
const auto& mode = manager->GetHMIMode();
const auto& hmi_modules = manager->GetStatus()->hmi_modules();
for (const auto& iter : mode.modules()) {
const std::string& module_name = iter.first;
const auto& module = iter.second;
if (module.required_for_safety() &&
!IsSafe(module_name, hmi_modules.at(module_name))) {
return false;
}
}
// Check monitored components status.
const auto& components = manager->GetStatus()->components();
for (const auto& iter : mode.monitored_components()) {
const std::string& component_name = iter.first;
const auto& component = iter.second;
if (component.required_for_safety() &&
!IsSafe(component_name, components.at(component_name).summary())) {
return false;
}
}
// Everything looks good.
return true;
}
- A juzgar si está en modo de piloto automático, si no, salta directamente
- Verifique si el estado de todos los componentes monitoreados es ERROR o FATAL
- Si lo es, no es seguro, si no lo es, es seguro
Análisis de la función RunOnce
- Comprobar el estado de seguridad actual
- Si es seguro, borre la información del estado anterior y regrese
- Si no es seguro, juzgue si se han llamado las medidas de seguridad: EStop, si Estop ya está funcionando, regrese
- Si se encuentra que ESTOP no ha comenzado a funcionar, verifique el tiempo para que el gatillo elimine de manera segura ESTOP y espere si no hay tiempo de espera.
Supervisión de la función de registro
El monitor de la grabadora es para el monitoreo del servicio de grabación por parte de apollo, suscribiéndose al tema /apollo/data/recorder/status para obtener el estado de la grabadora.
el código
class RecorderMonitor : public RecurrentRunner {
public:
RecorderMonitor();
void RunOnce(const double current_time) override;
};
void RecorderMonitor::RunOnce(const double current_time) {
auto manager = MonitorManager::Instance();
auto* component = apollo::common::util::FindOrNull(
*manager->GetStatus()->mutable_components(),
FLAGS_smart_recorder_component_name);
if (component == nullptr) {
// SmartRecorder is not monitored in current mode, skip.
return;
}
static auto reader =
manager->CreateReader<SmartRecorderStatus>(FLAGS_recorder_status_topic);
reader->Observe();
const auto status = reader->GetLatestObserved();
ComponentStatus* component_status = component->mutable_other_status();
component_status->clear_status();
if (status == nullptr) {
SummaryMonitor::EscalateStatus(ComponentStatus::ERROR,
"No SmartRecorderStatus received",
component_status);
return;
}
// Translate SmartRecorderStatus to ComponentStatus. Note that ERROR and FATAL
// will trigger safety mode in current settings.
switch (status->recording_state()) {
case RecordingState::RECORDING:
SummaryMonitor::EscalateStatus(ComponentStatus::OK, "", component_status);
break;
case RecordingState::TERMINATING:
SummaryMonitor::EscalateStatus(
ComponentStatus::WARN,
absl::StrCat("WARNNING: ", status->state_message()),
component_status);
break;
case RecordingState::STOPPED:
SummaryMonitor::EscalateStatus(
ComponentStatus::OK,
absl::StrCat("STOPPED: ", status->state_message()), component_status);
break;
default:
AFATAL << "Unknown recording status: " << status->recording_state();
break;
}
}
analizar
El primer paso aún es juzgar si el registrador es un módulo de monitoreo configurado, si no, regresar directamente.
Luego juzgue directamente el estado->recording_state(), si es RecordingState::TERMINATING (estado de terminación), informe una falla de ADVERTENCIA
Protocolo SmartRecorderStatus
enum RecordingState {
STOPPED = 0;
RECORDING = 1;
TERMINATING = 2;
}
message SmartRecorderStatus {
optional apollo.common.Header header = 1;
optional RecordingState recording_state = 2;
optional string state_message = 3;
}
Análisis de ubicación de informes de estado
módulos/datos/herramientas/smart_recorder/realtime_record_processor.cc
Podemos encontrar la asignación del estado de la grabadora en el archivo anterior, pero lamentablemente actualmente no hay ningún módulo en apollo que complete activamente el estado RecordingState::TERMINATING (terminación).
Servicio de resumen de información de seguimiento
el código
// A monitor which summarize other monitors' result and publish the whole status
// if it has changed.
class SummaryMonitor : public RecurrentRunner {
public:
SummaryMonitor();
void RunOnce(const double current_time) override;
// Escalate the status to a higher priority new status:
// FATAL > ERROR > WARN > OK > UNKNOWN.
static void EscalateStatus(const ComponentStatus::Status new_status,
const std::string& message,
ComponentStatus* current_status);
private:
size_t system_status_fp_ = 0;
double last_broadcast_ = 0;
};
void SummaryMonitor::RunOnce(const double current_time) {
auto manager = MonitorManager::Instance();
auto* status = manager->GetStatus();
// Escalate the summary status to the most severe one.
for (auto& component : *status->mutable_components()) {
auto* summary = component.second.mutable_summary();
const auto& process_status = component.second.process_status();
EscalateStatus(process_status.status(), process_status.message(), summary);
const auto& module_status = component.second.module_status();
EscalateStatus(module_status.status(), module_status.message(), summary);
const auto& channel_status = component.second.channel_status();
EscalateStatus(channel_status.status(), channel_status.message(), summary);
const auto& resource_status = component.second.resource_status();
EscalateStatus(resource_status.status(), resource_status.message(),
summary);
const auto& other_status = component.second.other_status();
EscalateStatus(other_status.status(), other_status.message(), summary);
}
// Get fingerprint of current status.
// Don't use DebugString() which has known bug on Map field. The string
// doesn't change though the value has changed.
static std::hash<std::string> hash_fn;
std::string proto_bytes;
status->SerializeToString(&proto_bytes);
const size_t new_fp = hash_fn(proto_bytes);
if (system_status_fp_ != new_fp ||
current_time - last_broadcast_ > FLAGS_system_status_publish_interval) {
static auto writer =
manager->CreateWriter<SystemStatus>(FLAGS_system_status_topic);
apollo::common::util::FillHeader("SystemMonitor", status);
writer->Write(*status);
status->clear_header();
system_status_fp_ = new_fp;
last_broadcast_ = current_time;
}
}
analizar
Consolide la información de fallas reportada por todos los monitores anteriores y envíela al tema /apollo/monitor/system_status.