Adicione o lidar de 16 linhas ao robô no gazebo para executar o LIO-SAM

prefácio

Recentemente, quero construir uma plataforma móvel de robô, mas o equipamento não está totalmente disponível. Antes de todo o equipamento estar disponível, faremos uma simulação no gazebo para implantar algoritmos e pacotes de funções relacionados. Nesta simulação, o robô está equipado com um radar a laser de 16 linhas, IMU e câmera RGB-D em um chassi móvel e, finalmente, executou um LIO-SAM, e o efeito de mapeamento não é ruim. Encontrei alguns problemas durante todo o processo, resolvi um a um, fiz alguns registros dos principais problemas, caso você tenha outras dúvidas, pode respondê-las na área de discussão. Além disso, o código-fonte deste projeto é colocado no GitHub e todos são bem-vindos para baixar e aprender.

1. Baixe o pacote de simulação de radar

Primeiro baixe o pacote de desenvolvimento de simulação VLP lidar em seu próprio espaço de trabalho

git clone https://bitbucket.org/DataspeedInc/velodyne_simulator/src/master/

Após o download, a estrutura do arquivo /src é a seguinte

1

Depois de baixar o pacote de simulação lidar, re-catkin_make novamente, principalmente para gerar o arquivo de biblioteca de nuvem de pontos lidar, caso contrário, não haverá tópicos relacionados à nuvem de pontos na simulação subsequente. Depois de compilar uma vez, duas bibliotecas de links dinâmicos serão geradas na pasta devel/lib do nosso espaço de trabalho da seguinte forma:

2

Na simulação, essas duas bibliotecas serão chamadas para gerar as informações da nuvem de pontos.

2. Adicione o arquivo de descrição do suporte do radar

Adicione um suporte ao radar a laser, posicione o radar a laser no carro, crie um novo arquivo laser_support.xacro na pasta urdf no pacote do seu robô e escreva o seguinte conteúdo

<?xml version="1.0"?>
<robot name="laser_support" xmlns:xacro="http://wiki.ros.org/xacro">
  <!-- 雷达支架 -->
  <xacro:property name="support_length" value="0.30" /> <!-- 支架长度 -->
  <xacro:property name="support_radius" value="0.025" /> <!-- 支架半径 -->
  <xacro:property name="support_x_size" value="-0.2" /> <!-- 支架安装的x坐标 -->
  <xacro:property name="support_y_size" value="0.0" /> <!-- 支架安装的y坐标 -->
  <xacro:property name="support_z_size" value="${base_z_size}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2  -->
  <xacro:property name="support_m" value="0.02" /> <!-- 支架质量 -->
  <link name="support">
      <visual>
          <geometry>
          	<cylinder radius="${support_radius}" length="${support_length}" />
          </geometry>
          <origin xyz="0 0 0" rpy="0.0 0.0 0.0" />
          <material name="red">
          	<color rgba="0.8 0.2 0.0 0.8" />
          </material>
      </visual>
      <collision>
          <geometry>
          	<cylinder radius="${support_radius}" length="${support_length}" />
          </geometry>
          <origin xyz="0 0 0" rpy="0.0 0.0 0.0" />
      </collision>
      <xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />
  </link>
  <joint name="support2base_link" type="fixed">
      <parent link="base_link" />
      <child link="support" />
      <origin xyz="${support_x_size} ${support_y_size} ${support_z_size}" />
  </joint>
  <gazebo reference="support">
  <material>Gazebo/White</material>
  </gazebo>
</robot>

3. Adicione o arquivo de descrição do radar

Adicione a descrição lidar no arquivo de descrição base.xacro do robô

Primeiro, o arquivo de descrição de suporte que contém o lidar

5

Em seguida, adicione duas variáveis ​​de descrição de atributo do radar

3

Finalmente, ele contém o arquivo de descrição do lidar, e as duas variáveis ​​de atributo acima serão usadas aqui

4

4. Inicie a simulação

Escreva um arquivo de inicialização, inicie o rviz para ver nosso robô

<launch>
    <arg name = "model_xacro" default = "$(find scout_gazebo)/urdf/base.xacro" />
    <!-- 将 Urdf 文件的内容加载到参数服务器 -->
    <param name="robot_description" command="$(find xacro)/xacro $(arg model_xacro)" />
    <!-- Launch  the joint state publisher -->
    <node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" ></node>
    <!-- Launch  the robot state publisher -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

    <!-- Loading rviz files -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find scout_gazebo)/config/show_robot.rviz" />
    <!-- 启动 gazebo -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(find scout_gazebo)/worlds/lab.world" />
    </include>
    <!-- 在 gazebo 中显示机器人模型  -->
   <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model scout -param robot_description"  />  
