@@ -64,6 +64,26 @@ namespace web_video_server
6464namespace streamers
6565{
6666
67+ namespace
68+ {
69+
70+ std::vector<std::string> get_image_topics (const rclcpp::Node::SharedPtr & node)
71+ {
72+ std::vector<std::string> result;
73+ auto topic_names_and_types = node->get_topic_names_and_types ();
74+ for (const auto & topic_and_types : topic_names_and_types) {
75+ for (const auto & type : topic_and_types.second ) {
76+ if (type == " sensor_msgs/msg/Image" ) {
77+ result.push_back (topic_and_types.first );
78+ break ;
79+ }
80+ }
81+ }
82+ return result;
83+ }
84+
85+ } // namespace
86+
6787ImageTransportStreamerBase::ImageTransportStreamerBase (
6888 const async_web_server_cpp::HttpRequest & request,
6989 async_web_server_cpp::HttpConnectionPtr connection, rclcpp::Node::SharedPtr node)
@@ -126,28 +146,8 @@ void ImageTransportStreamerBase::restream_frame(std::chrono::duration<double> ma
126146 if (inactive_ || !initialized_) {
127147 return ;
128148 }
129- try {
130- if (last_frame_ + max_age < std::chrono::steady_clock::now ()) {
131- std::scoped_lock lock (send_mutex_);
132- // don't update last_frame, it may remain an old value.
133- send_image (output_size_image, std::chrono::steady_clock::now ());
134- }
135- } catch (boost::system::system_error & e) {
136- // happens when client disconnects
137- RCLCPP_DEBUG (node_->get_logger (), " system_error exception: %s" , e.what ());
138- inactive_ = true ;
139- return ;
140- } catch (std::exception & e) {
141- auto & clk = *node_->get_clock ();
142- RCLCPP_ERROR_THROTTLE (node_->get_logger (), clk, 40 , " exception: %s" , e.what ());
143- inactive_ = true ;
144- return ;
145- } catch (...) {
146- auto & clk = *node_->get_clock ();
147- RCLCPP_ERROR_THROTTLE (node_->get_logger (), clk, 40 , " exception" );
148- inactive_ = true ;
149- return ;
150- }
149+
150+ try_send_image (output_size_image, last_frame_);
151151}
152152
153153void ImageTransportStreamerBase::image_callback (const sensor_msgs::msg::Image::ConstSharedPtr & msg)
@@ -191,17 +191,28 @@ void ImageTransportStreamerBase::image_callback(const sensor_msgs::msg::Image::C
191191 }
192192
193193 last_frame_ = std::chrono::steady_clock::now ();
194- send_image (output_size_image, last_frame_);
195194 } catch (cv_bridge::Exception & e) {
196195 auto & clk = *node_->get_clock ();
197196 RCLCPP_ERROR_THROTTLE (node_->get_logger (), clk, 40 , " cv_bridge exception: %s" , e.what ());
198197 inactive_ = true ;
199198 return ;
200199 } catch (cv::Exception & e) {
201200 auto & clk = *node_->get_clock ();
202- RCLCPP_ERROR_THROTTLE (node_->get_logger (), clk, 40 , " cv_bridge exception: %s" , e.what ());
201+ RCLCPP_ERROR_THROTTLE (node_->get_logger (), clk, 40 , " OpenCV exception: %s" , e.what ());
203202 inactive_ = true ;
204203 return ;
204+ }
205+
206+ try_send_image (output_size_image, last_frame_);
207+ }
208+
209+ void ImageTransportStreamerBase::try_send_image (
210+ const cv::Mat & img,
211+ const std::chrono::steady_clock::time_point & time)
212+ {
213+ try {
214+ std::scoped_lock lock (send_mutex_);
215+ send_image (img, std::chrono::steady_clock::now ());
205216 } catch (boost::system::system_error & e) {
206217 // happens when client disconnects
207218 RCLCPP_DEBUG (node_->get_logger (), " system_error exception: %s" , e.what ());
@@ -243,33 +254,13 @@ cv::Mat ImageTransportStreamerBase::decode_image(
243254std::vector<std::string> ImageTransportStreamerFactoryBase::get_available_topics (
244255 rclcpp::Node::SharedPtr node)
245256{
246- std::vector<std::string> result;
247- auto tnat = node->get_topic_names_and_types ();
248- for (auto topic_and_types : tnat) {
249- for (auto & type : topic_and_types.second ) {
250- if (type == " sensor_msgs/msg/Image" ) {
251- result.push_back (topic_and_types.first );
252- break ;
253- }
254- }
255- }
256- return result;
257+ return get_image_topics (node);
257258}
258259
259260std::vector<std::string> ImageTransportSnapshotStreamerFactoryBase::get_available_topics (
260261 rclcpp::Node::SharedPtr node)
261262{
262- std::vector<std::string> result;
263- auto tnat = node->get_topic_names_and_types ();
264- for (auto topic_and_types : tnat) {
265- for (auto & type : topic_and_types.second ) {
266- if (type == " sensor_msgs/msg/Image" ) {
267- result.push_back (topic_and_types.first );
268- break ;
269- }
270- }
271- }
272- return result;
263+ return get_image_topics (node);
273264}
274265
275266} // namespace streamers
0 commit comments