ROS编程(ETH)2018更新版习题说明(三)

举报
zhangrelay 发表于 2021/07/15 04:39:23 2021/07/15
【摘要】 习题3 课程要点: - ROS发布器 -rqt用户界面 - TF转换系统(可选) - 机器人模型(URDF)(可选) - 仿真描述(SDF)(可选) --练习-- 本课练习的目标是实现Husky机器人闭环控制。 首先,从激光扫描中获取支柱(singlepillar)的位置,然后控制机器人,使其行驶到支柱附近。 1. 修改上次练习中的启动文件,以便: a. ...

习题3

课程要点:

- ROS发布器

-rqt用户界面

- TF转换系统(可选)

- 机器人模型(URDF)(可选)

- 仿真描述(SDF)(可选)

--练习--

本课练习的目标是实现Husky机器人闭环控制。 首先,从激光扫描中获取支柱(singlepillar)的位置,然后控制机器人,使其行驶到支柱附近。

1. 修改上次练习中的启动文件,以便:
 a.  键盘遥控节点删除(keyboard twist node)。

 b.  $(find husky_highlevel_controller)/worlds/singlePillar.world作为世界环境加载,将singlePillar.world文件从RSL主页上下载Zip文件并复制到该文件夹。

A:  提示与结果



launch


  
  1. <?xml version="1.0"?>
  2. <!--
  3. -->
  4. <launch>
  5. <arg name="world_name" default="$(find husky_highlevel_controller)/worlds/singlePillar.world"/>
  6. <arg name="laser_enabled" default="true"/>
  7. <arg name="kinect_enabled" default="false"/>
  8. <include file="$(find gazebo_ros)/launch/empty_world.launch">
  9. <arg name="world_name" value="$(arg world_name)"/> <!-- world_name is wrt GAZEBO_RESOURCE_PATH environment variable -->
  10. <arg name="paused" value="false"/>
  11. <arg name="use_sim_time" value="true"/>
  12. <arg name="gui" value="true"/>
  13. <arg name="headless" value="false"/>
  14. <arg name="debug" value="false"/>
  15. </include>
  16. <include file="$(find husky_gazebo)/launch/spawn_husky.launch">
  17. <arg name="laser_enabled" value="$(arg laser_enabled)"/>
  18. <arg name="kinect_enabled" value="$(arg kinect_enabled)"/>
  19. </include>
  20. <!-- <node pkg="teleop_twist_keyboard" name="teleop_husky" type="teleop_twist_keyboard.py"/> -->
  21. <node pkg="husky_highlevel_controller" type="husky_highlevel_controller" name="husky_highlevel_controller"
  22. output="screen" launch-prefix="gnome-terminal --command">
  23. <rosparam command="load" file="$(find husky_highlevel_controller)/config/config.yaml" />
  24. </node>
  25. <node pkg="rviz" type="rviz" name="rviz" />
  26. </launch>

world


  
  1. <?xml version="1.0" ?>
  2. <sdf version="1.4">
  3. <world name="default">
  4. <!-- A global light source -->
  5. <include>
  6. <uri>model://sun</uri>
  7. </include>
  8. <!-- A ground plane -->
  9. <include>
  10. <uri>model://ground_plane</uri>
  11. </include>
  12. <!-- Cylinder -->
  13. <model name='unit_cylinder'>
  14. <pose frame=''>20 5 0.5 0 -0 0</pose>
  15. <link name='link'>
  16. <inertial>
  17. <mass>1</mass>
  18. <inertia>
  19. <ixx>0.145833</ixx>
  20. <ixy>0</ixy>
  21. <ixz>0</ixz>
  22. <iyy>0.145833</iyy>
  23. <iyz>0</iyz>
  24. <izz>0.125</izz>
  25. </inertia>
  26. </inertial>
  27. <collision name='collision'>
  28. <geometry>
  29. <cylinder>
  30. <radius>0.2</radius>
  31. <length>2</length>
  32. </cylinder>
  33. </geometry>
  34. <max_contacts>10</max_contacts>
  35. </collision>
  36. <visual name='visual'>
  37. <geometry>
  38. <cylinder>
  39. <radius>0.2</radius>
  40. <length>2</length>
  41. </cylinder>
  42. </geometry>
  43. <material>
  44. <script>
  45. <name>Gazebo/Grey</name>
  46. <uri>file://media/materials/scripts/gazebo.material</uri>
  47. </script>
  48. </material>
  49. </visual>
  50. <self_collide>0</self_collide>
  51. <kinematic>0</kinematic>
  52. </link>
  53. </model>
  54. </world>
  55. </sdf>

2. 从激光扫描中提取支柱相对于机器人的位置信息。

A: 这里只有一个支柱 ( 类似实验2 )

HuskyHighlevelController.hpp


  
  1. //------Pillar info----
  2. pillar position
  3. float x_pillar;
  4. float y_pillar;
  5. // the orientation of the pillar with respect to the x_axis
  6. float alpha_pillar;

HuskyHighlevelController.cpp


  
  1. int arr_size = floor((scan_msg.angle_max-scan_msg.angle_min)/scan_msg.angle_increment);
  2. for (int i=0 ; i< arr_size ;i++)
  3. {
  4. if (scan_msg.ranges[i] < smallest_distance)
  5. {
  6. smallest_distance = scan_msg.ranges[i];
  7. alpha_pillar = (scan_msg.angle_min + i*scan_msg.angle_increment);
  8. }
  9. }
  10. //Pillar Husky offset pose
  11. x_pillar = smallest_distance*cos(alpha_pillar);
  12. y_pillar = smallest_distance*sin(alpha_pillar);
  13. //cout<<"cout Minimum laser distance(m): "<<smallest_distance<<"\n";
  14. //ROS_INFO_STREAM("ROS_INFO_STREAM Minimum laser distance(m): "<<smallest_distance);
  15. //ROS_INFO("Pillar laser distance(m):%lf", smallest_distance);
  16. ROS_INFO("Pillar offset angle(rad):%lf", alpha_pillar);
  17. ROS_INFO("pillar x distance(m):%lf", x_pillar);
  18. ROS_INFO("pillar y distance(m):%lf", y_pillar);



