从实验1了解功能包到实验2熟练使用功能包,进入实验3定制优化各类功能包。


什么是进阶?
从绘制直边蝴蝶到卷边蝴蝶。
https://blog.csdn.net/zhangrelay/article/details/128304209

在这里插入图片描述

在这里插入图片描述
绘制曲线的控制器如何设计呢?


ROS2 Lyrical 实验3|趣味无代码案例:Turtlesim 小乌龟探险(全程不用写一行代码!)

适配实验3工具进阶,初学者友好:直接用ROS2自带小乌龟仿真,不需要新建功能包、不用写C++/Python代码,只用ROS2命令 + rqt工具 + bag2,把实验3全部工具串起来。
场景:小乌龟在窗口里乱跑,我们充当观测工程师,监控小乌龟状态、看轨迹曲线、录制回放小乌龟运动,排查“小乌龟迷路”的问题。

前置准备(安装自带包,一般Lyrical桌面版自带)

# 终端1:启动小乌龟仿真
ros2 run turtlesim turtlesim_node
# 终端2:键盘控制小乌龟
ros2 run turtlesim turtle_teleop_key

选中终端2,按方向键,小乌龟就会移动。

在这里插入图片描述

实验3所有工具,围绕小乌龟(无代码)

1. rqt_graph:查看系统通信图

新开终端

ros2 run rqt_graph rqt_graph

画面:

  • 两个节点:turtlesim_node(小乌龟模拟器)、turtle_teleop_key(键盘遥控器)
  • 话题:/turtle1/cmd_vel(键盘下发速度指令)、/turtle1/pose(小乌龟实时位置坐标)

趣味理解:一张图看清谁在发指令、谁接收指令。按键盘方向键,观察图上数据流。
在这里插入图片描述

2. rqt_plot:实时绘制小乌龟运动轨迹曲线(最直观好玩)

ros2 run rqt_plot rqt_plot

在输入框添加话题字段:/turtle1/pose/x,/turtle1/pose/y

  • x:小乌龟窗口横向坐标;y:纵向坐标
    操作:按住方向键移动小乌龟 → 窗口实时画出小乌龟走过位置的曲线!
    相当于实时GPS轨迹记录仪,小乌龟往哪爬,曲线就画到哪。
    在这里插入图片描述

3. rqt_console + rqt_logger_level:查看小乌龟日志,调节日志等级

ros2 run rqt_console rqt_console
ros2 run rqt_logger_level rqt_logger_level
  • rqt_console:小乌龟产生的日志在这里显示;比如小乌龟撞墙时会输出警告日志。
  • rqt_logger_level:选中turtlesim_node,动态切换日志等级,打开DEBUG日志,看到小乌龟底层位置更新信息,不用重启小乌龟。

4. bag2录制小乌龟探险全过程,离线回放(亮点!)

  1. 录制(移动小乌龟画一个圆圈)
ros2 bag record /turtle1/cmd_vel /turtle1/pose -o turtle_explore

移动小乌龟画一个圆,录制几秒后 Ctrl+C 停止录制。
2. 查看录制数据包信息

ros2 bag info turtle_explore
  1. 回放:不用键盘操作!小乌龟自动重复刚才画圈动作

先关闭键盘控制节点 turtle_teleop_key,保留小乌龟仿真窗口打开

ros2 bag play turtle_explore

✨效果:小乌龟自动复刻刚才的移动路线,重新画出一模一样的圆圈!

趣味比喻:录下小乌龟的探险视频,回放时小乌龟自动重走一遍探险路线。哪怕关掉bag重放,你还可以用rqt_plot再次看到回放时的轨迹曲线。

5. rqt_tf_tree 查看小乌龟坐标变换(拓展)

ros2 run rqt_tf_tree rqt_tf_tree

查看world世界坐标系 和 turtle1小乌龟本体坐标系之间变换关系。小乌龟一动,坐标实时更新。

6. ros2 wtf 系统自检

ros2 wtf

自动检查当前ROS2系统有没有通信异常、节点、话题配置问题。