</launch>

Após o roslaunch, você pode abrir o gazebo e o rviz, e ele mostrará que nosso robô está carregando um lidar da seguinte maneira:

6

7

Neste ponto, podemos abrir nosso tópico para ver se há um pouco de saída em nuvem

8

Pode-se ver que há um pouco de tópico de nuvem, vamos tentar visualizar a nuvem de pontos no rviz

9

Pode-se ver que nossa nuvem de pontos é gerada normalmente. Observe que para ver nosso robô no gazebo, não visualizamos a nuvem de pontos do laser no gazebo. Se você deseja visualizá-lo, pode modificar este local no arquivo VLP-16.urdf.xacro

9

Após a modificação, podemos ver a nuvem de pontos do laser no gazebo, da seguinte forma:

9

Cobrindo nosso carro, a nuvem de pontos do lidar de 16 linhas ainda é relativamente densa. Agora que o lidar foi adicionado à simulação, vamos executar uma estrutura SLAM a laser clássica LIO-SAM na próxima etapa.

5. Adicione o módulo IMU

Como o framework que precisamos rodar é o LIO-SAM, precisamos usar o módulo IMU, então adicionamos também na simulação. Da mesma forma, adicionamos outro arquivo imu.xacro na pasta urdf no projeto

<?xml version="1.0"?>
<robot xmlns:xacro="http://wiki.ros.org/xacro">  

    <xacro:macro name="imu" params="sensor_name parent_link *origin">

        <xacro:property name="imu_offset_x" value="0" />
        <xacro:property name="imu_offset_y" value="0" />
        <xacro:property name="imu_offset_z" value="0.2" />
        <xacro:property name="imu_size"     value="0.05" />
        <xacro:property name="imu_m" value="0.01" /> <!-- imu质量 -->
        <!-- imu -->
        <joint name="imutobase" type="fixed">
            <!-- <origin xyz="${imu_offset_x} ${imu_offset_y} ${imu_offset_z}" rpy="0 0 0" /> -->
            <xacro:insert_block name="origin" />
            <parent link="${parent_link}"/>
            <child link="imu_base"/>
        </joint>
            
        <link name="imu_base">
            <visual>
                <origin rpy="0 0 0" xyz="0 0 0" />
                <geometry>
                        <box size="${imu_size} ${imu_size} ${imu_size}"/>
                </geometry>                
                <material name= "black" >
                <color rgba="1.0 0.0 0.0 0.6" />
                </material>
            </visual>
            <collision>
                <geometry>
                    <box size="${imu_size} ${imu_size} ${imu_size}" />
                </geometry>
                <origin xyz="0.0 0.0 0" rpy="0.0 0.0 0.0" />
            </collision>
            <xacro:Box_inertial_matrix m = "${imu_m}" l = "${imu_size}" w = "${imu_size}" h = "${imu_size}"/>
        </link>

        <!-- 被引用的link -->
        <gazebo reference="imu_base">
            <material>Gazebo/Bule</material>
            <gravity>true</gravity>
            <sensor name="imu_sensor" type="imu">
            <always_on>true</always_on>
            <update_rate>100</update_rate>
            <visualize>true</visualize>
            <topic>__default_topic__</topic>
            <plugin filename="libgazebo_ros_imu_sensor.so" name="imu_plugin">
                <topicName>imu/data</topicName>
                <bodyName>imu_base</bodyName>
                <updateRateHZ>100.0</updateRateHZ>
                <gaussianNoise>0.01</gaussianNoise>
                <xyzOffset>0 0 0</xyzOffset>     
                <rpyOffset>0 0 0</rpyOffset>
                <frameName>imu_base</frameName>        
            </plugin>
            <pose>0 0 0 0 0 0</pose>
        </sensor>
        </gazebo>

    </xacro:macro>
</robot>

Em seguida, inclua este arquivo em nosso arquivo de descrição principal base.xacro

imagem-20220918224800561

6. Adicione uma câmera RGB-D

Aqui usamos uma câmera RGB-D da série realsense, primeiro baixe seu SDK de simulação

$ git clone https://github.com/nilseuropa/realsense_ros_gazebo.git

Aqui está o diretório de origem baixado para o projeto

imagem-20220918225325309

Da mesma forma, inclua a câmera no arquivo de descrição principal base.xarco

imagem-20220918225423235