3. 在创建一个发布者到主题 /cmd_vel 上,以便能够向Husky发送速度指令(twist),需要将geometry_msgs作为依赖项添加到CMakeLists.txt和package.xml(与sensor_msgs的结构相同)。 (参考讲座2,第18幻灯片)

A:

CMakeLists


  
  1. ## Find catkin macros and libraries
  2. find_package(catkin REQUIRED COMPONENTS
  3. roscpp
  4. sensor_msgs
  5. geometry_msgs
  6. )
  7. ## DEPENDS: system dependencies of this project that dependent projects also need
  8. catkin_package(
  9. INCLUDE_DIRS
  10. include
  11. # LIBRARIES
  12. CATKIN_DEPENDS
  13. roscpp
  14. sensor_msgs
  15. geometry_msgs
  16. # DEPENDS
  17. )

package


  
  1. <?xml version="1.0"?>
  2. <package format="2">
  3. <name>husky_highlevel_controller</name>
  4. <version>0.1.0</version>
  5. <description>The husky_highlevel_controller package</description>
  6. <maintainer email="dominic.jud@mavt.ethz.ch">Dominic Jud</maintainer>
  7. <license>BSD</license>
  8. <author email="dominic.jud@mavt.ethz.ch">Dominic Jud</author>
  9. <buildtool_depend>catkin</buildtool_depend>
  10. <depend>roscpp</depend>
  11. <depend>sensor_msgs</depend>
  12. <depend>geometry_msgs</depend>
  13. </package>

4. 编写一个简单的P控制器,使Husky行驶到支柱附件。 注意,使用ROS参数修改控制器增益(参考讲座2,第21幻灯片), 将代码写入到激光扫描主题的回调函数中。

A:

hpp


  
  1. //----Subscribers----// // subscriber to /scan topic
  2. ros::Subscriber scan_sub_;
  3. std::string subscriberTopic_;
  4. //------Pillar info----pillar position
  5. float x_pillar;
  6. float y_pillar;
  7. // the orientation of the pillar with respect to the x_axis
  8. float alpha_pillar;
  9. //-----Publishers-----publisher to /cmd_vel
  10. ros::Publisher cmd_pub_;
  11. //------msgs-------twist
  12. msggeometry_msgs::Twist vel_msg_;

cpp


  
  1. //P-Controller to drive husky towards the pillar
  2. //propotinal gain
  3. float p_gain_vel = 0.1;
  4. float p_gain_ang = 0.4;
  5. if(x_pillar>0.2)
  6. {
  7. if (x_pillar <= 0.4 )
  8. {
  9. vel_msg_.linear.x = 0;
  10. vel_msg_.angular.z = 0;
  11. }
  12. else
  13. {
  14. vel_msg_.linear.x = x_pillar * p_gain_vel ;
  15. vel_msg_.angular.z = -(y_pillar * p_gain_ang) ;
  16. }
  17. }
  18. else
  19. {
  20. vel_msg_.linear.x = 0;
  21. vel_msg_.angular.z = 0;
  22. }
  23. cmd_pub_.publish(vel_msg_);



5. 将一个RobotModel插件添加到RViz,可视化Husky机器人。 (参考讲座3,第17幻灯片)

A:



6. 将一个TF显示插件添加到RViz。 (参考讲座3,第7幻灯片)

A:




7. 发布RViz的可视化标记,显示支柱的估计位置。 两种方式如下:

(简易)将激光帧中的点作为RViz标记发布。 RViz会自动将标记转换为odom坐标。

参考:http://wiki.ros.org/rviz/DisplayTypes/Marker

(困难)实现一个TF监听器,将提取的点从激光帧变换到odom帧。 

参考:http://wiki.ros.org/tf/Tutorials/Writing%20a%20tf%20listener%20%28C%2B%2 B%29

在odom坐标中将该点作为RViz标记发布。参考:http://wiki.ros.org/rviz/DisplayTypes/Marker

A:

cpp


  
  1. //RViz Marker
  2. marker.header.frame_id = "base_laser"; //base no
  3. marker.header.stamp = ros::Time();
  4. marker.ns = "pillar";
  5. marker.id = 0;
  6. marker.type = visualization_msgs::Marker::SPHERE;
  7. marker.action = visualization_msgs::Marker::ADD;
  8. marker.pose.position.x = x_pillar;
  9. marker.pose.position.y = y_pillar;
  10. marker.scale.x = 0.2;
  11. marker.scale.y = 0.2;
  12. marker.scale.z = 2.0;
  13. marker.color.a = 1.0; // Don't forget to set the alpha!
  14. marker.color.r = 0.1;
  15. marker.color.g = 0.1;
  16. marker.color.b = 0.1;
  17. vis_pub_.publish(marker);

对比如下两图差异:




原图(选自原文档中):



--评分标准--

  • 启动launch文件。 Husky应该向支柱驶去。

        1. Husky正常行驶[20%]

        2. Husky到达支柱附近[30%]

  • 查看RViz配置(TF、机器人模型和激光扫描均正常显示)。[20%]

  • 可视化标记正确显示在RViz中。[30%]

--End--


文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。

原文链接:zhangrelay.blog.csdn.net/article/details/79956801

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。