机器人编程趣味实践14-机器人三维仿真(Gazebo+TurtleBot3)

举报
zhangrelay 发表于 2021/07/15 01:00:52 2021/07/15
【摘要】 之前,介绍了节点、主题、服务和行动等基本概念,以及rqt和rosbag2等工具。 采用了官方改版的二维环境,那么现在玩耍一下更为逼真的三维仿真环境吧。 仿真软件Gazebo机器人TurtleBot3 TurtleBot3支持仿真开发环境,可以在仿真中用虚拟机器人编程开发。 有两种开发环境可以做到这一点,一种是使用带有 3D 可视化工具 RViz 的假节点,另一种是使用...

之前,介绍了节点、主题、服务和行动等基本概念,以及rqt和rosbag2等工具。

采用了官方改版的二维环境,那么现在玩耍一下更为逼真的三维仿真环境吧。

  • 仿真软件Gazebo
  • 机器人TurtleBot3

TurtleBot3支持仿真开发环境,可以在仿真中用虚拟机器人编程开发。 有两种开发环境可以做到这一点,一种是使用带有 3D 可视化工具 RViz 的假节点,另一种是使用 3D 机器人模拟器 Gazebo。

  • 假节点适合用机器人模型和运动进行测试,但不支持传感器。
  • 如果需要执行 SLAM 或导航,Gazebo 将是一个可行的解决方案,因为它支持 IMU、LDS 和摄像头等传感器。

环境配置


  
  1. # TURTLEBOT3_MODEL
  2. export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/home/zhangrelay/RobSoft/turtlebot3/src/simulations/turtlebot3_gazebo/models
  3. export TURTLEBOT3_MODEL=burger
  4. # ROS2
  5. source /opt/ros/foxy/setup.bash
  6. #colcon
  7. source /usr/share/colcon_cd/function/colcon_cd.sh

源码编译

可以使用deb直接安装:

  • sudo apt install ros-foxy-turtlebot3-gazebo

注意包要装全。

这里,采用源码编译如下:

  • colcon build

功能包列表如上所示。

仿真实践

1 启动环境

  • ros2 launch turtlebot3_gazebo empty_world.launch.py

蓝色射线为激光的可视化效果。

empty_world.launch代码如下:


  
  1. import os
  2. from ament_index_python.packages import get_package_share_directory
  3. from launch import LaunchDescription
  4. from launch.actions import ExecuteProcess
  5. from launch.actions import IncludeLaunchDescription
  6. from launch.launch_description_sources import PythonLaunchDescriptionSource
  7. from launch.substitutions import LaunchConfiguration
  8. TURTLEBOT3_MODEL = os.environ['TURTLEBOT3_MODEL']
  9. def generate_launch_description():
  10. use_sim_time = LaunchConfiguration('use_sim_time', default='True')
  11. world_file_name = 'empty_worlds/' + TURTLEBOT3_MODEL + '.model'
  12. world = os.path.join(get_package_share_directory('turtlebot3_gazebo'),
  13. 'worlds', world_file_name)
  14. launch_file_dir = os.path.join(get_package_share_directory('turtlebot3_gazebo'), 'launch')
  15. pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
  16. return LaunchDescription([
  17. IncludeLaunchDescription(
  18. PythonLaunchDescriptionSource(
  19. os.path.join(pkg_gazebo_ros, 'launch', 'gzserver.launch.py')
  20. ),
  21. launch_arguments={'world': world}.items(),
  22. ),
  23. IncludeLaunchDescription(
  24. PythonLaunchDescriptionSource(
  25. os.path.join(pkg_gazebo_ros, 'launch', 'gzclient.launch.py')
  26. ),
  27. ),
  28. ExecuteProcess(
  29. cmd=['ros2', 'param', 'set', '/gazebo', 'use_sim_time', use_sim_time],
  30. output='screen'),
  31. IncludeLaunchDescription(
  32. PythonLaunchDescriptionSource([launch_file_dir, '/robot_state_publisher.launch.py']),
  33. launch_arguments={'use_sim_time': use_sim_time}.items(),
  34. ),
  35. ])

2 圆周运动

之前和之前二维环境圆周运动的指令非常类似哦。

  • ros2 topic pub --rate 2 /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.8}}"

3 键盘遥控

使用如下命令启动键盘遥控:

  • ros2 run turtlebot3_teleop teleop_keyboard

