惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
博客园_首页
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
小众软件
小众软件
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
M
MIT News - Artificial intelligence
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog

树 - 洞

SMTP2GO 拯救你的 25 端口限制 | 树 SMTP2GO 拯救你的 25 端口限制 | 树 Bilibili Linux 客户端 VAAPI 硬解折腾全记录 | 树 Bilibili Linux 客户端 VAAPI 硬解折腾全记录 | 树 震惊!insmtr 的 MySQL 数据库居然被勒索软件攻击了! | 树 震惊!insmtr 的 MySQL 数据库居然被勒索软件攻击了! | 树 再探阿里云 DNS 对 CloudFront 的解析情况 | 树 再探阿里云 DNS 对 CloudFront 的解析情况 | 树 为单板机配置超简单 VNC 环境 改良版 | 树 为单板机配置超简单 VNC 环境 改良版 | 树 Ubuntu 22.04 Rust OpenCV 注意事项 | 树 Redmi AX6000 hanwckf U-Boot 安装 OpenWrt 24 | 树 为单板机配置超简单 VNC 环境 | 树 Ubuntu 22.04 Rust OpenCV 注意事项 | 树 Redmi AX6000 hanwckf U-Boot 安装 OpenWrt 24 | 树 为单板机配置超简单 VNC 环境 | 树 在 WSL 中使用 ISE | 树 在 WSL 中使用 ISE | 树 Jetson AGX Orin CH340 驱动安装 | 树 Jetson AGX Orin CH340 驱动安装 | 树 在 Ubuntu 22.04 上运行 PX4-Autopilot 1.13 | 树 在 Thunderbird 里使用沉浸式翻译插件 | 树 在 Thunderbird 里使用沉浸式翻译插件 | 树 搭建自定义域名邮箱 | 树 - 洞 搭建自定义域名邮箱 | 树 - 洞 Android Box for root 透明代理 | 树 再见,曾经热爱的算法竞赛 | 树 - 洞 再见,曾经热爱的算法竞赛 | 树 - 洞
在 Ubuntu 22.04 上运行 PX4-Autopilot 1.13 | 树
insmtr · 2025-01-23 · via 树 - 洞

Gazebo-classic 在 Ubuntu 22.04 上已停止维护,但是新版的 Gazebo 无论从性能上还是体验上都不佳。PX4 1.13 也是最后一个支持 Gazebo-classic 的版本,并且我们依旧可以在 Ubuntu 22.04 上运行 PX4 1.13 仿真,并手动编写其启动脚本。

准备

由于 linux 的 sudo 默认是隔离环境变量的,所以即使开了魔法,并配置了 http_proxyhttps_proxy ,也无法正常在 sudo 下使用。所以我们先进行魔法的额外配置。

sudo visudo

找到有一堆的 Defaults 开头的地方,就在最前面,跟在它后面写一行:

Defaults	env_keep+="https_proxy http_proxy"

然后保存。Ubuntu 发行版大概率是用 nano 作为编辑器的,那就 Ctrl+S 保存,Ctrl+X 退出。

接着安装构建用的工具链以及 gazebo 。

sudo apt install -y ninja-build exiftool protobuf-compiler libeigen3-dev genromfs xmlstarlet libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libopencv-dev python3-pip gawk cmake gazebo libgazebo-dev
pip3 install packaging numpy empy==3.3.4 toml pyyaml jinja2 kconfiglib jsonschema future pyros-genmsg

编译

找一个合适的位置开始克隆并编译 PX4 。

git clone --rec -j$(nproc) -b v1.13.2 --depth 1 https://github.com/PX4/PX4-Autopilot
cd PX4-Autopilot
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
make px4_sitl_default gazebo

编译完后会弹出一个 gazebo 的界面,不用管它,在终端内 Ctrl+C 关掉。

编译完后里面有好多是根本没用的,徒占空间。我们删掉这些无用的东西,只留精华。

