You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
5.4 KiB

2 years ago
  1. ## Example 1
  2. <p align="center">
  3. <img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/main/images/move_stretch.gif"/>
  4. </p>
  5. The goal of this example is to give you an enhanced understanding of how to control the mobile base by sending `Twist` messages to a Stretch robot.
  6. Begin by running the following command in a new terminal.
  7. ```bash
  8. # Terminal 1
  9. roslaunch stretch_core stretch_driver.launch
  10. ```
  11. Switch the mode to *navigation* mode using a rosservice call. Then drive the robot forward with the [move.py](https://github.com/hello-robot/stretch_tutorials/tree/main/src/move.py) node.
  12. ```bash
  13. # Terminal 2
  14. rosservice call /switch_to_navigation_mode
  15. cd catkin_ws/src/stretch_tutorials/src/
  16. python move.py
  17. ```
  18. To stop the node from sending twist messages, type **Ctrl** + **c**.
  19. ### The Code
  20. Below is the code which will send *Twist* messages to drive the robot forward.
  21. ```python
  22. #!/usr/bin/env python
  23. import rospy
  24. from geometry_msgs.msg import Twist
  25. class Move:
  26. """
  27. A class that sends Twist messages to move the Stretch robot forward.
  28. """
  29. def __init__(self):
  30. """
  31. Function that initializes the subscriber.
  32. :param self: The self reference.
  33. """
  34. self.pub = rospy.Publisher('/stretch/cmd_vel', Twist, queue_size=1) #/stretch_diff_drive_controller/cmd_vel for gazebo
  35. def move_forward(self):
  36. """
  37. Function that publishes Twist messages
  38. :param self: The self reference.
  39. :publishes command: Twist message.
  40. """
  41. command = Twist()
  42. command.linear.x = 0.1
  43. command.linear.y = 0.0
  44. command.linear.z = 0.0
  45. command.angular.x = 0.0
  46. command.angular.y = 0.0
  47. command.angular.z = 0.0
  48. self.pub.publish(command)
  49. if __name__ == '__main__':
  50. rospy.init_node('move')
  51. base_motion = Move()
  52. rate = rospy.Rate(10)
  53. while not rospy.is_shutdown():
  54. base_motion.move_forward()
  55. rate.sleep()
  56. ```
  57. ### The Code Explained
  58. Now let's break the code down.
  59. ```python
  60. #!/usr/bin/env python
  61. ```
  62. Every Python ROS [Node](http://wiki.ros.org/Nodes) will have this declaration at the top. The first line makes sure your script is executed as a Python script.
  63. ```python
  64. import rospy
  65. from geometry_msgs.msg import Twist
  66. ```
  67. You need to import `rospy` if you are writing a ROS [Node](http://wiki.ros.org/Nodes). The `geometry_msgs.msg` import is so that we can send velocity commands to the robot.
  68. ```python
  69. class Move:
  70. def __init__(self):
  71. self.pub = rospy.Publisher('/stretch/cmd_vel', Twist, queue_size=1)#/stretch_diff_drive_controller/cmd_vel for gazebo
  72. ```
  73. This section of code defines the talker's interface to the rest of ROS. `pub = rospy.Publisher("/stretch/cmd_vel", Twist, queue_size=1)` declares that your node is publishing to the */stretch/cmd_vel* topic using the message type `Twist`. The `queue_size` argument limits the amount of queued messages if any subscriber is not receiving them fast enough.
  74. ```Python
  75. command = Twist()
  76. ```
  77. Make a `Twist` message. We're going to set all of the elements, since we can't depend on them defaulting to safe values.
  78. ```python
  79. command.linear.x = 0.1
  80. command.linear.y = 0.0
  81. command.linear.z = 0.0
  82. ```
  83. A `Twist` data structure has three linear velocities (in meters per second), along each of the axes. For Stretch, it will only pay attention to the x velocity, since it can't directly move in the y direction or the z direction.
  84. ```python
  85. command.angular.x = 0.0
  86. command.angular.y = 0.0
  87. command.angular.z = 0.0
  88. ```
  89. A `Twist` message also has three rotational velocities (in radians per second). The Stretch will only respond to rotations around the z (vertical) axis.
  90. ```python
  91. self.pub.publish(command)
  92. ```
  93. Publish the `Twist` commands in the previously defined topic name */stretch/cmd_vel*.
  94. ```Python
  95. rospy.init_node('move')
  96. base_motion = Move()
  97. rate = rospy.Rate(10)
  98. ```
  99. The next line, `rospy.init_node(NAME, ...)`, is very important as it tells rospy the name of your node -- until rospy has this information, it cannot start communicating with the ROS Master. **NOTE:** the name must be a base name, i.e. it cannot contain any slashes "/".
  100. The `rospy.Rate()` function creates a Rate object. With the help of its method `sleep()`, it offers a convenient way for looping at the desired rate. With its argument of 10, we should expect to go through the loop 10 times per second (as long as our processing time does not exceed 1/10th of a second!)
  101. ```python
  102. while not rospy.is_shutdown():
  103. base_motion.move_forward()
  104. rate.sleep()
  105. ```
  106. This loop is a fairly standard rospy construct: checking the `rospy.is_shutdown()` flag and then doing work. You have to check `is_shutdown()` to check if your program should exit (e.g. if there is a **Ctrl-C** or otherwise). The loop calls `rate.sleep()`, which sleeps just long enough to maintain the desired rate through the loop.
  107. ## Move Stretch in Simulation
  108. <p align="center">
  109. <img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/main/images/move.gif"/>
  110. </p>
  111. Using your preferred text editor, modify the topic name of the published `Twist` messages. Please review the edit in the **move.py** script below.
  112. ```python
  113. self.pub = rospy.Publisher('/stretch_diff_drive_controller/cmd_vel', Twist, queue_size=1)
  114. ```
  115. After saving the edited node, bringup [Stretch in the empty world simulation](gazebo_basics.md). To drive the robot with the node, type the following in a new terminal
  116. ```bash
  117. cd catkin_ws/src/stretch_tutorials/src/
  118. python move.py
  119. ```
  120. To stop the node from sending twist messages, type **Ctrl** + **c**.