From 9c4b71e34d3ed1efe94ec15a744aebe679fa1db0 Mon Sep 17 00:00:00 2001 From: Aaron Edsinger Date: Tue, 19 Jul 2022 02:34:50 -0700 Subject: [PATCH] wip --- .../robot_safety_guide.md | 0 docs/tool_change_tutorial.md | 247 ++++++++++++++++++ images/hello_robot_favicon.png | Bin 0 -> 1005 bytes images/hello_robot_logo_light.png | Bin 0 -> 7942 bytes mkdocs.yml | 14 +- 5 files changed, 254 insertions(+), 7 deletions(-) rename docs/{ => getting_started}/robot_safety_guide.md (100%) create mode 100644 docs/tool_change_tutorial.md create mode 100644 images/hello_robot_favicon.png create mode 100644 images/hello_robot_logo_light.png diff --git a/docs/robot_safety_guide.md b/docs/getting_started/robot_safety_guide.md similarity index 100% rename from docs/robot_safety_guide.md rename to docs/getting_started/robot_safety_guide.md diff --git a/docs/tool_change_tutorial.md b/docs/tool_change_tutorial.md new file mode 100644 index 0000000..befdfd2 --- /dev/null +++ b/docs/tool_change_tutorial.md @@ -0,0 +1,247 @@ +# Stretch RE1: Tool Change Tutorial + +Many users will want to work with tools other than the default Stretch Gripper that ships with the robot. In this tutorial you will learn how to configure the Stretch software interfaces to support other tools. + +## Changing Tool Interfaces in Stretch Body + +Stretch Body v0.1.x and later supports a plug-in based architecture for tools. A tool interface is an extension of the [EndOfArm](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm.py) class that supports additional degrees of freedom. + +### Standard Tools + +Stretch Body supports two tool interfaces by default: The [ToolNone & ToolStretchGripper](https://github.com/hello-robot/stretch_body/tree/master/body/end_of_arm_tools.py). We will explore swapping between these default tools. + +#### ToolStretchGripper + +The RE1 is configured to load the ToolStretchGripper interface by default. This tool is loaded according to the `stretch_re1_user_params.yaml` field: + +```yaml +robot: + tool: tool_stretch_gripper +``` + +We can interact with this tool from iPython + +```python +In [1]: import stretch_body.robot as robot + +In [2]: r=robot.Robot() + +In [3]: r.startup() + +In [4]: r.end_of_arm +Out[4]: + +In [5]: r.end_of_arm.motors +Out[5]: +{'stretch_gripper': , + 'wrist_yaw': } + +In [6]: r.end_of_arm.stow() +--------- Stowing Wrist Yaw ---- +--------- Stowing Gripper ---- +In [7]: r.stop() +``` + +#### ToolNone + +The ToolNone interface can be loaded when no tool is attached to the Wrist Yaw joint. To switch to this interface, simply update the field in your `stretch_re1_user_params.yaml` to: + +```yaml +robot: + tool: tool_none +``` + +After updating the YAML we can interact with the ToolNone via iPython + +```python +In [1]: import stretch_body.robot as robot + +In [2]: r=robot.Robot() + +In [3]: r.startup() + +In [4]: r.end_of_arm +Out[4]: + +In [5]: r.end_of_arm.motors +Out[5]: {'wrist_yaw': } + +In [6]: r.end_of_arm.stow() +--------- Stowing Wrist Yaw ---- +In [7]: r.stop() +``` + +## Loading Tool Interfaces from the Stretch Tool Share + +The [Stretch Tool Share](https://github.com/hello-robot/stretch_tool_share/) is an open Git repository for non-standard RE1 tools. It hosts the CAD, URDF, and Python files needed to integrate these tools onto your robot. + +To use Stretch Tool Share tools, first update your installation: + +```console +$ pip2 install hello-robot-stretch-tool-share +``` + +As an example, we see on the Tool Share that there is a tool, the [ToolDryEraseToolHolderV1](https://github.com/hello-robot/stretch_tool_share/blob/master/python/stretch_tool_share/dry_erase_holder_v1/tool.py) which [extends the EndOfArm](https://github.com/hello-robot/stretch_tool_share/blob/master/python/stretch_tool_share/usbcam_wrist_v1/tool.py) class. In order to load this tool interface , modify your `stretch_re1_user_params.yaml` to load the tool as before. We will also need to tell it where to find the tool's [parameter file](https://github.com/hello-robot/stretch_tool_share/blob/master/python/stretch_tool_share/dry_erase_holder_v1/params.py): + +```yaml +robot: + tool: tool_dry_erase_holder_v1 +params: +- stretch_tool_share.dry_erase_holder_v1.params +``` + +We can now interact with the tool in iPython: + +```python +In [1]: import stretch_body.robot as robot + +In [2]: r=robot.Robot() + +In [3]: r.startup() + +In [4]: r.end_of_arm +Out[4]: + +In [5]: r.end_of_arm.motors +Out[5]: {'wrist_yaw': } + +In [6]: r.end_of_arm.stow() +--------- Stowing Wrist Yaw ---- + +``` + +# Changing Tool Interfaces in Stretch ROS + +Next we'll show how to change the ROS interface for a tool. Here we will continue with the [ToolDryEraseHolderV1](https://github.com/hello-robot/stretch_tool_share/blob/master/python/stretch_tool_share/dry_erase_holder_v1/tool.py#L3) example. First, configure Stretch Body to use the tool as in the previous exercise. + +Next, ensure your ROS is up to date: + +```console +$ cd ~/catkin_ws/src/stretch_ros/ +$ git pull +``` + +To access the URDF data for the [ToolDryEraseHolderV1](https://github.com/hello-robot/stretch_tool_share/blob/master/python/stretch_tool_share/dry_erase_holder_v1/tool.py#L3) we'll need to clone the Tool Share repository: + +```console +$ cd ~/repos +$ git clone https://github.com/hello-robot/stretch_tool_share +``` + +Copy in the tool's URDF data into the Stretch ROS repository: + +```console +$ cd ~/repos/stretch_tool_share/tool_share/dry_erase_holder_v1 +$ cp stretch_description/urdf/*.xacro ~/catkin_ws/src/stretch_ros/stretch_description/urdf/ +$ cp stretch_description/meshes/*.STL ~/catkin_ws/src/stretch_ros/stretch_description/meshes/ +``` + +Now we will update the tool Xacro for Stretch. Open the file `~/catkin_ws/src/stretch_ros/stretch_description/urdf/stretch_description.xacro` in an editor. Comment out the current tool Xacro and include the Xacro for the dry erase holder. + +```xml + + + + + + + + + + + + +``` + +Finally, we'll update our already calibrated URDF to use this new tool: + +```console +$ cd ~/catkin_ws/src/stretch_ros/stretch_description/urdf +$ cp stretch.urdf stretch.urdf.bak +$ rosrun stretch_calibration update_urdf_after_xacro_change.sh +``` + +Ctrl-C when the `rosrun` command terminates and you're ready to visualize the tool in RViz: + +```console +$ roslaunch stretch_calibration simple_test_head_calibration.launch +``` + +![](./images/dry_erase_rviz.png) + +# Advanced Topics + +## Understanding How the Tool Plug-In Works + +For users looking to create their own custom tools it can be useful to understand how the tool plug-in architecture works. Here we will walk through the basics of the system for both Stretch Body and Stretch ROS + +### Stretch Body + +The [Robot](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/robot.py#L97) class expects an instance of EndOfArm tool to be present. The EndOfArm tool is an extension of the [DynamixelXChain](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_X_chain.py#L16) class, which manages a chain of Dynamixel servos. + +A tool is defined via its parameters (either in user YAML or Python). For example, the ToolStretchGripper is defined in [robot_params.py](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/robot_params.py). These parameters tell the plug-in which [DynamixelHelloXL430](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_hello_XL430.py) instances to load and manage. Here we see: + +```python +"tool_stretch_gripper": { + 'use_group_sync_read': 1, + 'retry_on_comm_failure': 1, + 'baud':115200, + 'verbose':0, + 'py_class_name': 'ToolStretchGripper', + 'py_module_name': 'stretch_body.end_of_arm_tools', + 'stow': {'stretch_gripper': 0, 'wrist_yaw': 3.4}, + 'devices': { + 'stretch_gripper': { + 'py_class_name': 'StretchGripper', + 'py_module_name': 'stretch_body.stretch_gripper' + }, + 'wrist_yaw': { + 'py_class_name': 'WristYaw', + 'py_module_name': 'stretch_body.wrist_yaw' + } + } +}, +``` + +This dictionary defines a tool of class ToolStretchGripper with two [DynamixelHelloXL430](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/dynamixel_hello_XL430.py) devices on its bus (StretchGripper and WristYaw). + +We see that the [ToolStretchGripper](https://github.com/hello-robot/stretch_body/blob/master/body/stretch_body/end_of_arm_tools.py#L7) class extends the EndOfArm class and provides its own stowing behavior: + +```python +class ToolStretchGripper(EndOfArm): + def __init__(self, name='tool_stretch_gripper'): + EndOfArm.__init__(self,name) + + def stow(self): + # Fold in wrist and gripper + print('--------- Stowing Wrist Yaw ----') + self.move_to('wrist_yaw', self.params['stow']['wrist_yaw']) + print('--------- Stowing Gripper ----') + self.move_to('stretch_gripper', self.params['stow']['stretch_gripper']) +``` + +For tools that are not a part of Stretch Body, such as from the Tool Share, you must include the tool parameters as well in your `stretch_re1_user_params.yaml`. A robot that must support many tools may have user YAML that looks like: + +```yaml +params: +- stretch_tool_share.usbcam_wrist_v1.params +- stretch_tool_share.stretch_dex_wrist_beta.params +- stretch_tool_share.dry_erase_holder_v1.params +robot: + tool: tool_dry_erase_holder_v1 + #tool: tool_none + #tool: tool_stretch_gripper + #tool: tool_usbcam_wrist_v1 + #tool: tool_stretch_dex_wrist_beta +``` + +For a more complex implementation of a tool we recommend reviewing the Stretch Dex Wrist implementation on the Stretch Tool Share. + +### Stretch ROS + +Stretch ROS also supports the tool plug-in architecture. Under ROS this is managed by extending the [SimpleCommandGroup](https://github.com/hello-robot/stretch_ros/blob/master/hello_helpers/src/hello_helpers/simple_command_group.py). + +More coming soon. + +------ +
All materials are Copyright 2020 by Hello Robot Inc. The Stretch RE1 robot has patents pending
diff --git a/images/hello_robot_favicon.png b/images/hello_robot_favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae562302d05af57af07f3932724941f6028caf2 GIT binary patch literal 1005 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+SzC{oH>NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!ItFh?!xdN1Q+aGJ{c&& zUgGKN%Kn6nm5)i~uSx8G1_q{&o-U3d5r^MSKkqN>D01B1c(?9SF3u%^Qlcvbl5HYf z>SR=foO>?TAISK!>SG7H(Bq>OpPx8BX4H4%SEZqV09<}=^qeLK77{JzTkv@jF7my8{Z;SG}=L^znG0^VH>nAvhWt6@R) ze_0PE{zgG*ix+lZcCyt+34U+h-MCt42hW^e-sjA-T@H?HdoFz~3&%{{8RQI+wi(dPt%{Zd!YhDooeaO#y-WKh&Pyh;1zlZ;+f)!ojD zSxk&F#}jp@E3X#`;)pl+$JnDN*Il@9`}A)SJ-Z5K>HXv${RaDmz=Xwk zib)_K=6kEdgNZk1Yb}`*8#s-5V)&{THzc_FHot8=BH_F*fI(AJqg5;Mcd%K)RHF?` zQcPw(Ikwn6<@)tXd+XhA_0oG1Gg4akKYw0wDRbKOYc`7&r24<;FjRX5`r{|ID-ld-#86X=^uzhy44zGkEXh0|EyB z_~+EKzKh&C@o#)=gTMujH-{D*m95}0V7$ZBR?i@i#o>z40H|5bPY^H3{9*IjI4}-Y;!9E1Cef~a1;%>`6-!cmAEyeUfcB=sDZ)L L)z4*}Q$iB}rU#$A literal 0 HcmV?d00001 diff --git a/images/hello_robot_logo_light.png b/images/hello_robot_logo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..7263472e21730d5755697851ae83a7d096760ff8 GIT binary patch literal 7942 zcmbU`2~?9;)}W&ZBB=$XC?r(}6czF3f|ZW`(G)p3c-QyGjylKYa7W^5g55k3{I0(ief!nA zZ;xMFmGT#li}IC`s;zqyX4h2A9K+>;;D1>xbwTOwyh0&_S2D? zE~RsC;u$!}7Q~Bzs8LSa<}LTX{qDh}8hOsfSn&-PZ#5$BvzVN7<19*X@%f&k3#L&I zcWVPC{?p&OK4zrQe5jZJ+u|a;jjHs<=V)~BuhzLIo^AY;(r6=Xlz$M!?LD*b_EB=8 z$%J?aRf)*54cXQv)Nl3hZf@i3tU)oD+E`Dy2kW`-hj?b`;umGgKCagg_gLbxUjMq+ zq3UD@xyK}$baszxV6KV^WjmHEcaB)oANoXB=wFyB){LM!PdzDQsL0J* z#&gifxOU;Kg$ECMj4AX$GEQK!>PS}fRPRpv`VZ#2Cf3_kQbyey&j_%qj$GA+5!dOD zSNO&r1)tBl?R_Nz(bvpSqjK>}cGQ|nxd93;Oia7*GJQ>x@I9;HY-K%4AYS#%;d=eD zQ|xCrIvJ7Ta!+A>ku@GR+G~gVa*Q(2%>?=RB3TPJhIw+cmlLIMF~(v-|+V z*hYPN#$PnTj#_)k=Z)UshfC81oTR5v2BE`Hw+0Ibm(B^WtDjZ9O%wLCsB>@L;mpbQ ztqGL4N}Bwb&pn#_xwR+Ra{E^+Y03FL+ZQ93C7+}sXYg28_$$l09DuyYfu#8U%_-S^e8tGT3~pm7{-0mBGrG`*#P*hxNB&_iwHQ^VZXXvr;X0*%(l_>b8o@vKtZ=BL z8XwtFiWqJ;j7jm@d1=2+q{XA$hIu{I;e=it2JgPDQH#v^}3 zZYGYrXHAw=FE@8Rw5Xd9S`{(W$6R#@k?E{HpR!B>ugBq_hk3e~ zfGR^)yJ=Ze=6Z~pV)fOpDp>>t1nGs&O-rHcHB`T(`W=k{0(}TAK7b0))A!Bj*>BqTuJ$bgc z7?FG1feTOZsHxPUYgC2f-a*fl@6i^h&i#)0v;0cF;Tlc*iF+=6^GWm4mC~}ca|wL2*k^RpBGNX#U|^Q z%XbfgOvinm$_V}1nf>Odq`Ini+tR51h;OH`9UKh5II=2tCT(#hAk*{WLY1=q25F4l zf<}boO_`=eU?xMKra>CM72xRtoYIN7L2BHQ6Hd+I=wriFL|4qzNS@p~!cu$R*bour z%!h077Qv`2>r<>GFkIZNu`c03$s)hOT}ZH=>Et#zQl`)TxtPOTOv@2{76 zcYXcNj#q3O-~Wm^%&=Dq4V$u32kE%K6J3H1F`>u_ya#N z^;MT&Y^is|<)j(7cpw{;!yjhV8Y9!}HI{wKh4W}^z1;jgMad@+g$|-o{cyO39r=-` zJ2EC!f9o@g*;B*&w%SQ1_!Q6gtDdw8O-W0$@}E>y#q>d6mtkDHa04rm^s4`0(^!_5 z?WG@?R??S)&p$dMI>L08Fq;Rk$u9BUT7D-A5}Tq=Ar7Xqa#@MQR|kCe*4EtR#3SZ9 z)<3ojtxv4UV8C)`!#qW!yTdy*BFNQRy@XF=zH8sENm`cHf|TU)q5ALdS)L(L;`651 zdik4o(bL8aGe+^i2S;~Rb3myD6h>GbDq)&xSX=H()@qP{_AK#KucbHFUt#=bFC*Iv~0_Hb4kH41W2Yf7{{f_g=7`(%!p$7}aSdjUtCzfrB> zYK}{|q>atcAKS5as@3h-h4O(kp|Le3S>E^nI4f=^j2EI%iZmBTDWA}Z+*tqkdOiFY z<)(ZaAca2RB|Rbt(%74)=-F*fT`W21Vemm*SJitk9ZPpkcDdy%5*~m_<8}*^P-Q*& z;GC-7e8e2Tx=fjvXG{LE-SAdiEXO&yywqt_Rf@SCQk-s(uO-2*P4%%u>UX?IY9EX&0qPO{o~iV60OHu1 zhunKp5x4m>wW_z2ySO-Zd$0{Ft$IZ9Z>LHJFH7#@T0Drs6ZcK6d8T_)6v=Pii=S8Z zX4WK#pVJwqFzyzTG4Oe^9=|^UF`3h}T*W3QTc2i=L1ES6`y16I9u9A3*>Fuh_ zE8xYnIJuzQkS1aix0H)#5Qitk$!uIc3be;>*|;R@{RO;$aB?6hS!Opee&ZP-XNBk% zCw&-2#qZ~;UKD*%G4%m$VINfp{3b+J)COG}K;WRR43Ua$1;_U?Z7oX}U znvtM}yav@3BQSh!6O@@#-vfN+xHrPwA9Nhnyd9l+-ssdG*QtkEIrvyX?X#{Rg;E55 z++f2DLa>cr#4m84jtod>&!q; zA8iwI-vmlvg$wy}1{G5bP-9#~QN3}{)^Lg+++Uh$TUQKu`iA|n-0p&Kw;^osK zVejddgE=#88xH9x;Y#DAPu-E)*q(vB{=te8Gc!=+o+>b0)Ms9rYO2D1ry$MMGN=GqsH|c`nKT7Q9s*z zC3*_*&p+)F`1D|EQKc5T*!+PT(NhoOhXsoqI%5Ri8q-9bk878Rs@sIt^u>B=3KC`NKPvOE^KdS=F&g^QulfbK*651r0K3eY> z8-14QQ@Ehu_guXrSi2{MX*2I_8u38|rJ={X%!%qbxa1{ZKHD1$le{>XA)cehpFj>C zB{P84=nQUiaqgpqTg>jmlXE=nTG>HbaxVlV+|e{(RwSGnD1&@iwDI_07AM-I@6{PDlf+ z*oNnVLZZFmZi9s3rZ+(2_R^FgzBlhQJ7kiohj@H#?L6T3~Ab00AGV2N2I zkZlJq2br5eofDgUNw0na-!bEC+DOyG4V51E<}8AcE4AjWiEOjFNaDY{!^tjMxH`dK z{8(#W+^mB|JOG7x)KVo`{|0kMMiJ=$Owz@9e2&F;RBsaGJb>o(E~FnALIA2|r_`6*09MgVB{=#0b*P}f6NplPX!H|p=IUk(&7AA5{HT+U`2 ze1%<32-3_kOl~z5te5HCioa@-uhud`r||m9K5hvmy>^kxtg7#DDg39GQm2IQ8N-OS`RL{ z3B*<|300jo{!qtD-pN1DeaVlb`)@y3(Zt0Z9423@FIgh=Zpd(O zv1bJEX9M?b$-9<2Kba+NB2Uwjiq*v>kMh;X3So8NN`@8OyLJMqP2~B<3mIN)nTx^3 zf@}Le60Gy@Wj#V@$#y*0K4qmqfbPDpkcl`B5J>8YSulLE;%aW!g5!gQW z#=coRF65gchSof@q*uKa(f_lhbb?(=m@}MU-C-NlaGn;eC7r8M#d=9Qpyk>&YL9h( zL9V*^DDH%yf$D`0E+9_r0Q&D{K*?CF%r%P>J%re)qghIS&bKS}9}kp#jt{#Ty=8Q2 z9qHUPWcRyPc-Cchgxb&k$BBnO)oMEcF{Oss5tikRVimf7K<13~sj&4KhYB2vE%rdm z_QlKn@SNfiZ5Z*oSH#;OyBwNvJ>CkOp9F5OboP^)AxmPSCi%l-Musc9qPOR|SIpB> zvIOWh=-XnJb5(}5^us;2AtB@&FeL*hyUuSN%yyJ^vFB>ufc_Ui zlIvShEl{TW1bzI&^dOb^pnxQcbgGRt@o+G3 zbwmmh)z}dmCR+2`9#hXe;S|IIs2VPG|G?5V4g~>3C2e+L@9a*ng|>oc`4wP`1X=~a z6J{Sb)fWt(>H^vc-Ws@)==*)*pdyHiLLGqz5t5)J`Ug=HKcbcz94={rM6LbB8@<&I zc*lmJURlFcKNwJuDZaIW<|N&PC7;h8M30Kw;=?MVUD)N~5E+N3lkzwi8=`SAT2w#i zTQDj11VrM4&Xa}{_W_h4(9R-obS;7WVXaE0L8Q zZveK?sSOie$?9Oz7Ce+ipo*TwaCoJq>RW8+-_k##Gp|I>$UkIwCV0hRTIqs zwCn3Q3#|Zys!Y^OtWz_&f@0I4bbbSg zR?>Q*8_6DWP99B_eeC-f!B)yW47{pKhPrS{Q#0VSDz>sG6|h$akd%;U(>>6^-xpYo zs+s)kD{rh5)RBUG9CV~*Rq-pcWLw76* z&AO4_7QZ)-Walo>eo6xiOxZ$)si1pb%(umW;TR>Y6S|+@ZV`k6BtW(8iV6;Wwji6v zI-#T`F8LD6Cx~W>K(BVP)dBPr0UD4h*HXdBR!Iw63IQ$va!ji)7SPi)Q_}E14_-Mh z4yJ{jGzY9*036->;*1r570U3G%gnf4DkpUB0n$1EA?-CtAvOr7B$Y{wTT-YcVF%d3 zbjYmK7SE;`^9ok$YO9(Ey057GlBQ-NaDcv(RLCgy5nBkr^nU{Y>gGY}b^>roU*IFV zSCN5I7T<39U-a{5-t)o<%zfoF^9dE3gTRa#XV^Obw8;u^aSb%xhLu?o=8S(gE@V4J zEwLY@+ux|zv%~&M8ZN+q>8q|b_z}}_pEeRs*Z~xk{iO+3EL?DiolAIkDGkuU`a=LK zHd|5T3Ii*eUa=v<|0fyOY6>>9X{LfM)btVC6}3RV73xMBCKFU_fQpR2RMCoxTl*ix z0CT{8eSZ5ShydSB4T@Sfftj0uDj*?%X@Gk|hWk&fHv;LJJAiwwu==}`tjMy$>u;I=zD@^{b=FfUD?2&4nNRT|jJG8`gk1SVm8I&6S>>n%W|5Zi|2wh-v$XC8_ z|5D(?VATFke_Wv-T5rVzZxR2xVL?!VVz2R!VFbbhFlt;t{ld$DLNKyyrU}A-awQ>w zK-pv>3tIyy74SfaXBZa5!~T)3A$TYok^Uhylq$1jsS>2FMqhh&Xg&2d$RhR-Din6I z_*?OH6a+I8?gHEzkcA?gX+_vkKcRw)_|kt@3AEb|6x%Q<)V>&xS=z>Qkc~Ek zS3I+4#jS-s%#8K~O{iTHUa16k+=Qj`&134TM~Aw9=wd0L&DJTP!3b2L)CqIdq8Ci$ zPFfVUysqsJHJ=cpSd%kN-C>e39Y(7Saa(7*4g({5oK+0HB%F*B<T0#8`E?}YAef%u&fC0uHEm;Irlm?S@`5nGhHrGlF t*v%<*R1os4iEIAT>+ru{4`VIsuUY$@>ywh7R3M1&tsRb4TAusc{{Zz!1K