ros2@ros2-cslg:~$ ros2 wtf
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: opennav_docking_core has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_interfaces has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_behavior_tree has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_theta_star_planner has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_core has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_storage_default_plugins has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: dwb_plugins has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: dwb_msgs has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_bt_navigator has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_smoother has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: opennav_following has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_util has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_constrained_smoother has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: opennav_docking_bt has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_route has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_navfn_planner has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_planner has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: dwb_core has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: navigation2 has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_rviz_plugins has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_mppi_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_graceful_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: mvsim has been updated to a new version. local: 1.4.0 < latest: 1.5.0
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_msgs has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_cpp has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav_2d_utils has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_storage has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: dwb_critics has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_rotation_shim_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_transport has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_py has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_smac_planner has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: lz4_cmake_module has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: mcap_vendor has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2 has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_examples_cpp has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: opennav_docking has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_behaviors has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav_2d_msgs has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_waypoint_follower has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_storage_sqlite3 has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: mola_demos has been updated to a new version. local: 3.2.0 < latest: 3.3.0
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_compression has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_ros_common has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_common has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_compression_zstd has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_regulated_pure_pursuit_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_storage_mcap has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_voxel_grid has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_map_server has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: realtime_tools has been updated to a new version. local: 5.3.0 < latest: 5.4.0
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_system_tests has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_dwb_controller has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_simple_commander has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_amcl has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: zstd_cmake_module has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_lifecycle_manager has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: dataspeed_can_usb has been updated to a new version. local: 2.0.7 < latest: 2.0.8
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_loopback_sim has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: costmap_queue has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: rosbag2_examples_py has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_velocity_smoother has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_collision_monitor has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: ros2bag has been updated to a new version. local: 0.33.3 < latest: 0.33.4
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: mrpt_libros_bridge has been updated to a new version. local: 3.5.3 < latest: 4.0.0
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_costmap_2d has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/package.py: 129: UserWarning: nav2_bringup has been updated to a new version. local: 1.5.1 < latest: 1.5.2
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/__init__.py: 219: UserWarning: Fail to call PlatformCheck class functions.
/opt/ros/lyrical/lib/python3.14/site-packages/ros2doctor/api/topic.py: 42: UserWarning: Publisher without subscriber detected on /turtle1/color_sensor.

All 4 checks passed

在这里插入图片描述
软件源中的功能包有些滞后,如果需要最新1.5.2,需要自行编译源代码或者等上半个月左右的时间。

可选小故障演示(理解调试,无代码)

  • 场景:bag回放小乌龟不动。
    排查:rqt_graph查看话题是否存在;检查回放QoS,或者确认是否关闭键盘控制节点。
  • 场景:rqt_plot看不到曲线。
    排查:话题名称输错,确认/turtle1/pose/x。

实验现象总结(写报告)

  1. rqt_graph可视化小乌龟仿真节点、键盘节点和话题之间通信关系,直观理解ROS2分布式通信。
  2. rqt_plot实时绘制小乌龟的x/y位置曲线,移动小乌龟可以实时看到运动轨迹。
  3. rqt_console捕获小乌龟运行日志,rqt_logger_level动态修改日志等级,无需重启仿真。
  4. bag2录制小乌龟运动指令和位置数据;回放时小乌龟自动复现之前画圈运动,实现动作离线复现。
  5. rqt_tf_tree观测世界与小乌龟本体坐标系变换;ros2 wtf检测系统通信状态。

思考题(适配小乌龟案例)

  1. bag回放小乌龟的时候,为什么不需要运行键盘控制节点?

答:bag录制时保存了/turtle1/cmd_vel速度指令消息;回放时bag2程序会代替键盘节点发布速度消息,小乌龟收到消息就会运动。

  1. rqt_plot查看 /turtle1/pose/x 和 /turtle1/pose/y,得到曲线代表什么?

答:小乌龟在仿真窗口内的实时坐标,曲线就是小乌龟移动的轨迹。

实验小结

本案例全程零代码,基于ROS2自带turtlesim小乌龟,完成实验3全部工具实操。不用关心C++/Python开发,专注掌握rqt可视化工具、日志工具、bag录制回放、系统自检等调试能力,非常适合初学者理解ROS2观测与调试。
在这里插入图片描述


在这里插入图片描述


ROS2 Lyrical 实验3 趣味示例:【心跳发光机器人】

只用这一个例子,贯穿本次实验3全部工具(日志、rqt_graph、rqt_plot、bag2、GDB调试),好玩直观,替代枯燥的数字累加示例。

案例简介

