Aplicación Apollo y análisis de código fuente: Monitoreo de monitoreo-software de monitoreo-posicionamiento, cámara, seguridad funcional, monitoreo de registros de datos

Tabla de contenido

Supervisión de posición

el código

analizar

Observación

monitoreo de cámara

el código

analizar

Monitoreo de seguridad funcional

el código

analizar

Análisis de la función CheckSafty

Análisis de la función RunOnce

Supervisión de la función de registro

el código

analizar

Protocolo SmartRecorderStatus

Análisis de ubicación de informes de estado

Servicio de resumen de información de seguimiento

el código

analizar


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

  1. Determinar si el módulo de posicionamiento pertenece al módulo monitoreado
  2. Suscríbase a localization_msf_status, si no puede leerlo, informe una falla de nivel de ERROR
  3. 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.
};
  1. recibe las últimas noticias
  2. 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;
}
  1. A juzgar si está en modo de piloto automático, si no, salta directamente
  2. Verifique si el estado de todos los componentes monitoreados es ERROR o FATAL
  3. Si lo es, no es seguro, si no lo es, es seguro

Análisis de la función RunOnce

  1. Comprobar el estado de seguridad actual
  2. Si es seguro, borre la información del estado anterior y regrese
  3. Si no es seguro, juzgue si se han llamado las medidas de seguridad: EStop, si Estop ya está funcionando, regrese
  4. 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.

Supongo que te gusta

Origin blog.csdn.net/qq_32378713/article/details/128112717
Recomendado
Clasificación