键盘遥控代码如下:


  
  1. import os
  2. import select
  3. import sys
  4. import rclpy
  5. from geometry_msgs.msg import Twist
  6. from rclpy.qos import QoSProfile
  7. if os.name == 'nt':
  8. import msvcrt
  9. else:
  10. import termios
  11. import tty
  12. BURGER_MAX_LIN_VEL = 0.22
  13. BURGER_MAX_ANG_VEL = 2.84
  14. WAFFLE_MAX_LIN_VEL = 0.26
  15. WAFFLE_MAX_ANG_VEL = 1.82
  16. LIN_VEL_STEP_SIZE = 0.01
  17. ANG_VEL_STEP_SIZE = 0.1
  18. TURTLEBOT3_MODEL = os.environ['TURTLEBOT3_MODEL']
  19. msg = """
  20. Control Your TurtleBot3!
  21. ---------------------------
  22. Moving around:
  23. w
  24. a s d
  25. x
  26. w/x : increase/decrease linear velocity (Burger : ~ 0.22, Waffle and Waffle Pi : ~ 0.26)
  27. a/d : increase/decrease angular velocity (Burger : ~ 2.84, Waffle and Waffle Pi : ~ 1.82)
  28. space key, s : force stop
  29. CTRL-C to quit
  30. """
  31. e = """
  32. Communications Failed
  33. """
  34. def get_key(settings):
  35. if os.name == 'nt':
  36. return msvcrt.getch().decode('utf-8')
  37. tty.setraw(sys.stdin.fileno())
  38. rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
  39. if rlist:
  40. key = sys.stdin.read(1)
  41. else:
  42. key = ''
  43. termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
  44. return key
  45. def print_vels(target_linear_velocity, target_angular_velocity):
  46. print('currently:\tlinear velocity {0}\t angular velocity {1} '.format(
  47. target_linear_velocity,
  48. target_angular_velocity))
  49. def make_simple_profile(output, input, slop):
  50. if input > output:
  51. output = min(input, output + slop)
  52. elif input < output:
  53. output = max(input, output - slop)
  54. else:
  55. output = input
  56. return output
  57. def constrain(input_vel, low_bound, high_bound):
  58. if input_vel < low_bound:
  59. input_vel = low_bound
  60. elif input_vel > high_bound:
  61. input_vel = high_bound
  62. else:
  63. input_vel = input_vel
  64. return input_vel
  65. def check_linear_limit_velocity(velocity):
  66. if TURTLEBOT3_MODEL == 'burger':
  67. return constrain(velocity, -BURGER_MAX_LIN_VEL, BURGER_MAX_LIN_VEL)
  68. else:
  69. return constrain(velocity, -WAFFLE_MAX_LIN_VEL, WAFFLE_MAX_LIN_VEL)
  70. def check_angular_limit_velocity(velocity):
  71. if TURTLEBOT3_MODEL == 'burger':
  72. return constrain(velocity, -BURGER_MAX_ANG_VEL, BURGER_MAX_ANG_VEL)
  73. else:
  74. return constrain(velocity, -WAFFLE_MAX_ANG_VEL, WAFFLE_MAX_ANG_VEL)
  75. def main():
  76. settings = None
  77. if os.name != 'nt':
  78. settings = termios.tcgetattr(sys.stdin)
  79. rclpy.init()
  80. qos = QoSProfile(depth=10)
  81. node = rclpy.create_node('teleop_keyboard')
  82. pub = node.create_publisher(Twist, 'cmd_vel', qos)
  83. status = 0
  84. target_linear_velocity = 0.0
  85. target_angular_velocity = 0.0
  86. control_linear_velocity = 0.0
  87. control_angular_velocity = 0.0
  88. try:
  89. print(msg)
  90. while(1):
  91. key = get_key(settings)
  92. if key == 'w':
  93. target_linear_velocity =\
  94. check_linear_limit_velocity(target_linear_velocity + LIN_VEL_STEP_SIZE)
  95. status = status + 1
  96. print_vels(target_linear_velocity, target_angular_velocity)
  97. elif key == 'x':
  98. target_linear_velocity =\
  99. check_linear_limit_velocity(target_linear_velocity - LIN_VEL_STEP_SIZE)
  100. status = status + 1
  101. print_vels(target_linear_velocity, target_angular_velocity)
  102. elif key == 'a':
  103. target_angular_velocity =\
  104. check_angular_limit_velocity(target_angular_velocity + ANG_VEL_STEP_SIZE)
  105. status = status + 1
  106. print_vels(target_linear_velocity, target_angular_velocity)
  107. elif key == 'd':
  108. target_angular_velocity =\
  109. check_angular_limit_velocity(target_angular_velocity - ANG_VEL_STEP_SIZE)
  110. status = status + 1
  111. print_vels(target_linear_velocity, target_angular_velocity)
  112. elif key == ' ' or key == 's':
  113. target_linear_velocity = 0.0
  114. control_linear_velocity = 0.0
  115. target_angular_velocity = 0.0
  116. control_angular_velocity = 0.0
  117. print_vels(target_linear_velocity, target_angular_velocity)
  118. else:
  119. if (key == '\x03'):
  120. break
  121. if status == 20:
  122. print(msg)
  123. status = 0
  124. twist = Twist()
  125. control_linear_velocity = make_simple_profile(
  126. control_linear_velocity,
  127. target_linear_velocity,
  128. (LIN_VEL_STEP_SIZE / 2.0))
  129. twist.linear.x = control_linear_velocity
  130. twist.linear.y = 0.0
  131. twist.linear.z = 0.0
  132. control_angular_velocity = make_simple_profile(
  133. control_angular_velocity,
  134. target_angular_velocity,
  135. (ANG_VEL_STEP_SIZE / 2.0))
  136. twist.angular.x = 0.0
  137. twist.angular.y = 0.0
  138. twist.angular.z = control_angular_velocity
  139. pub.publish(twist)
  140. except Exception as e:
  141. print(e)
  142. finally:
  143. twist = Twist()
  144. twist.linear.x = 0.0
  145. twist.linear.y = 0.0
  146. twist.linear.z = 0.0
  147. twist.angular.x = 0.0
  148. twist.angular.y = 0.0
  149. twist.angular.z = 0.0
  150. pub.publish(twist)
  151. if os.name != 'nt':
  152. termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
  153. if __name__ == '__main__':
  154. main()