虚拟机器人持续输出心跳信号:心跳频率随“机器人紧张程度”变化。

  • 紧张值越高,心跳越快;
  • 心跳信号输出正弦波形;
  • 日志打印心跳状态,心跳过快触发警告日志;
  • 我们用整套实验3工具观测、录制、回放心跳波形。

复用实验2的功能包 chapter2_exp2,新建节点 heartbeat_robot.cpp

1. 完整代码 heartbeat_robot.cpp

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/float64.hpp"
#include <cmath>

using namespace std::chrono_literals;

class HeartBeatRobot : public rclcpp::Node
{
public:
  HeartBeatRobot() : Node("heartbeat_robot"), tension_(0.0)
  {
    pub_ = this->create_publisher<std_msgs::msg::Float64>("/robot_heartbeat", 10);
    timer_ = this->create_wall_timer(100ms, std::bind(&HeartBeatRobot::timer_cb, this));
    RCLCPP_INFO_ONCE(this->get_logger(), "🤖 心跳机器人启动!");
  }

private:
  void timer_cb()
  {
    // 模拟紧张度缓慢上升
    tension_ += 0.02;
    if(tension_ > 3.0) tension_ = 0.0;

    // 心跳正弦信号
    double heartbeat = sin(tension_ * 2.0);

    std_msgs::msg::Float64 msg;
    msg.data = heartbeat;
    pub_->publish(msg);

    // 分级日志
    RCLCPP_DEBUG(this->get_logger(), "原始心跳值:%.2f", heartbeat);
    RCLCPP_INFO(this->get_logger(), "心跳信号:%.2f,紧张度:%.2f", heartbeat, tension_);

    // 心跳过高,限频警告,每2秒打印一次
    if (tension_ > 2.0)
    {
      RCLCPP_WARN_THROTTLE(this->get_logger(), this->get_clock(), 2000,
        "⚠️机器人紧张!心跳过快!");
    }
  }

  rclcpp::Publisher<std_msgs::msg::Float64>::SharedPtr pub_;
  rclcpp::TimerBase::SharedPtr timer_;
  double tension_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<HeartBeatRobot>());
  rclcpp::shutdown();
  return 0;
}

2. CMakeLists.txt 添加编译规则

add_executable(heartbeat_robot src/heartbeat_robot.cpp)
ament_target_dependencies(heartbeat_robot rclcpp std_msgs)
install(TARGETS
  heartbeat_robot
  DESTINATION lib/${PROJECT_NAME}
)

编译:

cd ~/lyrical_ws
colcon build --packages-select chapter2_exp2
source install/setup.bash

3. 实验3全部工具,围绕这个心跳机器人演示

✅ 任务1:日志系统(rqt_console / rqt_logger_level)

ros2 run chapter2_exp2 heartbeat_robot
ros2 run rqt_console rqt_console
ros2 run rqt_logger_level rqt_logger_level

效果:

  • 紧张度低:INFO打印心跳;DEBUG隐藏;
  • 紧张度>2.0:自动弹出黄色警告 ⚠️机器人紧张!心跳过快!;
  • 在rqt_logger_level打开DEBUG级别,立刻看到底层原始心跳数值,不用重启机器人节点。

✅ 任务2:rqt_graph 看通信图

ros2 run rqt_graph rqt_graph

看到节点 heartbeat_robot 发布话题 /robot_heartbeat,可视化机器人心跳数据流。

✅ 任务3:rqt_plot 绘制心跳波形(最有趣!)

ros2 run rqt_plot rqt_plot /robot_heartbeat/data

弹出窗口,实时画出正弦心跳曲线,就像医院心电监护仪!紧张度升高,波形变化。

✅ 任务4:bag2录制心跳,离线回放心电波形

#录制心跳数据
ros2 bag record /robot_heartbeat -o heartbeat_bag
#录制一段时间后 Ctrl+C停止
ros2 bag info heartbeat_bag

#关闭心跳机器人节点,回放数据包,波形复现!
ros2 bag play heartbeat_bag

亮点:关掉机器人,rqt_plot依然能看到一模一样的心电波形,相当于保存机器人的“心跳病历”,离线复盘。

✅ 任务5:GDB小演示(制造bug)

修改代码,加一行空指针模拟机器人崩溃:

// 在timer_cb内部添加
int *p = nullptr;
*p = 10;

编译运行,节点直接崩溃。用gdb启动,查看崩溃堆栈,定位机器人“猝死”的代码行。

4. 实验现象总结(写报告用)

