sensor2D.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (c) 2014
3  * VoXel Interaction Design GmbH
4  *
5  * @author Angel Merino Sastre
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  ******************************************************************************/
26 
42 #include <bta_ros/sensor2D.hpp>
43 
44 namespace bta_ros
45 {
46  Sensor2D::Sensor2D(ros::NodeHandle nh_camera,
47  ros::NodeHandle nh_private,
48  std::string nodeName) :
49  nh_(nh_camera),
50  nh_private_(nh_private),
51  it_(nh_camera),
52  cim_rgb_(nh_camera),
53  nodeName_(nodeName),
54  address_("192.168.0.10")
55  {
56 
60  }
61 
62  }
63 
65  {
66  stop();
67  }
68 
69  static void cb_new_pad (GstElement *element,
70  GstPad *pad,
71  gpointer data)
72  {
73  GstElement* elem = ( GstElement* ) data;
74  GstPad *sinkpad;
75  GstPadLinkReturn lres;
76 
77  sinkpad = gst_element_get_static_pad ( elem , "sink" );
78  g_assert (sinkpad);
79  lres == gst_pad_link ( pad, sinkpad );
80  g_assert (GST_PAD_LINK_SUCCESSFUL(lres));
81  gst_object_unref( sinkpad );
82  }
83 
84  void Sensor2D::init() {
85  GstElement *souphttpsrc,
86  *sdpdemux, *videodepay,
87  *videodecoder, *videoconvert,
88  *filter;
89  //GstElement *pipeline_;
90 
91  gboolean res;
92  GstPadLinkReturn lres;
93  GstPad *srcpad, *sinkpad;
94 
95  //GstPadTemplate *teePad;
96 
97  if(!nh_private_.getParam(nodeName_+"/2dURL",address_))
99  "No ip for download sdp file given. Trying with default: " << address_);
100 
101  // always init first
102  gst_init (NULL,NULL);
103 
104  // the pipeline_ to hold everything
105  pipeline_ = gst_pipeline_new ("pipeline");
106  g_assert (pipeline_);
107 
108  souphttpsrc = gst_element_factory_make ("souphttpsrc", "sdphttpsrc");
109  g_assert (souphttpsrc);
110  g_object_set (souphttpsrc, "location", address_.c_str(), NULL);
111 
112  sdpdemux = gst_element_factory_make ("sdpdemux", NULL);
113  g_assert (sdpdemux);
114  //g_object_set (sdpdemux, "debug", TRUE, NULL);
115  //g_object_set (sdpdemux, "redirect", FALSE, NULL);
116  //g_object_set (sdpdemux, "latency", 0, NULL);
117 
118  // the depayloading
119  videodepay = gst_element_factory_make ("rtph264depay", NULL);
120  g_assert (videodepay);
121 
122  /* the decoding */
123  videodecoder = gst_element_factory_make ("avdec_h264", NULL);
124  g_assert (videodecoder);
125  g_object_set (videodecoder, "skip-frame", 5, NULL);
126 
127  /*tee = gst_element_factory_make ("tee", NULL);
128  g_assert (tee);*/
129 
130  // queue for local visualization
131  /*queueLocal = gst_element_factory_make ("queue", NULL);
132  g_assert (queueLocal);*/
133 
134  /*queueApp = gst_element_factory_make ("queue", NULL);
135  g_assert (queueApp);*/
136 
137  /*videoflip = gst_element_factory_make ("videoflip", NULL);
138  g_assert (videoflip);
139  g_object_set (videoflip, "method", 1, NULL);
140 
141  videocrop = gst_element_factory_make ("videocrop", NULL);
142  g_assert (videocrop);
143  g_object_set (videocrop, "top", 0, NULL);
144  g_object_set (videocrop, "left", 0, NULL);
145  g_object_set (videocrop, "right", 0, NULL);
146  g_object_set (videocrop, "bottom", 0, NULL);*/
147 
148  // video playback
149  /*videosink = gst_element_factory_make ("autovideosink", NULL);
150  g_assert (videosink);
151  g_object_set (videosink, "sync", FALSE, NULL);*/
152 
153  videoconvert =gst_element_factory_make("videoconvert", NULL);
154  g_assert (videoconvert);
155 
156  filter = gst_element_factory_make ("capsfilter", "filter");
157  g_assert (filter);
158  GstCaps *filtercaps;
159  filtercaps = gst_caps_new_simple ("video/x-raw",
160  "format", G_TYPE_STRING, "BGR",
161  NULL);
162  g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
163  gst_caps_unref (filtercaps);
164 
165  appsink = gst_element_factory_make("appsink", NULL);
166  g_assert (appsink);
167  //g_object_set (appsink, "emit-signals", TRUE, NULL);
168  g_object_set (appsink, "drop", TRUE, NULL);
169  g_object_set (appsink, "max-buffers", 1, NULL);
170 
171  // add depayloading and playback to the pipeline_ and link
172  gst_bin_add_many (GST_BIN (pipeline_),
173  souphttpsrc,
174  sdpdemux,
175  videodepay,
176  videodecoder,
177  videoconvert,
178  filter,
179  appsink,
180  NULL);
181 
182  res = gst_element_link (souphttpsrc, sdpdemux);
183  g_assert (res == TRUE);
184  //g_print ("link %d result \n", res);
185 
186  g_signal_connect (sdpdemux, "pad-added", G_CALLBACK (cb_new_pad), videodepay);
187 
188  res = gst_element_link_many (videodepay, videodecoder, videoconvert, filter, appsink, NULL);
189  g_assert (res == TRUE);
190 
191 
192  //g_signal_connect(appsink, "new-sample", G_CALLBACK(newFrame), NULL);
193 
194  //GstElement *session = sdpdemux.session;
195  // the RTP pad that we have to connect to the depayloader will be created
196  // dynamically so we connect to the pad-added signal, pass the depayloader as
197  // user_data so that we can link to it.
198  //printf("rtpbin: %p\n",rtpbin);
199  //g_signal_connect (rtpbin, "pad-added", G_CALLBACK (pad_added_cb), videodepay);
200 
201  // give some stats when we receive RTCP
202  //g_signal_connect (sdpdemux, "on-ssrc-active", G_CALLBACK (on_ssrc_active_cb), videodepay);
203 
204  // set the pipeline_ to playing
205  ROS_INFO ("starting receiver pipeline");
206 
207  gst_element_set_state(pipeline_, GST_STATE_PAUSED);
208  if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
209  ROS_FATAL("Failed to PAUSE stream, check your configuration.");
210  ros::shutdown();
211  return;
212  } else {
213  ROS_DEBUG("Stream is PAUSED.");
214  }
215  gst_element_set_state (pipeline_, GST_STATE_PLAYING);
216  if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
217  ROS_WARN("Failed to PLAY stream.");
218  }
219  //loop = g_main_loop_new (NULL, FALSE);
220  //g_main_loop_run (loop);
221 
222  {
223  // Advertise all published topics
226  /*camera_info_url_*/"package://bta_ros/calib.yml")) {
227  cim_rgb_.loadCameraInfo("package://bta_ros/calib.yml");
228  ROS_INFO_STREAM("Loaded camera calibration from " <<
229  "package://bta_ros/calib.yml" );
230  } else {
231  ROS_WARN_STREAM("Camera info at: " <<
232  "package://bta_ros/calib.yml" <<
233  " not found. Using an uncalibrated config.");
234  }
235 
236  pub_rgb_ = it_.advertiseCamera(nodeName_ + "/sensor2d/image_raw", 1);
237 
238  //sub_amp_ = nh_private_.subscribe("bta_node_amp", 1, &BtaRos::ampCb, this);
239  //sub_dis_ = nh_private_.subscribe("bta_node_dis", 1, &BtaRos::disCb, this);
240  }
241  GstState state;
242  while (nh_.ok() && !ros::isShuttingDown()) {
243  gst_element_get_state(pipeline_, &state, NULL, -1);
244  if (state == GST_STATE_PLAYING)
245  getFrame();
246  else {
247  ROS_INFO("Stream STOPPED. Reconnecting");
248  gst_element_set_state (pipeline_, GST_STATE_NULL);
249  if (gst_element_set_state (pipeline_, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
250  ROS_ERROR("Failed to PLAY stream.");
251  }
252  }
253  ros::spinOnce ();
254  }
255 
256  //stop();
257 
258  return;
259  }
260 
261  void Sensor2D::stop() {
262  g_print ("Returned, stopping playback\n");
263  gst_element_set_state (pipeline_, GST_STATE_NULL);
264 
265  g_print ("Deleting pipeline_\n");
266  gst_object_unref (GST_OBJECT (pipeline_));
267 
268  return;
269  }
270 
272  GstSample *sample;
273 
274  sample = gst_app_sink_pull_sample((GstAppSink *)appsink);
275 
276  if(sample != NULL) {
277  ROS_DEBUG(" frame 2D Arrived");
278  sensor_msgs::ImagePtr rgb (new sensor_msgs::Image);
279  GstBuffer* sampleBuffer = NULL;
280  GstStructure *s;
281  gint width, height;
282  GstMapInfo bufferInfo;
283  gboolean res;
284  GstCaps *caps;
285 
286  caps = gst_sample_get_caps (sample);
287  s = gst_caps_get_structure (caps, 0);
288  res = gst_structure_get_int (s, "width", &width);
289  res |= gst_structure_get_int (s, "height", &height);
290  if (!res) {
291  ROS_DEBUG ("could not get snapshot dimension\n");
292  return;
293  }
294 
295  sampleBuffer = gst_sample_get_buffer(sample);
296  if(sampleBuffer != NULL)
297  {
298  gst_buffer_map(sampleBuffer, &bufferInfo, GST_MAP_READ);
299  //dis->header.seq = frame->frameCounter;
300  //dis->header.stamp.sec = frame->timeStamp;
301  rgb->height = height;
302  rgb->width = width;
303  rgb->encoding = sensor_msgs::image_encodings::BGR8;
304  rgb->step = width*(sizeof(unsigned char)*3);
305  rgb->data.resize(bufferInfo.size);
306  memcpy ( &rgb->data[0], bufferInfo.data, bufferInfo.size );
307 
308  sensor_msgs::CameraInfoPtr ci_rgb(
309  new sensor_msgs::CameraInfo(cim_rgb_.getCameraInfo()));
310  ci_rgb->header.frame_id = nodeName_+"/sensor2d";
311  rgb->header.frame_id = nodeName_+"/sensor2d";
312 
313  pub_rgb_.publish(rgb,ci_rgb);
314  }
315  gst_buffer_unmap (sampleBuffer, &bufferInfo);
316  gst_sample_unref(sample);
317  }
318  return;
319  }
320 
321 }
322 
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
#define ROS_FATAL(...)
camera_info_manager::CameraInfoManager cim_rgb_
Definition: sensor2D.hpp:74
sensor_msgs::CameraInfo getCameraInfo(void)
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
bool loadCameraInfo(const std::string &url)
XmlRpcServer s
image_transport::ImageTransport it_
Definition: sensor2D.hpp:75
#define ROS_WARN(...)
ros::NodeHandle nh_
Definition: sensor2D.hpp:72
GstElement * pipeline_
Definition: sensor2D.hpp:80
bool validateURL(const std::string &url)
static void cb_new_pad(GstElement *element, GstPad *pad, gpointer data)
Definition: sensor2D.cpp:69
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
GstElement * appsink
Definition: sensor2D.hpp:81
#define ROS_INFO(...)
image_transport::CameraPublisher pub_rgb_
Definition: sensor2D.hpp:76
ROSCPP_DECL bool isShuttingDown()
#define ROS_WARN_STREAM(args)
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
ros::NodeHandle nh_private_
Definition: sensor2D.hpp:72
ROSCPP_DECL void shutdown()
bool ok() const
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
#define ROSCONSOLE_DEFAULT_NAME
bool setCameraName(const std::string &cname)
#define ROS_DEBUG(...)


bta_tof_driver
Author(s): Angel Merino , Simon Vogl
autogenerated on Fri Jun 21 2019 19:57:15