Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions ign_rviz_common/include/ignition/rviz/common/frame_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <ignition/math/Pose3.hh>

#include <QObject>
#include <QTimer>

#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
Expand Down Expand Up @@ -80,33 +81,27 @@ class FrameManager : public QObject

/**
* @brief Get available tf frames
* @param[out] _frames: List of available frames
* @return List of available frames
*/
void getFrames(std::vector<std::string> & _frames);
std::vector<std::string> getFrames();

/**
* @brief Get fixed frame
* @return Fixed frame
*/
std::string getFixedFrame();

protected:
/**
* @brief Callback function to received transform messages
* @param[in] _msg: Transform message
*/
void tf_callback(const tf2_msgs::msg::TFMessage::SharedPtr _msg);
public slots:
void updateFrameList();

private:
rclcpp::Node::SharedPtr node;
std::mutex tf_mutex_;
std::string fixedFrame;
std::vector<std::string> frameList;
std::shared_ptr<tf2_ros::Buffer> tfBuffer;
std::shared_ptr<tf2_ros::TransformListener> tfListener;
rclcpp::Subscription<tf2_msgs::msg::TFMessage>::SharedPtr subscriber;
std::unordered_map<std::string, ignition::math::Pose3d> tfTree;
tf2::TimePoint timePoint;
unsigned int frameCount;
QTimer frameListTimer;
};
} // namespace common
} // namespace rviz
Expand Down
125 changes: 47 additions & 78 deletions ign_rviz_common/src/rviz/common/frame_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,20 @@ namespace common
* Creates a tf subscription and binds callback to it.
*/
FrameManager::FrameManager(rclcpp::Node::SharedPtr _node)
: QObject(), frameCount(0)
: QObject(), node(std::move(_node))
{
this->node = std::move(_node);

tfBuffer = std::make_shared<tf2_ros::Buffer>(this->node->get_clock());
tfListener = std::make_shared<tf2_ros::TransformListener>(*tfBuffer);

this->subscriber = this->node->create_subscription<tf2_msgs::msg::TFMessage>(
"/tf", 10,
std::bind(&FrameManager::tf_callback, this, std::placeholders::_1));
frameList = getFrames();
connect(&frameListTimer, SIGNAL(timeout()), this, SLOT(updateFrameList()));
frameListTimer.start(1000);
}

////////////////////////////////////////////////////////////////////////////////
void FrameManager::setFixedFrame(const std::string & _fixedFrame)
{
std::lock_guard<std::mutex>(this->tf_mutex_);

this->tfTree.clear();
this->fixedFrame = _fixedFrame;

// Send fixed frame changed event
Expand All @@ -71,102 +67,75 @@ std::string FrameManager::getFixedFrame()
}

////////////////////////////////////////////////////////////////////////////////
void FrameManager::getFrames(std::vector<std::string> & _frames)
std::vector<std::string> FrameManager::getFrames()
{
tfBuffer->_getFrameStrings(_frames);
return tfBuffer->getAllFrameNames();
}