启动心跳机器人后:

  1. 终端持续输出心跳数值与紧张度;紧张度超过阈值,周期性警告日志;rqt_console按颜色区分INFO/WARN/DEBUG。
  2. rqt_graph可以看到心跳节点和话题。
  3. rqt_plot实时绘制正弦心电波形,直观看到心跳周期性变化。
  4. bag2录制心跳数据;关闭原节点回放,心电波形完全复现,实现离线分析。
  5. 人为添加空指针bug,使用GDB捕获崩溃堆栈,定位程序故障。

5. 思考题(适配这个例子)

  1. 当机器人紧张度持续大于2.0,为什么警告信息不会疯狂刷屏?

答:代码使用RCLCPP_WARN_THROTTLE限频日志,限制每2秒输出一次警告,避免日志风暴。

  1. bag录制心跳信号有什么用处?

答:保存机器人心跳波形,后续可以脱离机器人节点反复回放波形,用于分析机器人紧张状态,类似保存心电记录。


ROS2‑Lyrical 实验3:工具进阶——定制优化各类功能包

实验递进关系:实验1了解功能包信息(只读查询)→实验2熟练使用功能包(创建、编译、开发节点、通信机制)→实验3工具进阶,利用全套调试可视化工具,对自研功能包做调试、观测、性能调优、离线复现,完成功能包的定制与工程优化。
适配环境:Ubuntu 26.04(Resolute)、ROS2 Lyrical Luth;桌面完整版(rqt全套、rviz2、rosbag2、turtlesim、诊断工具)
前置实验:实验1 ROS2系统入门;实验2 架构与核心(自建C++功能包、话题/服务/Action、自定义消息、launch文件)。

一、实验基本信息

实验目的(知识+实操+工程素养)

知识目标
  1. 掌握ROS2 Lyrical全套调试观测工具链,理解DDS去中心化架构下调试工具的工作原理,对比ROS1 roscore时代调试工具差异。
  2. 理解分级日志系统5个日志等级(DEBUG/INFO/WARN/ERROR/FATAL),掌握编译、静态配置、运行时动态修改三种日志控制方式。
  3. 理解底层调试GDB、Valgrind、core‑dump的适用场景;掌握rqt系列可视化工具、RViz2、TF2、bag2数据录制回放的原理。
  4. 掌握系统自检、机器人诊断监控手段,学会定位通信异常、内存泄漏、参数异常、节点崩溃类问题。
实操目标
  1. 在实验2自建功能包基础上,添加分级日志代码,分别使用命令行、配置文件、rqt_console/rqt_logger_level管控日志输出。
  2. 掌握GDB、Valgrind通过launch_prefix方式调试C++节点;配置core转储实现崩溃后离线分析。
  3. 使用rqt_graph、rqt_top、rqt_topic观测自研节点计算图、CPU内存、话题频率带宽;使用rqt_reconfigure为自定义节点增加动态参数回调。
  4. 使用rqt_plot观测标量时序数据;掌握rqt_tf_tree查看坐标变换树;掌握bag2录制、回放、数据分析,实现算法离线复现。
  5. 使用roswtf、colcon‑lint做功能包编译与运行时自检;掌握rqt_gui一体化自定义工作布局。
工程素养目标

建立机器人软件可观测性思维:开发不只是写代码,更要具备日志记录、状态观测、故障定位、离线复现的工程能力;养成“开发‑调试‑观测‑复现”闭环开发习惯,为实体机器人调试打下基础。

实验预习要点

  1. ROS2无中心化Master,所有调试工具本身就是普通DDS节点,依靠节点自动发现获取系统状态,不需要roscore。
  2. 日志五级等级:DEBUG(调试)、INFO(普通信息)、WARN(警告不崩溃)、ERROR(功能故障可恢复)、FATAL(致命,节点退出)。
  3. bag2是ROS2数据包,替代ROS1 bag,支持SQLite3存储、压缩;可以录制话题,脱离真实硬件复现全部传感器数据流。
  4. rqt_reconfigure动态参数:节点必须代码注册回调,默认节点不支持动态修改参数,不是工具故障。
  5. core dump:程序崩溃操作系统保存内存镜像,事后gdb离线分析,适合现场偶现崩溃问题排查。

ROS1与ROS2调试工具简要对比

