rgbd
server_shm.cpp
Go to the documentation of this file.
1 #include "rgbd/server_shm.h"
2 
3 #include "rgbd/image.h"
4 #include "rgbd/view.h"
5 
6 #include <boost/interprocess/sync/scoped_lock.hpp>
7 
8 #include <ros/console.h>
9 #include <ros/node_handle.h>
10 #include <ros/publisher.h>
11 #include <ros/rate.h>
12 
13 #include <std_msgs/String.h>
14 
15 namespace ipc = boost::interprocess;
16 
17 namespace rgbd
18 {
19 
20 // ----------------------------------------------------------------------------------------------------
21 
22 ServerSHM::ServerSHM() : buffer_header_(nullptr), image_data_(nullptr), check_shm_thread_ptr_(nullptr)
23 {
24 }
25 
26 // ----------------------------------------------------------------------------------------------------
27 
29 {
30  nh_.shutdown();
32  check_shm_thread_ptr_->join();
33 
34  if (!shared_mem_name_.empty())
35  ipc::shared_memory_object::remove(shared_mem_name_.c_str());
36 }
37 
38 // ----------------------------------------------------------------------------------------------------
39 
41 {
42  shared_mem_name_ = name;
44 }
45 
46 // ----------------------------------------------------------------------------------------------------
47 
48 void ServerSHM::send(const Image& image)
49 {
50  if (shared_mem_name_.empty())
51  {
52  ROS_ERROR_NAMED("ServerSHM", "rgbd::SharedMemServer is not initialized");
53  return;
54  }
55 
56  const cv::Mat& rgb = image.getRGBImage();
57  const cv::Mat& depth = image.getDepthImage();
58 
59  if (!buffer_header_)
60  {
61  // First time
62  // Make sure possibly existing memory with same name is removed
63  ipc::shared_memory_object::remove(shared_mem_name_.c_str());
64 
65  //Create a shared memory object.
66  shm_ = ipc::shared_memory_object(ipc::create_only, shared_mem_name_.c_str(), ipc::read_write);
67 
68  // Create SHM check thread
70  check_shm_thread_ptr_ = std::make_unique<std::thread>(&ServerSHM::checkSHMThreadFunc, this, 1);
71 
72  // Store size
73  rgb_data_size_ = static_cast<uint64_t>(rgb.cols * rgb.rows * 3);
74  depth_data_size_ = static_cast<uint64_t>(depth.cols * depth.rows * 4);
76 
77  //Set size
78  shm_.truncate(static_cast<ipc::offset_t>(sizeof(BufferHeader) + image_data_size_));
79 
80  // Map buffer region
81  mem_buffer_header_ = ipc::mapped_region(shm_, ipc::read_write, 0, sizeof(BufferHeader));
82  mem_image_ = ipc::mapped_region(shm_, ipc::read_write, sizeof(BufferHeader));
83 
84  buffer_header_ = new (mem_buffer_header_.get_address()) BufferHeader;
86 
87  image_data_ = new (mem_image_.get_address()) uchar[image_data_size_];
88 
89  buffer_header_->rgb_width = rgb.cols;
90  buffer_header_->rgb_height = rgb.rows;
91  buffer_header_->depth_width = depth.cols;
92  buffer_header_->depth_height = depth.rows;
93 
94  memcpy(buffer_header_->frame_id, image.getFrameId().c_str(), image.getFrameId().size() + 1);
95 
96  // CameraInfo
97  const sensor_msgs::CameraInfo& cam_info = image.getCameraModel().cameraInfo();
98  buffer_header_->height = cam_info.height;
99  buffer_header_->width = cam_info.width;
100  buffer_header_->binning_x = cam_info.binning_x;
101  buffer_header_->binning_y = cam_info.binning_y;
102  memcpy(buffer_header_->distortion_model, cam_info.distortion_model.c_str(), cam_info.distortion_model.size() + 1);
103  buffer_header_->size_D = std::min<size_t>(cam_info.D.size(), 5); // Max 5
104  memcpy(buffer_header_->D, cam_info.D.data(), buffer_header_->size_D*sizeof(double)); // std::vector
105  memcpy(buffer_header_->K, &(cam_info.K.elems), 9*sizeof(double)); // boost::array
106  memcpy(buffer_header_->R, &(cam_info.R.elems), 9*sizeof(double)); // boost::array
107  memcpy(buffer_header_->P, &(cam_info.P.elems), 12*sizeof(double)); // boost::array
108  // CameraInfo/roi
109  buffer_header_->roi_x_offset = cam_info.roi.x_offset;
110  buffer_header_->roi_y_offset = cam_info.roi.y_offset;
111  buffer_header_->roi_height = cam_info.roi.height;
112  buffer_header_->roi_width = cam_info.roi.width;
113  buffer_header_->roi_do_rectify = cam_info.roi.do_rectify;
114  }
115 
116  {
117  ipc::scoped_lock<ipc::interprocess_mutex> lock(buffer_header_->mutex);
118 
120 
121  memcpy(image_data_, rgb.data, rgb_data_size_);
122  memcpy(image_data_ + rgb_data_size_, depth.data, depth_data_size_);
123 
124  buffer_header_->cond_empty.notify_one();
126  }
127 }
128 
129 // ----------------------------------------------------------------------------------------
130 
131 void ServerSHM::checkSHMThreadFunc(const float frequency)
132 {
133  ROS_DEBUG_NAMED("ServerSHM", "ServerSHM::checkSHMThreadFunc");
134  ros::Rate r(frequency);
135  while(nh_.ok())
136  {
137  ROS_DEBUG_STREAM_NAMED("ServerSHM", "ServerSHM::checkSHMThreadFunc: checking shm on: " << shared_mem_name_);
138  try
139  {
140  ipc::shared_memory_object(ipc::open_only, shared_mem_name_.c_str(), ipc::read_only);
141  }
142  catch (ipc::interprocess_exception &ex)
143  {
144  ROS_FATAL_STREAM_NAMED("ServerSHM", "ServerSHM::checkSHMThreadFunc: SHM on '" << shared_mem_name_ << "' is corrupted: '" << ex.what() << "'");
145  ros::shutdown();
146  }
147  r.sleep();
148  }
149  ROS_DEBUG_NAMED("ServerSHM", "ServerSHM::checkSHMThreadFunc done");
150 }
151 
152 // ----------------------------------------------------------------------------------------
153 
154 void pubHostnameThreadFunc(ros::NodeHandle& nh, const std::string server_name, const std::string hostname, const float frequency)
155 {
156  ros::Publisher pub_shm_hostname = nh.advertise<std_msgs::String>(server_name + "/hosts", 1);
157  ros::WallRate r(frequency);
158  std_msgs::String msg;
159  msg.data = hostname;
160  while(nh.ok())
161  {
162  pub_shm_hostname.publish(msg);
163  r.sleep();
164  }
165 }
166 
167 } // end namespace rgbd
rgbd::BufferHeader::depth_width
int depth_width
Definition: image_header.h:28
rgbd::BufferHeader::frame_id
char frame_id[1000]
Definition: image_header.h:34
std::string
rgbd::Image::getDepthImage
const cv::Mat & getDepthImage() const
Get the depth image.
Definition: image.h:72
rgbd::Image::getTimestamp
double getTimestamp() const
Get the timestamp.
Definition: image.h:90
std::string::size
T size(T... args)
rgbd::ServerSHM::buffer_header_
BufferHeader * buffer_header_
Definition: server_shm.h:62
rgbd::ServerSHM::~ServerSHM
~ServerSHM()
Destructor.
Definition: server_shm.cpp:28
rgbd::BufferHeader::rgb_height
int rgb_height
Definition: image_header.h:27
rgbd::BufferHeader::roi_width
uint32_t roi_width
Definition: image_header.h:41
rgbd::BufferHeader::roi_height
uint32_t roi_height
Definition: image_header.h:41
rgbd::BufferHeader::D
double D[5]
Definition: image_header.h:39
rgbd::BufferHeader::rgb_width
int rgb_width
Definition: image_header.h:26
rgbd::pubHostnameThreadFunc
void pubHostnameThreadFunc(ros::NodeHandle &nh, const std::string server_name, const std::string hostname, const float frequency)
Definition: server_shm.cpp:154
rgbd::ServerSHM::checkSHMThreadFunc
void checkSHMThreadFunc(const float frequency)
Check if the SHM can be opened.
Definition: server_shm.cpp:131
rgbd::BufferHeader
Definition: image_header.h:12
rgbd::BufferHeader::timestamp
double timestamp
Definition: image_header.h:33
rgbd::BufferHeader::depth_height
int depth_height
Definition: image_header.h:29
std::replace
T replace(T... args)
rgbd::BufferHeader::binning_y
uint32_t binning_y
Definition: image_header.h:36
rgbd::ServerSHM::rgb_data_size_
uint64_t rgb_data_size_
Definition: server_shm.h:65
rgbd::ServerSHM::ServerSHM
ServerSHM()
Constructor.
Definition: server_shm.cpp:22
rgbd::Image
Definition: image.h:43
rgbd::BufferHeader::distortion_model
char distortion_model[1000]
Definition: image_header.h:37
rgbd::BufferHeader::mutex
boost::interprocess::interprocess_mutex mutex
Definition: image_header.h:17
rgbd::ServerSHM::check_shm_thread_ptr_
std::unique_ptr< std::thread > check_shm_thread_ptr_
Definition: server_shm.h:72
rgbd::BufferHeader::roi_x_offset
uint32_t roi_x_offset
Definition: image_header.h:41
rgbd::BufferHeader::roi_do_rectify
bool roi_do_rectify
Definition: image_header.h:42
std::string::c_str
T c_str(T... args)
rgbd
Definition: client.h:24
rgbd::ServerSHM::send
void send(const Image &image)
send Write a new image to the shared memory
Definition: server_shm.cpp:48
rgbd::BufferHeader::height
uint32_t height
Definition: image_header.h:36
rgbd::ServerSHM::image_data_size_
uint64_t image_data_size_
Definition: server_shm.h:67
image.h
rgbd::Image::getRGBImage
const cv::Mat & getRGBImage() const
Get the RGB color image.
Definition: image.h:78
rgbd::ServerSHM::depth_data_size_
uint64_t depth_data_size_
Definition: server_shm.h:66
rgbd::BufferHeader::P
double P[12]
Definition: image_header.h:39
rgbd::ServerSHM::initialize
void initialize(const std::string &name)
initialize Initialize shared memory server
Definition: server_shm.cpp:40
rgbd::ServerSHM::image_data_
unsigned char * image_data_
Definition: server_shm.h:63
rgbd::BufferHeader::K
double K[9]
Definition: image_header.h:39
rgbd::ServerSHM::shared_mem_name_
std::string shared_mem_name_
Definition: server_shm.h:55
rgbd::BufferHeader::R
double R[9]
Definition: image_header.h:39
rgbd::Image::getCameraModel
const image_geometry::PinholeCameraModel & getCameraModel() const
Get the camera model.
Definition: image.h:96
std::string::begin
T begin(T... args)
rgbd::Image::getFrameId
const std::string & getFrameId() const
Get the frame_id.
Definition: image.h:84
rgbd::ServerSHM::shm_
boost::interprocess::shared_memory_object shm_
Definition: server_shm.h:57
rgbd::BufferHeader::roi_y_offset
uint32_t roi_y_offset
Definition: image_header.h:41
view.h
rgbd::BufferHeader::binning_x
uint32_t binning_x
Definition: image_header.h:36
rgbd::BufferHeader::size_D
size_t size_D
Definition: image_header.h:38
std::string::empty
T empty(T... args)
rgbd::BufferHeader::cond_empty
boost::interprocess::interprocess_condition cond_empty
Definition: image_header.h:20
rgbd::ServerSHM::nh_
ros::NodeHandle nh_
Definition: server_shm.h:69
rgbd::BufferHeader::sequence_nr
uint64_t sequence_nr
Definition: image_header.h:14
std::string::end
T end(T... args)
rgbd::ServerSHM::mem_buffer_header_
boost::interprocess::mapped_region mem_buffer_header_
Definition: server_shm.h:59
rgbd::ServerSHM::mem_image_
boost::interprocess::mapped_region mem_image_
Definition: server_shm.h:60
server_shm.h
rgbd::BufferHeader::width
uint32_t width
Definition: image_header.h:36