rdk x3基于地平线官方库实现零拷贝的问题

目前在RDK X3板端利用零拷贝发布图像代码如下所示:
#include
#include
#include
#include <opencv2/opencv.hpp>

#include “rclcpp/rclcpp.hpp”
#include “hbm_img_msgs/msg/hbm_msg1080_p.hpp”
#include “builtin_interfaces/msg/time.hpp”

using namespace std::chrono_literals;

class HbmemCameraPublisher : public rclcpp::Node {
public:
HbmemCameraPublisher()
: Node(“hbmem_camera_publisher”) {
publisher_ = this->create_publisher_hbmem<hbm_img_msgs::msg::HbmMsg1080P>(
“/image_raw_hbmem”, rclcpp::SensorDataQoS());

cap_.open(8);
cap_.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
cap_.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
if (!cap_.isOpened()) {
  RCLCPP_ERROR(this->get_logger(), "无法打开摄像头");
  throw std::runtime_error("打开摄像头失败");
}

thread_ = std::thread(&HbmemCameraPublisher::publish_loop, this);

}

~HbmemCameraPublisher() override {
running_ = false;
if (thread_.joinable()) thread_.join();
cap_.release();
}

private:
void publish_loop() {
const auto delay = 20ms;
int index = 0;

while (rclcpp::ok() && running_) {
  cv::Mat frame;
  cap_ >> frame;
  if (frame.empty()) {
    RCLCPP_WARN(this->get_logger(), "图像帧为空");
    std::this_thread::sleep_for(delay);
    continue;
  }

  // 获取 ROS2 时间戳
  auto now = this->get_clock()->now();
  rclcpp::Time ros_now(now);

  size_t img_size = frame.total() * frame.elemSize();  // e.g., 1920*1080*3 = 6220800
  if (img_size > 6220800) {
    RCLCPP_WARN(this->get_logger(), "图像数据超过最大缓冲区");
    continue;
  }

  auto loaned_msg = publisher_->borrow_loaned_message();
  if (!loaned_msg.is_valid()) {
    RCLCPP_WARN(this->get_logger(), "获取 loaned message 失败");
    continue;
  }

  auto & msg = loaned_msg.get();
  msg.index = index++;
  msg.time_stamp.sec = ros_now.seconds();  // 返回 double,需要分解
  msg.time_stamp.nanosec = static_cast<uint32_t>((ros_now.seconds() - msg.time_stamp.sec) * 1e9);

  msg.height = frame.rows;
  msg.width = frame.cols;
  msg.data_size = static_cast<uint32_t>(img_size);
  msg.step = static_cast<uint32_t>(frame.step);

  // 设置编码为 "bgr8"
  const std::string encoding_str = "bgr8";
  std::memset(msg.encoding.data(), 0, msg.encoding.size());
  std::memcpy(msg.encoding.data(), encoding_str.c_str(),
              std::min(msg.encoding.size(), encoding_str.size()));

  // 拷贝图像数据
  std::memcpy(msg.data.data(), frame.data, img_size);

  publisher_->publish(std::move(loaned_msg));
  std::this_thread::sleep_for(delay);
}

}

rclcpp::PublisherHbmem<hbm_img_msgs::msg::HbmMsg1080P>::SharedPtr publisher_;
cv::VideoCapture cap_;
std::thread thread_;
bool running_ = true;
};

int main(int argc, char * argv) {
rclcpp::init(argc, argv);
auto node = std::make_shared();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
目前hb_mem_msgs包已经部署在工作空间中

当我的节点运行后,发布的图像话题如图所示:

image
利用官方的hobot_codec库也无法运行,运行的命令如下:

ros2 launch hobot_codec hobot_codec_encode.launch.py codec_in_mode:=shared_mem codec_out_mode:=ros codec_in_format:=bgr8 codec_out_format:=jpeg
codec_sub_topic:=/image_raw_hbmem0x21062611010001200216090803180318 codec_pub_topic:=/image2

你好,按照发帖规范提供板卡的详细信息: 提问模板 - 板卡使用 / RDK Model Zoo - 地瓜机器人论坛

官方的TROS功能包完全开源,二次开发遇到问题完全可以查看源码加以验证并解决问题: D-Robotics