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.

246 lines
8.7 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. # Tutorial: Working with Dynamixel Servos
  2. In this tutorial, we will go into the details with Dynamixel servos and Stretch.
  3. ## Overview
  4. Stretch comes with two Dynamixel buses - one for the head and one for the end-of-arm:
  5. ```{.bash .shell-prompt}
  6. ls /dev/hello-dynamixel-*
  7. ```
  8. Output:
  9. ```{.bash .no-copy}
  10. /dev/hello-dynamixel-head /dev/hello-dynamixel-wrist
  11. ```
  12. Typically, users will interact with these devices through either the [Head](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/head.py) or the [EndOfArm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm.py) interfaces. This tutorial is for users looking to work directly with the servos from the provided servo tools or through Stretch Body's low-level Dynamixel API.
  13. ## Servo Tools
  14. !!! note
  15. The servo tools here are part of the [Stretch Factory package](https://github.com/hello-robot/stretch_factory) which is installed as a part of Stretch Body.
  16. ### Jogging the Servos
  17. You can directly command each servo using the command line tool `REx_dynamixel_servo_jog.py`. This can be useful for debugging new servos added to the end-of-arm tool during system bring-up. For example, to command the head pan servo:
  18. ```{.bash .shell-prompt}
  19. REx_dynamixel_jog.py /dev/hello-dynamixel-head 11
  20. ```
  21. Output:
  22. ```{.bash .no-copy}
  23. [Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080
  24. ------ MENU -------
  25. m: menu
  26. a: increment position 50 tick
  27. b: decrement position 50 tick
  28. A: increment position 500 ticks
  29. B: decrement position 500 ticks
  30. v: set profile velocity
  31. u: set profile acceleration
  32. z: zero position
  33. h: show homing offset
  34. o: zero homing offset
  35. q: got to position
  36. p: ping
  37. r: reboot
  38. w: set max pwm
  39. t: set max temp
  40. i: set id
  41. d: disable torque
  42. e: enable torque
  43. -------------------
  44. ```
  45. ### Rebooting the Servos
  46. Under high-load conditions, the servos may enter an error state to protect themselves from thermal overload. In this case, the red LED on the servo will flash (if visible). In addition, the servo will be unresponsive to motion commands. In this case, allow the overheating servo to cool down and reboot the servos using the `stretch_robot_dynamixel_reboot.py` tool:
  47. ```{.bash .shell-prompt}
  48. stretch_robot_dynamixel_reboot.py
  49. ```
  50. Output:
  51. ```{.bash .no-copy}
  52. For use with S T R E T C H (TM) RESEARCH EDITION from Hello Robot Inc.
  53. ---- Rebooting Head ----
  54. [Dynamixel ID:011] Reboot Succeeded.
  55. [Dynamixel ID:012] Reboot Succeeded.
  56. ---- Rebooting Wrist ----
  57. [Dynamixel ID:013] Reboot Succeeded.
  58. [Dynamixel ID:014] Reboot Succeeded.
  59. ```
  60. ### Identify Servos on the Bus
  61. 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`.
  62. ```{.bash .shell-prompt}
  63. REx_dynamixel_id_scan.py /dev/hello-dynamixel-head --baud 57600
  64. ```
  65. Output:
  66. ```{.bash .no-copy}
  67. Scanning bus /dev/hello-dynamixel-head at baud rate 57600
  68. ----------------------------------------------------------
  69. [Dynamixel ID:000] ping Failed.
  70. [Dynamixel ID:001] ping Failed.
  71. [Dynamixel ID:002] ping Failed.
  72. [Dynamixel ID:003] ping Failed.
  73. [Dynamixel ID:004] ping Failed.
  74. [Dynamixel ID:005] ping Failed.
  75. [Dynamixel ID:006] ping Failed.
  76. [Dynamixel ID:007] ping Failed.
  77. [Dynamixel ID:008] ping Failed.
  78. [Dynamixel ID:009] ping Failed.
  79. [Dynamixel ID:010] ping Failed.
  80. [Dynamixel ID:011] ping Succeeded. Dynamixel model number : 1080
  81. [Dynamixel ID:012] ping Succeeded. Dynamixel model number : 1060
  82. [Dynamixel ID:013] ping Failed.
  83. [Dynamixel ID:014] ping Failed.
  84. [Dynamixel ID:015] ping Failed.
  85. [Dynamixel ID:016] ping Failed.
  86. [Dynamixel ID:017] ping Failed.
  87. [Dynamixel ID:018] ping Failed.
  88. [Dynamixel ID:019] ping Failed.
  89. [Dynamixel ID:020] ping Failed.
  90. [Dynamixel ID:021] ping Failed.
  91. [Dynamixel ID:022] ping Failed.
  92. [Dynamixel ID:023] ping Failed.
  93. [Dynamixel ID:024] ping Failed.
  94. ```
  95. ### Setting the Servo Baud Rate
  96. Stretch ships with its Dynamixel servos configured to `baudrate=115200`. When adding your servos to the end-of-arm tool, you may want to set the servo baud using the `REx_dynamixel_set_baud.py` tool. For example:
  97. ```{.bash .shell-prompt}
  98. REx_dynamixel_set_baud.py /dev/hello-dynamixel-wrist 13 115200
  99. ```
  100. Output:
  101. ```{.bash .no-copy}
  102. ---------------------
  103. Checking servo current baud for 57600
  104. ----
  105. Identified current baud of 57600. Changing baud to 115200
  106. Success at changing baud
  107. ```
  108. !!! note
  109. Earlier units of Stretch RE1 may be running Dynamixel servos at baud 57600.
  110. ### Setting the Servo ID
  111. 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:
  112. ```{.bash .shell-prompt}
  113. REx_dynamixel_id_change.py /dev/hello-dynamixel-wrist 1 13 --baud 115200
  114. ```
  115. Output:
  116. ```{.bash .no-copy}
  117. [Dynamixel ID:001] ping Succeeded. Dynamixel model number : 1080
  118. Ready to change ID 1 to 13. Hit enter to continue:
  119. [Dynamixel ID:013] ping Succeeded. Dynamixel model number : 1080
  120. Success at setting ID to 13
  121. ```
  122. ## Stretch Body Dynamixel API
  123. Stretch Body's low-level Dynamixel API includes a hierarchy of three classes
  124. | Class |
  125. | ------------------------------------------------------------ |
  126. | [DynamixelXChain](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_X_chain.py) |
  127. | [DynamixelHelloXL430](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_hello_XL430.py) |
  128. | [DynamixelXL430](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_XL430.py) |
  129. !!! note
  130. The naming of XL430 is for legacy reasons. These classes will work with all X Series servos.
  131. ### DynamixelXChain
  132. DynamixelXChain manages a set of daisy-chained servos on a single bus (for example the head_pan and head_tilt servos). It allows for greater communication bandwidth by doing a group read/write over USB.
  133. The [EndOfArm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm.py) class derives from DynamixelXChain to provide an extensible interface that supports a user in integrating additional degrees of freedom to the robot. The tutorial [Adding Custom Wrist DoF](./tutorial_custom_wrist_dof.md) explains how to do this.
  134. ### DynamixelHelloXL430
  135. DynamixelHelloXL430 provides an interface to servo motion that is consistent with the Stretch Body lift, arm, and base joints. It also manages the servo parameters and calibration. Let's explore this interface further. From iPython, let's look at the status message for DynamixelHelloXL430
  136. ```python
  137. import stretch_body.dynamixel_hello_XL430
  138. m = stretch_body.dynamixel_hello_XL430.DynamixelHelloXL430('head_pan')
  139. m.startup()
  140. m.pretty_print()
  141. ```
  142. Output:
  143. ```{.python .no-copy}
  144. ----- HelloXL430 ------
  145. Name head_pan
  146. Position (rad) -0.0
  147. Position (deg) -0.0
  148. Position (ticks) 1250
  149. Velocity (rad/s) -0.0
  150. Velocity (ticks/s) 0
  151. Effort (%) 0.0
  152. Effort (ticks) 0
  153. Temp 34.0
  154. Comm Errors 0
  155. Hardware Error 0
  156. Hardware Error: Input Voltage Error: False
  157. Hardware Error: Overheating Error: False
  158. Hardware Error: Motor Encoder Error: False
  159. Hardware Error: Electrical Shock Error: False
  160. Hardware Error: Overload Error: False
  161. Watchdog Errors: 0
  162. Timestamp PC 1661552966.7202659
  163. Range (ticks) [0, 3827]
  164. Range (rad) [ 1.9174759848570513 , -3.953068490381297 ]
  165. Stalled True
  166. Stall Overload False
  167. Is Calibrated 0
  168. ```
  169. We see that it reports the position in both radians (with respect to the joint frame) and ticks (with respect to the servo encoder). DynamixelHelloXL430 handles the calibration between the two using its method `ticks_to_world_rad` through the following params:
  170. ```{.bash .shell-prompt}
  171. stretch_params.py | grep head_pan | grep '_t '
  172. ```
  173. Output:
  174. ```{.bash .no-copy}
  175. stretch_configuration_params.yaml param.head_pan.range_t [0, 3827]
  176. stretch_configuration_params.yaml param.head_pan.zero_t 1250
  177. ```
  178. In addition to `move_to` and `move_by`, the class also implements a splined trajectory interface as discussed in the [Splined Trajectory Tutorial](./tutorial_splined_trajectories.md).
  179. ### DynamixelXL430
  180. DynamixelXL430 provides a thin wrapper to the [Robotis Dynamixel SDK](http://emanual.robotis.com/docs/en/dxl/x/xl430-w250/#control-table). You may choose to interact with the servo at this level as well. For example, to jog the head_pan 200 ticks:
  181. ```python
  182. import stretch_body.dynamixel_XL430
  183. import time
  184. m = stretch_body.dynamixel_XL430.DynamixelXL430(11, '/dev/hello-dynamixel-head',baud=115200)
  185. m.startup()
  186. x=m.get_pos() #In encoder ticks
  187. m.go_to_pos(x+200) #Move 200 ticks incremental
  188. time.sleep(2.0)
  189. m.stop()
  190. ```
  191. ------
  192. <div align="center"> All materials are Copyright 2022 by Hello Robot Inc. Hello Robot and Stretch are registered trademarks.</div>