简单加入中文方便使用:

阅读源码非常重要。

4 节点

5 主题

6 服务

ros2 service list -t

  • /apply_joint_effort [gazebo_msgs/srv/ApplyJointEffort]
  • /apply_link_wrench [gazebo_msgs/srv/ApplyLinkWrench]
  • /clear_joint_efforts [gazebo_msgs/srv/JointRequest]
  • /clear_link_wrenches [gazebo_msgs/srv/LinkRequest]
  • /delete_entity [gazebo_msgs/srv/DeleteEntity]
  • /gazebo/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /gazebo/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /gazebo/get_parameters [rcl_interfaces/srv/GetParameters]
  • /gazebo/list_parameters [rcl_interfaces/srv/ListParameters]
  • /gazebo/set_parameters [rcl_interfaces/srv/SetParameters]
  • /gazebo/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /get_model_list [gazebo_msgs/srv/GetModelList]
  • /pause_physics [std_srvs/srv/Empty]
  • /reset_simulation [std_srvs/srv/Empty]
  • /reset_world [std_srvs/srv/Empty]
  • /robot_state_publisher/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /robot_state_publisher/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /robot_state_publisher/get_parameters [rcl_interfaces/srv/GetParameters]
  • /robot_state_publisher/list_parameters [rcl_interfaces/srv/ListParameters]
  • /robot_state_publisher/set_parameters [rcl_interfaces/srv/SetParameters]
  • /robot_state_publisher/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /rqt_gui_py_node_4338/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /rqt_gui_py_node_4338/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /rqt_gui_py_node_4338/get_parameters [rcl_interfaces/srv/GetParameters]
  • /rqt_gui_py_node_4338/list_parameters [rcl_interfaces/srv/ListParameters]
  • /rqt_gui_py_node_4338/set_parameters [rcl_interfaces/srv/SetParameters]
  • /rqt_gui_py_node_4338/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /spawn_entity [gazebo_msgs/srv/SpawnEntity]
  • /teleop_keyboard/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /teleop_keyboard/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /teleop_keyboard/get_parameters [rcl_interfaces/srv/GetParameters]
  • /teleop_keyboard/list_parameters [rcl_interfaces/srv/ListParameters]
  • /teleop_keyboard/set_parameters [rcl_interfaces/srv/SetParameters]
  • /teleop_keyboard/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /turtlebot3_diff_drive/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /turtlebot3_diff_drive/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /turtlebot3_diff_drive/get_parameters [rcl_interfaces/srv/GetParameters]
  • /turtlebot3_diff_drive/list_parameters [rcl_interfaces/srv/ListParameters]
  • /turtlebot3_diff_drive/set_parameters [rcl_interfaces/srv/SetParameters]
  • /turtlebot3_diff_drive/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /turtlebot3_imu/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /turtlebot3_imu/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /turtlebot3_imu/get_parameters [rcl_interfaces/srv/GetParameters]
  • /turtlebot3_imu/list_parameters [rcl_interfaces/srv/ListParameters]
  • /turtlebot3_imu/set_parameters [rcl_interfaces/srv/SetParameters]
  • /turtlebot3_imu/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /turtlebot3_joint_state/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /turtlebot3_joint_state/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /turtlebot3_joint_state/get_parameters [rcl_interfaces/srv/GetParameters]
  • /turtlebot3_joint_state/list_parameters [rcl_interfaces/srv/ListParameters]
  • /turtlebot3_joint_state/set_parameters [rcl_interfaces/srv/SetParameters]
  • /turtlebot3_joint_state/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /turtlebot3_laserscan/describe_parameters [rcl_interfaces/srv/DescribeParameters]
  • /turtlebot3_laserscan/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
  • /turtlebot3_laserscan/get_parameters [rcl_interfaces/srv/GetParameters]
  • /turtlebot3_laserscan/list_parameters [rcl_interfaces/srv/ListParameters]
  • /turtlebot3_laserscan/set_parameters [rcl_interfaces/srv/SetParameters]
  • /turtlebot3_laserscan/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
  • /unpause_physics [std_srvs/srv/Empty]

7 行动

SLAM和导航时候再补充。

8 更多

可参考前13篇中对应案例,在此三维环境中进行实践哦。

总结

由二维环境到三维环境,仿真更炫酷,但是原理和指令几乎一样,学一招全掌控!

 

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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