ROS2 仿真与视觉
22 URDF 模型
22 URDF 模型(URDF Modeling)
22.1 URDF 概述
ROS 2 中的 URDF 是使用 XML 编写的机器人模型描述文件,用于定义机器人的连杆(link)、关节(joint)、几何形状、质量惯量、坐标系,以及碰撞和可视化模型等信息。它是 ROS 2 中机器人 TF 坐标、Gazebo/Ignition 仿真、RViz 可视化、运动规划等的基础。简而言之,URDF 是 ROS 2 用来"向系统展示机器人的外观以及组件如何连接"的标准模型文件。
22.1.1 什么是 URDF
URDF(Unified Robot Description Format)是一种 XML 格式的机器人描述文件,用于定义机器人的几何形状、关节、惯量等。
Plain Text URDF 文件结构:
robot.urdf
根元素
link 连杆定义
Visual 可视化
Collision 碰撞
Inertial 惯量
# 关节定义 父连杆 子连杆 变换
22.2 机器人的组成
在为机器人建模时,我们需要先熟悉它们的整体组成和关键参数。一般来说,机器人主要由四个部分组成:硬件结构、驱动系统、传感器系统和控制系统。市场上常见的机器人,无论是移动机器人还是机械臂,都可以根据这四个组成模块进行拆分和分析,从而为后续的建模奠定基础。

硬件结构是坚固可见的设备,如底盘、外壳、电机等;
驱动系统是能够驱动设备正常使用的设备,如电机驱动器、电源管理系统等;
传感系统包括电机上的编码器、板载 IMU、安装的相机、雷达等,使机器人能够感知自身状态和外部环境;
控制系统是我们开发过程中的主要载体,通常是树莓派、计算机等计算平台,以及内部的操作系统和应用程序。

机器人建模的过程,以类似的方式,就是用建模语言描述机器人的每一部分,并将其组合起来的过程。

22.3 URDF 语法
22.3.1 link 描述
link 标签用于描述机器人某一部件的外观和物理属性,包括尺寸、颜色、形状,以及质量、惯量矩阵、碰撞参数等物理属性。
例如,这个机械臂连杆的描述如下:

link 标签中的 name 是连杆的名称,我们可以自定义,以便将来在 link 连接时使用。
link 内的部分描述了机器人的外观,例如:
这是 stl 文件,看起来像真实的机器人。
这表示坐标相对于初始位置的偏差,具有 x、y、z 的水平偏移以及 roll、pitch、yaw 旋转,如果不需要偏差,则全部为 0。


第二部分描述碰撞参数,看起来与之前相同,差异较大。

部分重点描述机器人的外观,即视觉效果;

部分描述机器人的运动状态,例如机器人与外界的接触如何算作碰撞。

在这个机器人模型中,蓝色部分被描述出来,在物理控制过程中,这种复杂的外观在计算碰撞检测时要求更高,为了简化计算,我们将用于碰撞检测的模型简化为绿色框中的圆柱形,这就是其中描述的形状。同样适用于坐标系的偏差,可以描述刚体重心的偏差。
对于移动机器人,link 也可以用来描述车身、轮子等。
22.3.2 joint 关节描述
只有当机器人模型中的连杆最终通过关节连接后,才能产生相对运动。
URDF 中有六种关节运动类型。
continuous,描述旋转运动,可以无限地围绕轴旋转,例如汽车中的车轮就是这种类型。

revolute 与 continuous 类型也是旋转关节,但区别在于它不能无限旋转,而是有角度限制,例如机械臂中的两个连杆,属于这种运动类型。
prismatic 是滑动关节,可以沿着特定轴滑动,并且有位置限制,这与一般的直线动力相同。

fixed,固定关节,是唯一不允许运动的关节,尽管它仍然被频繁使用,例如安装在机器人上的相机,其相对位置是不变的,此时使用的连接是 fixed。
floating 是浮动关节,第六种 planar 是平面关节,使用相对较少。
在 URDF 模型中,每个 link 使用 xml 内容描述,例如关节的名称,运动的类型。
parent 标签:描述父连杆;
child 标签:描述子连杆,相对于父连杆运动;
origin:两个坐标系之间的关系,图中红色向量,可以理解为这两个坐标系应如何安装在一起;
axis 表示关节轴的单位向量,例如 z 等于 1,意味着围绕 z 轴向右方向进行旋转运动;
limit 表示一些运动限制,如最小位置、最大位置和最大速度。
22.4 完整的机器人模型
最终,所有 link 和 joint 标签完成机器人各部分的描述和组合,全部在一个 robot 标签中,形成完整的机器人模型。
所以当你查看特定 URDF 模型时,你查看每段代码的细节,寻找 link 和 joint,看看机器人由什么组成,你就知道全貌,然后看细节。
22.5 SO-ARM 机械臂的导入


22.5.1 克隆仓库:

cd ~/workspaces/src
git clone https://github.com/brukg/SO-100-arm.git22.5.2 编译项目
# Install dependencies
cd ..
rosdep install --from-paths src --ignore-src -r -y
# Build the package
colcon build --packages-select so_100_arm22.5.3 在 Gazebo 中查看机械臂
# Refresh environment variables
source install/setup.bash
ros2 launch so_100_arm rviz.launch.py22.6 后续步骤
Gazebo 仿真 - 学习物理仿真
2.24 摄像头预览 - 学习摄像头配置
23 Gazebo 仿真
23 Gazebo 仿真
23.1 Gazebo 概述

Gazebo 是一个常用的机器人仿真平台,可以构建虚拟环境来仿真机器人运动、传感器数据,以及现实世界中的物理交互(例如重力、碰撞、摩擦等)。它支持机器人模型(URDF/SDF)的导入,并可以仿真多种传感器,如相机、激光雷达和 IMU,因此经常用于机器人算法开发、调试和测试,特别是在 ROS/ROS2 生态系统中。通过 Gazebo,开发者可以快速验证控制、导航和 SLAM 等功能,而无需依赖真实硬件,显著降低开发成本和风险。
23.1.1 什么是 Gazebo
Plain Text Gazebo 仿真结构:
Gazebo Server
物理引擎 (ODE/Bullet) (OGRE) plugin
ROS 2 接口
cmd_vel odom scan

23.2 安装操作
通过 apt 命令安装 gazebo
sudo apt install ros-${ROS_DISTRO}-ros-gz通过以下命令启动 gazebo
# ros2 launch ros_gz_sim gz_sim.launch.py模型如下所示:
23.3 后续步骤
1.24 摄像头预览 - 学习摄像头配置
2.25 摄像头标定 - 学习摄像头标定
24 摄像头预览
24 摄像头预览
24.1 编译功能包
cd /opt/seeed/development_guide/12_llm_offline/seeed_ws
colcon build
source install/setup.bash24.2 启动摄像头
启动摄像头。
ros2 run camera camera_usb查看节点和话题
24.3 预览图像
使用 rqt 查看摄像头图像:rqt → Plugins → Visualization → Image View
rqt24.4 关键代码
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
class CameraNode(Node):
def __init__(self):
super().__init__('camera_usb')
self.publisher = self.create_publisher(Image, 'image_raw', 10)
self.bridge = CvBridge()
self.cap = cv2.VideoCapture(0)
if not self.cap.isOpened():
self.get_logger().error('Unable to open camera')
return
self.timer = self.create_timer(0.05, self.timer_callback)
def timer_callback(self):
ret, frame = self.cap.read()
if ret:
image_msg = self.bridge.cv2_to_imgmsg(frame, encoding="bgr8")
self.publisher.publish(image_msg)
else:
self.get_logger().warn('Failed to capture image')
def main(args=None):
rclpy.init(args=args)
node = CameraNode()
rclpy.spin(node)
node.cap.release()
rclpy.shutdown()
if __name__ == '__main__':
main()24.5 后续步骤
1.25 摄像头标定 - 学习摄像头标定
- 26 AR 视觉 - 学习 AR 视觉
25 摄像头标定
摄像头标定
25.1 摄像头标定概述
25.1.1 什么是摄像头标定


摄像头标定是确定摄像头内参(焦距、主点、畸变系数)和外参(位置、姿态)的过程。
摄像头是使用镜头成像的设备,由于镜头的物理特性会引入几何畸变。标定是通过数学模型描述并补偿这些异常。
Plain Text 摄像头参数详情:
Intrinsics - 摄像头固有的光学特性:
- 焦距
- 像素单位的镜头焦距,确定视场大小
- 主点
- 光轴与图像平面的交点,通常靠近图像中心 Distortion coefficients(畸变系数)
- 径向畸变(k1, k2, k3) - 桶形/枕形畸变 (p1, p2)
Extrinsics - 世界坐标系中的摄像头位置: Rotation Matrix(旋转矩阵)
- 描述摄像头坐标系相对于世界坐标系的旋转
- 平移向量(translation vector: 3x1)
- 描述摄像头坐标系原点相对于世界坐标系的偏移
摄像头内参矩阵(Camera Matrix): [fx 0 cx] K = [0 fy cy] (3x3 matrix) [0 0 1]
25.1.2 为什么要标定
| 目的 | 注解 | 精度要求 |
|---|---|---|
| 视觉测距 | 将像素距离转换为实际距离 | 高精度 |
| 三维重建 | 精确恢复 3D 信息,Structure from Motion | 高精度 |
| 摄像头协作 | 多摄像头图像融合,全景摄像头 | 中高精度 |
| 机器人导航 | 准确的环境感知,视觉里程计 | 高精度 |
| 物体检测 | 修正物体边缘,提高检测精度 | 中等精度 |
| AR/VR | 虚拟内容与现实世界精确对齐 | 高精度 |
25.1.3 摄像头畸变类型
Plain Text 畸变类型:
- 径向畸变(Radial Distortion)
桶形畸变(Barrel Distortion)
枕形畸变(Pincushion Distortion)
- 切向畸变(Tangential Distortion) 图像平面与镜头平面不完全平行导致
25.1.4 标定原理
摄像头标定基于针孔摄像头模型,通过已知的世界坐标(标定板上的角点)与图像坐标(检测到的像素位置)之间的关系来求解摄像头参数。
Plain Text 标定过程:
世界坐标 (3D) → 外参 → 摄像头坐标 (3D) → 内参 → 投影 2D [X,Y,Z,1] [x,y,z] K [u,v,1]
重投影误差(Reprojection error): 标定的质量指标,计算重投影点之间的误差差距 数值越小,标定越好。
25.2 标定工具的安装
安装摄像头包
sudo apt install ros-humble-camera-calibration25.3 下载棋盘格
从以下地址下载棋盘格
下载棋盘格并打印出来。
25.4 运行摄像头标定

# For 8x6 checkerboard with 25mm squares
ros2 run camera_calibration cameracalibrator --size 8x6 --square 0.025 \
--ros-args --remap image:=/camera/color/image_raw --remap camera:=/camera/color注意: --size 8x6 指内角点数量(8x6 = 48 个角点,对应 9x7 的格子) --square 0.025 指方格尺寸,单位为米(25 mm) 移动摄像头从不同角度捕捉图像
从不同角度收集图像,自动计算摄像头参数,并将标定数据保存到工具提示中。
25.5 后续步骤
完成摄像头标定的学习后:
- 26 AR 视觉 - 学习 AR 视觉和 ARUco 标记