无人机 · 2025年 11月 29日 11

Ubuntu 22.04 LTS 无人机仿真纪实(ROS2+PX4+Gazebo)

如今我成为了死神,乐队的毁灭者。——奥本海睦

八六:是吗……为什么要告诉我这个

非常坏惠普暗影精灵5060ti主机装ubuntu双系统

总之从笔记本迁移到台式了,但是惠普这个台式似乎显卡太新且底层跟安装盘有点冲突,安装一开始就会黑屏,就算装完还有grub挂载问题,解决办法来自CSDN:

ubuntu22.04+5060显卡双系统安装,各种黑屏踩坑记录

总之u盘启动刚开始的grub界面在try or install ubuntu选项按e,进去在quiet splash后面改为以下参数是对的:

nomodeset acpi=off noapic

安装推荐都选英文。装完报错先不管,系统已经装好只是需要修复grub。重新用安装盘启动并选择试用,然后boot-repair选自动修复:

sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt update
sudo apt install -y boot-repair
boot-repair

新系统进去再装个nvidia驱动,开机就不用再加参数了。我这装了open kernel的版本才能正常配置nvidia-smi和CUDA

ROS安装

官方Humble安装步骤:https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html

最后建议把这个环境变量直接写到~/.bashrc里:

source /opt/ros/humble/setup.bash

PX4与Gazebo配置

PX4飞控按官方步骤git下来就行:https://docs.px4.io/main/en/dev_setup/building_px4,会顺便自动装一个gazebo sim 8(Harmonic),因为版本问题(ROS2 Humble一般适配Fortress的Gazebo,但我怕PX4出问题没尝试换版本……),其和ROS2的桥接包要注意,不然gz话题无法正常发布到ROS2上,很难收,亲测这个能用:

sudo apt install ros-humble-ros-gzharmonic

为了和组的实机匹配,git完仓库之后我换成了v1.16.0,参考:https://blog.csdn.net/qq_62689471/article/details/136214621

QGC地面站

同样按官方流程:https://docs.qgroundcontrol.com/Stable_V5.0/en/qgc-user-guide/getting_started/download_and_install.html

基本的仿真,顺便python控制起降

代码控制无人机可以通过两种接口,封装好的MAVLink,或者比较底层的XRCE-DDS。后者搞了半天选择放弃……PX4官方和AI都会推荐后面这个,但一看相关github仓库里都没几个人在用。而MAVLink协议的方法又分两种:一是MAVROS,通过ROS2做中间商转发指令,后期再看看有没有必要吧,别人论文里是用的这个……二是python的mavsdk库,我大概或许似乎确凿是直接pip的。一个实例:

先cd到PX4仓库的根目录,然后启动无人机:

make px4_sitl gz_x500

python运行实例起降代码:

import asyncio
from mavsdk import System

# 14540 是 S.I.T.L. (Software-in-the-Loop) 默认暴露的 MAVLink 遥测端口
MAVLINK_ADDRESS = "udp://:14540" 

async def run():
    """连接到无人机并执行基本任务"""
    
    # --- 初始化 ---
    drone = System()
    print(f"尝试连接到无人机:{MAVLINK_ADDRESS}")
    await drone.connect(system_address=MAVLINK_ADDRESS)

    print("等待无人机连接...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print(f"无人机已连接!")
            break

    # --- 等待飞控初始化 (例如,等待 GPS 锁定/Home 位置设置) ---
    print("等待 Home 位置设置...")
    async for health in drone.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("Home 位置和全局定位正常。")
            break

    # --- 解锁/布防 ---
    print("-- 正在解锁/布防无人机")
    await drone.action.arm()
    
    # --- 起飞 ---
    # 默认高度是 2.5 米
    print("-- 正在起飞")
    await drone.action.takeoff()
    
    # 等待一段时间,让无人机到达起飞高度
    await asyncio.sleep(30)

    # --- 降落 ---
    print("-- 正在降落")
    await drone.action.land()

    # 等待降落完成
    await asyncio.sleep(10)
    
    # --- 上锁/撤防 (可选) ---
    print("-- 正在上锁/撤防无人机")
    # 注意:许多飞控在降落后会自动上锁
    try:
        await drone.action.disarm()
    except Exception as e:
        print(f"上锁失败或已自动上锁: {e}")

# Python 程序的入口点
if __name__ == "__main__":
    # 使用 asyncio 运行异步任务
    asyncio.run(run())

录屏:(中途用方块砸了下刚体无人机,八六教我怎么造出这种……)

深度相机仿真

解决了gz和ROS2的桥接问题这个就没问题。这次启动另一台带深度相机的无人机:

make px4_sitl gz_x500_depth

把gz里深度图和点云话题桥接到ROS2上,然后启动rviz2,添加image和PointCloud2对象,设定好对应的topic就显示出来了:

ros2 run ros_gz_bridge parameter_bridge   /depth_camera/points@sensor_msgs/msg/PointCloud2@gz.msgs.PointCloudPacked

ros2 run ros_gz_bridge parameter_bridge   /depth_camera@sensor_msgs/msg/Image@gz.msgs.Image

ros2 run rviz2 rviz2

场景绕圈拍摄示例:

耶配置好了,次回:实机实验(小心mamba out),最后祝您,身体健康。