qt-ros(noetic)界面开发2:Qrviz学习

例程学习

蒋程扬大佬例程学习

自定义qrviz

1.cmakelist添加rviz依赖

# qt_build provides the qt cmake glue, roscpp the comms for a default talker
find_package(catkin REQUIRED COMPONENTS  roscpp sensor_msgs
    cv_bridge
    std_msgs
    image_transport
    rviz
    )

2.添加自定义qrviz类

头文件命名为*.hpp,避免可能的闪退
修改新增类文件所在目录到响应目录下,重新编译,如果还是找不到hpp文件重启qt

3.初始化

    //创建rviz panel
    render_panel_=new rviz::RenderPanel();
    //向layout添加
    layout->addWidget(render_panel_);
    //创建rviz控制对象
    manager_=new rviz::VisualizationManager(render_panel_);
    tool_manager_=manager_->getToolManager();
    ROS_ASSERT(manager_!=NULL);//防止闪退bug
    //初始化render_panel 实现放大缩小等操作
    render_panel_->initialize(manager_->getSceneManager(),manager_);

    manager_->setFixedFrame("map");
    //初始化rviz控制对象
    manager_->initialize();
    manager_->startUpdate();
    manager_->removeAllDisplays();

4.创建display

void qrviz::Display_LaserScan(QString laser_topic,bool enable)
{
    if(LaserScan_!=NULL)
    {
        delete LaserScan_;
        LaserScan_=NULL;
    }
    LaserScan_=manager_->createDisplay("rviz/LaserScan","myLaser",enable);
    LaserScan_->subProp("Topic")->setValue(laser_topic);
    ROS_ASSERT(LaserScan_!=NULL);
}

librviz学习

以下内容均来自librviz源码

1.rviz::RenderPanel

渲染窗口,显示initialize传入的场景Ogre::SceneManager* scene_manager,并将鼠标以及键盘事件传递给可视化管理器DisplayContext* manager。接口如下

/**
 * A widget which shows an OGRE-rendered scene in RViz.
 *
 * RenderPanel displays a scene and forwards mouse and key events to
 * the DisplayContext (which further forwards them to the active
 * Tool, etc.)
 */
  /** Constructor.  Ogre::Root::createRenderWindow() is called within. */
  RenderPanel(QWidget* parent = nullptr);
  ~RenderPanel() override;

  /** This sets up the Ogre::Camera for this widget. */
  void initialize(Ogre::SceneManager* scene_manager, DisplayContext* manager);

2.rviz::VisualizationManager

  • VisualizationManager 类是 rviz 的中心管理器类,包含所有显示、工具、ViewControllers 和其他管理器。
  • 它保存主渲染窗口的当前视图控制器。
  • 它有一个定时器,可在所有显示屏上调用 update()。 它创建并保存指向其他管理器对象的指针:选择管理器(SelectionManager)、框架管理器(FrameManager)、属性管理器(PropertyManager)和 Ogre::SceneManager 对象的指针。
    以下为部分接口:
