Browse Source

Merge pull request #8 from hello-robot/fix/minor_edits

Updates and fix
pull/11/head
Chintan Desai 1 year ago
committed by GitHub
parent
commit
1e7c7f0de2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 180 additions and 94 deletions
  1. +3
    -2
      getting_started/quick_start_guide_re1.md
  2. +2
    -0
      getting_started/quick_start_guide_re2.md
  3. +2
    -2
      mkdocs.yml
  4. +5
    -6
      ros1/README.md
  5. +1
    -1
      ros1/autodocking_nav_stack.md
  6. +1
    -1
      ros1/example_4.md
  7. +1
    -1
      ros1/example_8.md
  8. +5
    -5
      ros1/follow_joint_trajectory.md
  9. +2
    -2
      ros2/README.md
  10. +2
    -2
      ros2/align_to_aruco.md
  11. +1
    -1
      ros2/deep_perception.md
  12. +7
    -8
      ros2/example_10.md
  13. +4
    -2
      ros2/example_2.md
  14. +1
    -1
      ros2/example_4.md
  15. +1
    -1
      ros2/follow_joint_trajectory.md
  16. +2
    -2
      ros2/getting_started.md
  17. +5
    -1
      ros2/internal_state_of_stretch.md
  18. +48
    -0
      ros2/perception.md
  19. +45
    -34
      stretch_body/tutorial_dynamixel_servos.md
  20. +20
    -9
      stretch_body/tutorial_introduction.md
  21. +7
    -3
      stretch_body/tutorial_parameter_management.md
  22. +11
    -6
      stretch_body/tutorial_robot_motion.md
  23. +4
    -1
      stretch_body/tutorial_splined_trajectories.md

+ 3
- 2
getting_started/quick_start_guide_re1.md View File

@ -143,7 +143,7 @@ Once the robot has homed, let's write some quick test code:
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ipython ipython
``` ```
Now let's move the robot around using the Robot API. Try typing in these interactive commands at the iPython prompt: Now let's move the robot around using the Robot API. Try typing in these interactive commands at the iPython prompt:
```{.python .no-copy} ```{.python .no-copy}
@ -177,7 +177,8 @@ robot.end_of_arm.move_to('stretch_gripper',-50)
robot.stow() robot.stow()
robot.stop() robot.stop()
``` ```
!!! note
The iPython interpreter also allows you to execute blocks of code in a single go instead of running commands line by line. To end the interpreter session, type exit() and press enter.
## Change Credentials ## Change Credentials
Finally, we recommend that you change the login credentials for the default user, hello-robot. Finally, we recommend that you change the login credentials for the default user, hello-robot.

+ 2
- 0
getting_started/quick_start_guide_re2.md View File

@ -194,6 +194,8 @@ robot.end_of_arm.move_to('stretch_gripper',-50)
robot.stow() robot.stow()
robot.stop() robot.stop()
``` ```
!!! note
The iPython interpreter also allows you to execute blocks of code in a single go instead of running commands line by line. To end the interpreter session, type exit() and press enter.
## Change Credentials ## Change Credentials

+ 2
- 2
mkdocs.yml View File

@ -130,7 +130,7 @@ nav:
- FUNMAP: https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap - FUNMAP: https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap
- Gazebo Basics: ./ros1/gazebo_basics.md - Gazebo Basics: ./ros1/gazebo_basics.md
- Other Examples: - Other Examples:
- Teleoperate Stretch with a Node: ./ros1/example_1.md
- Mobile Base Velocity Control: ./ros1/example_1.md
- Filter Laser Scans: ./ros1/example_2.md - Filter Laser Scans: ./ros1/example_2.md
- Mobile Base Collision Avoidance: ./ros1/example_3.md - Mobile Base Collision Avoidance: ./ros1/example_3.md
- Give Stretch a Balloon: ./ros1/example_4.md - Give Stretch a Balloon: ./ros1/example_4.md
@ -170,7 +170,7 @@ nav:
# - Other Nav Stack Features: ./ros2/other_nav_features.md # - Other Nav Stack Features: ./ros2/other_nav_features.md
# - Gazebo Basics: ./ros2/gazebo_basics.md # - Gazebo Basics: ./ros2/gazebo_basics.md
- Other Examples: - Other Examples:
- Teleoperate Stretch with a Node: ./ros2/example_1.md
- Mobile Base Velocity Control: ./ros2/example_1.md
- Filter Laser Scans: ./ros2/example_2.md - Filter Laser Scans: ./ros2/example_2.md
- Mobile Base Collision Avoidance: ./ros2/example_3.md - Mobile Base Collision Avoidance: ./ros2/example_3.md
- Give Stretch a Balloon: ./ros2/example_4.md - Give Stretch a Balloon: ./ros2/example_4.md

+ 5
- 6
ros1/README.md View File

