问题描述
在 Gazebo 中进行 PX4 的软件在环仿真时,执 make px4_sitl gazebo
命令时,整个编译过程都没问题,但是编译完成后,在启动 gazebo 时出现黑屏,报错如下:
gzserver: symbol lookup error: ~/Firmware/build/px4_sitl_default/build_gazebo/libgazebo_multirotor_base_plugin.so: undefined symbol: _ZN8mav_msgs4msgs10MotorSpeedC1Ev
原因分析
初步分析:
- 能成功编译但是启动时出错,说明这是运行时错误。
- 根据错误信息,可确定是与
libgazebo_multirotor_base_plugin
插件有关,具体来说是与mav_msgs
有关。
经过反复的研究,确定具体错误如下:
libgazebo_multirotor_base_plugin.cpp
源代码中使用了mav_msgs::msgs::MotorSpeed
消息,Firmware/Tools/sitl_gazebo/msgs
目录中存有 MotorSpeed.proto
消息的定义文件。该消息实际上并不是mav_msgs
功能包中定义的,在sitl_gazebo
目录中的CMakeLists.txt
文件中部分代码如下:
set(mav_msgs
msgs/CommandMotorSpeed.proto
msgs/MotorSpeed.proto
)
set(nav_msgs msgs/Odometry.proto)
set(physics_msgs msgs/Wind.proto)
set(std_msgs msgs/Int32.proto)
set(sensor_msgs
msgs/Imu.proto
msgs/IRLock.proto
msgs/Float.proto
msgs/Groundtruth.proto
msgs/Range.proto
msgs/SITLGps.proto
msgs/OpticalFlow.proto
msgs/MagneticField.proto
msgs/Pressure.proto
)
可以看出,sitl_gazebo
功能包将msgs
目录中的MotorSpeed
和CommandMotorSpeed
消息分别定义为了mav_msgs
。
由于自己昨天安装了rotors_simulator
无人机仿真框架,框架中也编写了一个 libgazebo_multirotor_base_plugin
插件,虽然功能一致,但实现方式却略有不同。运行rotors_simulator
需要先安装一个mav_msgs
功能包,而该功能包中并没有MotorSpeed
消息。
当编译rotors_simulator
功能包后,在当前的ROS工作空间的devel/lib
目录中会生成编译成功的libmav_msg.so
动态库文件。此时,你会发现存在两个不同的libmav_msg.so
库文件,而 gazebo 在启动时使用的刚好是lib
目录下的文件,导致运行出错。
~$ locate libmav_msgs
~/Firmware/build/px4_sitl_default/build_gazebo/libmav_msgs.so
~/catkin_ws/devel/lib/libmav_msgs.so
解决办法
删除 catkin_ws/devel/lib
目录下的libmav_msgs.so
文件即可。
这也意味着在一个
ROS_PACKAGE_PATH
路径中,不能同时包含rostors_simulator功能包
和sitl_gazebo
功能包,两者采用了两种不同的消息来实现libgazebo_multirotor_base_plugin
插件,但会生成相同名称的libmav_msg.so
动态库文件。此时,rotors_simulator
能正常运行,但是sitl_gazebo
就不行了。
总结
遇到与开发环境相关的问题时,如何快速排查原因?
- 回顾自己最近的操作(比如安装了什么功能包)
- 根据错误信息,查看相应的源代码
- 寻找两者之间存在的关联