Posicionamiento de fusión multisensor (construcción de mapas de nubes de 3 puntos y posicionamiento basado en mapas) Detección de bucles ScanContext de 3 realizaciones

Posicionamiento de fusión multisensor (construcción de mapas de nubes de 3 puntos y posicionamiento basado en mapas) Detección de bucles ScanContext de 3 realizaciones

Blog de referencia
cero hecho posicionamiento automático de la unidad (XI):
sistema de piloto automático de corrección de circuito cerrado y elemento de combate avanzado (iv) un mapa de piloto automático de reconocimiento de escena tridimensional detectado con precisión sistemas de construcción y
piloto automático de combate y elemento ( 5) Utilice SC-LEGO-LOAM para la construcción de mapas de nubes de puntos a gran escala y la optimización de circuito cerrado

Código fuente:
parte del código fuente utilizado aquí es de github sc-lego-loam. El
marco de código general es de Rengan github tag11 código de corrección de ciclo cerrado

pd: porque soy un poco blanco, aquí es solo para expresar mis propias opiniones e ideas de aprendizaje, espero corregirme

Idea de código

Marco general

Echemos un vistazo al marco general del
blog de referencia desde cero para hacer el posicionador automático del variador (IX): construya una optimización
Inserte la descripción de la imagen aquí
de la configuración del sistema de esto, para completar la detección de bucle módulo a módulo

Inserte la descripción de la imagen aquí
Entre ellos, el módulo de detección de bucle cerrado contiene dos partes: la coincidencia de la detección de tramas de bucle cerrado y la nube de puntos.
Los bloques de código correspondientes son los siguientes:

    //闭环检测模块  (任乾)
    if (!DetectNearestKeyFrame(key_frame_index))
        return false;
        
	//点云配准 
    if (!CloudRegistration(key_frame_index))
        return false;

Al llamar a ScanContext, la detección de bucle se realiza en la nube de puntos del cuadro actual y la nube de puntos del cuadro histórico, y se obtienen key_frame_index (cuadro de bucle detectado) y yaw diff (ángulo de desviación de pose); luego, el cuadro de bucle detectado se envía a la nube de puntos de registro. Módulo de registro

Escritura de código

Trasplantado sc-lego-franco de ScanContext código fuente pertinente y archivos de bibliotecas

Inserte la descripción de la imagen aquí
Agregar archivo de origen relacionado scan_context / Scancontext.cpp
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
agregar archivo de encabezado
Inserte la descripción de la imagen aquí

Tenga en cuenta que CMakeLists.txt agrega

Adición de ruta nativa OpenCV

#本机OpenCV路径查看
locate   OpenCVConfig.cmake

Inserte la descripción de la imagen aquí

Llame principalmente a dos funciones en SC

scManager.detectLoopClosureID (); Función de detección de tramas de bucle invertido, devuelve -1 si no se detecta y devuelve el índice de la trama correspondiente cuando se detecta una trama de bucle invertido

scManager.makeAndSaveScancontextAndKeys (* raw_cloud_ptr); Guarda la nube de puntos del marco actual en tiempo real para la coincidencia de bucles

Función de escritura

SaveCurrentFrame (int pcd_idx) se
utiliza para guardar la nube de puntos del marco actual, imitando el método de registro de la nube de puntos, obtener el pcd de la nube de puntos del marco actual del disco en tiempo real y almacenarlo en el puntero raw_cloud_ptr, y llamar a scManager.makeAndSaveScancontextAndKeys para guardar el marco actual

DetectScanContext (int & key_frame_index, int pcd_idx)
detecta el marco del bucle, si es verdadero, genera el índice y la pose de desviación del marco del bucle; de ​​lo contrario, flase devuelve -1

void LoopClosing::SaveCurrentFrame(int pcd_idx){
    
       
        // 读取并存储当前点云
    std::string file_path = key_frames_path_ + "/key_frame_" + std::to_string(pcd_idx) + ".pcd";
    CloudData::CLOUD_PTR raw_cloud_ptr(new CloudData::CLOUD());
     pcl::io::loadPCDFile(file_path, *raw_cloud_ptr);     //   raw_cloud_ptr  存储当前帧点云的point
    scManager.makeAndSaveScancontextAndKeys(*raw_cloud_ptr);     
}

// scan context  回环检测模块
int LoopClosing::DetectScanContext(int& key_frame_index,int pcd_idx) {
    
            
    SaveCurrentFrame(pcd_idx);

    auto detectResult = scManager.detectLoopClosureID();     //  进行回环帧的检测  first: nn index, second: yaw diff

    key_frame_index = detectResult.first;    // 获取回环帧的索引
    yawDiffRad = detectResult.second; // not use for v1 (because pcl icp withi initial somthing wrong...)
    
    return   key_frame_index;    //没有检测到返回 -1 ,检测到回环帧返回   对应帧 的索引 
}

Funciones de llamada

Reemplace la parte de detección de bucle de DetectNearestKeyFrame por el Sr.Ren Qian, por ejemplo: ScanContext hace un posicionamiento aproximado. Después de detectar el cuadro de bucle, envíe el cuadro de bucle al siguiente módulo de registro de nube de puntos CloudRegistration (posicionamiento fino) para completar todo el posicionamiento del bucle ¡Reparar! ! !

bool LoopClosing::Update(const KeyFrame key_frame, const KeyFrame key_gnss) {
    
    
    has_new_loop_pose_ = false;

    all_key_frames_.push_back(key_frame);
    all_key_gnss_.push_back(key_gnss);

    int key_frame_index = 0;

   //  scan  context   回环检测 
    if (DetectScanContext(key_frame_index,key_frame.index)  == -1)       //  key_frame_index  闭环检测帧 ;   key_frame.index  当前帧数
        return false;

    //任乾  闭环检测模块
    // if (!DetectNearestKeyFrame(key_frame_index))
    //     return false;
    
    if (!CloudRegistration(key_frame_index))
        return false;

    has_new_loop_pose_ = true;
        return true;
}

Error de depuración

Durante el proceso de depuración, se produjo el motivo de la lectura fuera de los límites. El motivo es que en el módulo de coincidencia de nubes de puntos, la estrategia de registro adoptada es el método Scan2Map. La construcción del mapa requiere la recuperación de la fusión del marco cerca del marco del anillo. Si el índice es 0, el mapa se construye Cuando el marco cercano no existe, dará lugar al error de señalar fuera de límites.
Inserte la descripción de la imagen aquí

Parte modificada: agregar en JointMap

//越界保护
  if (i < 0 || i >= all_key_frames_.size( ) )    continue;

Inserte la descripción de la imagen aquí

efecto final

Utilice la detección de bucle DetectNearestKeyFrame de Rengan

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

rosservice call /optimize_map

Genere optimizado.txt
Inserte la descripción de la imagen aquí
para la evaluación de evo

evo_ape kitti ground_truth.txt optimized.txt -r full --plot --plot_mode xyz

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Detección de bucle mediante DetectScanContext

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
A través de la comparación de datos, se puede ver que hay poca diferencia entre el módulo de detección de bucle del Sr.Ren Qian
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_41281151/article/details/109290982
Recomendado
Clasificación