项目ROS1 NoeticROS2 Lyrical
运行依赖需要roscoreDDS自动发现,无需主节点
日志底层log4cxxrcl内置日志,支持运行时切换日志后端
数据包bagbag2,多存储后端、分片压缩
动态参数dynamic_reconfiguredynamic_reconfigure,C++需注册回调
图形框架rqtrqt重构,适配DDS统计信息输出

二、实验原理

  1. 底层调试原理:ROS2节点本质是独立Linux可执行程序,可以直接复用GDB、Valgrind等Linux原生调试工具;launch文件的launch_prefix可以给可执行程序包装调试器,新开终端挂载调试会话;core‑dump由操作系统内核在程序崩溃时生成内存快照,供事后离线回溯堆栈。
  2. 分级日志系统:rclcpp/rclpy内置日志模块,日志可以编译期屏蔽、配置文件静态设置、运行时GUI动态修改;支持条件输出、限频输出、单次输出,减少无效打印。
  3. rqt工具集原理:全部基于DDS话题、服务、参数接口采集系统运行时信息;rqt_graph通过话题统计获取节点‑话题‑服务拓扑;rqt_top读取进程状态;rqt_plot订阅话题提取数值字段绘图。
  4. bag2录制回放原理:录制阶段订阅指定话题,把消息序列化存入本地存储;回放阶段模拟发布者,把存储的消息按原始时间戳重新发布到DDS,实现离线复现传感器数据。
  5. 系统诊断Diagnostic:标准化消息diagnostic_msgs/msg/DiagnosticArray,各个硬件/节点上报自身健康状态,聚合后可视化,用于电机、电池、传感器故障监控。

三、实验内容与详细步骤

前置:复用实验2自建工作空间~/lyrical_ws,基于chapter2_exp2功能包继续开发。

任务1:ROS2分级日志系统实操(必做)

修改实验2的C++发布节点,增加完整日志宏。

  1. 修改publisher.cpp,增加命名日志、条件输出、限频输出、单次输出。
#include "rclcpp/rclcpp.hpp"
#include "chapter2_exp2/msg/custom_data.hpp"
using namespace std::chrono_literals;

class CustomPublisher : public rclcpp::Node
{
public:
 CustomPublisher() : Node("custom_publisher")
 {
 pub_ = this->create_publisher<chapter2_exp2::msg::CustomData>("custom_topic", 10);
 timer_ = this->create_wall_timer(500ms, std::bind(&CustomPublisher::timer_callback, this));
 sub_logger_ = this->get_logger().get_child("sensor_module"); //子命名日志器
 }
private:
 void timer_callback()
 {
 chapter2_exp2::msg::CustomData msg;
 msg.num_a = 1;
 msg.num_b = 2;
 msg.num_c = msg.num_a + msg.num_b;

 RCLCPP_DEBUG(get_logger(),"调试信息,发布数据");
 RCLCPP_INFO(get_logger(),"Publishing a=%d,b=%d,c=%d",msg.num_a,msg.num_b,msg.num_c);
 RCLCPP_WARN_THROTTLE(get_logger(),2000,"警告:模拟限频打印,每2秒一次");
 RCLCPP_INFO_ONCE(get_logger(),"该消息只会打印一次");
 RCLCPP_INFO_COND(sub_logger_, msg.num_c>0,"条件输出:c大于0");

 pub_->publish(msg);
 }
 rclcpp::Publisher<chapter2_exp2::msg::CustomData>::SharedPtr pub_;
 rclcpp::TimerBase::SharedPtr timer_;
 rclcpp::Logger sub_logger_;
};

int main(int argc, char * argv[])
{
 rclcpp::init(argc, argv);
 rclcpp::spin(std::make_shared<CustomPublisher>());
 rclcpp::shutdown();
 return 0;
}
  1. 编译
cd ~/lyrical_ws
colcon build --packages-select chapter2_exp2
source install/setup.bash
  1. 方式一:rqt_console图形查看日志
ros2 run rqt_console rqt_console
ros2 run chapter2_exp2 publisher

观察窗口不同等级颜色输出,支持过滤、保存日志文件。
4. 方式二:rqt_logger_level动态修改日志等级

ros2 run rqt_logger_level rqt_logger_level

选择custom_publisher及其子日志器sensor_module,切换DEBUG/INFO等级,无需重启节点立刻生效。
5. 方式三:配置文件静态设置日志等级
新建config/logger.config

