{"action":"created","issue":{"url":"https://api.github.com/repos/ros-visualization/rviz/issues/1215","repository_url":"https://api.github.com/repos/ros-visualization/rviz","labels_url":"https://api.github.com/repos/ros-visualization/rviz/issues/1215/labels{/name}","comments_url":"https://api.github.com/repos/ros-visualization/rviz/issues/1215/comments","events_url":"https://api.github.com/repos/ros-visualization/rviz/issues/1215/events","html_url":"https://github.com/ros-visualization/rviz/issues/1215","id":311851426,"number":1215,"title":"Migrating RViz DisplayContext to tf2","user":{"login":"IanTheEngineer","id":850874,"avatar_url":"https://avatars3.githubusercontent.com/u/850874?v=4","gravatar_id":"","url":"https://api.github.com/users/IanTheEngineer","html_url":"https://github.com/IanTheEngineer","followers_url":"https://api.github.com/users/IanTheEngineer/followers","following_url":"https://api.github.com/users/IanTheEngineer/following{/other_user}","gists_url":"https://api.github.com/users/IanTheEngineer/gists{/gist_id}","starred_url":"https://api.github.com/users/IanTheEngineer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IanTheEngineer/subscriptions","organizations_url":"https://api.github.com/users/IanTheEngineer/orgs","repos_url":"https://api.github.com/users/IanTheEngineer/repos","events_url":"https://api.github.com/users/IanTheEngineer/events{/privacy}","received_events_url":"https://api.github.com/users/IanTheEngineer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2018-04-06T05:22:59Z","updated_at":"2018-04-30T16:37:59Z","closed_at":null,"author_association":"NONE","body":"TLDR: is there any way of coaxing RViz DisplayContext to return a `tf2_ros::Buffer` pointer? If not, what will it take to upgrade RViz to `tf2`?\r\n\r\nA little more background: I am in the midst of migrating MoveIt! to `tf2`, hopefully targeting the ROS Melodic release. This migration was requested by @dirk-thomas as the starting point for eventually porting MoveIt! to ROS2: https://github.com/ros-planning/moveit/issues/745\r\n\r\nOne snag that I've run into is that RViz' [`DisplayContext` `FrameManager` returns a `tf::TransformListener`](https://github.com/ros-visualization/rviz/blob/kinetic-devel/src/rviz/display_context.h#L89-L93), rather than a `tf2_ros::Buffer`, even on the `ros2` branch:\r\n```\r\n/** @brief Return the FrameManager instance. */\r\nvirtual FrameManager* getFrameManager() const = 0;\r\n\r\n/** @brief Convenience function: returns getFrameManager()->getTFClient(). */\r\nvirtual tf::TransformListener* getTFClient() const = 0;\r\n```\r\nMoveIt! uses this pointer to initialize its [`MoveGroupInterface` for the `motion_planning_rviz_plugin`](https://github.com/ros-planning/moveit/blob/kinetic-devel/moveit_ros/visualization/motion_planning_rviz_plugin/src/motion_planning_frame.cpp#L302-L303)\r\n```\r\nmove_group_.reset(new moveit::planning_interface::MoveGroupInterface(\r\nopt, context_->getFrameManager()->getTFClientPtr(), ros::WallDuration(30, 0)));\r\n```\r\nIt will need to receive a pointer to a `tf2_ros::Buffer` object. I have ported nearly all of MoveIt! to `tf2`, and this is (hopefully) one of the last roadblocks :)"},"comment":{"url":"https://api.github.com/repos/ros-visualization/rviz/issues/comments/385454990","html_url":"https://github.com/ros-visualization/rviz/issues/1215#issuecomment-385454990","issue_url":"https://api.github.com/repos/ros-visualization/rviz/issues/1215","id":385454990,"user":{"login":"IanTheEngineer","id":850874,"avatar_url":"https://avatars3.githubusercontent.com/u/850874?v=4","gravatar_id":"","url":"https://api.github.com/users/IanTheEngineer","html_url":"https://github.com/IanTheEngineer","followers_url":"https://api.github.com/users/IanTheEngineer/followers","following_url":"https://api.github.com/users/IanTheEngineer/following{/other_user}","gists_url":"https://api.github.com/users/IanTheEngineer/gists{/gist_id}","starred_url":"https://api.github.com/users/IanTheEngineer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IanTheEngineer/subscriptions","organizations_url":"https://api.github.com/users/IanTheEngineer/orgs","repos_url":"https://api.github.com/users/IanTheEngineer/repos","events_url":"https://api.github.com/users/IanTheEngineer/events{/privacy}","received_events_url":"https://api.github.com/users/IanTheEngineer/received_events","type":"User","site_admin":false},"created_at":"2018-04-30T16:37:59Z","updated_at":"2018-04-30T16:37:59Z","author_association":"NONE","body":"The \"solution\" that I presented above doesn't elegantly handle the reference counting of the already-allocated `tf2_ros::Buffer` object, and seems to slice the `Transformer` object before the `Buffer` is accessible. The stack trace for the latter issue:\r\n```\r\nassertion=0x7ffff78f0dae \"px != 0\",\r\nfile=0x7ffff78f0d70 \"/usr/include/boost/smart_ptr/shared_ptr.hpp\",\r\nline=648,\r\nfunction=0x7ffff78f1360 <boost::shared_ptr<Transformer2>::operator->() const::__PRETTY_FUNCTION__> \"typename boost::detail::sp_member_access<T>::type boost::shared_ptr<T>::operator->() const [with T = Transformer2; typename boost::detail::sp_member_access<T>::type = Transformer2*]\") at assert.c:101\r\nNo locals.\r\n#4  0x00007ffff77b944f in boost::shared_ptr<Transformer2>::operator->() const ()\r\nfrom /data/users/imcmahon/dev/moveit_catkin/devel/.private/rviz/lib/librviz.so\r\nNo symbol table info available.\r\n#5  0x00007ffff77b3d97 in rviz::FrameManager::FrameManager(boost::shared_ptr<tf::TransformListener>) ()\r\nfrom /data/users/imcmahon/dev/moveit_catkin/devel/.private/rviz/lib/librviz.so\r\nNo symbol table info available.\r\n#6  0x00007ffff78c5d6e in rviz::VisualizationManager::VisualizationManager(rviz::RenderPanel*, rviz::WindowManagerInterface*, boost::shared_ptr<tf::TransformListener>) ()\r\nfrom /data/users/imcmahon/dev/moveit_catkin/devel/.private/rviz/lib/librviz.so\r\nNo symbol table info available.\r\n#7  0x00007ffff78b516d in rviz::VisualizationFrame::initialize(QString const&) ()\r\nfrom /data/users/imcmahon/dev/moveit_catkin/devel/.private/rviz/lib/librviz.so\r\nNo symbol table info available.\r\n#8  0x00007ffff78cf1e0 in rviz::VisualizerApp::init(int, char**) ()\r\nfrom /data/users/imcmahon/dev/moveit_catkin/devel/.private/rviz/lib/librviz.so\r\nNo symbol table info available.\r\n#9  0x00000000004011d2 in main ()\r\nNo symbol table info available.\r\n\r\n```\r\nI'll rebuild with symbols and replace the above stack trace.\r\n\r\nthe diff:\r\n```\r\ndiff --git a/src/rviz/frame_manager.cpp b/src/rviz/frame_manager.cpp\r\nindex 6d9136d..998d219 100644\r\n--- a/src/rviz/frame_manager.cpp\r\n+++ b/src/rviz/frame_manager.cpp\r\n@@ -32,10 +32,21 @@\r\n #include \"properties/property.h\"\r\n \r\n #include <tf/transform_listener.h>\r\n+#include <tf2_ros/buffer.h>\r\n+#include <tf2_ros/transform_listener.h>\r\n #include <ros/ros.h>\r\n \r\n #include <std_msgs/Float32.h>\r\n \r\n+class Transformer2 : public tf::Transformer\r\n+{\r\n+public:\r\n+    tf2_ros::Buffer& getBuffer()\r\n+    {\r\n+        return tf2_buffer_;\r\n+    }\r\n+};\r\n+\r\n namespace rviz\r\n {\r\n \r\n@@ -44,6 +55,8 @@ FrameManager::FrameManager(boost::shared_ptr<tf::TransformListener> tf)\r\n   if (!tf) tf_.reset(new tf::TransformListener(ros::NodeHandle(), ros::Duration(10*60), true));\r\n   else tf_ = tf;\r\n \r\n+  tf2_buffer_.reset(&boost::dynamic_pointer_cast<Transformer2>(tf_)->getBuffer());\r\n+\r\ndiff --git a/src/rviz/frame_manager.h b/src/rviz/frame_manager.h\r\nindex e75b5b6..61d7eee 100644\r\n--- a/src/rviz/frame_manager.h\r\n+++ b/src/rviz/frame_manager.h\r\n@@ -52,6 +52,12 @@ namespace tf\r\n class TransformListener;\r\n }\r\n \r\n+namespace tf2_ros\r\n+{\r\n+class Buffer;\r\n+class TransformListener;\r\n+}\r\n+\r\n namespace rviz\r\n {\r\n class Display;\r\n@@ -186,6 +192,9 @@ public:\r\n   /** @brief Return a boost shared pointer to the tf::TransformListener used to receive transform data. */\r\n   const boost::shared_ptr<tf::TransformListener>& getTFClientPtr() { return tf_; }\r\n \r\n+  /** @brief Return a shared pointer to the tf2_ros::Buffer object used to receive tf2 transform data. */\r\n+  const std::shared_ptr<tf2_ros::Buffer> getTFBufferPtr() { return tf2_buffer_; };\r\n+\r\n   /** @brief Create a description of a transform problem.\r\n    * @param frame_id The name of the frame with issues.\r\n    * @param stamp The time for which the problem was detected.\r\n@@ -266,6 +275,8 @@ private:\r\n   M_Cache cache_;\r\n \r\n   boost::shared_ptr<tf::TransformListener> tf_;\r\n+  std::shared_ptr<tf2_ros::Buffer> tf2_buffer_;\r\n\r\n\r\n```"}}
{"actor":{"display_login":"IanTheEngineer"}}