////////////////////////////////////////////////////////////////////////////////
void FrameManager::tf_callback(const tf2_msgs::msg::TFMessage::SharedPtr _msg)
bool FrameManager::getFramePose(const std::string & _frame, ignition::math::Pose3d & _pose)
{
std::lock_guard<std::mutex>(this->tf_mutex_);
tf_mutex_.lock();
std::string fixedFrame = this->fixedFrame;
tf_mutex_.unlock();

if (this->fixedFrame.empty()) {
RCLCPP_ERROR(this->node->get_logger(), "No frame id specified");
return;
if (fixedFrame.empty()) {
RCLCPP_ERROR(this->node->get_logger(), "No fixed frame specified");
return false;
}

std::vector<std::string> frame_ids;
tfBuffer->_getFrameStrings(frame_ids);
try {
geometry_msgs::msg::TransformStamped tf = tfBuffer->lookupTransform(
fixedFrame,
_frame, rclcpp::Time(0));

if (frame_ids.size() != this->frameCount) {
// Send frame list changed event
if (ignition::gui::App()) {
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild<ignition::gui::MainWindow *>(),
new events::FrameListChanged());
}
_pose = ignition::math::Pose3d(
tf.transform.translation.x,
tf.transform.translation.y,
tf.transform.translation.z,
tf.transform.rotation.w,
tf.transform.rotation.x,
tf.transform.rotation.y,
tf.transform.rotation.z);

this->frameCount = frame_ids.size();
return true;
} catch (tf2::TransformException & e) {
RCLCPP_WARN(this->node->get_logger(), e.what());
}

builtin_interfaces::msg::Time timeStamp = _msg->transforms[0].header.stamp;
timePoint =
tf2::TimePoint(
std::chrono::seconds(timeStamp.sec) +
std::chrono::nanoseconds(timeStamp.nanosec));

for (const auto frame : frame_ids) {
try {
/*
* TODO(Sarathkrishnan Ramesh): Reducing the tiemout for lookupTransform affects
* smoothness of tf visualization.
*/
geometry_msgs::msg::TransformStamped tf = tfBuffer->lookupTransform(
fixedFrame, timePoint,
frame, timePoint,
fixedFrame, tf2::Duration(5000));

tfTree[tf.child_frame_id] = ignition::math::Pose3d(
tf.transform.translation.x,
tf.transform.translation.y,
tf.transform.translation.z,
tf.transform.rotation.w,
tf.transform.rotation.x,
tf.transform.rotation.y,
tf.transform.rotation.z);
} catch (tf2::LookupException & e) {
RCLCPP_WARN(this->node->get_logger(), e.what());
} catch (tf2::ConnectivityException & e) {
RCLCPP_WARN(this->node->get_logger(), e.what());
} catch (tf2::ExtrapolationException & e) {
RCLCPP_WARN(this->node->get_logger(), e.what());
} catch (tf2::InvalidArgumentException & e) {
RCLCPP_WARN(this->node->get_logger(), e.what());
}
}
return false;
}

////////////////////////////////////////////////////////////////////////////////
bool FrameManager::getFramePose(const std::string & _frame, ignition::math::Pose3d & _pose)
bool FrameManager::getParentPose(const std::string & _child, ignition::math::Pose3d & _pose)
{
std::lock_guard<std::mutex>(this->tf_mutex_);

_pose = math::Pose3d::Zero;

auto it = this->tfTree.find(_frame);
if (it != tfTree.end()) {
_pose = it->second;
return true;
std::string parent;
// TODO(shrijitsingh99): The _getParent() API is only present for backwards compatability,
// use some alternative method instead
if (tfBuffer->_getParent(_child, tf2::TimePointZero, parent)) {
return this->getFramePose(parent, _pose);
}

return false;
}

////////////////////////////////////////////////////////////////////////////////
bool FrameManager::getParentPose(const std::string & _child, ignition::math::Pose3d & _pose)
void FrameManager::updateFrameList()
{
std::lock_guard<std::mutex>(this->tf_mutex_);

std::string parent;
bool parentAvailable = tfBuffer->_getParent(_child, this->timePoint, parent);

if (!parentAvailable) {
return false;
auto updatedFrameList = getFrames();
if (frameList != updatedFrameList) {
// Send frame list changed event
if (ignition::gui::App()) {
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild<ignition::gui::MainWindow *>(),
new events::FrameListChanged());
}
}

return this->getFramePose(parent, _pose);
frameList = std::move(updatedFrameList);
}


} // namespace common
} // namespace rviz
} // namespace ignition
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public slots:
/**
* @brief Callback when refresh button is pressed.
*/
void onRefresh();
void refresh();

private:
void setScale();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public slots:
/**
* @brief Callback when refresh button is pressed.
*/
void onRefresh();
void refresh();