log_level.chapter2_exp2=INFO
log_level.chapter2_exp2.sensor_module=DEBUG

修改launch文件,注入环境变量RCLCPP_LOG_CONFIG加载配置,启动节点观察日志输出变化。

任务2:底层调试工具GDB / Valgrind / core‑dump(必做)

提示:制造简单空指针异常用于调试演示。

  1. 方法1:终端直接gdb启动可执行程序
cd ~/lyrical_ws/install/lib/chapter2_exp2
gdb publisher
(gdb) r #运行程序,触发崩溃
(gdb) bt #打印调用栈,定位崩溃代码行
  1. 方法2:通过launch文件挂载GDB(推荐,新开xterm终端)
    编写debug_gdb.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
 return LaunchDescription([
 Node(
 package="chapter2_exp2",
 executable="publisher",
 name="custom_publisher",
 output="screen",
 launch_prefix="xterm -e gdb --args"
 )
 ])

运行:

colcon build --packages-select chapter2_exp2
source install/setup.bash
ros2 launch chapter2_exp2 debug_gdb.launch.py
  1. Valgrind内存泄漏检测,修改launch_prefix
launch_prefix="valgrind --leak-check=full xterm -e"

启动后观测内存访问、泄漏报告。
4. core dump配置,用于事后离线分析崩溃

ulimit -c unlimited
echo 1 | sudo tee /proc/sys/kernel/core_uses_pid

节点崩溃后生成core.<pid>,事后分析:

gdb ./publisher core.12345
(gdb) bt

任务3:rqt系统观测工具集实操(必做)

保持publisher、subscriber两个节点运行。

  1. rqt_graph 通信拓扑可视化
ros2 run rqt_graph rqt_graph
#开启带宽频率统计
ros2 param set /rqt_graph enable_statistics true

观察custom_publisher、custom_subscriber节点、话题custom_topic连接关系,观察消息带宽、发布频率;断开话题、修改消息类型,观察标红异常提示。
2. rqt_top 进程资源监视器

ros2 run rqt_top rqt_top

查看两个节点PID、CPU占用、内存占用。
3. rqt_topic话题监视器

ros2 run rqt_topic rqt_topic

监控custom_topic消息结构、发布频率、带宽。
4. rqt_plot标量时序绘图
提取消息字段绘制时序曲线

ros2 run rqt_plot rqt_plot /custom_topic/data.num_a:/custom_topic/data.num_c

切换绘图后端(Matplotlib / PyQtGraph / Qwt),观察数值随时间变化曲线。
5. rqt_reconfigure动态参数拓展(拓展)
给自定义C++节点添加dynamic_reconfigure回调,编译后,运行

ros2 run rqt_reconfigure rqt_reconfigure

GUI修改节点参数,节点不重启即可获取参数更新。

任务4:bag2数据包录制、回放与数据分析(核心必做)

  1. 录制话题数据
#录制custom_topic话题
ros2 bag record /custom_topic -o exp3_bag
#查看bag信息
ros2 bag info exp3_bag
  1. 回放数据包(关闭原来publisher节点)
#0.8倍速回放
ros2 bag play exp3_bag --rate 0.8

订阅者节点可以收到回放发布出来的消息,实现脱离原发布节点复现数据。
3. rqt_bag2图形化查看bag包

ros2 run rqt_bag2 rqt_bag2

加载bag包,时间轴查看话题,查看原始消息内容。

任务5:系统自检与诊断监控(选做)

  1. roswtf系统故障扫描
ros2 wtf

输出静态包检查、运行时DDS图检查,识别环境变量、依赖、DDS通信异常。
2. colcon‑lint编译配置文件校验

sudo apt install ros‑lyrical‑colcon‑lint
colcon lint --packages-select chapter2_exp2

检查package.xml、CMakeLists.txt依赖缺失、语法、命名规范问题。
3. rqt_gui一体化集成界面

ros2 run rqt_gui rqt_gui

把rqt_console、rqt_graph、rqt_plot等多个插件放在同一窗口,保存布局perspective配置文件。

任务6:TF2坐标系可视化拓展(拓展选做)

如果有TF相关demo节点,运行:

ros2 run rqt_tf_tree rqt_tf_tree

查看frame父子关系,观测变换延时,排查坐标错位。