Depois de adicionar, nosso robô de simulação foi equipado com sensores como IMU, câmera RGB-D e lidar de 16 linhas. Vamos iniciar o ambiente e ver quantos tópicos foram publicados.

tema

Você pode ver que muitos tópicos foram publicados, incluindo propósito duplo, IMU e nuvem de pontos. Basicamente, a configuração do robô foi concluída. A seguir, vou executar um framework SLAM para tentar

7. Simulação LIO-SAM

instalar dependências

$ sudo apt-get install -y ros-noetic-navigation
$ sudo apt-get install -y ros-noetic-robot-localization
$ sudo apt-get install -y ros-noetic-robot-state-publisher

Instalar GTSAM

$ git clone https://github.com/borglab/gtsam
$ cd gtsam
$ mkdir build && cd build
# 注意这里要加-DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF这个选项,不然后面运行会报错
$ cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF ..
$ sudo make install -j8
$ sudo ln -s /usr/local/lib/libmetis-gtsam.so /usr/lib/libmetis-gtsam.so

Compilar LIO-SAM

$ cd ~/robot_ws/src
$ git clone https://github.com/TixiaoShan/LIO-SAM
$ cd ..
$ catkin_make

correr

Primeiro inicie o ambiente de simulação

$ roslaunch scout_gazebo scout_gazebo.launch

gazebo

Em seguida, inicie o lio-sam

$ roslaunch lio_sam run.launch

ver

Por fim, iniciamos nosso nó que controla o movimento do robô. Este nó é um pacote que vem com o ros. Ele é sudo apt install ros-noetic-teleop-twist-keyboardinstalado através de comandos. Este nó publica principalmente informações de velocidade para /cmd_valcontrolar o movimento do robô no gazebo, e o robô móvel pode construir um mapa.

$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

mapeamento

Pode-se ver que o robô recebe nossos comandos de controle de movimento para se mover no mirante, e o nó lio-sam realiza a estimativa e mapeamento de pose.

8. Código fonte

Aqui eu carrego o código-fonte para o meu GitHub warehouse, você pode baixá-lo para experimentação sozinho

https://github.com/linzs-online/robot_gazebo.git

problemas encontrados

1、erro: 'class std::unordered_map<unsigned int, std::vector >' não tem membro chamado 'serialize'

Motivo: O flann do qual a biblioteca PCl depende está em conflito com o Opencv. Algumas definições de macro no arquivo de cabeçalho opencv entram em conflito com a biblioteca flann
Solução: Certifique-se de que o flann dependente da biblioteca pcl esteja incluído antes do arquivo de cabeçalho opencv. Resolvi depois de colocar o arquivo de cabeçalho opencv na biblioteca PCL
imagem-20220923084018213

2. O robô ainda está no gazebo, mas pula repetidamente no rviz

Razão: lio-sam reduzirá a amostra e filtrará a nuvem de pontos. A configuração do voxel do filtro é muito grande e ocorrem erros no processo de correspondência, o que faz com que a pose otimizada pelo robô salte repetidamente.

Solução: como estamos construindo um mapa interno, defina o tamanho do voxel menor no arquivo de configuração lio-sam

imagem-20220919092444182

3. Um erro é relatado ao executar o processo [lio_sam_mapOptmization-5] foi encerrado [pid 260348, código de saída -11

Solução: Use este parâmetro ao compilar gtsam, cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF ...

4、运行时报错 erro ao carregar bibliotecas compartilhadas: libmetis-gtsam.so : não é possível abrir o arquivo de objeto compartilhado: nenhum arquivo ou diretório

Solução: sudo ln -s /usr/local/lib/libmetis-gtsam.so /usr/lib/libmetis-gtsam.so

5. Aviso: TF_REPEATED_DATA ignorando dados com timestamp redundante para quadro durante a execução

Motivo: a transformação do robô TF não é normal

erro

Solução: Analise a transformação do TF no ambiente atual executando roswtfo comando , e verifica-se aqui que existe um conflito base_linkcom odoma transformação entre essas duas coordenadas

analisar

Obviamente, o controle em nossa simulação gazebo base_linkliberou odoma transformação TF de para , mas nosso nó SLAM liberou novamente, e esses dois conflitos. Em seguida, resolvemos esse problema modificando a transformação TF liberada por lio-sam , modifique a configuração arquivo de lio-sam e altere o nome das coordenadas liberadas pelos resultados da estimativa de pose do SLAM

imagem-20220919094556770

Acho que você gosta

Origin blog.csdn.net/weixin_40599145/article/details/126929222
Recomendado
Clasificación