vpROSGrabber.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2021 by INRIA. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact INRIA about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
17  *
18  * This software was developed at:
19  * INRIA Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  * http://www.irisa.fr/lagadic
24  *
25  * If you have questions regarding the use of this file, please contact
26  * INRIA at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Camera video capture for ROS image_transort_compressed.
33  *
34  * Authors:
35  * Francois Pasteau
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
45 #include <visp_ros/vpROSGrabber.h>
46 
47 #if defined( VISP_HAVE_OPENCV )
48 
49 #include <visp3/core/vpFrameGrabberException.h>
50 #include <visp3/core/vpImageConvert.h>
51 
52 #include <cv_bridge/cv_bridge.h>
53 #include <sensor_msgs/CompressedImage.h>
54 
55 #include <iostream>
56 #include <math.h>
57 
62  : m_isInitialized( false )
63  , m_flip( false )
64  , m_rectify( true )
65  , m_mutex_image( true )
66  , m_mutex_param( true )
67  , m_first_img_received( false )
68  , m_first_param_received( false )
69  , m_sec( 0 )
70  , m_nsec( 0 )
71  , m_master_uri( "http://localhost:11311" )
72  , m_topic_image( "image" )
73  , m_topic_cam_info( "camera_info" )
74  , m_nodespace( "" )
75  , m_image_transport( "raw" )
76 {
77 }
78 
85 
97 void
98 vpROSGrabber::open( int argc, char **argv )
99 {
100 
101  if ( !m_isInitialized )
102  {
103  std::string str;
104  if ( !ros::isInitialized() )
105  ros::init( argc, argv, "visp_node", ros::init_options::AnonymousName );
106  m_n = new ros::NodeHandle;
107  if ( m_image_transport == "raw" )
108  {
109  if ( ros::param::get( "~image_transport", str ) )
110  {
111  m_image_transport = str;
112  }
113  else
114  {
115  m_image_transport = "raw";
116  ros::param::set( "~image_transport", "raw" );
117  }
118  }
119  if ( m_image_transport == "raw" )
120  {
121  std::cout << "Subscribe to raw image on " << m_nodespace + m_topic_image << " topic" << std::endl;
123  ros::TransportHints().tcpNoDelay() );
124  }
125  else
126  {
127  std::cout << "Subscribe to image on " << m_nodespace + m_topic_image << " topic" << std::endl;
129  ros::TransportHints().tcpNoDelay() );
130  }
131 
132  std::cout << "Subscribe to camera_info on " << m_nodespace + m_topic_cam_info << " topic" << std::endl;
134  ros::TransportHints().tcpNoDelay() );
135 
136  m_spinner = new ros::AsyncSpinner( 1 );
137  m_spinner->start();
138  m_width = 0;
139  m_height = 0;
140  m_isInitialized = true;
141  }
142 }
143 
154 void
156 {
158  {
159  close();
160  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError,
161  "ROS grabber already initialised with a different master_URI (" +
162  ros::master::getURI() + " != " + m_master_uri + ")" ) );
163  }
164  if ( !m_isInitialized )
165  {
166  int argc = 2;
167  char *argv[2];
168  argv[0] = new char[255];
169  argv[1] = new char[255];
170 
171  std::string exe = "ros.exe", arg1 = "__master:=";
172  strcpy( argv[0], exe.c_str() );
173  arg1.append( m_master_uri );
174  strcpy( argv[1], arg1.c_str() );
175  open( argc, argv );
176 
177  // Wait for a first image
178  while ( !m_first_img_received )
179  vpTime::wait( 40 );
180 
181  delete[] argv[0];
182  delete[] argv[1];
183  }
184 }
185 
195 void
196 vpROSGrabber::open( vpImage< unsigned char > &I )
197 {
198  open();
199  acquire( I );
200 }
201 
211 void
212 vpROSGrabber::open( vpImage< vpRGBa > &I )
213 {
214  open();
215  acquire( I );
216 }
217 
229 void
230 vpROSGrabber::acquire( vpImage< unsigned char > &I, struct timespec &timestamp )
231 {
232  if ( m_isInitialized == false )
233  {
234  close();
235  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
236  }
237  while ( !m_mutex_image || !m_first_img_received )
238  ;
239  m_mutex_image = false;
240  timestamp.tv_sec = m_sec;
241  timestamp.tv_nsec = m_nsec;
242  vpImageConvert::convert( m_img, I, m_flip );
243  m_first_img_received = false;
244  m_mutex_image = true;
245 }
246 
258 void
259 vpROSGrabber::acquire( vpImage< unsigned char > &I, double &timestamp_second )
260 {
261  struct timespec timestamp;
262  acquire( I, timestamp );
263  timestamp_second = timestamp.tv_sec + static_cast< double >( timestamp.tv_nsec ) * 1e-9;
264 }
265 
277 bool
278 vpROSGrabber::acquireNoWait( vpImage< unsigned char > &I, struct timespec &timestamp )
279 {
280  bool new_image = false;
281  if ( m_isInitialized == false )
282  {
283  close();
284  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
285  }
286  while ( !m_mutex_image )
287  ;
288  m_mutex_image = false;
289  timestamp.tv_sec = m_sec;
290  timestamp.tv_nsec = m_nsec;
291  vpImageConvert::convert( m_img, I, m_flip );
292  new_image = m_first_img_received;
293  m_first_img_received = false;
294  m_mutex_image = true;
295  return new_image;
296 }
297 
307 void
308 vpROSGrabber::acquire( vpImage< vpRGBa > &I, struct timespec &timestamp )
309 {
310  if ( m_isInitialized == false )
311  {
312  close();
313  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
314  }
315  while ( !m_mutex_image || !m_first_img_received )
316  ;
317  m_mutex_image = false;
318  timestamp.tv_sec = m_sec;
319  timestamp.tv_nsec = m_nsec;
320  vpImageConvert::convert( m_img, I, m_flip );
321  m_first_img_received = false;
322  m_mutex_image = true;
323 }
324 
334 void
335 vpROSGrabber::acquire( vpImage< vpRGBa > &I, double &timestamp_second )
336 {
337  struct timespec timestamp;
338  acquire( I, timestamp );
339  timestamp_second = timestamp.tv_sec + static_cast< double >( timestamp.tv_nsec ) * 1e-9;
340 }
341 
353 bool
354 vpROSGrabber::acquireNoWait( vpImage< vpRGBa > &I, struct timespec &timestamp )
355 {
356  bool new_image = false;
357  if ( m_isInitialized == false )
358  {
359  close();
360  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
361  }
362  while ( !m_mutex_image )
363  ;
364  m_mutex_image = false;
365  timestamp.tv_sec = m_sec;
366  timestamp.tv_nsec = m_nsec;
367  vpImageConvert::convert( m_img, I, m_flip );
368  new_image = m_first_img_received;
369  m_first_img_received = false;
370  m_mutex_image = true;
371  return new_image;
372 }
373 
384 cv::Mat
385 vpROSGrabber::acquire( struct timespec &timestamp )
386 {
387  cv::Mat img;
388  if ( m_isInitialized == false )
389  {
390  close();
391  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
392  }
393  while ( !m_mutex_image || !m_first_img_received )
394  ;
395  m_mutex_image = false;
396  timestamp.tv_sec = m_sec;
397  timestamp.tv_nsec = m_nsec;
398  img = m_img.clone();
399  m_first_img_received = false;
400  m_mutex_image = true;
401  return img;
402 }
403 
411 void
412 vpROSGrabber::acquire( vpImage< unsigned char > &I )
413 {
414  struct timespec timestamp;
415  acquire( I, timestamp );
416 }
417 
427 bool
428 vpROSGrabber::acquireNoWait( vpImage< unsigned char > &I )
429 {
430  struct timespec timestamp;
431  return acquireNoWait( I, timestamp );
432 }
433 
441 void
442 vpROSGrabber::acquire( vpImage< vpRGBa > &I )
443 {
444  struct timespec timestamp;
445  acquire( I, timestamp );
446 }
447 
457 bool
458 vpROSGrabber::acquireNoWait( vpImage< vpRGBa > &I )
459 {
460  struct timespec timestamp;
461  return acquireNoWait( I, timestamp );
462 }
463 
472 cv::Mat
474 {
475  struct timespec timestamp;
476  return acquire( timestamp );
477 }
478 
479 void
481 {
482  if ( m_isInitialized )
483  {
484  m_isInitialized = false;
485  m_spinner->stop();
486  delete m_spinner;
487  delete m_n;
488  }
489 }
490 
502 void
503 vpROSGrabber::setFlip( bool flipType )
504 {
505  m_flip = flipType;
506 }
507 
516 void
518 {
519  m_rectify = rectify;
520 }
521 
528 void
529 vpROSGrabber::getWidth( unsigned int width ) const
530 {
531  width = getWidth();
532 }
533 
541 void
542 vpROSGrabber::getHeight( unsigned int height ) const
543 {
544  height = getHeight();
545 }
546 
553 unsigned int
555 {
556  return m_width;
557 }
558 
565 unsigned int
567 {
568  return m_height;
569 }
570 
578 void
579 vpROSGrabber::setCameraInfoTopic( const std::string &topic_name )
580 {
581  m_topic_cam_info = topic_name;
582 }
583 
591 void
592 vpROSGrabber::setImageTopic( const std::string &topic_name )
593 {
594  m_topic_image = topic_name;
595 }
596 
604 void
605 vpROSGrabber::setMasterURI( const std::string &master_uri )
606 {
607  m_master_uri = master_uri;
608 }
609 
617 void
618 vpROSGrabber::setNodespace( const std::string &nodespace )
619 {
620  m_nodespace = nodespace;
621 }
622 
623 void
624 setImageTransport( const std::string image_transport );
625 
635 void
637 {
639 }
640 
648 bool
649 vpROSGrabber::getCameraInfo( vpCameraParameters &cam )
650 {
651  if ( !m_isInitialized )
652  {
653  close();
654  throw( vpFrameGrabberException( vpFrameGrabberException::initializationError, "Grabber not initialized." ) );
655  }
656 
657  // Test: if we get an image (m_first_img_received=true) we should have the camera parameters
658  // (m_first_param_received=true) if they are available
660  return false;
661  while ( !m_mutex_param || !m_first_img_received )
662  ;
663  m_mutex_param = false;
664  cam = m_cam;
665  m_mutex_param = true;
666 
667  return true;
668 }
669 
670 void
671 vpROSGrabber::imageCallback( const sensor_msgs::CompressedImage::ConstPtr &msg )
672 {
673  cv::Mat img = cv::imdecode( msg->data, 1 );
674  cv::Size data_size = img.size();
675 
676  while ( !m_mutex_image )
677  ;
678  m_mutex_image = false;
679  if ( m_rectify && m_p.initialized() )
680  {
681  m_p.rectifyImage( img, m_img );
682  }
683  else
684  {
685  img.copyTo( m_img );
686  }
687  m_width = static_cast< unsigned int >( data_size.width );
688  m_height = static_cast< unsigned int >( data_size.height );
689  m_sec = msg->header.stamp.sec;
690  m_nsec = msg->header.stamp.nsec;
691  m_first_img_received = true;
692  m_mutex_image = true;
693 }
694 
695 void
696 vpROSGrabber::imageCallbackRaw( const sensor_msgs::Image::ConstPtr &msg )
697 {
698  while ( !m_mutex_image )
699  ;
700  m_mutex_image = false;
702  try
703  {
704  cv_ptr = cv_bridge::toCvShare( msg, "bgr8" );
705  }
706  catch ( cv_bridge::Exception &e )
707  {
708  ROS_ERROR( "cv_bridge exception: %s", e.what() );
709  return;
710  }
711  if ( m_rectify && m_p.initialized() )
712  {
713  m_p.rectifyImage( cv_ptr->image, m_img );
714  }
715  else
716  {
717  cv_ptr->image.copyTo( m_img );
718  }
719  cv::Size data_size = m_img.size();
720  m_width = static_cast< unsigned int >( data_size.width );
721  m_height = static_cast< unsigned int >( data_size.height );
722  m_sec = msg->header.stamp.sec;
723  m_nsec = msg->header.stamp.nsec;
724  m_first_img_received = true;
725  m_mutex_image = true;
726 }
727 
728 void
729 vpROSGrabber::paramCallback( const sensor_msgs::CameraInfo::ConstPtr &msg )
730 {
731  if ( m_rectify )
732  {
733  while ( !m_mutex_image )
734  ;
735  m_mutex_image = false;
737  m_p.fromCameraInfo( msg );
738  m_first_param_received = true;
739  m_mutex_image = true;
740  }
741 }
742 
743 #endif
ros::init_options::AnonymousName
AnonymousName
vpROSGrabber::m_img
cv::Mat m_img
Definition: vpROSGrabber.h:115
vpROSGrabber::m_mutex_param
volatile bool m_mutex_param
Definition: vpROSGrabber.h:118
vpROSGrabber::m_sec
volatile uint32_t m_sec
Definition: vpROSGrabber.h:124
vpROSGrabber::m_nodespace
std::string m_nodespace
Definition: vpROSGrabber.h:128
vpROSGrabber::m_first_param_received
volatile bool m_first_param_received
Definition: vpROSGrabber.h:123
boost::shared_ptr
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
vpROSGrabber::m_first_img_received
volatile bool m_first_img_received
Definition: vpROSGrabber.h:122
ros::param::get
ROSCPP_DECL bool get(const std::string &key, bool &b)
ros::AsyncSpinner::start
void start()
vpROSGrabber::m_topic_cam_info
std::string m_topic_cam_info
Definition: vpROSGrabber.h:127
vpROSGrabber::getCameraInfo
bool getCameraInfo(vpCameraParameters &cam)
Definition: vpROSGrabber.cpp:649
image_geometry::PinholeCameraModel::rectifyImage
void rectifyImage(const cv::Mat &raw, cv::Mat &rectified, int interpolation=cv::INTER_LINEAR) const
vpROSGrabber::open
void open()
Definition: vpROSGrabber.cpp:155
vpROSGrabber::imageCallbackRaw
void imageCallbackRaw(const sensor_msgs::Image::ConstPtr &msg)
Definition: vpROSGrabber.cpp:696
ros::AsyncSpinner
ros::TransportHints
vpROSGrabber::m_cam
vpCameraParameters m_cam
Definition: vpROSGrabber.h:130
vpROSGrabber::m_topic_image
std::string m_topic_image
Definition: vpROSGrabber.h:126
cv_bridge::Exception
vpROSGrabber::setFlip
void setFlip(bool flipType)
Definition: vpROSGrabber.cpp:503
vpROSGrabber::m_flip
bool m_flip
Definition: vpROSGrabber.h:116
setImageTransport
void setImageTransport(const std::string image_transport)
visp_bridge::toVispCameraParameters
vpCameraParameters toVispCameraParameters(const sensor_msgs::CameraInfo &cam_info)
vpROSGrabber::~vpROSGrabber
virtual ~vpROSGrabber()
Definition: vpROSGrabber.cpp:84
image_geometry::PinholeCameraModel::fromCameraInfo
bool fromCameraInfo(const sensor_msgs::CameraInfo &msg)
vpROSGrabber::acquireNoWait
bool acquireNoWait(vpImage< unsigned char > &I)
Definition: vpROSGrabber.cpp:428
vpROSGrabber::m_mutex_image
volatile bool m_mutex_image
Definition: vpROSGrabber.h:118
vpROSGrabber::paramCallback
void paramCallback(const sensor_msgs::CameraInfo::ConstPtr &msg)
Definition: vpROSGrabber.cpp:729
ros::isInitialized
ROSCPP_DECL bool isInitialized()
vpROSGrabber::setNodespace
void setNodespace(const std::string &nodespace)
Definition: vpROSGrabber.cpp:618
ROS_ERROR
#define ROS_ERROR(...)
vpROSGrabber::getWidth
unsigned int getWidth() const
Definition: vpROSGrabber.cpp:554
vpROSGrabber::m_img_sub
ros::Subscriber m_img_sub
Definition: vpROSGrabber.h:108
vpROSGrabber::setImageTopic
void setImageTopic(const std::string &topic_name)
Definition: vpROSGrabber.cpp:592
vpROSGrabber::setMasterURI
void setMasterURI(const std::string &master_uri)
Definition: vpROSGrabber.cpp:605
vpROSGrabber::m_rectify
volatile bool m_rectify
Definition: vpROSGrabber.h:117
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
vpROSGrabber::m_n
ros::NodeHandle * m_n
Definition: vpROSGrabber.h:107
vpROSGrabber::setCameraInfoTopic
void setCameraInfoTopic(const std::string &topic_name)
Definition: vpROSGrabber.cpp:579
vpROSGrabber::acquire
cv::Mat acquire()
Definition: vpROSGrabber.cpp:473
ros::AsyncSpinner::stop
void stop()
ros::param::set
ROSCPP_DECL void set(const std::string &key, bool b)
vpROSGrabber::getHeight
unsigned int getHeight() const
Definition: vpROSGrabber.cpp:566
vpROSGrabber::m_nsec
volatile uint32_t m_nsec
Definition: vpROSGrabber.h:124
vpROSGrabber::setImageTransport
void setImageTransport(const std::string &image_transport)
Definition: vpROSGrabber.cpp:636
vpROSGrabber::m_height
volatile unsigned int m_height
Definition: vpROSGrabber.h:113
cv_bridge.h
vpROSGrabber::m_image_transport
std::string m_image_transport
Definition: vpROSGrabber.h:129
image_transport
vpROSGrabber::m_isInitialized
volatile bool m_isInitialized
Definition: vpROSGrabber.h:111
vpROSGrabber::imageCallback
void imageCallback(const sensor_msgs::CompressedImage::ConstPtr &msg)
Definition: vpROSGrabber.cpp:671
vpROSGrabber::m_master_uri
std::string m_master_uri
Definition: vpROSGrabber.h:125
cv_bridge::toCvShare
CvImageConstPtr toCvShare(const sensor_msgs::Image &source, const boost::shared_ptr< void const > &tracked_object, const std::string &encoding=std::string())
vpROSGrabber::vpROSGrabber
vpROSGrabber()
Definition: vpROSGrabber.cpp:61
vpROSGrabber::m_p
image_geometry::PinholeCameraModel m_p
Definition: vpROSGrabber.h:114
image_geometry::PinholeCameraModel::initialized
bool initialized() const
ros::master::getURI
const ROSCPP_DECL std::string & getURI()
vpROSGrabber::m_width
volatile unsigned int m_width
Definition: vpROSGrabber.h:112
vpROSGrabber::setRectify
void setRectify(bool rectify)
Definition: vpROSGrabber.cpp:517
vpROSGrabber::m_cam_info_sub
ros::Subscriber m_cam_info_sub
Definition: vpROSGrabber.h:109
vpROSGrabber.h
class for Camera video capture for ROS middleware.
vpROSGrabber::close
void close()
Definition: vpROSGrabber.cpp:480
ros::NodeHandle
vpROSGrabber::m_spinner
ros::AsyncSpinner * m_spinner
Definition: vpROSGrabber.h:110


visp_ros
Author(s): Francois Pasteau, Fabien Spindler, Gatien Gaumerais, Alexander Oliva
autogenerated on Wed Mar 2 2022 01:13:33