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