-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ImageTransportManager which handles the image_transport subscri…
…ptions to ensure that work is not performed multiple times if multiple ImageTransportSubscribers subscribe to the same camera. Added throttleRate to enable throttling of camera messages.
- Loading branch information
1 parent
e899e50
commit b475332
Showing
12 changed files
with
699 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
============== | ||
ImageTransport | ||
============== | ||
|
||
Seeing what the robot sees is one of the most important features of any user interface. | ||
To enable this, this library provides the :cpp:class:`ImageTransportSubscriber <qml_ros_plugin::ImageTransportSubscriber>`. | ||
It allows easy subscription of camera messages and provides them in a QML native format as a VideoSource. | ||
|
||
Example: | ||
|
||
.. code-block:: qml | ||
ImageTransportSubscriber { | ||
id: imageSubscriber | ||
// Enter a valid image topic here | ||
topic: "/front_rgbd_cam/color/image_rect_color" | ||
// This is the default transport, change if compressed is not available | ||
defaultTransport: "compressed" | ||
} | ||
VideoOutput { | ||
anchors.fill: parent | ||
// Can be used in increments of 90 to rotate the video | ||
orientation: 90 | ||
source: imageSubscriber | ||
} | ||
The :cpp:class:`ImageTransportSubscriber <qml_ros_plugin::ImageTransportSubscriber>` can be used as the source of a | ||
``VideoOutput`` to display the camera images as they are received. | ||
Additionally, it can be configured to show a blank image after x milliseconds using the ``timeout`` property which is set | ||
to 3000ms (3s) by default. This can be disabled by setting the ``timeout`` to 0. | ||
If you do not want the full camera rate, you can throttle the rate by setting ``throttleRate`` to a value greater than 0 | ||
(which is the default and disables throttling). E.g. a rate of 0.2 would show a new frame every 5 seconds. | ||
Since there is no ROS functionality for a throttled subscription, this means the ``image_transport::Subscriber`` is shut | ||
down and newly subscribed for each frame. This comes at some overhead, hence, it should only be used to throttle to low | ||
rates <1. | ||
To avoid all throttled subscribers subscribing at the same time causing huge network spikes, the throttled rates are | ||
load balanced by default. This can be disabled globally using | ||
:cpp:func:`ImageTransportManager::setLoadBalancingEnabled <qml_ros_plugin::ImageTransportManagerSingletonWrapper::setLoadBalancingEnabled>` | ||
which is available in QML using the singleton ``ImageTransportManager``. | ||
|
||
API | ||
--- | ||
|
||
.. doxygenclass:: qml_ros_plugin::ImageTransportSubscriber | ||
:members: | ||
|
||
.. doxygenclass:: qml_ros_plugin::ImageTransportManagerSingletonWrapper | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// | ||
// Created by stefan on 22.02.21. | ||
// | ||
|
||
#ifndef QML_ROS_PLUGIN_IMAGE_TRANSPORT_MANAGER_H | ||
#define QML_ROS_PLUGIN_IMAGE_TRANSPORT_MANAGER_H | ||
|
||
#include "qml_ros_plugin/node_handle.h" | ||
|
||
#include <image_transport/image_transport.h> | ||
#include <QAbstractVideoSurface> | ||
|
||
namespace qml_ros_plugin | ||
{ | ||
class ImageTransportSubscriptionHandle; | ||
|
||
class ImageTransportManagerSingletonWrapper : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
//! @copydoc ImageTransportManager::setLoadBalancingEnabled | ||
Q_INVOKABLE void setLoadBalancingEnabled( bool value ); | ||
}; | ||
|
||
/*! | ||
* Encapsulates the image transport communication to share the subscription resources, avoiding multiple conversions of | ||
* the same image and subscription overhead if multiple cameras are set to throttle. | ||
*/ | ||
class ImageTransportManager | ||
{ | ||
ImageTransportManager(); | ||
|
||
struct SubscriptionManager; | ||
struct Subscription; | ||
public: | ||
|
||
static ImageTransportManager &getInstance(); | ||
|
||
//! Sets whether the manager should try to balance throttled subscriptions_ to ensure they don't update at the same | ||
//! time which would result in network spikes. | ||
void setLoadBalancingEnabled( bool value ); | ||
|
||
/*! | ||
* Note: Can only be called with a ready NodeHandle! | ||
* | ||
* Subscribes to the given topic with the given settings. Makes sure that multiple subscriptions_ (especially throttled) | ||
* only result in a single (throttled) subscription. | ||
* If multiple subscriptions_ of the same topic and namespace are created, the settings of the first subscription are used. | ||
* Except for the throttle interval where the minimum value across all active subscriptions_ is used. | ||
* @param nh The NodeHandle the subscription is made from if it is the first subscribe call | ||
* @param qtopic | ||
* @param queue_size | ||
* @param transport_hints | ||
* @param callback | ||
* @param surface | ||
* @param throttle_interval | ||
* @return | ||
*/ | ||
std::shared_ptr<ImageTransportSubscriptionHandle> | ||
subscribe( const NodeHandle::Ptr &nh, const QString &qtopic, quint32 queue_size, | ||
const image_transport::TransportHints &transport_hints, | ||
const std::function<void( const QVideoFrame & )> &callback, QAbstractVideoSurface *surface = nullptr, | ||
int throttle_interval = 0 ); | ||
|
||
private: | ||
int getLoadBalancedTimeout( int desired_throttle_interval ); | ||
|
||
std::map<std::string, std::shared_ptr<SubscriptionManager>> subscriptions_; | ||
std::vector<long> timeouts_; | ||
bool load_balancing_enabled_ = true; | ||
|
||
friend class ImageTransportSubscriptionHandle; | ||
}; | ||
|
||
class ImageTransportSubscriptionHandle | ||
{ | ||
public: | ||
|
||
~ImageTransportSubscriptionHandle(); | ||
|
||
//! The interval the subscription waits between receiving images. | ||
int throttleInterval() const { return throttle_interval; } | ||
|
||
//! Set the interval the subscription may wait between images. | ||
//! The images may still arrive at a higher rate if other subscriptions_ request it. | ||
void updateThrottleInterval( int interval ); | ||
|
||
std::string getTopic(); | ||
|
||
private: | ||
int throttle_interval = 0; | ||
std::shared_ptr<ImageTransportManager::Subscription> subscription; | ||
QAbstractVideoSurface *surface = nullptr; | ||
std::function<void( const QVideoFrame & )> callback; | ||
|
||
friend class ImageTransportManager; | ||
}; | ||
} | ||
|
||
#endif //QML_ROS_PLUGIN_IMAGE_TRANSPORT_MANAGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.