@ -17,12 +17,11 @@ This tutorial track is for users looking to get familiar with programming Stretc
| 4 | [Internal State of Stretch](internal_state_of_stretch.md) | Monitor the joint states of Stretch. | | 4 | [Internal State of Stretch](internal_state_of_stretch.md) | Monitor the joint states of Stretch. |
| 5 | [RViz Basics](rviz_basics.md) | Visualize topics in Stretch. | | 5 | [RViz Basics](rviz_basics.md) | Visualize topics in Stretch. |
| 6 | [Navigation Stack](navigation_stack.md) | Motion planning and control for the mobile base using Nav stack. | | 6 | [Navigation Stack](navigation_stack.md) | Motion planning and control for the mobile base using Nav stack. |
| 7 | [MoveIt! Basics](moveit_basics.md) | Motion planning and control for the arm using MoveIt. |
| 8 | [Follow Joint Trajectory Commands](follow_joint_trajectory.md) | Control joints using joint trajectory server. |
| 9 | [Perception](perception.md) | Use the Realsense D435i camera to visualize the environment. |
| 10 | [ArUco Marker Detection](aruco_marker_detection.md) | Localize objects using ArUco markers. |
| 11 | [ReSpeaker Microphone Array](respeaker_microphone_array.md) | Learn to use the ReSpeaker Microphone Array. |
| 12 | [FUNMAP](https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap) | Fast Unified Navigation, Manipulation and Planning. |
| 7 | [Follow Joint Trajectory Commands](follow_joint_trajectory.md) | Control joints using joint trajectory server. |
| 8 | [Perception](perception.md) | Use the Realsense D435i camera to visualize the environment. |
| 9 | [ArUco Marker Detection](aruco_marker_detection.md) | Localize objects using ArUco markers. |
| 10 | [ReSpeaker Microphone Array](respeaker_microphone_array.md) | Learn to use the ReSpeaker Microphone Array. |
| 11 | [FUNMAP](https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap) | Fast Unified Navigation, Manipulation and Planning. |
## Other Examples ## Other Examples

+ 1
- 1
ros1/autodocking_nav_stack.md View File

@ -71,7 +71,7 @@ The third child of the root node is the `Move to dock` action node. This is a si
The fourth and final child of the sequence node is another `fallback` node with two children - the `Charging?` condition node and the `Move to predock` action node with an `inverter` decorator node (+/- sign). The `Charging?` condition node is a subscriber that checks if the 'present' attribute of the `BatteryState` message is True. If the robot has backed up correctly into the docking station and the charger port latched, this node should return SUCCESS and the autodocking would succeed. If not, the robot moves back to the predock pose through the `Move to predock` action node and tries again. The fourth and final child of the sequence node is another `fallback` node with two children - the `Charging?` condition node and the `Move to predock` action node with an `inverter` decorator node (+/- sign). The `Charging?` condition node is a subscriber that checks if the 'present' attribute of the `BatteryState` message is True. If the robot has backed up correctly into the docking station and the charger port latched, this node should return SUCCESS and the autodocking would succeed. If not, the robot moves back to the predock pose through the `Move to predock` action node and tries again.
## Code Breakdown ## Code Breakdown
Let's jump into the code to see how things work under the hood. Follow along [here]() (TODO after merge) to have a look at the entire script.
Let's jump into the code to see how things work under the hood. Follow along [here](https://github.com/hello-robot/stretch_ros/blob/noetic/stretch_demos/nodes/autodocking_bt.py) to have a look at the entire script.
We start off by importing the dependencies. The ones of interest are those relating to py-trees and the various behaviour classes in autodocking.autodocking_behaviours, namely, MoveBaseActionClient, CheckTF and VisualServoing. We also created custom ROS action messages for the ArucoHeadScan action defined in the action directory of stretch_demos package. We start off by importing the dependencies. The ones of interest are those relating to py-trees and the various behaviour classes in autodocking.autodocking_behaviours, namely, MoveBaseActionClient, CheckTF and VisualServoing. We also created custom ROS action messages for the ArucoHeadScan action defined in the action directory of stretch_demos package.
```python ```python

+ 1
- 1
ros1/example_4.md View File

@ -172,7 +172,7 @@ The next line, `rospy.init_node(NAME, ...)`, is very important as it tells rospy
Instantiate class with `Balloon()`. Instantiate class with `Balloon()`.
Give control to ROS with `rospy.spin()`. This will allow the callback to be called whenever new messages come in. If we don't put this line in, then the node will not work, and ROS will not process any messages.
The `rospy.rate()` is the rate at which the node is going to publish information (10 Hz).
```python ```python
while not rospy.is_shutdown(): while not rospy.is_shutdown():

+ 1
- 1
ros1/example_8.md View File

