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進行窗口程序設計
參考
前言
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,又可以編出像樣的界面,哈哈!