00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00042 #include <bta_ros/sensor2D.hpp>
00043
00044 namespace bta_ros
00045 {
00046 Sensor2D::Sensor2D(ros::NodeHandle nh_camera,
00047 ros::NodeHandle nh_private,
00048 std::string nodeName) :
00049 nh_(nh_camera),
00050 nh_private_(nh_private),
00051 it_(nh_camera),
00052 cim_rgb_(nh_camera),
00053 nodeName_(nodeName),
00054 address_("192.168.0.10")
00055 {
00056
00057 if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME,
00058 ros::console::levels::Debug) ) {
00059 ros::console::notifyLoggerLevelsChanged();
00060 }
00061
00062 }
00063
00064 Sensor2D::~Sensor2D()
00065 {
00066 stop();
00067 }
00068
00069 static void cb_new_pad (GstElement *element,
00070 GstPad *pad,
00071 gpointer data)
00072 {
00073 GstElement* elem = ( GstElement* ) data;
00074 GstPad *sinkpad;
00075 GstPadLinkReturn lres;
00076
00077 sinkpad = gst_element_get_static_pad ( elem , "sink" );
00078 g_assert (sinkpad);
00079 lres == gst_pad_link ( pad, sinkpad );
00080 g_assert (GST_PAD_LINK_SUCCESSFUL(lres));
00081 gst_object_unref( sinkpad );
00082 }
00083
00084 void Sensor2D::init() {
00085 GstElement *souphttpsrc,
00086 *sdpdemux, *videodepay,
00087 *videodecoder, *videoconvert,
00088 *filter;
00089
00090
00091 gboolean res;
00092 GstPadLinkReturn lres;
00093 GstPad *srcpad, *sinkpad;
00094
00095
00096
00097 if(!nh_private_.getParam(nodeName_+"/2dURL",address_))
00098 ROS_INFO_STREAM(
00099 "No ip for download sdp file given. Trying with default: " << address_);
00100
00101
00102 gst_init (NULL,NULL);
00103
00104
00105 pipeline_ = gst_pipeline_new ("pipeline");
00106 g_assert (pipeline_);
00107
00108 souphttpsrc = gst_element_factory_make ("souphttpsrc", "sdphttpsrc");
00109 g_assert (souphttpsrc);
00110 g_object_set (souphttpsrc, "location", address_.c_str(), NULL);
00111
00112 sdpdemux = gst_element_factory_make ("sdpdemux", NULL);
00113 g_assert (sdpdemux);
00114
00115
00116
00117
00118
00119 videodepay = gst_element_factory_make ("rtph264depay", NULL);
00120 g_assert (videodepay);
00121
00122
00123 videodecoder = gst_element_factory_make ("avdec_h264", NULL);
00124 g_assert (videodecoder);
00125 g_object_set (videodecoder, "skip-frame", 5, NULL);
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 videoconvert =gst_element_factory_make("videoconvert", NULL);
00154 g_assert (videoconvert);
00155
00156 filter = gst_element_factory_make ("capsfilter", "filter");
00157 g_assert (filter);
00158 GstCaps *filtercaps;
00159 filtercaps = gst_caps_new_simple ("video/x-raw",
00160 "format", G_TYPE_STRING, "BGR",
00161 NULL);
00162 g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
00163 gst_caps_unref (filtercaps);
00164
00165 appsink = gst_element_factory_make("appsink", NULL);
00166 g_assert (appsink);
00167
00168 g_object_set (appsink, "drop", TRUE, NULL);
00169 g_object_set (appsink, "max-buffers", 1, NULL);
00170
00171
00172 gst_bin_add_many (GST_BIN (pipeline_),
00173 souphttpsrc,
00174 sdpdemux,
00175 videodepay,
00176 videodecoder,
00177 videoconvert,
00178 filter,
00179 appsink,
00180 NULL);
00181
00182 res = gst_element_link (souphttpsrc, sdpdemux);
00183 g_assert (res == TRUE);
00184
00185
00186 g_signal_connect (sdpdemux, "pad-added", G_CALLBACK (cb_new_pad), videodepay);
00187
00188 res = gst_element_link_many (videodepay, videodecoder, videoconvert, filter, appsink, NULL);
00189 g_assert (res == TRUE);
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 ROS_INFO ("starting receiver pipeline");
00206
00207 gst_element_set_state(pipeline_, GST_STATE_PAUSED);
00208 if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00209 ROS_FATAL("Failed to PAUSE stream, check your configuration.");
00210 ros::shutdown();
00211 return;
00212 } else {
00213 ROS_DEBUG("Stream is PAUSED.");
00214 }
00215 gst_element_set_state (pipeline_, GST_STATE_PLAYING);
00216 if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00217 ROS_WARN("Failed to PLAY stream.");
00218 }
00219
00220
00221
00222 {
00223
00224 cim_rgb_.setCameraName(nodeName_);
00225 if(cim_rgb_.validateURL(
00226 "package://bta_ros/calib.yml")) {
00227 cim_rgb_.loadCameraInfo("package://bta_ros/calib.yml");
00228 ROS_INFO_STREAM("Loaded camera calibration from " <<
00229 "package://bta_ros/calib.yml" );
00230 } else {
00231 ROS_WARN_STREAM("Camera info at: " <<
00232 "package://bta_ros/calib.yml" <<
00233 " not found. Using an uncalibrated config.");
00234 }
00235
00236 pub_rgb_ = it_.advertiseCamera(nodeName_ + "/sensor2d/image_raw", 1);
00237
00238
00239
00240 }
00241 GstState state;
00242 while (nh_.ok() && !ros::isShuttingDown()) {
00243 gst_element_get_state(pipeline_, &state, NULL, -1);
00244 if (state == GST_STATE_PLAYING)
00245 getFrame();
00246 else {
00247 ROS_INFO("Stream STOPPED. Reconnecting");
00248 gst_element_set_state (pipeline_, GST_STATE_NULL);
00249 if (gst_element_set_state (pipeline_, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
00250 ROS_ERROR("Failed to PLAY stream.");
00251 }
00252 }
00253 ros::spinOnce ();
00254 }
00255
00256
00257
00258 return;
00259 }
00260
00261 void Sensor2D::stop() {
00262 g_print ("Returned, stopping playback\n");
00263 gst_element_set_state (pipeline_, GST_STATE_NULL);
00264
00265 g_print ("Deleting pipeline_\n");
00266 gst_object_unref (GST_OBJECT (pipeline_));
00267
00268 return;
00269 }
00270
00271 void Sensor2D::getFrame() {
00272 GstSample *sample;
00273
00274 sample = gst_app_sink_pull_sample((GstAppSink *)appsink);
00275
00276 if(sample != NULL) {
00277 ROS_DEBUG(" frame 2D Arrived");
00278 sensor_msgs::ImagePtr rgb (new sensor_msgs::Image);
00279 GstBuffer* sampleBuffer = NULL;
00280 GstStructure *s;
00281 gint width, height;
00282 GstMapInfo bufferInfo;
00283 gboolean res;
00284 GstCaps *caps;
00285
00286 caps = gst_sample_get_caps (sample);
00287 s = gst_caps_get_structure (caps, 0);
00288 res = gst_structure_get_int (s, "width", &width);
00289 res |= gst_structure_get_int (s, "height", &height);
00290 if (!res) {
00291 ROS_DEBUG ("could not get snapshot dimension\n");
00292 return;
00293 }
00294
00295 sampleBuffer = gst_sample_get_buffer(sample);
00296 if(sampleBuffer != NULL)
00297 {
00298 gst_buffer_map(sampleBuffer, &bufferInfo, GST_MAP_READ);
00299
00300
00301 rgb->height = height;
00302 rgb->width = width;
00303 rgb->encoding = sensor_msgs::image_encodings::BGR8;
00304 rgb->step = width*(sizeof(unsigned char)*3);
00305 rgb->data.resize(bufferInfo.size);
00306 memcpy ( &rgb->data[0], bufferInfo.data, bufferInfo.size );
00307
00308 sensor_msgs::CameraInfoPtr ci_rgb(
00309 new sensor_msgs::CameraInfo(cim_rgb_.getCameraInfo()));
00310 ci_rgb->header.frame_id = nodeName_+"/sensor2d";
00311 rgb->header.frame_id = nodeName_+"/sensor2d";
00312
00313 pub_rgb_.publish(rgb,ci_rgb);
00314 }
00315 gst_buffer_unmap (sampleBuffer, &bufferInfo);
00316 gst_sample_unref(sample);
00317 }
00318 return;
00319 }
00320
00321 }
00322