• ROS1云课→14可视化交互


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


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

    InteractiveMarker

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

    1. /*
    2. * Copyright (c) 2011, Willow Garage, Inc.
    3. * All rights reserved.
    4. *
    5. * Redistribution and use in source and binary forms, with or without
    6. * modification, are permitted provided that the following conditions are met:
    7. *
    8. * * Redistributions of source code must retain the above copyright
    9. * notice, this list of conditions and the following disclaimer.
    10. * * Redistributions in binary form must reproduce the above copyright
    11. * notice, this list of conditions and the following disclaimer in the
    12. * documentation and/or other materials provided with the distribution.
    13. * * Neither the name of the Willow Garage, Inc. nor the names of its
    14. * contributors may be used to endorse or promote products derived from
    15. * this software without specific prior written permission.
    16. *
    17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    27. * POSSIBILITY OF SUCH DAMAGE.
    28. */
    29. #include
    30. #include
    31. #include
    32. #include
    33. using namespace visualization_msgs;
    34. boost::shared_ptr server;
    35. std::vector< tf::Vector3 > positions;
    36. void processFeedback( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
    37. {
    38. switch ( feedback->event_type )
    39. {
    40. case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
    41. {
    42. //compute difference vector for this cube
    43. tf::Vector3 fb_pos(feedback->pose.position.x, feedback->pose.position.y, feedback->pose.position.z);
    44. unsigned index = atoi( feedback->marker_name.c_str() );
    45. if ( index > positions.size() )
    46. {
    47. return;
    48. }
    49. tf::Vector3 fb_delta = fb_pos - positions[index];
    50. // move all markers in that direction
    51. for ( unsigned i=0; isize(); i++ )
    52. {
    53. float d = fb_pos.distance( positions[i] );
    54. float t = 1 / (d*5.0+1.0) - 0.2;
    55. if ( t < 0.0 ) t=0.0;
    56. positions[i] += t * fb_delta;
    57. if ( i == index ) {
    58. ROS_INFO_STREAM( d );
    59. positions[i] = fb_pos;
    60. }
    61. geometry_msgs::Pose pose;
    62. pose.position.x = positions[i].x();
    63. pose.position.y = positions[i].y();
    64. pose.position.z = positions[i].z();
    65. std::stringstream s;
    66. s << i;
    67. server->setPose( s.str(), pose );
    68. }
    69. break;
    70. }
    71. }
    72. server->applyChanges();
    73. }
    74. InteractiveMarkerControl& makeBoxControl( InteractiveMarker &msg )
    75. {
    76. InteractiveMarkerControl control;
    77. control.always_visible = true;
    78. control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
    79. control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
    80. control.independent_marker_orientation = true;
    81. Marker marker;
    82. marker.type = Marker::CUBE;
    83. marker.scale.x = msg.scale;
    84. marker.scale.y = msg.scale;
    85. marker.scale.z = msg.scale;
    86. marker.color.r = 0.2+0.7*msg.pose.position.x;
    87. marker.color.g = 0.2+0.7*msg.pose.position.y;
    88. marker.color.b = 0.2+0.7*msg.pose.position.z;
    89. marker.color.a = 1.0;
    90. control.markers.push_back( marker );
    91. msg.controls.push_back( control );
    92. return msg.controls.back();
    93. }
    94. void makeCube( )
    95. {
    96. int side_length = 10;
    97. float step = 1.0/ (float)side_length;
    98. int count = 0;
    99. positions.reserve( side_length*side_length*side_length );
    100. for ( double x=-0.5; x<0.5; x+=step )
    101. {
    102. for ( double y=-0.5; y<0.5; y+=step )
    103. {
    104. for ( double z=0.0; z<1.0; z+=step )
    105. {
    106. InteractiveMarker int_marker;
    107. int_marker.header.frame_id = "base_link";
    108. int_marker.scale = step;
    109. int_marker.pose.position.x = x;
    110. int_marker.pose.position.y = y;
    111. int_marker.pose.position.z = z;
    112. positions.push_back( tf::Vector3(x,y,z) );
    113. std::stringstream s;
    114. s << count;
    115. int_marker.name = s.str();
    116. makeBoxControl(int_marker);
    117. server->insert( int_marker );
    118. server->setCallback( int_marker.name, &processFeedback );
    119. count++;
    120. }
    121. }
    122. }
    123. }
    124. int main(int argc, char** argv)
    125. {
    126. ros::init(argc, argv, "cube");
    127. server.reset( new interactive_markers::InteractiveMarkerServer("cube") );
    128. ros::Duration(0.1).sleep();
    129. ROS_INFO("initializing..");
    130. makeCube();
    131. server->applyChanges();
    132. ROS_INFO("ready.");
    133. ros::spin();
    134. server.reset();
    135. }

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

    01- 

     

    02-

     int_marker.header.frame_id = "base_link";

     

    03-

    背景色改为浅白色

    04- 

    查看

     

    部分终端数据:

    shiyanlou:demo_ws/ $ rosrun interactive_marker_tutorials cube        [22:11:38]
    [ERROR] [1661955135.491224279]: [registerPublisher] Failed to contact master at [localhost:11311].  Retrying...
    [ INFO] [1661955142.587063541]: Connected to master at [localhost:11311]
    [ INFO] [1661955142.698239311]: initializing..
    [ INFO] [1661955142.711385709]: ready.
    [ INFO] [1661955433.851128054]: 2.35608e-08
    [ INFO] [1661955433.862355866]: 0.455605
    [ INFO] [1661955433.985751109]: 0
    [ INFO] [1661955434.060073593]: 0.0117029
    [ INFO] [1661955434.147889679]: 0.0464634
    [ INFO] [1661955434.224687924]: 0.011576
    [ INFO] [1661955434.317503688]: 0.140218
    [ INFO] [1661955434.375525722]: 0.0114497
    [ INFO] [1661955434.456775907]: 0
    [ INFO] [1661955434.533680882]: 0
    [ INFO] [1661955434.614335283]: 0
    [ INFO] [1661955434.666641382]: 0
    [ INFO] [1661955434.744000213]: 0
    [ INFO] [1661955434.821070352]: 0
    [ INFO] [1661955434.902700050]: 0
    [ INFO] [1661955434.951841464]: 0
    [ INFO] [1661955435.033664385]: 0
    [ INFO] [1661955435.115341065]: 0.0351378
    [ INFO] [1661955435.172467772]: 0.0694076
    [ INFO] [1661955435.250404696]: 0.070476
    [ INFO] [1661955435.340758065]: 0.046382
    [ INFO] [1661955435.418613802]: 0.0348074
    [ INFO] [1661955435.474156388]: 0.0230308
    [ INFO] [1661955435.556194217]: 0.0115739
    [ INFO] [1661955435.636080060]: 0
    [ INFO] [1661955435.713566499]: 0.0117843
    [ INFO] [1661955435.768091911]: 0.0349274
    [ INFO] [1661955435.854893311]: 0.0351311
    [ INFO] [1661955435.930366401]: 0
    [ INFO] [1661955436.015312457]: 0.034488
    [ INFO] [1661955436.072866533]: 0.0121057
    [ INFO] [1661955436.157107743]: 0.0465924
    [ INFO] [1661955436.236680402]: 0
    [ INFO] [1661955436.314375243]: 0
    [ INFO] [1661955436.366920278]: 0
    [ INFO] [1661955436.447782631]: 0
    [ INFO] [1661955436.525610924]: 0
    [ INFO] [1661955436.604214948]: 0
    [ INFO] [1661955436.658894075]: 0.0117842
    [ INFO] [1661955436.745685687]: 0.070666 


    稍作修改:

    CYLINDER

     


    小结:

    在 RViz 中,执行以下操作:

    将固定坐标设置为“/base_link”。
    通过单击“显示”面板中的“添加”来添加“交互式标记”显示。

    将此显示的更新主题设置为“/basic_controls/update”。 这应该会立即在 rviz 中调出几个灰色立方体。

    现在在工具面板中选择“交互”。 这将启用主视图中的所有交互元素,这将在框周围显示额外的箭头和环。 您可以左键单击这些控件,在某些情况下还可以单击框本身来更改每个交互式标记的姿势。 一些标记有一个上下文菜单,可以通过右键单击它们来访问它。

    添加“网格”显示。 这是一个有用的视觉线索,可以帮助在拖动标记时了解它们在空间中的移动方式。

     

     

     

     

    1. /*
    2. * Copyright (c) 2011, Willow Garage, Inc.
    3. * All rights reserved.
    4. *
    5. * Redistribution and use in source and binary forms, with or without
    6. * modification, are permitted provided that the following conditions are met:
    7. *
    8. * * Redistributions of source code must retain the above copyright
    9. * notice, this list of conditions and the following disclaimer.
    10. * * Redistributions in binary form must reproduce the above copyright
    11. * notice, this list of conditions and the following disclaimer in the
    12. * documentation and/or other materials provided with the distribution.
    13. * * Neither the name of the Willow Garage, Inc. nor the names of its
    14. * contributors may be used to endorse or promote products derived from
    15. * this software without specific prior written permission.
    16. *
    17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    27. * POSSIBILITY OF SUCH DAMAGE.
    28. */
    29. // %Tag(fullSource)%
    30. #include
    31. #include
    32. void processFeedback(
    33. const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
    34. {
    35. ROS_INFO_STREAM( feedback->marker_name << " is now at "
    36. << feedback->pose.position.x << ", " << feedback->pose.position.y
    37. << ", " << feedback->pose.position.z );
    38. }
    39. int main(int argc, char** argv)
    40. {
    41. ros::init(argc, argv, "simple_marker");
    42. // create an interactive marker server on the topic namespace simple_marker
    43. interactive_markers::InteractiveMarkerServer server("simple_marker");
    44. // create an interactive marker for our server
    45. visualization_msgs::InteractiveMarker int_marker;
    46. int_marker.header.frame_id = "base_link";
    47. int_marker.header.stamp=ros::Time::now();
    48. int_marker.name = "my_marker";
    49. int_marker.description = "Simple 1-DOF Control";
    50. // create a grey box marker
    51. visualization_msgs::Marker box_marker;
    52. box_marker.type = visualization_msgs::Marker::CUBE;
    53. box_marker.scale.x = 0.45;
    54. box_marker.scale.y = 0.45;
    55. box_marker.scale.z = 0.45;
    56. box_marker.color.r = 0.5;
    57. box_marker.color.g = 0.5;
    58. box_marker.color.b = 0.5;
    59. box_marker.color.a = 1.0;
    60. // create a non-interactive control which contains the box
    61. visualization_msgs::InteractiveMarkerControl box_control;
    62. box_control.always_visible = true;
    63. box_control.markers.push_back( box_marker );
    64. // add the control to the interactive marker
    65. int_marker.controls.push_back( box_control );
    66. // create a control which will move the box
    67. // this control does not contain any markers,
    68. // which will cause RViz to insert two arrows
    69. visualization_msgs::InteractiveMarkerControl rotate_control;
    70. rotate_control.name = "move_x";
    71. rotate_control.interaction_mode =
    72. visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
    73. // add the control to the interactive marker
    74. int_marker.controls.push_back(rotate_control);
    75. // add the interactive marker to our collection &
    76. // tell the server to call processFeedback() when feedback arrives for it
    77. server.insert(int_marker, &processFeedback);
    78. // 'commit' changes and send to all clients
    79. server.applyChanges();
    80. // start the ROS main loop
    81. ros::spin();
    82. }
    83. // %Tag(fullSource)%

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

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

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

     <> 消息的结构

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

     

    interactive_marker_architecture



     

  • 相关阅读:
    劲松中西医医院谭巍主任在线分析:HPV复阳的三大祸首
    JDK JRE JVM解释及Java代码编译运行过程
    使用线段树解决数组任意区间元素修改问题
    在ios设备上运行Unity Profiler
    高并发下单例线程安全
    Android/AutoMotive 多用户操作
    第五十二天 数论
    HTML5数据推送SSE原理及应用开发
    java计算机毕业设计竞赛信息发布及组队系统源码+数据库+lw文档+系统
    springMvc53-简单异常处理
  • 原文地址:https://blog.csdn.net/ZhangRelay/article/details/126632951