当前位置:   article > 正文

ROS2机器人编程简述humble-第三章-BUMP AND GO BEHAVIOR IN PYTHON .4_ros2机器狗趴下代码

ros2机器狗趴下代码

前一篇,书中介绍了C++实现方式。在这一节,主要使用Python。

ROS2机器人编程简述humble-第三章-BUMP AND GO IN C++ .3

除了C++,Python是ROS2通过rcppy客户端库正式支持的语言之一。本节将再现在上一节中所做的,但使用Python。通过比较验证两种语言发展过程中的差异和相似性。此外,在前面的章节中解释了ROS2的原理,将认识到Python代码中ROS2的元素,因为原理是相同的。

cpp:

python:


main-cpp:

  1. #include <memory>
  2. #include "br2_fsm_bumpgo_cpp/BumpGoNode.hpp"
  3. #include "rclcpp/rclcpp.hpp"
  4. int main(int argc, char * argv[])
  5. {
  6. rclcpp::init(argc, argv);
  7. auto bumpgo_node = std::make_shared<br2_fsm_bumpgo_cpp::BumpGoNode>();
  8. rclcpp::spin(bumpgo_node);
  9. rclcpp::shutdown();
  10. return 0;
  11. }

main-python:

  1. from geometry_msgs.msg import Twist
  2. import rclpy
  3. from rclpy.duration import Duration
  4. from rclpy.node import Node
  5. from rclpy.qos import qos_profile_sensor_data
  6. from rclpy.time import Time
  7. from sensor_msgs.msg import LaserScan
  8. class BumpGoNode(Node):
  9. def __init__(self):
  10. super().__init__('bump_go')
  11. self.FORWARD = 0
  12. self.BACK = 1
  13. self.TURN = 2
  14. self.STOP = 3
  15. self.state = self.FORWARD
  16. self.state_ts = self.get_clock().now()
  17. self.TURNING_TIME = 2.0
  18. self.BACKING_TIME = 2.0
  19. self.SCAN_TIMEOUT = 1.0
  20. self.SPEED_LINEAR = 0.3
  21. self.SPEED_ANGULAR = 0.3
  22. self.OBSTACLE_DISTANCE = 1.0
  23. self.last_scan = None
  24. self.scan_sub = self.create_subscription(
  25. LaserScan,
  26. 'input_scan',
  27. self.scan_callback,
  28. qos_profile_sensor_data)
  29. self.vel_pub = self.create_publisher(Twist, 'output_vel', 10)
  30. self.timer = self.create_timer(0.05, self.control_cycle)
  31. def scan_callback(self, msg):
  32. self.last_scan = msg
  33. def control_cycle(self):
  34. if self.last_scan is None:
  35. return
  36. out_vel = Twist()
  37. if self.state == self.FORWARD:
  38. out_vel.linear.x = self.SPEED_LINEAR
  39. if self.check_forward_2_stop():
  40. self.go_state(self.STOP)
  41. if self.check_forward_2_back():
  42. self.go_state(self.BACK)
  43. elif self.state == self.BACK:
  44. out_vel.linear.x = -self.SPEED_LINEAR
  45. if self.check_back_2_turn():
  46. self.go_state(self.TURN)
  47. elif self.state == self.TURN:
  48. out_vel.angular.z = self.SPEED_ANGULAR
  49. if self.check_turn_2_forward():
  50. self.go_state(self.FORWARD)
  51. elif self.state == self.STOP:
  52. if self.check_stop_2_forward():
  53. self.go_state(self.FORWARD)
  54. self.vel_pub.publish(out_vel)
  55. def go_state(self, new_state):
  56. self.state = new_state
  57. self.state_ts = self.get_clock().now()
  58. def check_forward_2_back(self):
  59. pos = round(len(self.last_scan.ranges) / 2)
  60. return self.last_scan.ranges[pos] < self.OBSTACLE_DISTANCE
  61. def check_forward_2_stop(self):
  62. elapsed = self.get_clock().now() - Time.from_msg(self.last_scan.header.stamp)
  63. return elapsed > Duration(seconds=self.SCAN_TIMEOUT)
  64. def check_stop_2_forward(self):
  65. elapsed = self.get_clock().now() - Time.from_msg(self.last_scan.header.stamp)
  66. return elapsed < Duration(seconds=self.SCAN_TIMEOUT)
  67. def check_back_2_turn(self):
  68. elapsed = self.get_clock().now() - self.state_ts
  69. return elapsed > Duration(seconds=self.BACKING_TIME)
  70. def check_turn_2_forward(self):
  71. elapsed = self.get_clock().now() - self.state_ts
  72. return elapsed > Duration(seconds=self.TURNING_TIME)
  73. def main(args=None):
  74. rclpy.init(args=args)
  75. bump_go_node = BumpGoNode()
  76. rclpy.spin(bump_go_node)
  77. bump_go_node.destroy_node()
  78. rclpy.shutdown()
  79. if __name__ == '__main__':
  80. main()

可以看到Python,基本一个全包了……

之前C++,分别为头文件,功能实现和主程序等。

launch:

  1. from launch import LaunchDescription
  2. from launch_ros.actions import Node
  3. def generate_launch_description():
  4. kobuki_cmd = Node(package='br2_fsm_bumpgo_py',
  5. executable='bump_go_main',
  6. output='screen',
  7. parameters=[{
  8. 'use_sim_time': True
  9. }],
  10. remappings=[
  11. ('input_scan', '/scan_raw'),
  12. ('output_vel', '/nav_vel')
  13. ])
  14. ld = LaunchDescription()
  15. ld.add_action(kobuki_cmd)
  16. return ld

没有了CMakelist但需要setup:

  1. from glob import glob
  2. import os
  3. from setuptools import setup
  4. package_name = 'br2_fsm_bumpgo_py'
  5. setup(
  6. name=package_name,
  7. version='0.0.0',
  8. packages=[package_name],
  9. data_files=[
  10. ('share/ament_index/resource_index/packages',
  11. ['resource/' + package_name]),
  12. ('share/' + package_name, ['package.xml']),
  13. (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py'))
  14. ],
  15. install_requires=['setuptools'],
  16. zip_safe=True,
  17. maintainer='fmrico',
  18. maintainer_email='fmrico@gmail.com',
  19. description='TODO: Package description',
  20. license='TODO: License declaration',
  21. tests_require=['pytest'],
  22. entry_points={
  23. 'console_scripts': [
  24. 'bump_go_main = br2_fsm_bumpgo_py.bump_go_main:main'
  25. ],
  26. },
  27. )

具体内容参考书中介绍。

剩下的几乎一致了。

为了运行程序,首先通过在终端中键入以下命令启动模拟程序:

$ ros2 launch br2 tiago sim.launch.py

打开另一个终端,然后运行程序:

$ ros2 run br2 fsm bumpgo py bump go main --ros-args -r output vel:=/nav vel -r

input scan:=/scan raw -p use sim time:=true

还可以使用类似于C++版本的启动器,只需键入:

$ ros2 launch br2 fsm bumpgo py bump and go.launch.py

建议的练习:

1.修改Bump and Go项目,使机器人感知到前方左右对角线上的障碍物。它不是总是转向同一侧,而是转向没有障碍物的一侧。

2.修改“凹凸”(避障)项目,使机器人准确地转向无障碍物或更远的障碍物的角度。尝试两种方法:

开环:转弯前计算转弯时间和速度。

闭环:旋转,直到检测到前方的没有障碍物(开阔区域)。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号