+
    Rj(                         R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt RtRt	Rt
RtR]P                  ,          ],          t]R]P                  ,          ,          t^(t^?t^t^7t^t^^^utttRR	 lt ! R
 R4      tR# )u&  Shared Feetech STS bus helper — refactored from our_feetech_controller so the
calibration + live-mirror tools share one connection/read/zero implementation.

Importing this module monkey-patches scservo_sdk (via scservo_patch) so methods
take (motor_id, ...) without an explicit portHandler.
N)PortHandler)sms_stsz/dev/tty.usbserial-0001i  i   i   g       @c                >    W\         ,
          ,          \        ,          # )zCSigned servo tick -> URDF radians about the joint zero (tick 2048).)CENTER_TICKTICKS_TO_RAD)tickssigns   &&feetech_bus.pyticks_to_radr
      s    ;&',66    c                   f   a  ] tR t^#t o ]]3R ltR tR tR t	R t
RR ltR tRR ltR	 tR
tV tR# )Busc                   \        V4      V n        V P                  P                  4       '       g   \        R V 24      hV P                  P	                  V4      '       g   \        RV 24      h\        V P                  4      V n        R# )zFailed to open serial port zFailed to set baud N)r   portopenPortRuntimeErrorsetBaudRater   sts)selfr   bauds   &&&r	   __init__Bus.__init__$   sl    %	yy!!##!<TFCDDyy$$T**!4TF;<<499%r   c                b    V P                   P                  V4      w  r#pV^ 8H  ;'       d    V^ 8H  # )    )r   ping)r   mid_commerrs   &&   r	   r   Bus.ping,   s.    xx}}S)qy%%SAX%r   c                T    V P                   P                  V4      w  r#pV^ 8X  d   V# R# r   N)r   ReadPos)r   r   posr   r   s   &&   r	   read_posBus.read_pos0   s+    xx'',1ais)T)r   c                ^    V P                   P                  V\        4      w  r#pV^ 8X  d   V# R# r!   )r   read1ByteTxRx	ADDR_TEMP)r   r   valr   r   s   &&   r	   	read_tempBus.read_temp4   s-    xx--c9=1ais)T)r   c                `    V P                   P                  T\        ^V'       d   ^M^ .4       R# )zIEnable/disable holding torque. Off => the joint is back-drivable by hand.N)r   	writeTxRxADDR_TORQUE_ENABLE)r   r   ons   &&&r	   torque
Bus.torque8   s"    3 2ARQ7GHr   c                    \        V4       F~  p^ .^,          pW\        &   ^V\        &   \        V\        &   V P
                  P                  V P
                  P                  V4      w  r5pV^ 8X  d    R# \        P                  ! R4       K  	  R# )z|INST_OFSCAL: make the servo's CURRENT physical position read as 2048.
Persists to EEPROM, so the zero survives power cycles.T皙?F)
range_PKT_ID_PKT_LENGTHINST_OFSCAL_PKT_INSTRUCTIONr   
txRxPacketportHandlertimesleep)r   r   retriesr   txresults   &&&   r	   set_zero_hereBus.set_zero_here<   sv     wAqBwKB{O#.B 88..txx/C/CRHLAq{JJsO   r   c                   V P                   P                  V\        ^^ .4       \        P                  ! R4       V P                   P                  V\
        ^V.4       \        P                  ! R4       V P                  V4      '       g   R# V P                   P                  V\        ^^.4       \        P                  ! R4       V P                  V4      # )a>  Change a servo's EEPROM id. Only ONE servo should share old_id on the bus.
Unlock -> write id -> relock (via the new id) -> verify. The servo often changes
its id before acking the write (SDK reports RX timeout), so we verify by pinging
the new id rather than trusting the write's return code. Returns True on success.g?F)r   r-   	ADDR_LOCKr;   r<   ADDR_IDr   )r   old_idnew_ids   &&&r	   set_id
Bus.set_idJ   s    
 	69a!5

467Ax8

4yy  69a!5

4yy  r   c                    \        V4       FL  p\        P                  ! R4        V P                  P	                  V4      w  rEpV^ 8X  d   V^ 8X  d   Vu # KL  KN  	  R#   \
         d     K`  i ; i)zORead position tolerantly right after INST_OFSCAL (reply can be slow/truncated).r3   N)r4   r;   r<   r   r"   
IndexError)r   r   triesr   pr   r   s   &&&    r	   read_pos_settleBus.read_pos_settleY   sj    uAJJsO#xx//419H "*9	    s   -AA-,A-c                :    V P                   P                  4        R # )N)r   	closePort)r   s   &r	   close	Bus.closee   s    		r   )r   r   N)   )   )__name__
__module____qualname____firstlineno__USB_PORT_DEFAULTBAUD_DEFAULTr   r   r$   r*   r0   r@   rG   rM   rQ   __static_attributes____classdictcell__)__classdict__s   @r	   r   r   #   s=     ,< &&**I!
 r   r   )   )__doc__mathr;   scservo_patchscservo_sdkr   scservo_sdk.sms_stsr   rY   rZ   r   TICKS_PER_REVpir   RAD_TO_TICKSr.   r(   rD   rC   r7   r5   r6   r8   r
   r    r   r	   <module>rh      s       # ', dgg.dgg. 	
	)*Aq &&7
C Cr   