cd ..
mv PX4-Autopilot PX4-Autopilot_
mkdir -p PX4-Autopilot/build/px4_sitl_default/build_gazebo
mkdir -p PX4-Autopilot/Tools/sitl_gazebo
cp -r PX4-Autopilot_/build/px4_sitl_default/bin PX4-Autopilot/build/px4_sitl_default
cp -r PX4-Autopilot_/build/px4_sitl_default/build_gazebo/*.so PX4-Autopilot/build/px4_sitl_default/build_gazebo
cp -r PX4-Autopilot_/build/px4_sitl_default/etc PX4-Autopilot/build/px4_sitl_default
cp -r PX4-Autopilot_/Tools/sitl_gazebo/models PX4-Autopilot/Tools/sitl_gazebo
cp -r PX4-Autopilot_/Tools/sitl_gazebo/worlds PX4-Autopilot/Tools/sitl_gazebo
rm -rf PX4-Autopilot_

然后往 .bashrc 里加一些内容。注意,如果你是 Nvidia 显卡,记得添加倒数第二行。如果你的电脑没有 N 卡只有 Intel 核显,则建议添加最后一行。(最后一行注释不算一行)

export PX4_DIR=你的 PX4 仿真目录
export GAZEBO_PLUGIN_PATH=$PX4_DIR/build/px4_sitl_default/build_gazebo
export GAZEBO_MODEL_PATH=$PX4_DIR/Tools/sitl_gazebo/models
export LD_LIBRARY_PATH=$PX4_DIR/build/px4_sitl_default/build_gazebo:$LD_LIBRARY_PATH
# export MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA  # 如果你是 Nvidia 显卡
# export LIBGL_ALWAYS_SOFTWARE=1                 # 如果你是 Intel 核显用户,建议添加
                                                 # AMD yes

启动!

PX4 的编译就算完了,现在安装 humble 版的 mavros 。

sudo apt install -y ros-humble-mavros ros-humble-mavros-extras
curl -sL https://github.com/mavlink/mavros/raw/ros2/mavros/scripts/install_geographiclib_datasets.sh | sudo bash

PX4-Autopilot 项目里有写好的有 ROS1 的 launch 文件,可以直接启动,但是没有提供 ROS2 版的,所以我们可以写一个简单的 px4 启动脚本。

nano px4

里面写上:

#!/bin/bash
mkdir -p ~/.gazebo/models
mkdir -p ~/.gazebo/worlds
MODEL="$PX4_DIR/Tools/sitl_gazebo/models/iris/iris.sdf"
MODEL_NAME="iris"
WORLD="$PX4_DIR/Tools/sitl_gazebo/worlds/empty.world"
while [[ $# -gt 0 ]]; do
  case $1 in
    --model)
      MODEL="$2"
      shift 2
      ;;
    --model-name)
      MODEL_NAME="$2"
      shift 2
      ;;
    --world)
      WORLD="$2"
      shift 2
      ;;
    *)
      echo "Unknown option: $1"
      exit 1
      ;;
  esac
done
export PX4_SIM_MODEL="iris"
if [[ ! "$MODEL" =~ ^/ ]]; then
    MODEL="$HOME/.gazebo/models/$MODEL"
fi
if [[ ! "$WORLD" =~ ^/ ]]; then
    WORLD="$HOME/.gazebo/worlds/$WORLD"
fi
gzserver --verbose "$WORLD" &
GZSERVER_PID=$!
gz model --spawn-file="$MODEL" --model-name="$MODEL_NAME" -z 1.0
gzclient &
GZCLIENT_PID=$!
ros2 run mavros mavros_node --ros-args -p fcu_url:=udp://:14540@:14580 &
MAVROS_PID=$!
cd $PX4_DIR/build/px4_sitl_default
./bin/px4 -s etc/init.d-posix/rcS
kill -9 $GZSERVER_PID 2>/dev/null
kill -9 $GZCLIENT_PID 2>/dev/null
kill -9 $MAVROS_PID 2>/dev/null

Ctrl+S 保存,Ctrl+X 退出。

然后把 px4 作为命令安装。

sudo install px4 /usr/local/bin/px4
rm px4

最后记得 source 一下 .bashrc ,或者直接重新打开终端,之后就可以用 px4 命令直接启动了!

. ~/.bashrc
px4

在 px4 的 mavlink 控制台内输入:

param set COM_RCL_EXCEPT 4
param save

这样就可以用 mavlink 来让飞机进入 Offboard 模式了!

摄像头模拟

gazebo 内有摄像头模组,px4 基于它做了一个转发到 mavros 的插件。在 ROS1 下,编译 PX4-Autopilot 时会自动编译这个插件,而现在我们用的 ROS2 ,需要手动安装。

sudo apt install -y ros-humble-gazebo-ros-pkgs

然后再启动带有摄像头的 px4 模型仿真:

px4 --model $PX4_DIR/Tools/sitl_gazebo/models/iris_fpv_cam/iris_fpv_cam.sdf

在另外一个终端中就可以看到摄像头的图像了:

ros2 topic list  # 可以看到有 /camera/camera_info 和 /camera/image_raw 两个话题
rviz2            # rviz2 内添加一个 Image 类型的话题,选择 topic 为 /camera/image_raw 就可以看到图像了

摄像头话题

按照上一节的步骤,我们已经可以成功发布摄像头话题了,但是如果我们在模型中添加两个及以上摄像头的话,就必须想办法修改每个摄像头的话题了。不然的话,两个摄像头的画面数据就会混在一个话题里面,当然这种情况在 ROS2 中是被允许的

由于 gazebo-ros-pkgs 中 gazebo-plugins 代码的 ROS1 版本和 ROS2 版本差异巨大,处理话题发布部分的代码也大相径庭。具体可以查看源码链接 ROS1 版本 ROS2 版本

查看代码后不难发现,使用 ROS1 版本的 gazebo-ros-pkgs 时,摄像头话题可以通过模型文件里面 camera_plugin 插件的配置项 cameraNameimageTopicName 来配置。而在 ROS2 版本中,代码有明显重写过。简单来讲,所有的配置项都从原来的「小驼峰命名法」变成了「蛇形命名法」,并且只支持用 camera_name 配置项来配置话题的前缀,后缀则固定为 /image_raw ,不能通过类似 image_topic_name 配置项配置。

这边给出一个对地摄像头的示例配置:

<sensor name='camera' type='camera'>
  <camera name='__default__'>
    <horizontal_fov>1.571</horizontal_fov>
    <image>
      <width>640</width>
      <height>480</height>
    </image>
    <clip>
      <near>0.1</near>
      <far>100</far>
    </clip>
    <lens>
      <type>custom</type>
      <custom_function>
        <c1>1.05</c1>
        <c2>4</c2>
        <f>1</f>
        <fun>tan</fun>
      </custom_function>
      <scale_to_hfov>1</scale_to_hfov>
      <cutoff_angle>3.1415</cutoff_angle>
      <env_texture_size>1080</env_texture_size>
    </lens>
  </camera>
  <always_on>1</always_on>
  <update_rate>30</update_rate>
  <visualize>1</visualize>
  <plugin name='camera_plugin' filename='libgazebo_ros_camera.so'>
    <camera_name>camera/ground_camera</camera_name>
    <frame_name>/robot_camera_link</frame_name>
    <P_cx>320.5</P_cx>
    <cx>320.5</cx>
    <cy>240.5</cy>
    <hack_baseline>0</hack_baseline>
    <focal_length>277.191356</focal_length>
    <distortion_k1>0.0</distortion_k1>
    <distortion_k2>0.0</distortion_k2>
    <distortion_k3>0.0</distortion_k3>
    <distortion_t1>0.0</distortion_t1>
    <distortion_t2>0.0</distortion_t2>
  </plugin>
</sensor>

使用带该摄像头模型的飞机模型启动 gazebo :

ros2 topic list  # 可以看到有 /camera/ground_camera/camera_info 和 /camera/ground_camera/image_raw 两个话题
rviz2            # rviz2 内添加一个 Image 类型的话题,选择 topic 为 /camera/ground_camera/image_raw 就可以看到图像了

这样就可以实现摄像头话题的分离了。

如果你一定要使用完全自定义的话题名的话,我们可以用 topic-tools 工具来转发话题。比如我们可以编辑刚才我们创建的 px4 一键启动程序。

🖊 Info

由于前面我们已经使用 install 命令将 px4 作为脚本安装在系统里了,所以我们需要直接编辑这个安装过的脚本。你也可以选择重复「启动!」一节里的步骤重新创建脚本,做好编辑之后再次运行 sudo install px4 /usr/local/bin/px4 命令安装。

先安装 topic-tools

sudo apt install -y ros-humble-topic-tools

接着用 sudo 权限编辑 /usr/local/bin/px4 ,在启动 mavros 节点和 px4 的命令之间插入:

ros2 run topic_tools relay /camera/ground_camera/image_raw /video/ground_camera &

保存退出,再次用带这个摄像头模型的飞机模型启动 gazebo

ros2 topic list  # 可以看到有 /video/ground_camera 这个话题
rviz2            # rviz2 内添加一个 Image 类型的话题,选择 topic 为 /video/ground_camera 就可以看到图像了

写在最后

我写了一个 px4 启动脚本来实现仿真的启动,这个脚本可以直接通过参数来指定飞机模型(model)和世界(world),具体使用方法是:

px4 --model $PX4_DIR/Tools/sitl_gazebo/models/iris/iris.sdf --model-name iris --world $PX4_DIR/Tools/sitl_gazebo/worlds/empty.world

这样就可以启动自定义飞机模型在自定义世界了。由于 gazebo 不支持读取带 ~ 的路径的模型,所以指定参数时请使用完整路径。

--model 参数的默认相对路径是 ~/.gazebo/models/--world 参数的默认相对路径是 ~/.gazebo/worlds/ ,如果你将模型或者世界放在了这两个目录下,也可以直接使用相对路径,例如:

px4 --model iris/iris.sdf --model-name iris --world empty.world

祝各位代码永无 bug ,飞机永无失控!电赛加油!