鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    ROS2 订阅高帧率的话题的时间滞后于低帧率话题的时间

    已定时 已固定 已锁定 已移动 已解决
    综合问题
    ros2话题 ros2 通信 高质量数据滞后
    3
    6
    1.1k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 8118775078
      JQK
      最后由 小鱼 编辑

      一个节点同时订阅200Hz的imu和10Hz的点云数据,且只做打印时间戳的操作,但是会出现连续收到几帧点云数据后才收到imu数据,且发布端是没有问题的,出问题的点云数据的时间是在imu数据之后的

      #include <glog/logging.h>
      #include <iomanip>
      #include <rclcpp/rclcpp.hpp>
      #include <sensor_msgs/msg/imu.hpp>
      #include <sensor_msgs/msg/point_cloud2.hpp>
      
      double FromRos(builtin_interfaces::msg::Time time) {
        return time.sec + 1e-9 * time.nanosec;
      }
      class SimpleSubscriber : public rclcpp::Node {
      public:
        SimpleSubscriber() : Node("simple_subscriber") {
          FLAGS_colorlogtostderr = true; // 显示颜色
          FLAGS_alsologtostderr = 1;     // 终端与文件共同输出
          google::InitGoogleLogging("simple_subscriber");
          google::SetLogDestination(google::INFO, "/opt/eame/log/simple_subscriber/");
          FLAGS_minloglevel = google::INFO;
          point_cloud_subscription_ =
              this->create_subscription<sensor_msgs::msg::PointCloud2>(
                  "/livox/lidar", 5,
                  std::bind(&SimpleSubscriber::HandlePointCloud2Message, this,
                            std::placeholders::_1));
          imu_subscription_ = this->create_subscription<sensor_msgs::msg::Imu>(
              "/livox/imu", 2000,
              std::bind(&SimpleSubscriber::HandleImuMessage, this,
                        std::placeholders::_1));
        }
      
      private:
        void
        HandlePointCloud2Message(const sensor_msgs::msg::PointCloud2::SharedPtr msg) {
          const double lidar_stamp = FromRos(msg->header.stamp);
          if (last_lidar_stamp_) {
            const double delta_time = lidar_stamp - *last_lidar_stamp_;
            LOG_IF(ERROR, delta_time > 0.12)
                << "delta_time is " << delta_time << ", lidar_stamp: " << std::fixed
                << std::setprecision(3) << lidar_stamp
                << ", last_lidar_stamp_: " << std::fixed << std::setprecision(3)
                << *last_lidar_stamp_;
          }
          last_lidar_stamp_ = std::make_unique<double>(lidar_stamp);
          LOG(INFO) << "lidar time: " << std::fixed << std::setprecision(3)
                    << FromRos(msg->header.stamp);
          LOG_IF(WARNING, !imu_is_comming_) << "Imu data is later.";
          imu_is_comming_ = false;
        }![订阅器.png](/forum/assets/uploads/files/1718777955759-订阅器.png) 
        void HandleImuMessage(const sensor_msgs::msg::Imu::SharedPtr msg) {
          imu_is_comming_ = true;
          LOG(INFO) << "imu time: " << std::fixed << std::setprecision(3)
                    << FromRos(msg->header.stamp);
        }
        rclcpp::Subscription<sensor_msgs::msg::PointCloud2>::SharedPtr
            point_cloud_subscription_;
        rclcpp::Subscription<sensor_msgs::msg::Imu>::SharedPtr imu_subscription_;
        bool imu_is_comming_ = true;
        std::unique_ptr<double> last_lidar_stamp_;
      };
      
      int main(int argc, char *argv[]) {
        rclcpp::init(argc, argv);
        rclcpp::spin(std::make_shared<SimpleSubscriber>());
        rclcpp::shutdown();
        return 0;
      }
      

      该订阅器的日志:
      订阅器.png

      发布器的日志
      发布器.png

      订阅器日志中“Imu data is later”处表示连续收到几帧点云后,才收到之前已经发布的imu数据,且发布器日志中该时间段内imu数据在正常发布,发布时间与本身时间戳并无过大差别。

      各位大佬,请问这是什么原因导致的,有无办法解决?

      8118775078 1 条回复 最后回复 回复 引用 0
      • 8118775078
        JQK @ros769974864
        最后由 编辑

        @ros769974864

        解决了,
        设置发布方的qos为
        auto qos = rclcpp::QoS(
        rclcpp::QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, queue_size));
        qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);
        qos.durability(RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);

        订阅方的qos为
        auto qos = rclcpp::QoS(
        rclcpp::QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, queue_size));
        qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);

        queue_size我设置为帧率的10倍

        1 条回复 最后回复 回复 引用 0
        • 小伊小
          机器人小伊
          最后由 编辑

          你遇到的问题可能涉及到ROS 2中的消息传递和时间同步。由于ROS 2是分布式系统,节点之间的消息传递并不是实时的,且可能会受到系统负载、网络延迟和消息队列的影响。下面是一些可能导致你看到的现象的原因以及可能的解决方案:

          可能的原因

          1. 消息队列大小:你的IMU订阅器设置了队列大小为2000,而点云订阅器队列大小为5。如果IMU数据生成得太快,而处理速度跟不上,那么IMU消息可能会在队列中堆积,导致接收时间延迟。

          2. 处理时间:如果HandleImuMessage或HandlePointCloud2Message的回调函数中花费的时间太长,那么新的消息可能会在回调处理完成之前就被阻塞。

          3. 系统调度:ROS 2节点可能受到操作系统调度策略的影响,导致某些节点的回调处理被延迟。

          4. 时间同步:ROS 2使用模拟时钟或系统时钟,如果时钟不同步或存在漂移,可能导致时间戳的误解。

          可能的解决方案

          1. 调整队列大小:根据实际的硬件能力和需求调整队列大小。过大的队列可能导致内存消耗过高,而过小的队列可能导致消息丢失。

          2. 优化处理时间:确保回调函数中的操作尽可能高效,避免不必要的计算或I/O操作。

          3. 使用QoS策略:ROS 2提供了QoS(Quality of Service)策略来控制消息传递的可靠性、持久性和深度。你可以尝试调整这些策略来改善性能。

          4. 确保时间同步:使用NTP(Network Time Protocol)或其他时间同步机制确保所有ROS 2节点的时间同步。

          5. 使用消息过滤器:你可以使用如message_filters这样的包来同步不同频率的消息。这对于需要精确时间对齐的应用(如传感器融合)非常有用。

          6. 检查ROS 2版本和配置:确保你使用的ROS 2版本是稳定的,并且配置是正确的。某些版本或配置可能存在已知的性能问题。

          7. 分析性能:使用ROS 2的性能分析工具(如ros2 topic hz、ros2 bag等)来检查系统的性能瓶颈。

          注意事项

          • 确保你的IMU和点云发布器的时间戳是准确的,并且与ROS 2的时间同步。
          • 检查你的ROS 2网络设置,确保没有网络瓶颈或延迟。
          • 如果可能的话,尝试在不同的硬件或网络环境下运行你的系统,以排除硬件或网络问题的可能性。

          最后,记住ROS 2是一个复杂的分布式系统,涉及到许多不同的组件和配置。解决性能问题可能需要一些时间和耐心。通过系统地分析和优化你的系统,你应该能够找到导致问题的根本原因,并找到有效的解决方案。


          以上为生成回答,仅供参考~

          我是小伊,已接入ChatGpt,所有回复,仅供参考~

          1 条回复 最后回复 回复 引用 0
          • 8118775078
            JQK
            最后由 编辑

            补充:
            订阅器日志:

            订阅器.png

            发布器日志:
            发布器.png

            1 条回复 最后回复 回复 引用 0
            • R
              ros769974864
              最后由 编辑

              兄弟,这个问题最后有解决吗,我们也遇到了同样的问题

              8118775078 1 条回复 最后回复 回复 引用 0
              • 8118775078
                JQK @811877507
                最后由 编辑

                此回复已被删除!
                1 条回复 最后回复 回复 引用 0
                • 8118775078
                  JQK @ros769974864
                  最后由 编辑

                  @ros769974864

                  解决了,
                  设置发布方的qos为
                  auto qos = rclcpp::QoS(
                  rclcpp::QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, queue_size));
                  qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);
                  qos.durability(RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);

                  订阅方的qos为
                  auto qos = rclcpp::QoS(
                  rclcpp::QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, queue_size));
                  qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);

                  queue_size我设置为帧率的10倍

                  1 条回复 最后回复 回复 引用 0
                  • 小鱼小 小鱼 将这个主题标记为已解决,在
                  • 第一个帖子
                    最后一个帖子
                  皖ICP备16016415号-7
                  Powered by NodeBB | 鱼香ROS