Índice:
- problemas encontrados
-
-
-
- 1、erro: 'class std::unordered_map<unsigned int, std::vector<unsigned int> >' não tem membro chamado 'serialize'
- 2. O robô ainda está no gazebo, mas pula repetidamente no rviz
- 3. Um erro é relatado ao executar o processo [lio_sam_mapOptmization-5] foi encerrado [pid 260348, código de saída -11
- 4、运行时报错 erro ao carregar bibliotecas compartilhadas: [libmetis-gtsam.so](https://link.zhihu.com/?target=http%3A//libmetis-gtsam.so/): não é possível abrir o arquivo de objeto compartilhado : Não existe tal arquivo ou diretório
- 5. Aviso: TF_REPEATED_DATA ignorando dados com timestamp redundante para quadro durante a execução
-
-
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
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:
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
Em seguida, adicione duas variáveis de descrição de atributo do radar
Finalmente, ele contém o arquivo de descrição do lidar, e as duas variáveis de atributo acima serão usadas aqui
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:
Neste ponto, podemos abrir nosso tópico para ver se há um pouco de saída em nuvem
Pode-se ver que há um pouco de tópico de nuvem, vamos tentar visualizar a nuvem de pontos no rviz
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
Após a modificação, podemos ver a nuvem de pontos do laser no gazebo, da seguinte forma:
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
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
Da mesma forma, inclua a câmera no arquivo de descrição principal base.xarco
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.
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
Em seguida, inicie o lio-sam
$ roslaunch lio_sam run.launch
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-keyboard
instalado através de comandos. Este nó publica principalmente informações de velocidade para /cmd_val
controlar o movimento do robô no gazebo, e o robô móvel pode construir um mapa.
$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py
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
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
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
Solução: Analise a transformação do TF no ambiente atual executando
roswtf
o comando , e verifica-se aqui que existe um conflitobase_link
comodom
a transformação entre essas duas coordenadasObviamente, o controle em nossa simulação gazebo
base_link
liberouodom
a 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