ROS标记工具
ROS标记工具
参考
前言
visuallization_msgs/markers
Sending Basic Shapes to RViz
基本原理
关键代码
Sending Points and lines
Interactive Marker
基本原理
Simple Interactive Marker Server
Basic Control
按钮
Context Menu
多客户端单服务器交互
为RViz写插件
使用QT和librviz进行窗口程序设计
TOC
参考
前言
visuallization_msgs/markers
Sending Basic Shapes to RViz
基本原理
关键代码
Sending Points and lines
Interactive Marker
基本原理
Simple Interactive Marker Server
Basic Control
按钮
Context Menu
多客户端单服务器交互
为RViz写插件
使用QT和librviz进行窗口程序设计
参考
前言
- 顾名思义,标记工具就是在数据可视化的基础上加上用户自定义标记,用来强调某种特征或者添加用户自己想加上的东西
- 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,又可以编出像样的界面,哈哈!