前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ROS1云课→14可视化交互

ROS1云课→14可视化交互

作者头像
zhangrelay
发布2022-09-26 10:43:30
1.3K0
发布2022-09-26 10:43:30
举报
文章被收录于专栏:机器人课程与技术

ROS1云课→13三维可视化工具rviz


上一节,可视化点云案例常用于显示深度视觉或三维激光雷达数据,那么rviz是否支持输入呢?

InteractiveMarker

官方示例代码(C++):

代码语言:javascript
复制
/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


#include <ros/ros.h>

#include <interactive_markers/interactive_marker_server.h>

#include <math.h>

#include <tf/LinearMath/Vector3.h>


using namespace visualization_msgs;

boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;

std::vector< tf::Vector3 > positions;

void processFeedback( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
{
  switch ( feedback->event_type )
  {
    case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
    {
      //compute difference vector for this cube

      tf::Vector3 fb_pos(feedback->pose.position.x, feedback->pose.position.y, feedback->pose.position.z);
      unsigned index = atoi( feedback->marker_name.c_str() );

      if ( index > positions.size() )
      {
        return;
      }
      tf::Vector3 fb_delta = fb_pos - positions[index];

      // move all markers in that direction
      for ( unsigned i=0; i<positions.size(); i++ )
      {
        float d = fb_pos.distance( positions[i] );
        float t = 1 / (d*5.0+1.0) - 0.2;
        if ( t < 0.0 ) t=0.0;

        positions[i] += t * fb_delta;

        if ( i == index ) {
          ROS_INFO_STREAM( d );
          positions[i] = fb_pos;
        }

        geometry_msgs::Pose pose;
        pose.position.x = positions[i].x();
        pose.position.y = positions[i].y();
        pose.position.z = positions[i].z();

        std::stringstream s;
        s << i;
        server->setPose( s.str(), pose );
      }


      break;
    }
  }
  server->applyChanges();
}

InteractiveMarkerControl& makeBoxControl( InteractiveMarker &msg )
{
  InteractiveMarkerControl control;
  control.always_visible = true;
  control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
  control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
  control.independent_marker_orientation = true;

  Marker marker;

  marker.type = Marker::CUBE;
  marker.scale.x = msg.scale;
  marker.scale.y = msg.scale;
  marker.scale.z = msg.scale;
  marker.color.r = 0.2+0.7*msg.pose.position.x;
  marker.color.g = 0.2+0.7*msg.pose.position.y;
  marker.color.b = 0.2+0.7*msg.pose.position.z;
  marker.color.a = 1.0;

  control.markers.push_back( marker );
  msg.controls.push_back( control );

  return msg.controls.back();
}


void makeCube( )
{
  int side_length = 10;
  float step = 1.0/ (float)side_length;
  int count = 0;

  positions.reserve( side_length*side_length*side_length );

  for ( double x=-0.5; x<0.5; x+=step )
  {
    for ( double y=-0.5; y<0.5; y+=step )
    {
      for ( double z=0.0; z<1.0; z+=step )
      {
        InteractiveMarker int_marker;
        int_marker.header.frame_id = "base_link";
        int_marker.scale = step;

        int_marker.pose.position.x = x;
        int_marker.pose.position.y = y;
        int_marker.pose.position.z = z;

        positions.push_back( tf::Vector3(x,y,z) );

        std::stringstream s;
        s << count;
        int_marker.name = s.str();

        makeBoxControl(int_marker);

        server->insert( int_marker );
        server->setCallback( int_marker.name, &processFeedback );

        count++;
      }
    }
  }
}

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

  server.reset( new interactive_markers::InteractiveMarkerServer("cube") );

  ros::Duration(0.1).sleep();

  ROS_INFO("initializing..");
  makeCube();
  server->applyChanges();
  ROS_INFO("ready.");

  ros::spin();

  server.reset();
}

如果需要在rviz中显示并测试,步骤如下:

01- 

02-

代码语言:javascript
复制
 int_marker.header.frame_id = "base_link";

03-

背景色改为浅白色

04- 

查看

部分终端数据:

shiyanlou:demo_ws/ $ rosrun interactive_marker_tutorials cube        22:11:38 1661955135.491224279: registerPublisher Failed to contact master at localhost:11311.  Retrying... INFO: Connected to master at localhost:11311 1661955142.698239311: initializing.. INFO: ready. INFO: 2.35608e-08 INFO: 0.455605 INFO: 0 INFO: 0.0117029 INFO: 0.0464634 INFO: 0.011576 INFO: 0.140218 INFO: 0.0114497 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0.0351378 INFO: 0.0694076 INFO: 0.070476 INFO: 0.046382 INFO: 0.0348074 INFO: 0.0230308 INFO: 0.0115739 INFO: 0 INFO: 0.0117843 INFO: 0.0349274 INFO: 0.0351311 INFO: 0 INFO: 0.034488 INFO: 0.0121057 INFO: 0.0465924 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0 INFO: 0.0117842 INFO: 0.070666 


稍作修改:

CYLINDER


小结:

在 RViz 中,执行以下操作: 将固定坐标设置为“/base_link”。 通过单击“显示”面板中的“添加”来添加“交互式标记”显示。 将此显示的更新主题设置为“/basic_controls/update”。 这应该会立即在 rviz 中调出几个灰色立方体。 现在在工具面板中选择“交互”。 这将启用主视图中的所有交互元素,这将在框周围显示额外的箭头和环。 您可以左键单击这些控件,在某些情况下还可以单击框本身来更改每个交互式标记的姿势。 一些标记有一个上下文菜单,可以通过右键单击它们来访问它。 添加“网格”显示。 这是一个有用的视觉线索,可以帮助在拖动标记时了解它们在空间中的移动方式。

代码语言:javascript
复制
/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


// %Tag(fullSource)%
#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();
}
// %Tag(fullSource)%

引用(wiki.ros.org/rviz/Tutorials/):

交互式标记类似于前面教程中描述的“常规”标记,但是它们允许用户通过更改位置或旋转、单击它们或从分配给每个标记的上下文菜单中选择某些内容来与它们进行交互。

它们由visualization_msgs/InteractiveMarker 消息表示,该消息包含一个上下文菜单和几个控件(visualization_msgs/InteractiveMarkerControl)。这些控件定义了交互式标记的不同可视部分,可以由几个常规标记(visualization_msgs/Marker)组成,并且每个都可以具有不同的功能。

 <<MsgLink(visualization_msgs/InteractiveMarker)>> 消息的结构

如果要创建提供一组交互式标记的节点,则需要实例化一个 InteractiveMarkerServer 对象。这将处理与客户端(通常是 RViz)的连接,并确保您所做的所有更改都被传输,并且您的应用程序被通知用户在交互式标记上执行的所有操作。

interactive_marker_architecture



本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档