【ROS2】ros2笔记杂类
·
1. /joint_states 来自于那里?
我们从这个章节 了解到,robot_state_publisher 会订阅 /joint_states,来计算对应的坐标变化。 那么, /joint_states 来自于那里呢?
根据场景不同,我们总结了以下来源:
| 来源节点 | 说明 | 是否实际连接物理设备 |
|---|---|---|
| joint_state_publisher | 从 URDF 参数中读取所有关节定义,生成模拟的 joint_state(通常给静态或手动控制用) | ❌ 无物理设备,只是虚拟 joint 数据 |
| joint_state_publisher_gui | 同上,但提供图形界面(滑动条调关节角度) | ❌ |
硬件驱动节点(如 ros2_control / 实际机器人驱动) |
从机器人控制器读取真实传感器值,发布真实 joint 状态 | ✅ 有物理设备 |
| 仿真节点(如 Gazebo / Ignition) | 仿真环境中的物理引擎发布 | ✅ 虚拟设备(仿真) |
1. 1 关于joint_state_publisher
joint_state_publisher 根据 /robot_description 参数中的关节描述, 模拟或手动设置的关节角度。 它并不会生成实际的关节状态,而是模拟的。 在没有实际硬件时,用于仿真、调试、可视化。真正的关节变化,一定是来自于机器人的传感器。
2. 传感器融合 - robot_localization
robot_localization 是ROS/ROS2 社区里 “开箱即用” 的传感器融合神器。robot_localization 提供:
- 扩展卡尔曼滤波(EKF)节点
- 无迹卡尔曼滤波(UKF)节点
| 节点 | 作用 |
|---|---|
ekf_node |
基于扩展卡尔曼滤波融合传感器数据(线性化滤波),适合大部分机器人 |
ukf_node |
基于无迹卡尔曼滤波,可处理强非线性情况,但计算量大,适合动态环境或非线性运动模型 |
它能把 雷达 + 超声波 + 里程计 + IMU数据 全部塞进同一个 EKF/UKF Node 里,吐出一条 平滑、连续、漂移极小 的 /odometry/filtered 里程计,坐标系统一到 odom 或 map。
其主要用于:
- 融合多源传感器数据,生成一致的机器人位姿(位置 + 姿态)和速度信息。
- 输出 odometry-like 信息,用于导航和控制。
- 处理传感器噪声、延迟和不一致问题,使机器人对运动状态的估计更准确。
在 没有融合之前,每个传感器都有自己的优缺点:
| 传感器 | 优点 | 缺点 |
|---|---|---|
| IMU | 高频率、短时漂移小 | 长时间积分会累积漂移(位置) |
| 里程计(编码器) | 短时间位置精度高 | 滑轮打滑会导致误差 |
| 激光雷达 | 精度高、可定位 | 更新频率低、依赖特征 |
| 超声波 | 检测近距离障碍物 | 精度低、容易受干扰 |
融合之后:
- IMU 提供高频姿态更新
- 里程计提供短期位移约束
- 雷达/超声波提供环境位置校正
这样就能得到相对稳定、低噪声的 odom 信息,供导航使用。
给出一个关于融合前后的误差的案例:
误差曲线:纯轮式 1 min 漂 1.8 m , 融合后 0.07 m
2.1 robot_localization 通用性
非常通用,但需要配置。
- 输入数据类型,可以接收:
- sensor_msgs/Imu
- nav_msgs/Odometry
- geometry_msgs/TwistWithCovariance
- 自定义话题(只要消息类型匹配)
- 配置灵活,可以指定每个传感器的:
- Covariance(噪声矩阵)
- 是否用于位置/姿态/速度融合
- 更新频率
- 输出标准化:
- /odom 或 /odometry/filtered 话题
- 可以直接作为导航(Nav2 / move_base)输入
所以无论是差速、全向、阿克曼,或者是地面 / 水下 / 空中机器人,只要你提供正确的传感器输入,它都能用。
2.2 配置robot_localization
robot_localization 的核心是 YAML 配置文件,定义传感器输入、噪声矩阵、融合策略等。常见文件名如 ekf.yaml 或 ukf.yaml。
ekf_filter_node:
ros__parameters:
# ────────────────────── 1. 核心节奏 ──────────────────────
frequency: 50.0 # 50Hz 丝滑输出
sensor_timeout: 0.2 # 丢 0.2s 就纯预测,防卡死
two_d_mode: true # 平面车,关 3D!
print_diagnostics: true # 出错直接 echo /diagnostics_agg 看
# ────────────────────── 2. 坐标系(一改全活) ──────────────────────
map_frame: map # 激光建图用
odom_frame: odom_combined # 连续 odom(Nav2 吃这根!)
base_link_frame: base_footprint # 底盘固定名字
world_frame: odom_combined # 重要!输出在 odom 系
# ────────────────────── 3. 轮式里程计(防打滑) ──────────────────────
odom0: /odom # 默认话题
odom0_config: [true, true, false, # X Y
false,false,false, # roll pitch
true, true, false, # yaw
true, true, false, # VX VY
false,false,false] # 加速度不用
odom0_queue_size: 10
odom0_differential: false # 是绝对位姿
odom0_nodelay: true
# ────────────────────── 4. IMU(零速修正+防侧滑) ──────────────────────
imu0: /imu/data_raw # 轮趣原始 IMU
imu0_config: [false,false,false,
true, true, true, # 角速度全开
false,false,false,
true, true, true, # 线加速度全开
false,false,false]
imu0_queue_size: 10
imu0_differential: false # 绝对角速度
imu0_remove_gravitational_acceleration: true # 自动去重力
imu0_nodelay: true
# ────────────────────── 5. 激光 Cartographer(全局定位) ──────────────────────
pose0: /cartographer/odom # carto 吐的 odom
pose0_config: [true, true, false,
false,false,false,
true, true, false,
true, true, false,
false,false,false]
pose0_queue_size: 5
pose0_differential: false
pose0_relative: false
# ────────────────────── 6. 超声波墙距(室内神器) ──────────────────────
pose1: /sonar_pose # 你自己写的节点
pose1_config: [true, true, false,
false,false,false,
false,false,false,
false,false,false,
false,false,false]
pose1_queue_size: 5
# ────────────────────── 7. 控制输入(急转弯更准) ──────────────────────
use_control: true
control_timeout: 0.1
control_config: [true, false, false, false, false, true] # 只控 X 和 yaw
# ────────────────────── 8. 噪声(复制粘贴,永不调参) ──────────────────────
process_noise_covariance: [0.08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0.08,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1e3,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0.03,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0.03,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0.08,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0.03,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0.03,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1e3,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0.02,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0.02,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0.04,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.02]
# ────────────────────── 9. 初始误差(1e-9 秒收敛) ──────────────────────
initial_estimate_covariance: [1e-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1e-9,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1e-9,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1e-9,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1e-9,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1e-9,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1e-9,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1e-9,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1e-9,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1e-9,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1e-9,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1e-9,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,1e-9,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1e-9,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,1e-9]
更多推荐



所有评论(0)