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 进行窗口程序设计
参考
- http://wiki.ros.org/visualization_msgs
- http://wiki.ros.org/visualization/Tutorials
- RViz Turorials http://wiki.ros.org/rviz
- RViz User Guid http://wiki.ros.org/rviz/UserGuide
前言
顾名思义, 标记工具就是在数据可视化的基础上加上用户自定义标记, 用来强调某种特征或者添加用户自己想加上的东西
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
帮助文档 http://wiki.ros.org/interactive_marker_tutorials
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, 又可以编出像样的界面, 哈哈!
来源: http://www.bubuko.com/infodetail-3110620.html