美文网首页ROS
RViz学习笔记(八) - 交互式marker:cube.cpp

RViz学习笔记(八) - 交互式marker:cube.cpp

作者: Savior2016 | 来源:发表于2017-03-18 17:04 被阅读51次
    cube.pngcube.png

    源码

    /*
     * 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.65+0.7*msg.pose.position.x;
      marker.color.g = 0.65+0.7*msg.pose.position.y;
      marker.color.b = 0.65+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();
    }
    

    源码分析

    #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;
    

    建立了一个服务器和一个三维向量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.65+0.7*msg.pose.position.x;
      marker.color.g = 0.65+0.7*msg.pose.position.y;
      marker.color.b = 0.65+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();
    }
    

    这个之前说过了,就是建立一个带着marker的控制,并添加到交互式marker上。

    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++;
          }
        }
      }
    }
    

    这个就是建立一组cube的程序。

    主函数就不说了,跟上次的一样。

    相关文章

      网友评论

        本文标题:RViz学习笔记(八) - 交互式marker:cube.cpp

        本文链接:https://www.haomeiwen.com/subject/qwwunttx.html