@ -9,7 +9,7 @@ This example will showcase how to save the interpreted speech from Stretch's [Re
Begin by running the `respeaker.launch` file in a terminal. Begin by running the `respeaker.launch` file in a terminal.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
roslaunch respeaker_ros sample_respeaker.launch
roslaunch respeaker_ros respeaker.launch
``` ```
Then run the [speech_text.py](https://github.com/hello-robot/stretch_tutorials/blob/noetic/src/speech_text.py) node. In a new terminal, execute: Then run the [speech_text.py](https://github.com/hello-robot/stretch_tutorials/blob/noetic/src/speech_text.py) node. In a new terminal, execute:

+ 5
- 5
ros1/follow_joint_trajectory.md View File

@ -293,12 +293,12 @@ You can also actuate a single joint for the Stretch. Below is the list of joints
```{.bash .no-copy} ```{.bash .no-copy}
############################# JOINT LIMITS ############################# ############################# JOINT LIMITS #############################
joint_lift: lower_limit = 0.15, upper_limit = 1.10 # in meters
joint_lift: lower_limit = 0.00, upper_limit = 1.10 # in meters
wrist_extension: lower_limit = 0.00, upper_limit = 0.50 # in meters wrist_extension: lower_limit = 0.00, upper_limit = 0.50 # in meters
joint_wrist_yaw: lower_limit = -1.75, upper_limit = 4.00 # in radians joint_wrist_yaw: lower_limit = -1.75, upper_limit = 4.00 # in radians
joint_head_pan: lower_limit = -2.80, upper_limit = 2.90 # in radians
joint_head_tilt: lower_limit = -1.60, upper_limit = 0.40 # in radians
joint_gripper_finger_left: lower_limit = -0.35, upper_limit = 0.165 # in radians
joint_head_pan: lower_limit = -3.90, upper_limit = 1.50 # in radians
joint_head_tilt: lower_limit = -1.53, upper_limit = 0.79 # in radians
joint_gripper_finger_left: lower_limit = -0.6, upper_limit = 0.6 # in radians
# INCLUDED JOINTS IN POSITION MODE # INCLUDED JOINTS IN POSITION MODE
translate_mobile_base: No lower or upper limit. Defined by a step size in meters translate_mobile_base: No lower or upper limit. Defined by a step size in meters
@ -410,4 +410,4 @@ trajectory_goal.trajectory.header.stamp = rospy.Time(0.0)
trajectory_goal.trajectory.header.frame_id = 'base_link' trajectory_goal.trajectory.header.frame_id = 'base_link'
``` ```
Set `trajectory_goal` as a `FollowJointTrajectoryGoal` and define the joint names as a list. Then `trajectory_goal.trajectory.points` set by your list of points. Specify the coordinate frame that we want (*base_link*) and set the time to be now.
Set `trajectory_goal` as a `FollowJointTrajectoryGoal` and define the joint names as a list. Then `trajectory_goal.trajectory.points` set by your list of points. Specify the coordinate frame that we want (*base_link*) and set the time to be now.

+ 2
- 2
ros2/README.md View File

@ -18,10 +18,10 @@ This tutorial track is for users looking to get familiar with programming Stretc
| 2 | [Follow Joint Trajectory Commands](follow_joint_trajectory.md) | Control joints using joint trajectory server. | | 2 | [Follow Joint Trajectory Commands](follow_joint_trajectory.md) | Control joints using joint trajectory server. |
| 3 | [Internal State of Stretch](internal_state_of_stretch.md) | Monitor the joint states of Stretch. | | 3 | [Internal State of Stretch](internal_state_of_stretch.md) | Monitor the joint states of Stretch. |
| 4 | [RViz Basics](rviz_basics.md) | Visualize topics in Stretch. | | 4 | [RViz Basics](rviz_basics.md) | Visualize topics in Stretch. |
| 5 | [MoveIt2 Basics](moveit_basics.md) | Motion planning and control for the arm using MoveIt. |
<!--| 5 | [MoveIt2 Basics](moveit_basics.md) | Motion planning and control for the arm using MoveIt. |
| 6 | [MoveIt2 with Rviz](moveit_rviz_demo.md) | Motion planning and control for the arm using MoveIt. | | 6 | [MoveIt2 with Rviz](moveit_rviz_demo.md) | Motion planning and control for the arm using MoveIt. |
| 7 | [MoveIt2 MoveGroup C++ API](moveit_movegroup_demo.md) | Motion planning and control for the arm using MoveIt. | | 7 | [MoveIt2 MoveGroup C++ API](moveit_movegroup_demo.md) | Motion planning and control for the arm using MoveIt. |
<!--| 9 | [Perception](coming_soon.md) | Use the Realsense D435i camera to visualize the environment. |
| 9 | [Perception](coming_soon.md) | Use the Realsense D435i camera to visualize the environment. |
| 10 | [ArUco Marker Detection](coming_soon.md) | Localize objects using ArUco markers. | | 10 | [ArUco Marker Detection](coming_soon.md) | Localize objects using ArUco markers. |
| 11 | [ReSpeaker Microphone Array](coming_soon.md) | Learn to use the ReSpeaker Microphone Array. | | 11 | [ReSpeaker Microphone Array](coming_soon.md) | Learn to use the ReSpeaker Microphone Array. |
| 12 | [FUNMAP](https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap) | Fast Unified Navigation, Manipulation and Planning. | | 12 | [FUNMAP](https://github.com/hello-robot/stretch_ros/tree/master/stretch_funmap) | Fast Unified Navigation, Manipulation and Planning. |

+ 2
- 2
ros2/align_to_aruco.md View File

@ -84,7 +84,7 @@ The joint_states_callback is the callback method that receives the most recent j
self.joint_state = joint_state self.joint_state = joint_state
``` ```
The copute_difference() method is where we call the get_transform() method from the FrameListener class to compute the difference between the base_link and base_right frame with an offset of 0.5 m in the negative y-axis.
The compute_difference() method is where we call the get_transform() method from the FrameListener class to compute the difference between the base_link and base_right frame with an offset of 0.5 m in the negative y-axis.
```python ```python
def compute_difference(self): def compute_difference(self):
self.trans_base, self.trans_camera = self.node.get_transforms() self.trans_base, self.trans_camera = self.node.get_transforms()
@ -103,7 +103,7 @@ To compute the (x, y) coordinates of the SE2 pose goal, we compute the transform
base_position_y = P_base[1, 0] base_position_y = P_base[1, 0]
``` ```
From this, it is relatively straightforward to compute the angle phi and the euclidean distance dist. We then compute the angle z_rot_base to perform the last angle correction.
From this, it is relatively straightforward to compute the angle **phi** and the euclidean distance **dist**. We then compute the angle z_rot_base to perform the last angle correction.
```python ```python
phi = atan2(base_position_y, base_position_x) phi = atan2(base_position_y, base_position_x)

+ 1
- 1
ros2/deep_perception.md View File

@ -134,7 +134,7 @@ ros2 launch stretch_deep_perception stretch_detect_faces.launch.py
![detect_faces](https://user-images.githubusercontent.com/97639181/196327737-7091cd61-f79a-4ff0-a291-039ab3f7127a.gif) ![detect_faces](https://user-images.githubusercontent.com/97639181/196327737-7091cd61-f79a-4ff0-a291-039ab3f7127a.gif)
## Code Breakdown ## Code Breakdown
Ain't that something! If you followed the breakdown in object detection, you'll find that the only change if you are looking to detect faces, facial landmarks or estimat head pose instead of detecting objects is in using a different deep learning model that does just that. For this, we will explore how to use the OpenVINO toolkit. Let's head to the detect_faces.py [node](https://github.com/hello-robot/stretch_ros2/blob/galactic/stretch_deep_perception/stretch_deep_perception/detect_faces.py) to begin.
Ain't that something! If you followed the breakdown in object detection, you'll find that the only change if you are looking to detect faces, facial landmarks or estimate head pose instead of detecting objects is in using a different deep learning model that does just that. For this, we will explore how to use the OpenVINO toolkit. Let's head to the detect_faces.py [node](https://github.com/hello-robot/stretch_ros2/blob/galactic/stretch_deep_perception/stretch_deep_perception/detect_faces.py) to begin.
In the main() method, we see a similar structure as with the object detction node. We first create an instance of the detector using the HeadPoseEstimator class from the [head_estimator.py](https://github.com/hello-robot/stretch_ros2/blob/galactic/stretch_deep_perception/stretch_deep_perception/head_estimator.py) script to configure the deep learning models. Next, we pass this to an instance of the DetectionNode class from the detection_node.py script and call the main function. In the main() method, we see a similar structure as with the object detction node. We first create an instance of the detector using the HeadPoseEstimator class from the [head_estimator.py](https://github.com/hello-robot/stretch_ros2/blob/galactic/stretch_deep_perception/stretch_deep_perception/head_estimator.py) script to configure the deep learning models. Next, we pass this to an instance of the DetectionNode class from the detection_node.py script and call the main function.
```python ```python

+ 7
- 8
ros2/example_10.md View File

@ -1,4 +1,4 @@
# Example 10
## Example 10
!!! note !!! note
ROS 2 tutorials are still under active development. ROS 2 tutorials are still under active development.
@ -21,13 +21,13 @@ ros2 run rviz2 rviz2
Then run the tf2 broadcaster node to visualize three static frames. Then run the tf2 broadcaster node to visualize three static frames.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 run stretch_ros_tutorials tf2_broadcaster
ros2 run stretch_ros_tutorials tf_broadcaster
``` ```
The GIF below visualizes what happens when running the previous node. The GIF below visualizes what happens when running the previous node.
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/ROS2/images/tf2_broadcaster.gif"/>
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/tf2_broadcaster.gif"/>
</p> </p>
**OPTIONAL**: If you would like to see how the static frames update while the robot is in motion, run the stow command node and observe the tf frames in RViz. **OPTIONAL**: If you would like to see how the static frames update while the robot is in motion, run the stow command node and observe the tf frames in RViz.
@ -35,9 +35,8 @@ The GIF below visualizes what happens when running the previous node.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 run stretch_ros_tutorials stow_command ros2 run stretch_ros_tutorials stow_command
``` ```
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/ROS2/images/tf2_broadcaster_with_stow.gif"/>
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/tf2_broadcaster_with_stow.gif"/>
</p> </p>
### The Code ### The Code
@ -222,13 +221,13 @@ ros2 launch stretch_core stretch_driver.launch.py
Then run the tf2 broadcaster node to create the three static frames. Then run the tf2 broadcaster node to create the three static frames.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 run stretch_ros_tutorials tf2_broadcaster
ros2 run stretch_ros_tutorials tf_broadcaster
``` ```
Finally, run the tf2 listener node to print the transform between two links. Finally, run the tf2 listener node to print the transform between two links.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 run stretch_ros_tutorials tf2_listener
ros2 run stretch_ros_tutorials tf_listener
``` ```
Within the terminal the transform will be printed every 1 second. Below is an example of what will be printed in the terminal. There is also an image for reference of the two frames. Within the terminal the transform will be printed every 1 second. Below is an example of what will be printed in the terminal. There is also an image for reference of the two frames.
@ -247,7 +246,7 @@ rotation:
``` ```
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/ROS2/images/tf2_listener.png"/>
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/tf2_listener.png"/>
</p> </p>
### The Code ### The Code

+ 4
- 2
ros2/example_2.md View File

@ -59,9 +59,11 @@ ros2 run stretch_ros_tutorials scan_filter
Then run the following command to bring up a simple RViz configuration of the Stretch robot. Then run the following command to bring up a simple RViz configuration of the Stretch robot.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 run rviz2 rviz2 -d `ros2 pkg prefix stretch_calibration`/rviz/stretch_simple_test.rviz
ros2 run rviz2 rviz2 -d `ros2 pkg prefix stretch_calibration`/share/stretch_calibration/rviz/stretch_simple_test.rviz
``` ```
!!! note
If the laser scan points published by the scan or the scan_filtered topic are not visible in RViz, you can visualize them by adding them using the 'Add' button in the left panel, selecting the 'By topic' tab, and then selecting the scan or scan_filtered topic.
Change the topic name from the LaserScan display from */scan* to */filter_scan*. Change the topic name from the LaserScan display from */scan* to */filter_scan*.
<p align="center"> <p align="center">

+ 1
- 1
ros2/example_4.md View File

@ -9,7 +9,7 @@ Let's bring up Stretch in RViz by using the following command.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 launch stretch_core stretch_driver.launch.py ros2 launch stretch_core stretch_driver.launch.py
ros2 run rviz2 rviz2 -d `ros2 pkg prefix stretch_calibrtion`/rviz/stretch_simple_test.rviz
ros2 run rviz2 rviz2 -d `ros2 pkg prefix stretch_calibration`/share/stretch_calibration/rviz/stretch_simple_test.rviz
``` ```
In a new terminal run the following commands to create a marker. In a new terminal run the following commands to create a marker.

+ 1
- 1
ros2/follow_joint_trajectory.md View File

@ -1,6 +1,6 @@
## FollowJointTrajectory Commands ## FollowJointTrajectory Commands
!!! note !!! note
ROS 2 tutorials are still under active development.
ROS 2 tutorials are still under active development. For this exercise you'll need to have Ubuntu 22.04 and ROS Iron for it to work completly.
Stretch driver offers a [`FollowJointTrajectory`](http://docs.ros.org/en/api/control_msgs/html/action/FollowJointTrajectory.html) action service for its arm. Within this tutorial, we will have a simple FollowJointTrajectory command sent to a Stretch robot to execute. Stretch driver offers a [`FollowJointTrajectory`](http://docs.ros.org/en/api/control_msgs/html/action/FollowJointTrajectory.html) action service for its arm. Within this tutorial, we will have a simple FollowJointTrajectory command sent to a Stretch robot to execute.

+ 2
- 2
ros2/getting_started.md View File

@ -22,13 +22,13 @@ We will disable ROS1 by commenting out the ROS1 related lines by adding '#' in f
Save this configuration using **Ctrl + S**. Close out of the current terminal and open a new one. ROS2 is now enabled! Save this configuration using **Ctrl + S**. Close out of the current terminal and open a new one. ROS2 is now enabled!
## Refreshing the ROS2 workspace ## Refreshing the ROS2 workspace
While Stretch ROS2 is in beta, there will be frequent updates to the ROS2 software. Therefore, it makes sense to refresh the ROS2 software to the latest available release. In the ROS and ROS2 world, software is organized into "ROS Workspaces", where packages can be developed, compiled, and be made available to run from the command line. We are going to refresh the ROS2 workspace, which is called "~/ament_ws" and available in the home directory. Follow the [Create a new ROS Workspace guide](https://docs.hello-robot.com/0.2/stretch-install/docs/ros_workspace/) to run the `stretch_create_ament_workspace.sh` script. This will delete the existing "~/ament_ws", create a new one with all of the required ROS2 packages for Stretch, and compile it.
While Stretch ROS2 is in beta, there will be frequent updates to the ROS2 software. Therefore, it makes sense to refresh the ROS2 software to the latest available release. In the ROS and ROS2 world, software is organized into "ROS Workspaces", where packages can be developed, compiled, and be made available to run from the command line. We are going to refresh the ROS2 workspace, which is called "~/ament_ws" and available in the home directory. Follow the [Create a new ROS Workspace guide](https://docs.hello-robot.com/0.2/stretch-install/docs/ros_workspace/) to run the `stretch_create_ament_workspace.sh` script. This will delete the existing "~/ament_ws", create a new one with all of the required ROS2 packages for Stretch, and compile it. Also we need to take into account that building the workspace is different in ROS2, we need to type colcon build instead of catkin make for it to work.
## Testing Keyboard Teleop ## Testing Keyboard Teleop
We can test whether the ROS2 workspace was enabled successfully by testing out the ROS2 drivers package, called "stretch_core", with keyboard teleop. In one terminal, we'll launch Stretch's ROS2 drivers using: We can test whether the ROS2 workspace was enabled successfully by testing out the ROS2 drivers package, called "stretch_core", with keyboard teleop. In one terminal, we'll launch Stretch's ROS2 drivers using:
```{.bash .shell-prompt} ```{.bash .shell-prompt}
ros2 launch stretch_core stretch_driver.launch.py mode:=manipulation
ros2 launch stretch_core stretch_driver.launch.py
``` ```
In the second terminal, launch the keyboard teleop node using: In the second terminal, launch the keyboard teleop node using:

+ 5
- 1
ros2/internal_state_of_stretch.md View File

@ -41,6 +41,10 @@ A powerful tool to visualize the ROS communication is through the rqt_graph pack
ros2 run rqt_graph rqt_graph ros2 run rqt_graph rqt_graph
``` ```
![image](https://raw.githubusercontent.com/hello-robot/stretch_tutorials/ROS2/images/rqt_graph.png)
![image](https://github.com/hello-robot/stretch_tutorials/assets/141784078/9d6a303c-1681-4723-932c-212f5ced1044)
The graph allows a user to observe and affirm if topics are broadcasted to the correct nodes. This method can also be utilized to debug communication issues. The graph allows a user to observe and affirm if topics are broadcasted to the correct nodes. This method can also be utilized to debug communication issues.

+ 48
- 0
ros2/perception.md View File

@ -0,0 +1,48 @@
## Perception Introduction
The Stretch robot is equipped with the [Intel RealSense D435i camera](https://www.intelrealsense.com/depth-camera-d435i/), an essential component that allows the robot to measure and analyze the world around it. In this tutorial, we are going to showcase how to visualize the various topics published by the camera.
Begin by running the stretch `driver.launch.py` file.
```{.bash .shell-prompt}
ros2 launch stretch_core stretch_driver.launch.py
```
To activate the [RealSense camera](https://www.intelrealsense.com/depth-camera-d435i/) and publish topics to be visualized, run the following launch file in a new terminal.
```{.bash .shell-prompt}
ros2 launch stretch_core d435i_low_resolution.launch.py
```
Within this tutorial package, there is an [RViz config file](https://github.com/hello-robot/stretch_tutorials/blob/noetic/rviz/perception_example.rviz) with the topics for perception already in the Display tree. You can visualize these topics and the robot model by running the command below in a new terminal.
```{.bash .shell-prompt}
ros2 run rviz2 rviz2 -d /home/hello-robot/ament_ws/src/stretch_tutorials/rviz/perception_example.rviz
```
### PointCloud2 Display
A list of displays on the left side of the interface can visualize the camera data. Each display has its properties and status that notify a user if topic messages are received.
For the `PointCloud2` display, a [sensor_msgs/pointCloud2](http://docs.ros.org/en/lunar/api/sensor_msgs/html/msg/PointCloud2.html) message named `/camera/depth/color/points` is received and the GIF below demonstrates the various display properties when visualizing the data.
<p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/perception_rviz.gif"/>
</p>
### Image Display
The `Image` display when toggled creates a new rendering window that visualizes a [sensor_msgs/Image](http://docs.ros.org/en/lunar/api/sensor_msgs/html/msg/Image.html) messaged, */camera/color/image_raw*. This feature shows the image data from the camera; however, the image comes out sideways.
<p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/perception_image.gif"/>
</p>
### DepthCloud Display
The `DepthCloud` display is visualized in the main RViz window. This display takes in the depth image and RGB image provided by RealSense to visualize and register a point cloud.
<p align="center">
<img src="https://raw.githubusercontent.com/hello-robot/stretch_tutorials/noetic/images/perception_depth.gif"/>
</p>
## Deep Perception
Hello Robot also has a ROS package that uses deep learning models for various detection demos. A link to the tutorials is provided: [stretch_deep_perception](https://docs.hello-robot.com/0.2/stretch-tutorials/ros2/deep_perception/).

+ 45
- 34
stretch_body/tutorial_dynamixel_servos.md View File

@ -32,7 +32,7 @@ REx_dynamixel_jog.py /dev/hello-dynamixel-head 11
Output: Output:
```{.bash .no-copy} ```{.bash .no-copy}
[Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080
[Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080. Baud 115200
------ MENU ------- ------ MENU -------
m: menu m: menu
a: increment position 50 tick a: increment position 50 tick
@ -52,6 +52,10 @@ t: set max temp
i: set id i: set id
d: disable torque d: disable torque
e: enable torque e: enable torque
x: put in multi-turn mode
y: put in position mode
w: put in pwm mode
f: put in vel mode
------------------- -------------------
``` ```
@ -67,12 +71,14 @@ Output:
```{.bash .no-copy} ```{.bash .no-copy}
For use with S T R E T C H (TM) RESEARCH EDITION from Hello Robot Inc. For use with S T R E T C H (TM) RESEARCH EDITION from Hello Robot Inc.
Rebooting: head_pan
[Dynamixel ID:011] Reboot Succeeded. [Dynamixel ID:011] Reboot Succeeded.
Rebooting: head_tilt
[Dynamixel ID:012] Reboot Succeeded. [Dynamixel ID:012] Reboot Succeeded.
[Dynamixel ID:013] Reboot Succeeded.
Rebooting: stretch_gripper
[Dynamixel ID:014] Reboot Succeeded. [Dynamixel ID:014] Reboot Succeeded.
Rebooting: wrist_yaw
[Dynamixel ID:013] Reboot Succeeded.
``` ```
### Identify Servos on the Bus ### Identify Servos on the Bus
@ -80,38 +86,42 @@ For use with S T R E T C H (TM) RESEARCH EDITION from Hello Robot Inc.
If it is unclear which servos are on the bus, and at what baud rate, you can use the `REx_dynamixel_id_scan.py` tool. Here we see that the two head servos are at ID `11` and `12` at baud `57600`. If it is unclear which servos are on the bus, and at what baud rate, you can use the `REx_dynamixel_id_scan.py` tool. Here we see that the two head servos are at ID `11` and `12` at baud `57600`.
```{.bash .shell-prompt} ```{.bash .shell-prompt}
REx_dynamixel_id_scan.py /dev/hello-dynamixel-head --baud 57600
REx_dynamixel_id_scan.py /dev/hello-dynamixel-head
``` ```
Output: Output:
```{.bash .no-copy} ```{.bash .no-copy}
Scanning bus /dev/hello-dynamixel-head at baud rate 57600 Scanning bus /dev/hello-dynamixel-head at baud rate 57600
---------------------------------------------------------- ----------------------------------------------------------
[Dynamixel ID:000] ping Failed.
[Dynamixel ID:001] ping Failed.
[Dynamixel ID:002] ping Failed.
[Dynamixel ID:003] ping Failed.
[Dynamixel ID:004] ping Failed.
[Dynamixel ID:005] ping Failed.
[Dynamixel ID:006] ping Failed.
[Dynamixel ID:007] ping Failed.
[Dynamixel ID:008] ping Failed.
[Dynamixel ID:009] ping Failed.
[Dynamixel ID:010] ping Failed.
[Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080
[Dynamixel ID:012] ping Succeeded. Dynamixel model number : 1060
[Dynamixel ID:013] ping Failed.
[Dynamixel ID:014] ping Failed.
[Dynamixel ID:015] ping Failed.
[Dynamixel ID:016] ping Failed.
[Dynamixel ID:017] ping Failed.
[Dynamixel ID:018] ping Failed.
[Dynamixel ID:019] ping Failed.
[Dynamixel ID:020] ping Failed.
[Dynamixel ID:021] ping Failed.
[Dynamixel ID:022] ping Failed.
[Dynamixel ID:023] ping Failed.
[Dynamixel ID:024] ping Failed.
Scanning bus /dev/hello-dynamixel-head
Checking ID 0
Checking ID 1
Checking ID 2
Checking ID 3
Checking ID 4
Checking ID 5
Checking ID 6
Checking ID 7
Checking ID 8
Checking ID 9
Checking ID 10
Checking ID 11
[Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080. Baud 115200
Checking ID 12
[Dynamixel ID:012] ping Succeeded. Dynamixel model number : 1060. Baud 115200
Checking ID 13
Checking ID 14
Checking ID 15
Checking ID 16
Checking ID 17
Checking ID 18
Checking ID 19
Checking ID 20
Checking ID 21
Checking ID 22
Checking ID 23
Checking ID 24
``` ```
### Setting the Servo Baud Rate ### Setting the Servo Baud Rate
@ -125,10 +135,8 @@ REx_dynamixel_set_baud.py /dev/hello-dynamixel-wrist 13 115200
Output: Output:
```{.bash .no-copy} ```{.bash .no-copy}
--------------------- ---------------------
Checking servo current baud for 57600
Identified current baud of 57600. Changing baud to 115200
Success at changing baud
Success at changing baud. Current baud is 115200 for servo 13 on bus /dev/hello-dynamixel-wrist
``` ```
!!! note !!! note
@ -139,15 +147,15 @@ Success at changing baud
Dynamixel servos come with `ID=1` from the factory. When adding your servos to the end-of-arm tool, you may want to set the servo ID using the `REx_dynamixel_id_change.py` tool. For example: Dynamixel servos come with `ID=1` from the factory. When adding your servos to the end-of-arm tool, you may want to set the servo ID using the `REx_dynamixel_id_change.py` tool. For example:
```{.bash .shell-prompt} ```{.bash .shell-prompt}
REx_dynamixel_id_change.py /dev/hello-dynamixel-wrist 1 13 --baud 115200
REx_dynamixel_id_change.py /dev/hello-dynamixel-wrist 1 13
``` ```
Output: Output:
```{.bash .no-copy} ```{.bash .no-copy}
[Dynamixel ID:001] ping Succeeded. Dynamixel model number : 1080
[Dynamixel ID:001] ping Succeeded. Dynamixel model number : 1080. Baud 115200
Ready to change ID 1 to 13. Hit enter to continue: Ready to change ID 1 to 13. Hit enter to continue:
[Dynamixel ID:013] ping Succeeded. Dynamixel model number : 1080
[Dynamixel ID:013] ping Succeeded. Dynamixel model number : 1080. Baud 115200
Success at setting ID to 13 Success at setting ID to 13
``` ```

+ 20
- 9
stretch_body/tutorial_introduction.md View File

@ -95,24 +95,35 @@ Parameters may be named with a suffix to help describe the unit type. For exampl
### The Robot Status ### The Robot Status
The Robot derives from the [Device class](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/device.py). It also encapsulates several other Devices:
The Robot derives from the [Device class](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/device.py) and we have subclasses that derives from this Device class such as the [Prismatic Joint](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/prismatic_joint.py) and the [Dynamixel XL460](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_hello_XL430.py). It also encapsulates several other Devices:
* [robot.head](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/head.py)
* [robot.arm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/arm.py)
* [robot.lift](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/lift.py)
**Device**
* [robot.base](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/base.py) * [robot.base](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/base.py)
* [robot.wacc](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/wacc.py) * [robot.wacc](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/wacc.py)
* [robot.pimu](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/pimu.py) * [robot.pimu](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/pimu.py)
**Prismatic Joint**
* [robot.arm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/arm.py)
* [robot.lift](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/lift.py)
**Dynamixel XL460**
* [robot.head](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/head.py)
* [robot.end_of_arm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm.py) * [robot.end_of_arm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm.py)
All devices contain a Status dictionary. The Status contains the most recent sensor and state data of that device. For example, looking at the Arm class we see: All devices contain a Status dictionary. The Status contains the most recent sensor and state data of that device. For example, looking at the Arm class we see:
```python ```python
class Arm(Device):
def __init__(self):
class Arm(PrismaticJoint):
def __init__(self,usb=None):
```
As we can see the arm class is part of the PrismaticJoint class but this is also part of the Device class as we can see here:
```python
class PrismaticJoint(Device):
def __init__(self,name,usb=None):
... ...
self.status = {'pos': 0.0, 'vel': 0.0, 'force':0.0, \
'motor':self.motor.status,'timestamp_pc':0}
self.status = {'timestamp_pc':0,'pos':0.0, 'vel':0.0, \
'force':0.0,'motor':self.motor.status}
``` ```
The Status dictionaries are automatically updated by a background thread of the Robot class at around 25Hz. The Status data can be accessed via the Robot class as below: The Status dictionaries are automatically updated by a background thread of the Robot class at around 25Hz. The Status data can be accessed via the Robot class as below:
@ -189,4 +200,4 @@ robot.stop()
The Dynamixel servos do not use the Hello Robot communication protocol. As such, the head, wrist, and gripper will move immediately upon issuing a motion command. The Dynamixel servos do not use the Hello Robot communication protocol. As such, the head, wrist, and gripper will move immediately upon issuing a motion command.
------ ------
<div align="center"> All materials are Copyright 2022 by Hello Robot Inc. Hello Robot and Stretch are registered trademarks.</div>
<div align="center"> All materials are Copyright 2022 by Hello Robot Inc. Hello Robot and Stretch are registered trademarks.</div>

+ 7
- 3
stretch_body/tutorial_parameter_management.md View File

@ -15,7 +15,9 @@ a.params
```{.python .no-copy} ```{.python .no-copy}
Out[7]: Out[7]:
{'chain_pitch': 0.0167,
{'usb_name': '/dev/hello-motor-arm',
'force_N_per_A': 55.9
'chain_pitch': 0.0167,
'chain_sprocket_teeth': 10, 'chain_sprocket_teeth': 10,
'gr_spur': 3.875, 'gr_spur': 3.875,
'i_feedforward': 0, 'i_feedforward': 0,
@ -42,7 +44,9 @@ a.robot_params['lift']
```{.python .no-copy} ```{.python .no-copy}
Out[9]: Out[9]:
{'calibration_range_bounds': [1.094, 1.106],
{'usb_name': '/dev/hello-motor-lift',
'force_N_per_A': 75.0
'calibration_range_bounds': [1.094, 1.106],
'contact_model': 'effort_pct', 'contact_model': 'effort_pct',
'contact_model_homing': 'effort_pct', 'contact_model_homing': 'effort_pct',
'contact_models': {'effort_pct': {'contact_thresh_calibration_margin': 10.0, 'contact_models': {'effort_pct': {'contact_thresh_calibration_margin': 10.0,
@ -149,4 +153,4 @@ robot.write_user_param_to_YAML('base.wheel_separation_m', d_avg)
This will update the file `stretch_user_params.yaml`. This will update the file `stretch_user_params.yaml`.
------ ------
<div align="center"> All materials are Copyright 2022 by Hello Robot Inc. Hello Robot and Stretch are registered trademarks.</div>
<div align="center"> All materials are Copyright 2022 by Hello Robot Inc. Hello Robot and Stretch are registered trademarks.</div>

+ 11
- 6
stretch_body/tutorial_robot_motion.md View File

@ -4,13 +4,14 @@ As we've seen in previous tutorials, commanding robot motion is simple and strai
```python linenums="1" ```python linenums="1"
import stretch_body.robot import stretch_body.robot
import time
robot=stretch_body.robot.Robot() robot=stretch_body.robot.Robot()
robot.startup() robot.startup()
robot.arm.move_by(0.1) robot.arm.move_by(0.1)
robot.push_command() robot.push_command()
time.sleep(2.0) time.sleep(2.0)
robot.stop() robot.stop()
``` ```
@ -18,13 +19,14 @@ The absolute motion can be commanded by:
```python linenums="1" ```python linenums="1"
import stretch_body.robot import stretch_body.robot
import time
robot=stretch_body.robot.Robot() robot=stretch_body.robot.Robot()
robot.startup() robot.startup()
robot.arm.move_to(0.1) robot.arm.move_to(0.1)
robot.push_command() robot.push_command()
time.sleep(2.0) time.sleep(2.0)
robot.stop() robot.stop()
``` ```
@ -34,6 +36,7 @@ In the above examples, we executed a `time.sleep()` after `robot.push_command()`
```python linenums="1" ```python linenums="1"
import stretch_body.robot import stretch_body.robot
import time
robot=stretch_body.robot.Robot() robot=stretch_body.robot.Robot()
robot.startup() robot.startup()
@ -50,7 +53,7 @@ robot.push_command()
time.sleep(2.0) time.sleep(2.0)
robot.arm.move_to(0.0) robot.arm.move_to(0.0)
robot.arm.wait_until_at_setpoint() robot.arm.wait_until_at_setpoint()
robot.stop() robot.stop()
``` ```
@ -118,7 +121,7 @@ robot.arm.wait_until_at_setpoint()
robot.arm.move_to(0.5) robot.arm.move_to(0.5)
robot.push_command() robot.push_command()
robot.arm.wait_until_at_setpoint() robot.arm.wait_until_at_setpoint()
robot.stop() robot.stop()
``` ```
@ -130,6 +133,7 @@ As we see here, the `robot.push_command()` call is not required as the motion be
```python ```python
import stretch_body.robot import stretch_body.robot
import time
from stretch_body.hello_utils import deg_to_rad from stretch_body.hello_utils import deg_to_rad
robot=stretch_body.robot.Robot() robot=stretch_body.robot.Robot()
@ -144,7 +148,7 @@ robot.head.move_to('head_pan',deg_to_rad(90.0))
robot.head.move_to('head_tilt',deg_to_rad(45.0)) robot.head.move_to('head_tilt',deg_to_rad(45.0))
time.sleep(3.0) time.sleep(3.0)
robot.stop() robot.stop()
``` ```
@ -152,6 +156,7 @@ Similar to the stepper joints, the Dynamixel joints accept motion profile and mo
```python ```python
import stretch_body.robot import stretch_body.robot
import time
robot=stretch_body.robot.Robot() robot=stretch_body.robot.Robot()
robot.startup() robot.startup()
@ -172,7 +177,7 @@ a = robot.params['head_pan']['motion']['slow']['accel']
robot.head.move_to('head_pan',deg_to_rad(90.0),v_r=v, a_r=a) robot.head.move_to('head_pan',deg_to_rad(90.0),v_r=v, a_r=a)
time.sleep(3.0) time.sleep(3.0)
robot.stop() robot.stop()
``` ```

+ 4
- 1
stretch_body/tutorial_splined_trajectories.md View File

@ -61,6 +61,7 @@ Programming a splined trajectory is straightforward. For example, try the follow
import stretch_body.robot import stretch_body.robot
r=stretch_body.robot.Robot() r=stretch_body.robot.Robot()
r.startup() r.startup()
#r.arm.motor.disable_sync_mode() **If you want to try running the code with this command you'll need to coment the r.push_command() and it will work as well
#Define the waypoints #Define the waypoints
times = [0.0, 10.0, 20.0] times = [0.0, 10.0, 20.0]
@ -73,6 +74,8 @@ for waypoint in zip(times, positions, velocities):
#Begin execution #Begin execution
r.arm.follow_trajectory() r.arm.follow_trajectory()
r.push_command()
time.sleep(0.1)
#Wait unti completion #Wait unti completion
while r.arm.is_trajectory_active(): while r.arm.is_trajectory_active():
@ -87,7 +90,7 @@ This will cause the arm to move from its current position to 0.45m, then back to
* This will execute a Cubic spline as we did not pass in accelerations to in `r.arm.trajectory.add` * This will execute a Cubic spline as we did not pass in accelerations to in `r.arm.trajectory.add`
* The call to `r.arm.follow_trajectory` is non-blocking and the trajectory generation is handled by a background thread of the Robot class * The call to `r.arm.follow_trajectory` is non-blocking and the trajectory generation is handled by a background thread of the Robot class
If you're interested in exploring the trajectory API further the [code for the `stretch_trajectory_jog.py`](https://github.com/hello-robot/stretch_body/blob/master/tools/bin/stretch_trajectory_jog.py) is a great reference to get started.
If you're interested in exploring the trajectory API further. the [code for the `stretch_trajectory_jog.py`](https://github.com/hello-robot/stretch_body/blob/master/tools/bin/stretch_trajectory_jog.py) is a great reference to get started.
## Advanced: Controller Parameters ## Advanced: Controller Parameters

Loading…
Cancel
Save