private:
std::mutex lock;
Expand Down
9 changes: 8 additions & 1 deletion ign_rviz_plugins/res/qml/AxesDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Item {
text: "\u21bb"
Material.background: Material.primary
onClicked: {
AxesDisplay.onRefresh();
AxesDisplay.refresh();
}
}

Expand All @@ -51,6 +51,13 @@ Item {

AxesDisplay.setFrame(textAt(currentIndex));
}

Connections {
target: combo.popup
onAboutToShow: {
AxesDisplay.refresh();
}
}
}
}

Expand Down
9 changes: 8 additions & 1 deletion ign_rviz_plugins/res/qml/GlobalOptions.qml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Item {
text: "\u21bb"
Material.background: Material.primary
onClicked: {
GlobalOptions.onRefresh();
GlobalOptions.refresh();
}
}

Expand All @@ -56,6 +56,13 @@ Item {
GlobalOptions.setFrame(textAt(currentIndex));
}

Connections {
target: combo.popup
onAboutToShow: {
GlobalOptions.refresh();
}
}

Connections {
target: GlobalOptions
onSetCurrentIndex: {
Expand Down
13 changes: 6 additions & 7 deletions ign_rviz_plugins/src/rviz/plugins/AxesDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ bool AxesDisplay::eventFilter(QObject * object, QEvent * event)
}

// Update combo-box on frame list change
if (event->type() == rviz::events::FrameListChanged::kType) {
this->onRefresh();
}
// if (event->type() == rviz::events::FrameListChanged::kType) {
// this->onRefresh();
// }

return QObject::eventFilter(object, event);
}
Expand Down Expand Up @@ -148,7 +148,7 @@ void AxesDisplay::setFrameManager(std::shared_ptr<common::FrameManager> _frameMa
this->frame = this->frameManager->getFixedFrame();

// Update frame list
this->onRefresh();
this->refresh();
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -158,14 +158,13 @@ QStringList AxesDisplay::getFrameList() const
}

////////////////////////////////////////////////////////////////////////////////
void AxesDisplay::onRefresh()
void AxesDisplay::refresh()
{
// Clear
this->frameList.clear();

// Get updated list
std::vector<std::string> allFrames;
this->frameManager->getFrames(allFrames);
std::vector<std::string> allFrames = this->frameManager->getFrames();
std::sort(allFrames.begin(), allFrames.end());

this->frameList.push_back(QString::fromStdString("<Fixed Frame>"));
Expand Down
12 changes: 3 additions & 9 deletions ign_rviz_plugins/src/rviz/plugins/GlobalOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void GlobalOptions::setFrameManager(std::shared_ptr<common::FrameManager> _frame
this->frameList.clear();

// Update frame list
this->onRefresh();
this->refresh();
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -99,11 +99,6 @@ bool GlobalOptions::eventFilter(QObject * _object, QEvent * _event)
}
}

// Update combo-box on frame list change
if (_event->type() == rviz::events::FrameListChanged::kType) {
this->onRefresh();
}

return QObject::eventFilter(_object, _event);
}

Expand All @@ -121,11 +116,10 @@ QStringList GlobalOptions::getFrameList() const
}

////////////////////////////////////////////////////////////////////////////////
void GlobalOptions::onRefresh()
void GlobalOptions::refresh()
{
// Get updated list
std::vector<std::string> allFrames;
this->frameManager->getFrames(allFrames);
std::vector<std::string> allFrames = this->frameManager->getFrames();

if (allFrames.size() != 0) {
// Clear
Expand Down
7 changes: 3 additions & 4 deletions ign_rviz_plugins/src/rviz/plugins/TFDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,10 @@ void TFDisplay::refresh()
{
std::lock_guard<std::mutex>(this->lock);

std::vector<std::string> frames;
this->frameManager->getFrames(frames);
std::vector<std::string> allFrames = this->frameManager->getFrames();

if (frames.size() > 0) {
for (const auto frame : frames) {
if (allFrames.size() > 0) {
for (const auto frame : allFrames) {
this->frameInfo.insert({frame, true});
}

Expand Down