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,又可以編出像樣的界面,哈哈!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM