void callback(const sensor_msgs::ImageConstPtr &img, const sensor_msgs::CameraInfoConstPtr &info) { boost::mutex::scoped_lock lock(mutex_); ros::Time now = ros::Time::now(); static boost::circular_buffer<double> in_times(100); static boost::circular_buffer<double> out_times(100); static boost::circular_buffer<double> in_bytes(100); static boost::circular_buffer<double> out_bytes(100); ROS_DEBUG("resize: callback"); if ( !publish_once_ || cp_.getNumSubscribers () == 0 ) { ROS_DEBUG("resize: number of subscribers is 0, ignoring image"); return; } in_times.push_front((now - last_subscribe_time_).toSec()); in_bytes.push_front(img->data.size()); // try { int width = dst_width_ ? dst_width_ : (resize_x_ * info->width); int height = dst_height_ ? dst_height_ : (resize_y_ * info->height); double scale_x = dst_width_ ? ((double)dst_width_)/info->width : resize_x_; double scale_y = dst_height_ ? ((double)dst_height_)/info->height : resize_y_; cv_bridge::CvImagePtr cv_img = cv_bridge::toCvCopy(img); cv::Mat tmpmat(height, width, cv_img->image.type()); cv::resize(cv_img->image, tmpmat, cv::Size(width, height)); cv_img->image = tmpmat; sensor_msgs::CameraInfo tinfo = *info; tinfo.height = height; tinfo.width = width; tinfo.K[0] = tinfo.K[0] * scale_x; // fx tinfo.K[2] = tinfo.K[2] * scale_x; // cx tinfo.K[4] = tinfo.K[4] * scale_y; // fy tinfo.K[5] = tinfo.K[5] * scale_y; // cy tinfo.P[0] = tinfo.P[0] * scale_x; // fx tinfo.P[2] = tinfo.P[2] * scale_x; // cx tinfo.P[3] = tinfo.P[3] * scale_x; // T tinfo.P[5] = tinfo.P[5] * scale_y; // fy tinfo.P[6] = tinfo.P[6] * scale_y; // cy if ( !use_messages_ || now - last_publish_time_ > period_ ) { cp_.publish(cv_img->toImageMsg(), boost::make_shared<sensor_msgs::CameraInfo> (tinfo)); out_times.push_front((now - last_publish_time_).toSec()); out_bytes.push_front(cv_img->image.total()*cv_img->image.elemSize()); last_publish_time_ = now; } } catch( cv::Exception& e ) { ROS_ERROR("%s", e.what()); } float duration = (now - last_rosinfo_time_).toSec(); if ( duration > 2 ) { int in_time_n = in_times.size(); int out_time_n = out_times.size(); double in_time_mean = 0, in_time_rate = 1.0, in_time_std_dev = 0.0, in_time_max_delta, in_time_min_delta; double out_time_mean = 0, out_time_rate = 1.0, out_time_std_dev = 0.0, out_time_max_delta, out_time_min_delta; std::for_each( in_times.begin(), in_times.end(), (in_time_mean += boost::lambda::_1) ); in_time_mean /= in_time_n; in_time_rate /= in_time_mean; std::for_each( in_times.begin(), in_times.end(), (in_time_std_dev += (boost::lambda::_1 - in_time_mean)*(boost::lambda::_1 - in_time_mean) ) ); in_time_std_dev = sqrt(in_time_std_dev/in_time_n); if ( in_time_n > 1 ) { in_time_min_delta = *std::min_element(in_times.begin(), in_times.end()); in_time_max_delta = *std::max_element(in_times.begin(), in_times.end()); } std::for_each( out_times.begin(), out_times.end(), (out_time_mean += boost::lambda::_1) ); out_time_mean /= out_time_n; out_time_rate /= out_time_mean; std::for_each( out_times.begin(), out_times.end(), (out_time_std_dev += (boost::lambda::_1 - out_time_mean)*(boost::lambda::_1 - out_time_mean) ) ); out_time_std_dev = sqrt(out_time_std_dev/out_time_n); if ( out_time_n > 1 ) { out_time_min_delta = *std::min_element(out_times.begin(), out_times.end()); out_time_max_delta = *std::max_element(out_times.begin(), out_times.end()); } double in_byte_mean = 0, out_byte_mean = 0; std::for_each( in_bytes.begin(), in_bytes.end(), (in_byte_mean += boost::lambda::_1) ); std::for_each( out_bytes.begin(), out_bytes.end(), (out_byte_mean += boost::lambda::_1) ); in_byte_mean /= duration; out_byte_mean /= duration; ROS_INFO_STREAM(" in bandwidth: " << std::fixed << std::setw(11) << std::setprecision(3) << in_byte_mean/1000*8 << " Kbps rate:" << std::fixed << std::setw(7) << std::setprecision(3) << in_time_rate << " hz min:" << std::fixed << std::setw(7) << std::setprecision(3) << in_time_min_delta << " s max: " << std::fixed << std::setw(7) << std::setprecision(3) << in_time_max_delta << " s std_dev: "<< std::fixed << std::setw(7) << std::setprecision(3) << in_time_std_dev << "s n: " << in_time_n); ROS_INFO_STREAM(" out bandwidth: " << std::fixed << std::setw(11) << std::setprecision(3) << out_byte_mean/1000*8 << " kbps rate:" << std::fixed << std::setw(7) << std::setprecision(3) << out_time_rate << " hz min:" << std::fixed << std::setw(7) << std::setprecision(3) << out_time_min_delta << " s max: " << std::fixed << std::setw(7) << std::setprecision(3) << out_time_max_delta << " s std_dev: "<< std::fixed << std::setw(7) << std::setprecision(3) << out_time_std_dev << "s n: " << out_time_n); in_times.clear(); in_bytes.clear(); out_times.clear(); out_bytes.clear(); last_rosinfo_time_ = now; } last_subscribe_time_ = now; if(use_snapshot_) { publish_once_ = false; } }
int getNumRGBSubscribers() { return realsense_reg_points_pub.getNumSubscribers() + realsense_rgb_image_pub.getNumSubscribers(); }
void imageCb(const sensor_msgs::ImageConstPtr& l_image, const sensor_msgs::CameraInfoConstPtr& l_cam_info, const sensor_msgs::ImageConstPtr& r_image, const sensor_msgs::CameraInfoConstPtr& r_cam_info) { ROS_INFO("In callback, seq = %u", l_cam_info->header.seq); // Convert ROS messages for use with OpenCV cv::Mat left, right; try { left = l_bridge_.imgMsgToCv(l_image, "mono8"); right = r_bridge_.imgMsgToCv(r_image, "mono8"); } catch (sensor_msgs::CvBridgeException& e) { ROS_ERROR("Conversion error: %s", e.what()); return; } cam_model_.fromCameraInfo(l_cam_info, r_cam_info); frame_common::CamParams cam_params; cam_params.fx = cam_model_.left().fx(); cam_params.fy = cam_model_.left().fy(); cam_params.cx = cam_model_.left().cx(); cam_params.cy = cam_model_.left().cy(); cam_params.tx = cam_model_.baseline(); if (vslam_system_.addFrame(cam_params, left, right)) { /// @todo Not rely on broken encapsulation of VslamSystem here int size = vslam_system_.sba_.nodes.size(); if (size % 2 == 0) { // publish markers sba::drawGraph(vslam_system_.sba_, cam_marker_pub_, point_marker_pub_); } // Publish VO tracks if (vo_tracks_pub_.getNumSubscribers() > 0) { frame_common::drawVOtracks(left, vslam_system_.vo_.frames, vo_display_); IplImage ipl = vo_display_; sensor_msgs::ImagePtr msg = sensor_msgs::CvBridge::cvToImgMsg(&ipl); msg->header = l_cam_info->header; vo_tracks_pub_.publish(msg, l_cam_info); } // Refine large-scale SBA. const int LARGE_SBA_INTERVAL = 10; if (size > 4 && size % LARGE_SBA_INTERVAL == 0) { ROS_INFO("Running large SBA on %d nodes", size); vslam_system_.refine(); } if (pointcloud_pub_.getNumSubscribers() > 0 && size % 2 == 0) publishRegisteredPointclouds(vslam_system_.sba_, vslam_system_.frames_, pointcloud_pub_); // Publish odometry data to tf. if (0) // TODO: Change this to parameter. { ros::Time stamp = l_cam_info->header.stamp; std::string image_frame = l_cam_info->header.frame_id; Eigen::Vector4d trans = -vslam_system_.sba_.nodes.back().trans; Eigen::Quaterniond rot = vslam_system_.sba_.nodes.back().qrot.conjugate(); trans.head<3>() = rot.toRotationMatrix()*trans.head<3>(); tf_transform_.setOrigin(tf::Vector3(trans(0), trans(1), trans(2))); tf_transform_.setRotation(tf::Quaternion(rot.x(), rot.y(), rot.z(), rot.w()) ); tf::Transform simple_transform; simple_transform.setOrigin(tf::Vector3(0, 0, 0)); simple_transform.setRotation(tf::Quaternion(.5, -.5, .5, .5)); tf_broadcast_.sendTransform(tf::StampedTransform(tf_transform_, stamp, image_frame, "visual_odom")); tf_broadcast_.sendTransform(tf::StampedTransform(simple_transform, stamp, "visual_odom", "pgraph")); // Publish odometry data on topic. if (odom_pub_.getNumSubscribers() > 0) { tf::StampedTransform base_to_image; tf::Transform base_to_visodom; try { tf_listener_.lookupTransform(image_frame, "/base_footprint", stamp, base_to_image); } catch (tf::TransformException ex) { ROS_WARN("%s",ex.what()); return; } base_to_visodom = tf_transform_.inverse() * base_to_image; geometry_msgs::PoseStamped pose; nav_msgs::Odometry odom; pose.header.frame_id = "/visual_odom"; pose.pose.position.x = base_to_visodom.getOrigin().x(); pose.pose.position.y = base_to_visodom.getOrigin().y(); pose.pose.position.z = base_to_visodom.getOrigin().z(); pose.pose.orientation.x = base_to_visodom.getRotation().x(); pose.pose.orientation.y = base_to_visodom.getRotation().y(); pose.pose.orientation.z = base_to_visodom.getRotation().z(); pose.pose.orientation.w = base_to_visodom.getRotation().w(); odom.header.stamp = stamp; odom.header.frame_id = "/visual_odom"; odom.child_frame_id = "/base_footprint"; odom.pose.pose = pose.pose; /* odom.pose.covariance[0] = 1; odom.pose.covariance[7] = 1; odom.pose.covariance[14] = 1; odom.pose.covariance[21] = 1; odom.pose.covariance[28] = 1; odom.pose.covariance[35] = 1; */ odom_pub_.publish(odom); } } } }