class RVIZ_EXPORT VisualizationManager : public DisplayContext : public QObject
  /**
   * \brief Constructor
   * Creates managers and sets up global properties.
   * @param render_panel a pointer to the main render panel widget of the app.
   * @param wm a pointer to the window manager
   *        (which is really just a VisualizationFrame, the top-level container widget of rviz).
   * @param tf_buffer an (optional) pointer to the tf2_ros::Buffer to be used by the FrameManager
   * @param tf_listener an (optional) pointer to the tf2_ros::TransformListener to be used
   *        This listener's tf buffer needs to be the same as the passed tf_buffer!
   *        Both tf_buffer and tf_listener are automatically created if not provided.
   */
  explicit VisualizationManager(
      RenderPanel* render_panel,
      WindowManagerInterface* wm = nullptr,
      std::shared_ptr<tf2_ros::Buffer> tf_buffer = std::shared_ptr<tf2_ros::Buffer>(),
      std::shared_ptr<tf2_ros::TransformListener> tf_listener =
          std::shared_ptr<tf2_ros::TransformListener>());
  /**
   * \brief Do initialization that wasn't done in constructor.
   * Initializes tool manager, view manager, selection manager.
   */
  void initialize();

  /**
   * \brief Start timers.
   * Creates and starts the update and idle timers, both set to 30Hz (33ms).
   */
  void startUpdate();

  /*
   * \brief Stop the update timers. No Displays will be updated and no ROS
   *        callbacks will be called during this period.
   */
  void stopUpdate();

  /**
   * \brief Create and add a display to this panel, by class lookup name
   * @param class_lookup_name "lookup name" of the Display subclass, for pluginlib.
   *        Should be of the form "packagename/displaynameofclass", like "rviz/Image".
   * @param name The name of this display instance shown on the GUI, like "Left arm camera".
   * @param enabled Whether to start enabled
   * @return A pointer to the new display.
   */
  Display* createDisplay(const QString& class_lookup_name, const QString& name, bool enabled);

  /**
   * \brief Add a display to be managed by this panel
   * @param display The display to be added
   */
  void addDisplay(Display* display, bool enabled);

  /**
   * \brief Remove and delete all displays
   */
  void removeAllDisplays();

  /** @brief Load the properties of each Display and most editable rviz data.
   *
   * This is what is called when loading a "*.rviz" file.
   *
   * @param config The Config object to read from.  Expected to be a Config::Map type.
   * @sa save()
   */
  void load(const Config& config);

  /**
   * \brief Save the properties of each Display and most editable rviz
   *        data.
   *
   * This is what is called when saving a "*.vcg" file.
   * \param config The object to write to.
   * \sa loadDisplayConfig()
   */
  void save(Config config) const;

  /** @brief Return the fixed frame name.
   * @sa setFixedFrame() */
  QString getFixedFrame() const override;

  /** @brief Set the coordinate frame we should be transforming all fixed data into.
   * @param frame The name of the frame -- must match the frame name broadcast to libTF
   * @sa getFixedFrame() */
  void setFixedFrame(const QString& frame);

  /**
   * @brief Convenience function: returns getFrameManager()->getTF2BufferPtr().
   */
  std::shared_ptr<tf2_ros::Buffer> getTF2BufferPtr() const;

  /**
   * @brief Returns the Ogre::SceneManager used for the main RenderPanel.
   */
  Ogre::SceneManager* getSceneManager() const override
  {
    return scene_manager_;
  }

  /**
   * @brief Return the main RenderPanel.
   */
  RenderPanel* getRenderPanel() const
  {
    return render_panel_;
  }

  /**
   * @brief Return a pointer to the SelectionManager.
   */
  SelectionManager* getSelectionManager() const override
  {
    return selection_manager_;
  }

  /** @brief Return a pointer to the ToolManager. */
  ToolManager* getToolManager() const override
  {
    return tool_manager_;
  }

  /** @brief Return a pointer to the ViewManager. */
  ViewManager* getViewManager() const override
  {
    return view_manager_;
  }

  /**
   * @brief Return the window manager, if any.
   */
  WindowManagerInterface* getWindowManager() const override
  {
    return window_manager_;
  }

  /** @brief Return the FrameManager instance. */
  FrameManager* getFrameManager() const override
  {
    return frame_manager_;
  }

  /** @brief Return the current value of the frame count.
   *
   * The frame count is just a number which increments each time a
   * frame is rendered.  This lets clients check if a new frame has
   * been rendered since the last time they did something. */
  uint64_t getFrameCount() const override
  {
    return frame_count_;
  }

  /** @brief Return a factory for creating Display subclasses based on a class id string. */
  DisplayFactory* getDisplayFactory() const override
  {
    return display_factory_;
  }

  PropertyTreeModel* getDisplayTreeModel() const
  {
    return display_property_tree_model_;
  }

3.rviz::Display

例程实现Display基本都是用VisualizationManager::createDisplay
设置Display属性使用Property::subProp()->setValue(map_topic)

class RVIZ_EXPORT Display : public BoolProperty : public Property : public QObject
  /**
   * \brief Create and add a display to this panel, by class lookup name
   * @param class_lookup_name "lookup name" of the Display subclass, for pluginlib.
   *        Should be of the form "packagename/displaynameofclass", like "rviz/Image".
   * @param name The name of this display instance shown on the GUI, like "Left arm camera".
   * @param enabled Whether to start enabled
   * @return A pointer to the new display.
   */
  Display* createDisplay(const QString& class_lookup_name, const QString& name, bool enabled);
  /** @brief Return the first child Property with the given name, or
   * the FailureProperty if no child has the name.
   *
   * If no child is found with the given name, an instance of a
   * special Property subclass named FailureProperty is returned and
   * an error message is printed to stdout.
   * FailureProperty::subProp() always returns itself, which means you
   * can safely chain a bunch of subProp() calls together and not have
   * a crash even if one of the sub-properties does not actually
   * exist.  For instance:
   *
   *     float width = prop->subProp( "Dimenshons" )->subProp( "Width" )->getValue().toFloat();
   *
   * If the first property @c prop has a "Dimensions" property but not
   * a "Dimenshons" one, @c width will end up set to 0 and an error
   * message will be printed, but the program will not crash here.
   *
   * This is an Order(N) operation in the number of subproperties. */
  virtual Property* subProp(const QString& sub_name);
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值