• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

ROS系统学习9—节点间的内存共享(中级篇)—图像收发

人工智能 _寒潭雁影 2942次浏览 0个评论

前篇文章介绍了如何实现最简单的节点间内存共享。但因为篇幅所限,并没有深入介绍怎么将其实用化。本篇我们将用之前专门介绍的循环队列内存共享技术,将一个节点的图像数据直接共享给另外的节点。   为了比较内存共享机制和ROS自带的话题传输机制,本文用:ROS系统学习5—OpenCV的使用这篇文章提供的图像发送和接收节点做对比。结果发现用自带的话题传输机制传一张1080p的图像延时大概在600ms,而用内存共享机制传输延时只有10ms左右,性能相差了几十倍。   另外,ROS自身也提供了nodelet做内存共享,只是本人研究了几天发现特别乱就放弃了,感觉这东西迟早要被抛弃(事实上ROS2.0就不用这种机制了),如果有老哥有兴趣也可以去研究下。   下面贴出实现代码,其中最重要的“shmobject.h”在循环队列内存共享已经提供过,需要的可以直接去那边下。   发送节点:  

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
#include <stdio.h>
#include "../../shmobject.h"
 
int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;
 
  cv::Mat image = cv::imread("/home/weixin/图片/2.jpeg", CV_LOAD_IMAGE_COLOR);
  if(image.empty())
  {
    printf("open error\n");
  }
  shmobject shmobj(10+image.rows*image.step,10,66);//共享内存对象
  unsigned char* shmdata=NULL;
  
  ros::Rate loop_rate(1);//每秒5帧
  while (nh.ok()) 
  {
    shmdata=shmobj.requiredata();//要求数据
    if(shmdata!=NULL)
    {
        memcpy(&shmdata[10],image.data,image.rows*image.step);
        shmobj.updatashm(shmdata);//更新数据,可被读取
        ROS_INFO("I send");
    }
    ros::spinOnce();
    loop_rate.sleep();
  }
  shmobj.writerelease();
}

  接收节点:  

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
#include "../../shmobject.h"
 
int main(int argc, char **argv)
{
  ros::init(argc, argv, "image_listener");
  ros::NodeHandle nh;
  image_transport::ImageTransport it(nh);
  shmobject shmobj(66);
 
  ros::Rate loop_rate(30);//每秒5帧
 
  cv::Mat image(1080,1920,CV_8UC3);
 
  while (nh.ok())
  {
    unsigned char *readdata= shmobj.getdataforread();
    if(readdata!=NULL)//表示已经获取到可读数据
    {
        ROS_INFO("I heard");
        memcpy(image.data,&readdata[10],image.rows*image.step);
       // cv::imshow("",image);
       // cv::waitKey(3);
       // printf("图像显示\n");
        readdata[0]=0;//读取完成标志位
    }
    else
    {
        //printf("无可读数据,请等待写入,稍候重试\n");
    }
    loop_rate.sleep();
  }
  image.release();
  ros::spin();
  shmobj.readrelease();
}

 


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明ROS系统学习9—节点间的内存共享(中级篇)—图像收发
喜欢 (0)

您必须 登录 才能发表评论!

加载中……