RViz学习笔记(六) - 交互式marker:Simple_marker.cpp分析

Simple_marker

源码

/*
 * 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_mk";
  int_marker.header.stamp=ros::Time::now();
  int_marker.name = "my_marker";
  int_marker.description = "Simple king 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 = 1.0;
  box_marker.color.g = 0.0;
  box_marker.color.b = 0.0;
  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)%

分析

#include <ros/ros.h>

#include <interactive_markers/interactive_marker_server.h>

首先包含了头文件,主要是包含了<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 );
}

这个在运行的时候就可以看出,是返回交互信息的。

主函数里:

ros::init(argc, argv, "simple_marker");

ros初始化。

interactive_markers::InteractiveMarkerServer server("simple_marker");

首先建立一个服务器,它负责把所有改动告知rviz.

  visualization_msgs::InteractiveMarker int_marker;
  int_marker.header.frame_id = "base_mk";
  int_marker.header.stamp=ros::Time::now();
  int_marker.name = "my_marker";
  int_marker.description = "Simple king Control";

创建一个交互式marker——int_marker;定义了它的frame_id什么的。

  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 = 1.0;
  box_marker.color.g = 0.0;
  box_marker.color.b = 0.0;
  box_marker.color.a = 1.0;

这个只是个方块,用来包含我们的交互式marker,好有个外形。下面的设定前面都见过。我现在知道的也不多,有新的理解再来补充。

  visualization_msgs::InteractiveMarkerControl box_control;
  box_control.always_visible = true;
  box_control.markers.push_back( box_marker );

这个是非交互式控制,是为了在移动方块时仍然能显示方块。最后一句,把这个控制块添加到了前面建的方块marker box_marker上。应该是把方块添加到了这个控制上。

int_marker.controls.push_back( box_control );

又把非交互式控制添加到了交互的marker上。

 visualization_msgs::InteractiveMarkerControl rotate_control;
  rotate_control.name = "move_x";
  rotate_control.interaction_mode =
      visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;

又创建了一个交互,用来移动方块,最后一句,是创建两个箭头来移动。

int_marker.controls.push_back(rotate_control);

把这个控制也添加给交互式marker。

server.insert(int_marker, &processFeedback);

把int_marker添加到了服务器的收集器,并且让服务器在有feedback到来的时候调用反馈函数。

server.applyChanges();

服务器提交改变并发送到所有的客户端。

ros::spin();

开启ROS主循环

总结

整个交互式的marker分为以下几部分:

  • 交互式部分:就是交互式marker的主体,所有的其他部分都要添加到它上面来,组成一个交互式主体,它的信息也就是主体信息。
  • Marker部分:这个是显示的主体,相当于是个外包装。
  • non-control部分:它是用来承载marker部分的。
    我原本想把中间一段程序改成这样:
// 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 );
  int_marker.markers.push_back( box_marker );

结果发现int_marker没有markers这个属性,所以需要一个non-control。

  • 一个control,这个control就是用来控制可交互marker的

最后,将marker注册到服务器的collection,服务器会监视它的状态,它有什么改变,都会被通告服务器调用processFeedback

然后使服务器将改变发送到所有客户端。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 123,111评论 18 134
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 159,991评论 24 690
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 12,280评论 1 91
  • 巧书的确是很巧,用了很多很巧的方法让我们直面自己,直面自己一直想掩盖的,或者无意掩盖,但是却没有意识的自我。 今天...
    慧子永远没有太晚的开始阅读 229评论 2 5
  • 文/爱猫的胖妞 从我记事起,就能深刻感到国人的爱好总是扎堆成群的,随之产生的热潮也总是一波一波的。 近期国内掀起了...
    爱猫的胖妞阅读 172评论 0 0