四、实验现象与结果

  1. 日志系统:rqt_console可以区分不同等级日志颜色;rqt_logger_level切换等级,DEBUG日志可以动态打开关闭,无需重启节点;配置文件加载后日志等级符合配置设定。
  2. 底层调试:GDB触发崩溃后,bt可以打印调用栈,定位源码行号;Valgrind输出内存读写、泄漏报告;core文件生成成功,gdb可离线回溯崩溃堆栈。
  3. rqt观测工具:
    • rqt_graph可以清晰看到自研节点‑话题拓扑,开启统计后显示消息频率带宽;异常连接标红。
    • rqt_top可以看到节点CPU、内存资源占用。
    • rqt_plot成功绘制消息字段时序曲线。
  4. bag2数据包:录制成功;ros2 bag info显示话题、消息数量、时长;回放时订阅节点正常接收数据;rqt_bag2图形界面可浏览时间轴与消息。
  5. 系统自检:ros2 wtf输出系统警告与错误;colcon lint输出功能包配置规范检查结果;rqt_gui可以自定义多插件布局并保存。

常见故障排查(Ubuntu26.04 + ROS2 Lyrical)

  1. rqt_logger_level修改等级无效:节点没有对应命名日志;环境变量冲突。
  2. gdb+launch_prefix xterm不弹出:没有安装xterm,执行sudo apt install xterm。
  3. bag2回放,订阅者收不到消息:QoS策略不匹配;话题名称拼写错误。
  4. rqt_reconfigure看不到自定义节点:C++代码没有注册dynamic_reconfigure回调,不是bug,节点默认不支持动态参数。
  5. core文件不生成:ulimit -c unlimited只对当前终端会话生效,新开终端需要重新设置。

五、实验思考题(含参考答案,可直接写实验报告)

  1. ROS2相比ROS1,调试工具最大架构变化是什么?

答:ROS1依赖中心化roscore;ROS2全部调试工具作为普通DDS节点,依靠分布式节点自动发现,不需要主节点;支持单机、多机跨机器调试观测系统状态。

  1. DEBUG等级日志在产品发布版本如何屏蔽?有哪三种控制日志等级的方式?

答:编译时CMake定义RCLCPP_MIN_SEVERITY屏蔽DEBUG;配置文件静态加载;运行时通过rqt_logger_level动态修改日志等级。

  1. GDB、Valgrind、core dump三者分别适合排查哪一类bug?

答:GDB:现场断点调试,复现问题时打断点看堆栈;Valgrind:内存泄漏、野指针、越界访问;core dump:偶现崩溃,无法现场复现,事后离线分析崩溃快照。

  1. bag2数据包有什么工程价值?什么时候优先使用bag2?

答:录制传感器/控制话题数据,可以脱离真实硬件回放复现全部数据流;适合算法开发、问题复现、离线调参;硬件不方便反复运行、现场偶现bug,优先录制bag用于实验室复现。

  1. rqt_reconfigure动态参数有什么工程价值?自定义C++节点直接打开工具看不到节点参数,是什么原因?

答:运行时修改参数不需要重启节点,调试PID、传感器滤波参数效率高;自定义节点必须代码注册dynamic_reconfigure回调函数,节点默认不启用动态参数,不是工具故障。

  1. ros2 wtf与colcon lint有什么区别?

答:colcon lint属于编译期检查,校验package.xml、CMakeLists.txt配置语法、依赖;ros2 wtf是运行时检查,检测DDS通信、环境变量、节点运行状态。

六、实验总结

本实验承接实验2,在自建功能包基础上完整实践ROS2‑Lyrical全套调试、观测、可视化工具链。

  1. 掌握分级日志系统三种配置方式,学会日志的合理打印与过滤。
  2. 掌握Linux原生调试工具GDB、Valgrind、core‑dump,定位C++节点崩溃、内存问题。
  3. 熟练使用rqt系列工具集观测计算图拓扑、进程资源、话题数据、标量时序曲线;理解DDS去中心化调试机制。
  4. 掌握bag2录制回放,实现机器人数据流离线复现,建立“录制‑回放‑分析”的调试流程。
  5. 掌握系统自检工具,学会从编译阶段、运行时两个维度排查功能包问题。

通过本实验建立机器人软件可观测性工程思维,不再只看程序是否跑通,学会观测节点状态、消息数据流、资源占用,为后续URDF、TF2、RViz2、导航综合实验打好调试基础。

后续实验预告:实验4 URDF机器人建模与Gazebo Garden仿真。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