ROS 2 Humble Hawksbill 图形工具 rqt

rqt包全家福:

ros-humble-rqt-action                ros-humble-rqt-image-overlay-dbgsym  ros-humble-rqt-robot-dashboard
ros-humble-rqt-bag                   ros-humble-rqt-image-overlay-layer   ros-humble-rqt-robot-monitor
ros-humble-rqt-bag-plugins           ros-humble-rqt-image-view            ros-humble-rqt-robot-steering
ros-humble-rqt-common-plugins        ros-humble-rqt-image-view-dbgsym     ros-humble-rqt-runtime-monitor
ros-humble-rqt-console               ros-humble-rqt-moveit                ros-humble-rqt-service-caller
ros-humble-rqt-graph                 ros-humble-rqt-msg                   ros-humble-rqt-shell
ros-humble-rqt-gui                   ros-humble-rqt-plot                  ros-humble-rqt-srv
ros-humble-rqt-gui-cpp               ros-humble-rqt-publisher             ros-humble-rqt-top
ros-humble-rqt-gui-cpp-dbgsym        ros-humble-rqt-py-common             ros-humble-rqt-topic
ros-humble-rqt-gui-py                ros-humble-rqt-py-console
ros-humble-rqt-image-overlay         ros-humble-rqt-reconfigure

输入rqt即可使用,全部窗口操作。

ROS 2 Humble Hawksbill 图形工具 rqt

简介:rqt 是一个 GUI 框架,能够将各种插件工具加载为可停靠窗口。 当前没有选择插件。 要添加插件,请从插件菜单中选择项目。还可以使用 Perspectives 菜单将插件的特定排列保存为透视图。 

插件有如下:

ROS 2 Humble Hawksbill 图形工具 rqt

ROS 2 Humble Hawksbill 图形工具 rqt

以concole为例,ROS 2 的记录器级别按严重性排序:

  1. Fatal
  2. Error
  3. Warn
  4. Info
  5. Debug

每个级别表示的内容没有确切的标准,但可以安全地假设:

  1. 致命消息Fatal表明系统将终止以试图保护自己免受损害。
  2. 错误消息Error表明重大问题不一定会损坏系统,但会阻止系统正常运行。
  3. 警告消息Warn表示可能代表更深层次问题的意外活动或非理想结果,但不会直接损害功能。
  4. 信息消息Info指示事件和状态更新,作为系统按预期运行的视觉验证。
  5. 调试消息Debug详细说明了系统执行的整个逐步过程。

默认级别为信息。 只会看到默认严重级别和更严重级别的消息。

通常,只有 Debug 消息被隐藏,因为它们是唯一没有 Info 严重的级别。 例如,如果将默认级别设置为 Warn,将只能看到严重性为 Warn、Error 和 Fatal 的消息。

例如将小乌龟节点设置级别:

ros2 run turtlesim turtlesim_node –ros-args –log-level WARN

对比如下两段代码分别用Python和C++实现类似功能:

Python

import os

from python_qt_binding.QtCore import qDebug, qWarning
from qt_gui.composite_plugin_provider import CompositePluginProvider

import rclpy
from rqt_gui.ros2_plugin_context import Ros2PluginContext
from rqt_gui.rospkg_plugin_provider import RospkgPluginProvider
from rqt_gui_py.rclpy_spinner import RclpySpinner


class RosPyPluginProvider(CompositePluginProvider):

    def __init__(self):
        super(RosPyPluginProvider, self).__init__(
            [RospkgPluginProvider('rqt_gui', 'rqt_gui_py::Plugin')])
        self.setObjectName('RosPyPluginProvider')
        self._node_initialized = False
        self._node = None
        self._spinner = None
        self._shutdown_timeout = 2000

    def shutdown(self):
        qDebug('Shutting down RosPyPluginProvider')
        if self._spinner:
            self._spinner.quit()
            joined = self._spinner.wait(msecs=self._shutdown_timeout)
            if not joined:
                qWarning('Timed out attempting to join the RclpySpinner thread')
                return
        if self._node:
            self._destroy_node()
        super().shutdown()

    def load(self, plugin_id, plugin_context):
        self._init_node()
        ros_plugin_context = Ros2PluginContext(handler=plugin_context._handler, node=self._node)

        return super(RosPyPluginProvider, self).load(plugin_id, ros_plugin_context)

    def unload(self, plugin_instance):
        return super(RosPyPluginProvider, self).unload(plugin_instance)

    def _init_node(self):
        # initialize node once
        if not self._node_initialized:
            name = 'rqt_gui_py_node_%d' % os.getpid()
            qDebug('RosPyPluginProvider._init_node() initialize ROS node "%s"' % name)
            if not rclpy.ok():
                rclpy.init()
            self._node = rclpy.create_node(name)
            self._spinner = RclpySpinner(self._node)
            self._spinner.start()
            self._node_initialized = True

    def _destroy_node(self):
        if self._node_initialized:
            self._node.destroy_node()
            rclpy.shutdown()
            self._node_initialized = False

C++ 

#include "roscpp_plugin_provider.h"

#include "nodelet_plugin_provider.h"
#include <rqt_gui_cpp/plugin.h>

#include <qt_gui_cpp/plugin_provider.h>
#include <rclcpp/rclcpp.hpp>

#include <pluginlib/class_list_macros.hpp>

#include <stdexcept>
#include <sys/types.h>

namespace rqt_gui_cpp {

RosCppPluginProvider::RosCppPluginProvider()
  : qt_gui_cpp::CompositePluginProvider()
  , rclcpp_initialized_(false)
{
  if (rclcpp::ok())
  {
    rclcpp_initialized_ = true;
  }

  init_rclcpp();
  QList<PluginProvider*> plugin_providers;
  plugin_providers.append(new NodeletPluginProvider("rqt_gui", "rqt_gui_cpp::Plugin"));
  set_plugin_providers(plugin_providers);
}

RosCppPluginProvider::~RosCppPluginProvider()
{
  if (rclcpp::ok())
  {
    rclcpp::shutdown();
  }
}

void* RosCppPluginProvider::load(const QString& plugin_id, qt_gui_cpp::PluginContext* plugin_context)
{
  qDebug("RosCppPluginProvider::load(%s)", plugin_id.toStdString().c_str());
  init_rclcpp();
  return qt_gui_cpp::CompositePluginProvider::load(plugin_id, plugin_context);
}

qt_gui_cpp::Plugin* RosCppPluginProvider::load_plugin(const QString& plugin_id, qt_gui_cpp::PluginContext* plugin_context)
{
  qDebug("RosCppPluginProvider::load_plugin(%s)", plugin_id.toStdString().c_str());
  init_rclcpp();
  return qt_gui_cpp::CompositePluginProvider::load_plugin(plugin_id, plugin_context);
}

void RosCppPluginProvider::init_rclcpp()
{
  // initialize ROS node once
  if (!rclcpp_initialized_)
  {
    int argc = 0;
    char** argv = 0;

    // Initialize any global resources needed by the middleware and the client library.
    // This will also parse command line arguments one day (as of Beta 1 they are not used).
    // You must call this before using any other part of the ROS system.
    // This should be called once per process.
    rclcpp::init(argc, argv);


    // Don't do this again in this process
    rclcpp_initialized_ = true;
  }
}

}

PLUGINLIB_EXPORT_CLASS(rqt_gui_cpp::RosCppPluginProvider, qt_gui_cpp::PluginProvider)

 

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年5月28日
下一篇 2022年5月28日

相关推荐