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.

121 lines
4.3 KiB

  1. # Hello World Demo
  2. FUNMAP is a hardware-targeted perception, planning, and navigation framework developed by Hello Robot for ROS developers and researchers. Some of the key features provided by FUNMAP include cliff detection, closed-loop navigation, and mapping. In this tutorial, we will explore a hello world writing demo using FUNMAP.
  3. ## Motivation
  4. Stretch is a contacts-sensitive robot, making it compliant in human spaces. This contact sensitivity can be leveraged for surface and obstacles detection. Through this demo we demonstrate one specific application of contacts detection - surface writing. In this demo, Stretch writes out the letters 'H', 'E', 'L', 'L', and 'O' in a sequential manner.
  5. ## Workspace Setup
  6. Things that you will need
  7. - Whiteboard
  8. - Marker
  9. Ideally, this demo requires a whiteboard that is placed at the same height as the Stretch. The writing surface must be flat and reachable by the robot's arm.
  10. ## How-to-run
  11. After building and sourcing the workspace, home the robot:
  12. ```bash
  13. stretch_robot_home.py
  14. ```
  15. This ensures that the underlying stretch_body package knows the exact joint limits and provides the user with a good starting joint configuration.
  16. After homing, launch the hello world demo:
  17. ```bash
  18. ros2 launch stretch_demos hello_world.launch.py
  19. ```
  20. This command will launch stretch_driver, stretch_funmap, and the hello_world nodes.
  21. Next, in a separate terminal, run:
  22. ```bash
  23. ros2 run stretch_core keyboard_teleop --ros-args -p hello_world_on:=true
  24. ```
  25. You will be presented with a keyboard teleoperation menu. Teleoperate the robot so that the arm is perpendicular to the writing surface, about 30 cm away. Place a marker pointing outward in the robot's gripper. Once the robot is ready, press ‘`’ or '~’ to trigger hello world writing.
  26. ## Code Explained
  27. The clean_surface node uses the joint_trajectory_server inside stretch_core to send out target joint positions.
  28. ```python
  29. self.trajectory_client = ActionClient(self,
  30. FollowJointTrajectory,
  31. '/stretch_controller/follow_joint_trajectory',
  32. callback_group=self.callback_group
  33. )
  34. server_reached = self.trajectory_client.wait_for_server(timeout_sec=60.0)
  35. if not server_reached:
  36. self.get_logger().error('Unable to connect to joint_trajectory_server. Timeout exceeded.')
  37. sys.exit()
  38. ```
  39. Additionally, the node also subscribes to Stretch’s joint states topic.
  40. ```python
  41. self.joint_states_subscriber = self.create_subscription(JointState,
  42. '/stretch/joint_states',
  43. callback=self.joint_states_callback,
  44. qos_profile=10,
  45. callback_group=self.callback_group
  46. )
  47. ```
  48. Whenever the user triggers the hello world write service, the robot moves to an initial joint configuration:
  49. ```python
  50. def move_to_initial_configuration(self):
  51. initial_pose = {'wrist_extension': 0.01,
  52. 'joint_lift': self.letter_top_lift_m,
  53. 'joint_wrist_yaw': 0.0}
  54. self.logger.info('Move to initial arm pose for writing.')
  55. self.move_to_pose(initial_pose)
  56. ```
  57. Thereafter, the node uses FUNMAP's `align_to_nearest_cliff` service to align the Stretch w.r.t the whiteboard.
  58. ```python
  59. def align_to_surface(self):
  60. self.logger.info('align_to_surface')
  61. trigger_request = Trigger.Request()
  62. trigger_result = self.trigger_align_with_nearest_cliff_service.call_async(trigger_request)
  63. self.logger.info('trigger_result = {0}'.format(trigger_result))
  64. ```
  65. After aligning with the whiteboard, the node then proceeds to execute joint position goals to draw out each letter of the word "hello":
  66. ```python
  67. self.letter_h()
  68. self.space()
  69. self.letter_e()
  70. self.space()
  71. self.letter_l()
  72. self.space()
  73. self.letter_l()
  74. self.space()
  75. self.letter_o()
  76. self.space()
  77. return Trigger.Response(
  78. success=True,
  79. message='Completed writing hello!'
  80. )
  81. ```
  82. ## Results and Expectations
  83. This demo serves as an experimental setup to explore whiteboard writing with Stretch. Please be advised that this code is not expected to work perfectly. Some of the shortcomings of the demo include:
  84. - Each Stretch has unique calibration thresholds. The contacts thresholds defined in the stock demo code might not work for your Stretch. Additional tuning might be necessary.
  85. - The quality of the written text structure is also highly dependent on mobile base movements. Currently, navigation is open-loop and does not account for accumulated error terms.
  86. Users are encouraged to try this demo and submit improvements.