7.15-ROS可视化工具-标记

ROS标记工具

TOC

参考

visualization_msgs
Tutorials
RViz Turorials
RViz User Guid

前言

  • 顾名思义,标记工具就是在数据可视化的基础上加上用户自定义标记,用来强调某种特征或者添加用户自己想加上的东西
  • visualization stack 现在已经包含到RViz中,但是我们主要还是要学习这个包集中的东西

visuallization_msgs/markers

Sending Basic Shapes to RViz

基本原理

  • 注册一个visualization::marker消息,定义好,然后发出去,RViz在收到后在指定位置显示特定形状

关键代码

  • package.xml
catkin_create_pkg using_markers roscpp visualization_msgs
  • CMakeList.txt
add_executable(basic_shapes src/basic_shapes.cpp)
target_link_libraries(basic_shapes ${catkin_LIBRARIES})
  • .cpp
#include <visualization_msgs/Marker.h>
ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 1);
uint32_t shape = visualization_msgs::Marker::CUBE;
    visualization_msgs::Marker marker;
// Set the frame ID and timestamp.  See the TF tutorials for information on these.
marker.header.frame_id = "/my_frame";
marker.header.stamp = ros::Time::now();
// Set the namespace and id for this marker.  This serves to create a unique ID
// Any marker sent with the same namespace and id will overwrite the old one
marker.ns = "basic_shapes";
marker.id = 0;
// Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
marker.type = shape;
// Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
marker.action = visualization_msgs::Marker::ADD;

// Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
marker.pose.position.x = 0;
marker.pose.position.y = 0;
marker.pose.position.z = 0;
marker.pose.orientation.x = 0.0;
marker.pose.orientation.y = 0.0;
marker.pose.orientation.z = 0.0;
marker.pose.orientation.w = 1.0;
// Set the scale of the marker -- 1x1x1 here means 1m on a side
marker.scale.x = 1.0;
marker.scale.y = 1.0;
marker.scale.z = 1.0;
// Set the color -- be sure to set alpha to something non-zero!
marker.color.r = 0.0f;
marker.color.g = 1.0f;
marker.color.b = 0.0f;
marker.color.a = 1.0;
marker.lifetime = ros::Duration();
// Publish the marker
while (marker_pub.getNumSubscribers() < 1)
{
    if (!ros::ok())
    {
        return 0;
    }
    ROS_WARN_ONCE("Please create a subscriber to the marker");
    sleep(1);
}
marker_pub.publish(marker);

Sending Points and lines

  • 本质同发送基本形状,都是定义一个消息,然后发送即可,只是点和线可能是数组数据结构,定义起来麻烦一点

Interactive Marker

基本原理

  • 不仅是将特定形状显示在RViz中,而且用户可以使用鼠标和上下文菜单进行交互,从而实现更复杂的任务
  • 依然是由消息类型来定义,visualization_msgs/InteractiveMarker,这个消息包含一个上下文菜单,多个控件(visualization_msgs/InteractiveMarkerControl消息类型表示)。这些控件用来定义交互式标记的各个部分,每一部分都有不同功能。
  • 要使用交互式标记,需要在节点中实例化一个InteractiveMarkerServer对象,作为与RViz联系的代理服务器,RViz作为客户端向节点发送不同的消息通知,以此来产生交互。
  • 相关的消息类型有
    • visualization_msgs/InteractiveMarker
    • visualization_msgs/InteractiveMarkerControl
    • visualization_msgs/InteractiveMarkerFeedback
      此外还有MenuHandler
  • 帮助文档

Simple Interactive Marker Server

  • 关键思想
    • InteractiveMarker-->control-->Marker,标记包含控件,类间是组合关系,均是一对多。
    • 咦?为什么同时有将control赋给marker的属性和将marker赋给control的属性?原来如此
    • Server给RViz发送Update消息,RViz给Server发送Feedback,Server处定义对Feedback的响应函数
  • 关键代码
#include <ros/ros.h>

#include <interactive_markers/interactive_marker_server.h>

void processFeedback(
    const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
{
  ROS_INFO_STREAM( feedback->marker_name << " is now at "
      << feedback->pose.position.x << ", " << feedback->pose.position.y
      << ", " << feedback->pose.position.z );
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "simple_marker");

  // create an interactive marker server on the topic namespace simple_marker
  interactive_markers::InteractiveMarkerServer server("simple_marker");

  // create an interactive marker for our server
  visualization_msgs::InteractiveMarker int_marker;
  int_marker.header.frame_id = "base_link";
  int_marker.header.stamp=ros::Time::now();
  int_marker.name = "my_marker";
  int_marker.description = "Simple 1-DOF Control";

  // create a grey box marker
  visualization_msgs::Marker box_marker;
  box_marker.type = visualization_msgs::Marker::CUBE;
  box_marker.scale.x = 0.45;
  box_marker.scale.y = 0.45;
  box_marker.scale.z = 0.45;
  box_marker.color.r = 0.5;
  box_marker.color.g = 0.5;
  box_marker.color.b = 0.5;
  box_marker.color.a = 1.0;

  // create a non-interactive control which contains the box
  visualization_msgs::InteractiveMarkerControl box_control;
  box_control.always_visible = true;
  box_control.markers.push_back( box_marker );

  // add the control to the interactive marker
  int_marker.controls.push_back( box_control );

  // create a control which will move the box
  // this control does not contain any markers,
  // which will cause RViz to insert two arrows
  visualization_msgs::InteractiveMarkerControl rotate_control;
  rotate_control.name = "move_x";
  rotate_control.interaction_mode =
      visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;

  // add the control to the interactive marker
  int_marker.controls.push_back(rotate_control);

  // add the interactive marker to our collection &
  // tell the server to call processFeedback() when feedback arrives for it
  server.insert(int_marker, &processFeedback);

  // 'commit' changes and send to all clients
  server.applyChanges();

  // start the ROS main loop
  ros::spin();
}

Basic Control

  • 告诉你怎样制作一个6-DOF的控件(包括在控制时控件和场景一起移动的,和控件固定的)
  • 关键代码

按钮

  • 基本思路
    • 就像菜单栏中的按钮一样
    • 默认是响应鼠标左键
  • 关键代码
https://raw.githubusercontent.com/ros-visualization/visualization_tutorials/groovy-devel/interactive_marker_tutorials/src/basic_controls.cpp

Context Menu

  • 基本思路
    • 将静态菜单附着到一个交互式标记(Interactive Marker)上

多客户端单服务器交互

  • 意义
    • 可以同时有多个RViz客户端控制一个或多个交互式控件Marker
    • 这个例子实现了一个简易乒乓球游戏
    • 以后再学吧。

为RViz写插件

  • 感觉没有学这个的需求啊。。。

使用QT和librviz进行窗口程序设计

  • 这个相当于是使用QT对RViz进行简单的二次开发,感觉应该要学,既不需要深度了解QT,又可以编出像样的界面,哈哈!
原文地址:https://www.cnblogs.com/lizhensheng/p/11117585.html