zivid_camera.cpp
Go to the documentation of this file.
1 #include "zivid_camera.h"
2 
6 #include <dynamic_reconfigure/config_tools.h>
7 
8 #include <Zivid/Firmware.h>
9 #include <Zivid/Frame2D.h>
10 #include <Zivid/Settings2D.h>
11 #include <Zivid/Version.h>
12 #include <Zivid/CaptureAssistant.h>
13 #include <Zivid/Experimental/Calibration.h>
14 
15 #include <boost/algorithm/string.hpp>
16 #include <boost/predef.h>
17 
18 #include <sstream>
19 #include <thread>
20 #include <cstdint>
21 
22 namespace
23 {
24 sensor_msgs::PointField createPointField(std::string name, uint32_t offset, uint8_t datatype, uint32_t count)
25 {
26  sensor_msgs::PointField point_field;
27  point_field.name = name;
28  point_field.offset = offset;
29  point_field.datatype = datatype;
30  point_field.count = count;
31  return point_field;
32 }
33 
34 bool big_endian()
35 {
36  return BOOST_ENDIAN_BIG_BYTE;
37 }
38 
39 template <class T>
40 void fillCommonMsgFields(T& msg, const std_msgs::Header& header, std::size_t width, std::size_t height)
41 {
42  msg.header = header;
43  msg.height = static_cast<uint32_t>(height);
44  msg.width = static_cast<uint32_t>(width);
45  msg.is_bigendian = big_endian();
46 }
47 
48 sensor_msgs::ImagePtr makeImage(const std_msgs::Header& header, const std::string& encoding, std::size_t width,
49  std::size_t height)
50 {
51  auto image = boost::make_shared<sensor_msgs::Image>();
52  fillCommonMsgFields(*image, header, width, height);
53  image->encoding = encoding;
54  const auto bytes_per_pixel = static_cast<std::size_t>(sensor_msgs::image_encodings::numChannels(encoding) *
56  image->step = static_cast<uint32_t>(bytes_per_pixel * width);
57  return image;
58 }
59 
60 template <typename ZividDataType>
61 sensor_msgs::ImagePtr makePointCloudImage(const Zivid::PointCloud& point_cloud, const std_msgs::Header& header,
62  const std::string& encoding)
63 {
64  auto image = makeImage(header, encoding, point_cloud.width(), point_cloud.height());
65  image->data.resize(image->step * image->height);
66  point_cloud.copyData<ZividDataType>(reinterpret_cast<ZividDataType*>(image->data.data()));
67  return image;
68 }
69 
70 std::string toString(zivid_camera::CameraStatus camera_status)
71 {
72  switch (camera_status)
73  {
75  return "Connected";
77  return "Disconnected";
79  return "Idle";
80  }
81  return "N/A";
82 }
83 
84 } // namespace
85 
86 namespace zivid_camera
87 {
89  : nh_(nh)
90  , priv_(priv)
91  , camera_status_(CameraStatus::Idle)
92  , use_latched_publisher_for_points_xyz_(false)
93  , use_latched_publisher_for_points_xyzrgba_(false)
94  , use_latched_publisher_for_color_image_(false)
95  , use_latched_publisher_for_depth_image_(false)
96  , use_latched_publisher_for_snr_image_(false)
97  , image_transport_(nh_)
98  , header_seq_(0)
99 {
100  ROS_INFO("Zivid ROS driver version %s", ZIVID_ROS_DRIVER_VERSION);
101 
102  ROS_INFO("Node's namespace is '%s'", nh_.getNamespace().c_str());
103  if (ros::this_node::getNamespace() == "/")
104  {
105  // Require the user to specify the namespace that this node will run in.
106  // See REP-135 http://www.ros.org/reps/rep-0135.html
107  throw std::runtime_error("Zivid ROS driver started in the global namespace ('/')! This is unsupported. "
108  "Please specify namespace, e.g. using the ROS_NAMESPACE environment variable.");
109  }
110 
111  ROS_INFO_STREAM("Built towards Zivid Core version " << ZIVID_CORE_VERSION);
112  ROS_INFO_STREAM("Running with Zivid Core version " << Zivid::Version::coreLibraryVersion());
113  if (Zivid::Version::coreLibraryVersion() != ZIVID_CORE_VERSION)
114  {
115  throw std::runtime_error("Zivid library mismatch! The running Zivid Core version does not match the "
116  "version this ROS driver was built towards. Hint: Try to clean and re-build your project "
117  "from scratch.");
118  }
119 
120  std::string serial_number;
121  priv_.param<decltype(serial_number)>("serial_number", serial_number, "");
122 
123  int max_capture_acquisitions;
124  priv_.param<decltype(max_capture_acquisitions)>("max_capture_acquisitions", max_capture_acquisitions, 10);
125 
126  priv_.param<decltype(frame_id_)>("frame_id", frame_id_, "zivid_optical_frame");
127 
128  std::string file_camera_path;
129  priv_.param<decltype(file_camera_path)>("file_camera_path", file_camera_path, "");
130  const bool file_camera_mode = !file_camera_path.empty();
131 
132  priv_.param<bool>("use_latched_publisher_for_points_xyz", use_latched_publisher_for_points_xyz_, false);
133  priv_.param<bool>("use_latched_publisher_for_points_xyzrgba", use_latched_publisher_for_points_xyzrgba_, false);
134  priv_.param<bool>("use_latched_publisher_for_color_image", use_latched_publisher_for_color_image_, false);
135  priv_.param<bool>("use_latched_publisher_for_depth_image", use_latched_publisher_for_depth_image_, false);
136  priv_.param<bool>("use_latched_publisher_for_snr_image", use_latched_publisher_for_snr_image_, false);
137 
138  if (file_camera_mode)
139  {
140  ROS_INFO("Creating file camera from file '%s'", file_camera_path.c_str());
141  camera_ = zivid_.createFileCamera(file_camera_path);
142  }
143  else
144  {
145  auto cameras = zivid_.cameras();
146  ROS_INFO_STREAM(cameras.size() << " cameras found");
147  if (cameras.empty())
148  {
149  throw std::runtime_error("No cameras found. Ensure that the camera is connected to the USB3 port on your PC.");
150  }
151  else if (serial_number.empty())
152  {
153  camera_ = [&]() {
154  ROS_INFO("Selecting first available camera");
155  for (auto& c : cameras)
156  {
157  if (c.state().isAvailable())
158  return c;
159  }
160  throw std::runtime_error("No available cameras found. Is the camera in use by another process?");
161  }();
162  }
163  else
164  {
165  if (serial_number.find(":") == 0)
166  {
167  serial_number = serial_number.substr(1);
168  }
169  camera_ = [&]() {
170  ROS_INFO("Searching for camera with serial number '%s' ...", serial_number.c_str());
171  for (auto& c : cameras)
172  {
173  if (c.info().serialNumber() == Zivid::CameraInfo::SerialNumber(serial_number))
174  return c;
175  }
176  throw std::runtime_error("No camera found with serial number '" + serial_number + "'");
177  }();
178  }
179 
180  if (!Zivid::Firmware::isUpToDate(camera_))
181  {
182  ROS_INFO("The camera firmware is not up-to-date, starting update");
183  Zivid::Firmware::update(camera_, [](double progress, const std::string& state) {
184  ROS_INFO(" [%.0f%%] %s", progress, state.c_str());
185  });
186  ROS_INFO("Firmware update completed");
187  }
188  }
189 
191  if (!file_camera_mode)
192  {
193  ROS_INFO_STREAM("Connecting to camera '" << camera_.info().serialNumber() << "'");
194  camera_.connect();
195  }
196  ROS_INFO_STREAM("Connected to camera '" << camera_.info().serialNumber() << "'");
198 
201 
203  std::make_unique<Capture3DSettingsController>(nh_, camera_, "settings", max_capture_acquisitions);
204 
205  // HDR is not supported in 2D mode, but for future-proofing the 2D configuration API is analogous
206  // to 3D except there is only 1 acquisition.
207  capture_2d_settings_controller_ = std::make_unique<Capture2DSettingsController>(nh_, camera_, "settings_2d", 1);
208 
209  ROS_INFO("Advertising topics");
211  nh_.advertise<sensor_msgs::PointCloud2>("points/xyz", 1, use_latched_publisher_for_points_xyz_);
213  nh_.advertise<sensor_msgs::PointCloud2>("points/xyzrgba", 1, use_latched_publisher_for_points_xyzrgba_);
215  image_transport_.advertiseCamera("color/image_color", 1, use_latched_publisher_for_color_image_);
216  depth_image_publisher_ = image_transport_.advertiseCamera("depth/image", 1, use_latched_publisher_for_depth_image_);
217  snr_image_publisher_ = image_transport_.advertiseCamera("snr/image", 1, use_latched_publisher_for_snr_image_);
218 
219  ROS_INFO("Advertising services");
221  nh_.advertiseService("camera_info/model_name", &ZividCamera::cameraInfoModelNameServiceHandler, this);
223  nh_.advertiseService("camera_info/serial_number", &ZividCamera::cameraInfoSerialNumberServiceHandler, this);
224  is_connected_service_ = nh_.advertiseService("is_connected", &ZividCamera::isConnectedServiceHandler, this);
225  capture_service_ = nh_.advertiseService("capture", &ZividCamera::captureServiceHandler, this);
226  capture_2d_service_ = nh_.advertiseService("capture_2d", &ZividCamera::capture2DServiceHandler, this);
227  capture_assistant_suggest_settings_service_ = nh_.advertiseService(
228  "capture_assistant/suggest_settings", &ZividCamera::captureAssistantSuggestSettingsServiceHandler, this);
229 
230  ROS_INFO("Zivid camera driver is now ready!");
231 }
232 
234 {
235  ROS_DEBUG_STREAM(__func__);
236  try
237  {
239  }
240  catch (const std::exception& e)
241  {
242  ROS_INFO("%s failed with exception '%s'", __func__, e.what());
243  }
244 }
245 
247 {
248  ROS_DEBUG_STREAM(__func__);
249 
250  const auto state = camera_.state();
251  if (state.isConnected().value())
252  {
254  }
255  else
256  {
258 
259  // The camera handle needs to be refreshed to ensure we get the correct
260  // "available" status. This is a bug in the API.
261  auto cameras = zivid_.cameras();
262  for (auto& c : cameras)
263  {
264  if (camera_.info().serialNumber() == c.info().serialNumber())
265  {
266  camera_ = c;
267  }
268  }
269 
270  if (state.isAvailable().value())
271  {
272  ROS_INFO_STREAM("The camera '" << camera_.info().serialNumber()
273  << "' is not connected but is available. Re-connecting ...");
274  camera_.connect();
275  ROS_INFO("Successfully reconnected to camera!");
277  }
278  else
279  {
280  ROS_INFO_STREAM("The camera '" << camera_.info().serialNumber() << "' is not connected nor available.");
281  }
282  }
283 }
284 
286 {
287  if (camera_status_ != camera_status)
288  {
289  std::stringstream ss;
290  ss << "Camera status changed to " << toString(camera_status) << " (was " << toString(camera_status_) << ")";
291  if (camera_status == CameraStatus::Connected)
292  {
293  ROS_INFO_STREAM(ss.str());
294  }
295  else
296  {
297  ROS_WARN_STREAM(ss.str());
298  }
299  camera_status_ = camera_status;
300  }
301 }
302 
303 bool ZividCamera::cameraInfoModelNameServiceHandler(zivid_camera::CameraInfoModelName::Request&,
304  zivid_camera::CameraInfoModelName::Response& res)
305 {
306  res.model_name = camera_.info().modelName().toString();
307  return true;
308 }
309 
310 bool ZividCamera::cameraInfoSerialNumberServiceHandler(zivid_camera::CameraInfoSerialNumber::Request&,
311  zivid_camera::CameraInfoSerialNumber::Response& res)
312 {
313  res.serial_number = camera_.info().serialNumber().toString();
314  return true;
315 }
316 
317 bool ZividCamera::captureServiceHandler(Capture::Request&, Capture::Response&)
318 {
319  ROS_DEBUG_STREAM(__func__);
320 
322 
323  const auto settings = capture_settings_controller_->zividSettings();
324 
325  if (settings.acquisitions().isEmpty())
326  {
327  throw std::runtime_error("capture called with 0 enabled acquisitions!");
328  }
329 
330  ROS_INFO("Capturing with %zd acquisition(s)", settings.acquisitions().size());
331  ROS_DEBUG_STREAM(settings);
332  publishFrame(camera_.capture(settings));
333  return true;
334 }
335 
336 bool ZividCamera::capture2DServiceHandler(Capture2D::Request&, Capture2D::Response&)
337 {
338  ROS_DEBUG_STREAM(__func__);
339 
341 
342  const auto settings2D = capture_2d_settings_controller_->zividSettings();
343 
344  if (settings2D.acquisitions().isEmpty())
345  {
346  throw std::runtime_error("capture_2d called with 0 enabled acquisitions!");
347  }
348 
349  ROS_DEBUG_STREAM(settings2D);
350  auto frame2D = camera_.capture(settings2D);
351  if (shouldPublishColorImg())
352  {
353  const auto header = makeHeader();
354  auto image = frame2D.imageRGBA();
355  const auto intrinsics = Zivid::Experimental::Calibration::intrinsics(camera_);
356  const auto camera_info = makeCameraInfo(header, image.width(), image.height(), intrinsics);
357  publishColorImage(header, camera_info, image);
358  }
359  return true;
360 }
361 
362 bool ZividCamera::captureAssistantSuggestSettingsServiceHandler(CaptureAssistantSuggestSettings::Request& req,
363  CaptureAssistantSuggestSettings::Response&)
364 {
365  ROS_DEBUG_STREAM(__func__ << ": Request: " << req);
366 
368 
369  if (capture_settings_controller_->numAcquisitionConfigServers() < 10)
370  {
371  throw std::runtime_error("To use the CaptureAssistant the launch parameter 'max_capture_acquisitions' "
372  "must be at least 10, since the Capture Assistant may suggest up to 10 acquisitions. "
373  "See README.md for more information.");
374  }
375 
376  using SuggestSettingsParameters = Zivid::CaptureAssistant::SuggestSettingsParameters;
377 
378  const auto max_capture_time =
379  std::chrono::round<std::chrono::milliseconds>(std::chrono::duration<double>{ req.max_capture_time.toSec() });
380  const auto ambient_light_frequency = [&req]() {
381  switch (req.ambient_light_frequency)
382  {
383  case CaptureAssistantSuggestSettings::Request::AMBIENT_LIGHT_FREQUENCY_NONE:
384  return SuggestSettingsParameters::AmbientLightFrequency::none;
385  case CaptureAssistantSuggestSettings::Request::AMBIENT_LIGHT_FREQUENCY_50HZ:
386  return SuggestSettingsParameters::AmbientLightFrequency::hz50;
387  case CaptureAssistantSuggestSettings::Request::AMBIENT_LIGHT_FREQUENCY_60HZ:
388  return SuggestSettingsParameters::AmbientLightFrequency::hz60;
389  }
390  throw std::runtime_error("Unhandled AMBIENT_LIGHT_FREQUENCY value: " + std::to_string(req.ambient_light_frequency));
391  }();
392 
393  SuggestSettingsParameters suggest_settings_parameters{ SuggestSettingsParameters::MaxCaptureTime{ max_capture_time },
394  ambient_light_frequency };
395  ROS_INFO_STREAM("Getting suggested settings using parameters: " << suggest_settings_parameters);
396  const auto suggested_settings = Zivid::CaptureAssistant::suggestSettings(camera_, suggest_settings_parameters);
397  ROS_INFO_STREAM("CaptureAssistant::suggestSettings returned " << suggested_settings.acquisitions().size()
398  << " acquisitions");
399  capture_settings_controller_->setZividSettings(suggested_settings);
400 
401  return true;
402 } // namespace zivid_camera
403 
405 {
408  {
409  throw std::runtime_error("Unable to capture since the camera is not connected. Please re-connect the camera and "
410  "try again.");
411  }
412 }
413 
414 bool ZividCamera::isConnectedServiceHandler(IsConnected::Request&, IsConnected::Response& res)
415 {
416  res.is_connected = camera_status_ == CameraStatus::Connected;
417  return true;
418 }
419 
420 void ZividCamera::publishFrame(Zivid::Frame&& frame)
421 {
422  const bool publish_points_xyz = shouldPublishPointsXYZ();
423  const bool publish_points_xyzrgba = shouldPublishPointsXYZRGBA();
424  const bool publish_color_img = shouldPublishColorImg();
425  const bool publish_depth_img = shouldPublishDepthImg();
426  const bool publish_snr_img = shouldPublishSnrImg();
427 
428  if (publish_points_xyz || publish_points_xyzrgba || publish_color_img || publish_depth_img || publish_snr_img)
429  {
430  const auto header = makeHeader();
431  auto point_cloud = frame.pointCloud();
432 
433  // Transform point cloud from millimeters (Zivid SDK) to meter (ROS).
434  const float scale = 0.001f;
435  const auto transformationMatrix = Zivid::Matrix4x4{ scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1 };
436  point_cloud.transform(transformationMatrix);
437 
438  if (publish_points_xyz)
439  {
440  publishPointCloudXYZ(header, point_cloud);
441  }
442  if (publish_points_xyzrgba)
443  {
444  publishPointCloudXYZRGBA(header, point_cloud);
445  }
446  if (publish_color_img || publish_depth_img || publish_snr_img)
447  {
448  const auto intrinsics = Zivid::Experimental::Calibration::intrinsics(camera_);
449  const auto camera_info = makeCameraInfo(header, point_cloud.width(), point_cloud.height(), intrinsics);
450 
451  if (publish_color_img)
452  {
453  publishColorImage(header, camera_info, point_cloud);
454  }
455  if (publish_depth_img)
456  {
457  publishDepthImage(header, camera_info, point_cloud);
458  }
459  if (publish_snr_img)
460  {
461  publishSnrImage(header, camera_info, point_cloud);
462  }
463  }
464  }
465 }
466 
468 {
470 }
471 
473 {
475 }
476 
478 {
480 }
481 
483 {
485 }
486 
488 {
490 }
491 
492 std_msgs::Header ZividCamera::makeHeader()
493 {
494  std_msgs::Header header;
495  header.seq = header_seq_++;
496  header.stamp = ros::Time::now();
497  header.frame_id = frame_id_;
498  return header;
499 }
500 
501 void ZividCamera::publishPointCloudXYZ(const std_msgs::Header& header, const Zivid::PointCloud& point_cloud)
502 {
503  ROS_DEBUG("Publishing points/xyz");
504 
505  // We are using the Zivid::XYZW type here for compatibility with the pcl::PointXYZ type, which contains an
506  // padding float for performance reasons. We could use the "pcl_conversion" utility functions to construct
507  // the PointCloud2 message. However, those are observed to add significant overhead due to extra unnecssary
508  // copies of the data.
509  using ZividDataType = Zivid::PointXYZW;
510  auto msg = boost::make_shared<sensor_msgs::PointCloud2>();
511  fillCommonMsgFields(*msg, header, point_cloud.width(), point_cloud.height());
512  msg->fields.reserve(3);
513  msg->fields.push_back(createPointField("x", 0, sensor_msgs::PointField::FLOAT32, 1));
514  msg->fields.push_back(createPointField("y", 4, sensor_msgs::PointField::FLOAT32, 1));
515  msg->fields.push_back(createPointField("z", 8, sensor_msgs::PointField::FLOAT32, 1));
516  msg->is_dense = false;
517  msg->point_step = sizeof(ZividDataType);
518  msg->row_step = msg->point_step * msg->width;
519  msg->data.resize(msg->row_step * msg->height);
520  point_cloud.copyData<ZividDataType>(reinterpret_cast<ZividDataType*>(msg->data.data()));
522 }
523 
524 void ZividCamera::publishPointCloudXYZRGBA(const std_msgs::Header& header, const Zivid::PointCloud& point_cloud)
525 {
526  ROS_DEBUG("Publishing points/xyzrgba");
527 
528  auto msg = boost::make_shared<sensor_msgs::PointCloud2>();
529  fillCommonMsgFields(*msg, header, point_cloud.width(), point_cloud.height());
530  msg->fields.reserve(4);
531  msg->fields.push_back(createPointField("x", 0, sensor_msgs::PointField::FLOAT32, 1));
532  msg->fields.push_back(createPointField("y", 4, sensor_msgs::PointField::FLOAT32, 1));
533  msg->fields.push_back(createPointField("z", 8, sensor_msgs::PointField::FLOAT32, 1));
534  msg->fields.push_back(createPointField("rgba", 12, sensor_msgs::PointField::FLOAT32, 1));
535  msg->is_dense = false;
536 
537  // Note that the "rgba" field is actually byte order "bgra" on little-endian systems. For this
538  // reason we use the Zivid BGRA type.
539  using ZividDataType = Zivid::PointXYZColorBGRA;
540  msg->point_step = sizeof(ZividDataType);
541  msg->row_step = msg->point_step * msg->width;
542  msg->data.resize(msg->row_step * msg->height);
543  point_cloud.copyData<ZividDataType>(reinterpret_cast<ZividDataType*>(msg->data.data()));
545 }
546 
547 void ZividCamera::publishColorImage(const std_msgs::Header& header, const sensor_msgs::CameraInfoConstPtr& camera_info,
548  const Zivid::PointCloud& point_cloud)
549 {
550  ROS_DEBUG("Publishing color image");
551  auto image = makePointCloudImage<Zivid::ColorRGBA>(point_cloud, header, sensor_msgs::image_encodings::RGBA8);
552  color_image_publisher_.publish(image, camera_info);
553 }
554 
555 void ZividCamera::publishColorImage(const std_msgs::Header& header, const sensor_msgs::CameraInfoConstPtr& camera_info,
556  const Zivid::Image<Zivid::ColorRGBA>& image)
557 {
558  ROS_DEBUG("Publishing color image");
559 
560  auto msg = makeImage(header, sensor_msgs::image_encodings::RGBA8, image.width(), image.height());
561  const auto uint8_ptr_begin = reinterpret_cast<const uint8_t*>(image.data());
562  const auto uint8_ptr_end = reinterpret_cast<const uint8_t*>(image.data() + image.size());
563  msg->data = std::vector<uint8_t>(uint8_ptr_begin, uint8_ptr_end);
564  color_image_publisher_.publish(msg, camera_info);
565 }
566 
567 void ZividCamera::publishDepthImage(const std_msgs::Header& header, const sensor_msgs::CameraInfoConstPtr& camera_info,
568  const Zivid::PointCloud& point_cloud)
569 {
570  ROS_DEBUG("Publishing depth image");
571  auto image = makePointCloudImage<Zivid::PointZ>(point_cloud, header, sensor_msgs::image_encodings::TYPE_32FC1);
572  depth_image_publisher_.publish(image, camera_info);
573 }
574 
575 void ZividCamera::publishSnrImage(const std_msgs::Header& header, const sensor_msgs::CameraInfoConstPtr& camera_info,
576  const Zivid::PointCloud& point_cloud)
577 {
578  ROS_DEBUG("Publishing SNR image");
579  auto image = makePointCloudImage<Zivid::SNR>(point_cloud, header, sensor_msgs::image_encodings::TYPE_32FC1);
580  snr_image_publisher_.publish(image, camera_info);
581 }
582 
583 sensor_msgs::CameraInfoConstPtr ZividCamera::makeCameraInfo(const std_msgs::Header& header, std::size_t width,
584  std::size_t height,
585  const Zivid::CameraIntrinsics& intrinsics)
586 {
587  auto msg = boost::make_shared<sensor_msgs::CameraInfo>();
588  msg->header = header;
589  msg->width = static_cast<uint32_t>(width);
590  msg->height = static_cast<uint32_t>(height);
591  msg->distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
592 
593  // k1, k2, t1, t2, k3
594  const auto distortion = intrinsics.distortion();
595  msg->D.resize(5);
596  msg->D[0] = distortion.k1().value();
597  msg->D[1] = distortion.k2().value();
598  msg->D[2] = distortion.p1().value();
599  msg->D[3] = distortion.p2().value();
600  msg->D[4] = distortion.k3().value();
601 
602  // Intrinsic camera matrix for the raw (distorted) images.
603  // [fx 0 cx]
604  // K = [ 0 fy cy]
605  // [ 0 0 1]
606  const auto camera_matrix = intrinsics.cameraMatrix();
607  msg->K[0] = camera_matrix.fx().value();
608  msg->K[2] = camera_matrix.cx().value();
609  msg->K[4] = camera_matrix.fy().value();
610  msg->K[5] = camera_matrix.cy().value();
611  msg->K[8] = 1;
612 
613  // R (identity)
614  msg->R[0] = 1;
615  msg->R[4] = 1;
616  msg->R[8] = 1;
617 
618  // Projection/camera matrix
619  // [fx' 0 cx' Tx]
620  // P = [ 0 fy' cy' Ty]
621  // [ 0 0 1 0]
622  msg->P[0] = camera_matrix.fx().value();
623  msg->P[2] = camera_matrix.cx().value();
624  msg->P[5] = camera_matrix.fy().value();
625  msg->P[6] = camera_matrix.cy().value();
626  msg->P[10] = 1;
627 
628  return msg;
629 }
630 
631 } // namespace zivid_camera
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
std::unique_ptr< Capture2DSettingsController > capture_2d_settings_controller_
Definition: zivid_camera.h:98
void publish(const boost::shared_ptr< M > &message) const
void publishSnrImage(const std_msgs::Header &header, const sensor_msgs::CameraInfoConstPtr &camera_info, const Zivid::PointCloud &point_cloud)
bool use_latched_publisher_for_color_image_
Definition: zivid_camera.h:82
bool captureServiceHandler(Capture::Request &req, Capture::Response &res)
image_transport::ImageTransport image_transport_
Definition: zivid_camera.h:87
uint32_t getNumSubscribers() const
bool shouldPublishSnrImg() const
ros::NodeHandle priv_
Definition: zivid_camera.h:77
CameraStatus camera_status_
Definition: zivid_camera.h:79
ros::ServiceServer is_connected_service_
Definition: zivid_camera.h:96
bool captureAssistantSuggestSettingsServiceHandler(CaptureAssistantSuggestSettings::Request &req, CaptureAssistantSuggestSettings::Response &res)
bool capture2DServiceHandler(Capture2D::Request &req, Capture2D::Response &res)
bool shouldPublishPointsXYZ() const
ros::ServiceServer capture_assistant_suggest_settings_service_
Definition: zivid_camera.h:95
void publishColorImage(const std_msgs::Header &header, const sensor_msgs::CameraInfoConstPtr &camera_info, const Zivid::PointCloud &point_cloud)
image_transport::CameraPublisher snr_image_publisher_
Definition: zivid_camera.h:90
void publishDepthImage(const std_msgs::Header &header, const sensor_msgs::CameraInfoConstPtr &camera_info, const Zivid::PointCloud &point_cloud)
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
bool use_latched_publisher_for_depth_image_
Definition: zivid_camera.h:83
ROSCPP_DECL const std::string & getNamespace()
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
bool use_latched_publisher_for_points_xyz_
Definition: zivid_camera.h:80
const std::string TYPE_32FC1
ros::Publisher points_xyz_publisher_
Definition: zivid_camera.h:85
Zivid::Application zivid_
Definition: zivid_camera.h:99
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
const std::string & getNamespace() const
bool use_latched_publisher_for_points_xyzrgba_
Definition: zivid_camera.h:81
void publishPointCloudXYZRGBA(const std_msgs::Header &header, const Zivid::PointCloud &point_cloud)
ros::ServiceServer capture_2d_service_
Definition: zivid_camera.h:94
#define ROS_WARN_STREAM(args)
ros::ServiceServer capture_service_
Definition: zivid_camera.h:93
#define ROS_DEBUG_STREAM(args)
void setCameraStatus(CameraStatus camera_status)
bool shouldPublishColorImg() const
sensor_msgs::CameraInfoConstPtr makeCameraInfo(const std_msgs::Header &header, std::size_t width, std::size_t height, const Zivid::CameraIntrinsics &intrinsics)
image_transport::CameraPublisher depth_image_publisher_
Definition: zivid_camera.h:89
ZividCamera(ros::NodeHandle &nh, ros::NodeHandle &priv)
bool cameraInfoModelNameServiceHandler(CameraInfoModelName::Request &req, CameraInfoModelName::Response &res)
bool isConnectedServiceHandler(IsConnected::Request &req, IsConnected::Response &res)
uint32_t getNumSubscribers() const
static int numChannels(const std::string &encoding)
std::unique_ptr< Capture3DSettingsController > capture_settings_controller_
Definition: zivid_camera.h:97
#define ROS_INFO_STREAM(args)
void publishPointCloudXYZ(const std_msgs::Header &header, const Zivid::PointCloud &point_cloud)
ros::ServiceServer camera_info_model_name_service_
Definition: zivid_camera.h:92
static Time now()
ros::Timer camera_connection_keepalive_timer_
Definition: zivid_camera.h:78
void publishFrame(Zivid::Frame &&frame)
static int bitDepth(const std::string &encoding)
ros::ServiceServer camera_info_serial_number_service_
Definition: zivid_camera.h:91
std_msgs::Header makeHeader()
void onCameraConnectionKeepAliveTimeout(const ros::TimerEvent &event)
ros::Publisher points_xyzrgba_publisher_
Definition: zivid_camera.h:86
bool cameraInfoSerialNumberServiceHandler(CameraInfoSerialNumber::Request &req, CameraInfoSerialNumber::Response &res)
bool shouldPublishDepthImg() const
void serviceHandlerHandleCameraConnectionLoss()
bool shouldPublishPointsXYZRGBA() const
image_transport::CameraPublisher color_image_publisher_
Definition: zivid_camera.h:88
#define ROS_DEBUG(...)


zivid_camera
Author(s): Zivid
autogenerated on Sat Apr 17 2021 02:51:05