
    ni6                     L   S r SSKrSSKJrJrJr  SSKrSSKrSSK	J
r
  SrS\\\4   S\\   S\\\4   4S	 jrS
\R                  S\R                  S\R                  4S jrS\R                  S\R                  S\R                  4S jr\R"                   " S S\5      5       rg)zBHelper class to load and manage the robot URDF file in simulation.    N)DictTextTuple)bullet_client
robot_basejoint_name_to_idjoint_namesreturnc                 X    [         R                  " 5       nUc  U$ U H	  nX   X#'   M     U$ N)collectionsOrderedDict)r   r	   sub_dictnames       i/home/james-whalen/.local/lib/python3.13/site-packages/pybullet_envs/minitaur/robots/robot_urdf_loader.py	_sub_dictr      s4    $$&(Od%+HN 	/    robot_space_joint_anglesjoint_offsetsjoint_directionsc                     X-  U-   $ r    )r   r   r   s      r   convert_to_urdf_joint_anglesr      s    
 
"	4}	DDr   urdf_space_joint_anglesc                     X-
  U-  $ r   r   )r   r   r   s      r   convert_to_robot_joint_anglesr   #   s    
 "
15E	EEr   c                       \ rS rSrSr            S-S\R                  S\S\S\S\	\
   S	\	\
   S
\	\
   S\	\   S\\\
4   S\\\
4   S\\\4   S\	\   S\	\   S\\\	\   4   4S jjrS.S\	\   S\\\4   4S jjrS.S\	\   S\\\4   4S jjrS.S\	\   S\\\4   4S jjrS.S\	\   S\\\4   4S jjr S.S\	\   S\\\4   4S jjr S.S\	\   S\\\
4   4S jjr S.S\	\   S\\\4   4S jjr\S 5       r\S 5       r\S 5       r\S 5       r\S  5       rS! rS" rS# r    S/S\S\	\
   S	\	\
   S\\\
4   4S$ jjrS\S\	\
   S	\	\
   S\4S% jrS.S&\\\
4   4S' jjr   S0S(\	\
   S)\	\
   4S* jjr!\S+ 5       r"S,r#g)1RobotUrdfLoader+   z1A abstract class to manage the robot urdf in sim.Npybullet_client	urdf_pathconstrained_baseenable_self_collisioninit_base_position init_base_orientation_quaternioninit_base_orientation_rpy
base_namesinit_joint_anglesr   r   motor_namesend_effector_names
user_groupc                 (   Xl         X l        XPl        Ub  X`l        O.Uc  [	        S5      eU R                   R                  U5      U l        X0l        X@l        Xl        Xl	        Xl
        Xl        Xl        Xl        Xl        U R                  UUUU	S9  g)a  Initialize the class.

Args:
  pybullet_client: A pybullet client.
  urdf_path: The path to the URDF to load.
  constrained_base: Whether to create a FIXED constraint to the base of the
    URDF. Needs to be True for kinematic robots. This allows us to "hang"
    the simulated robot in air, and the hanging point can follow arbitrary
    provided paths.
  enable_self_collision: Determines if the robot can collide with itself.
  init_base_position: The base x, y, z after loading.
  init_base_orientation_quaternion: The base rotation after loading.
  init_base_orientation_rpy: The base rotation after loading, presented in
    roll, pitch, yaw.
  base_names: The base joint names. Used to find additional links that
    belong to the base. Optional because the base might only contain a
    single mesh/block, which always has the id of "-1".
  init_joint_angles: Maps joint name to the desired joint pose after loading
    URDF. If not provided, will use the URDF default. This can be a subset
    of all joints in the URDF. This should be in the robot joint convention,
    which can be different from the URDF convention.
  joint_offsets: The "zero" position of joint angles in the URDF space.
  joint_directions: To convert between robot sdk/control and urdf joint
    convention.
  motor_names: The motor joint names in the URDF. Typically a subset of all
    movable joints/DoFs.
  end_effector_names: A subset of joints specifying the end-effector
    joint(s). For example for legged robots the end effectors are the toe
    joints (if provided). For arms this group includes left and right
    grippers.
  user_group: User defined joint groups. For example for quadrupeds, we may
    want to organize all joints according to which leg they belong to.
NzOEither init_base_orientation_quaterion or init_base_orientation_rpy is required)r#   r$   r%   r(   )_pybullet_client
_urdf_path_init_base_position!_init_base_orientation_quaternion
ValueErrorgetQuaternionFromEuler_constrained_base_enable_self_collision_base_names_init_joint_angles_joint_offsets_joint_directions_motor_names_end_effector_names_user_groupload)selfr    r!   r"   r#   r$   r%   r&   r'   r(   r   r   r)   r*   r+   s                  r   __init__RobotUrdfLoader.__init__/   s    d ,O1'3/O,	"	* D E 	E 


6
6') , ."7!/'-#1!II3-)I+	  -r   r   r
   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )
_base_dictr   r=   r   s     r   get_base_id_dict RobotUrdfLoader.get_base_id_dict|   s"    |__T__d++r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )_joint_name_to_idr   rB   s     r   get_joint_id_dict!RobotUrdfLoader.get_joint_id_dict   s&    |###T++T22r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )_link_name_to_idr   rB   s     r   get_link_id_dict RobotUrdfLoader.get_link_id_dict   s&    |"""T**D11r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )_motor_dictr   rB   s     r   get_motor_id_dict!RobotUrdfLoader.get_motor_id_dict   s&    |T%%t,,r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )r8   r   rB   s     r   get_joint_direction_dict(RobotUrdfLoader.get_joint_direction_dict   s&    |###T++T22r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )r7   r   rB   s     r   get_joint_offset_dict%RobotUrdfLoader.get_joint_offset_dict   s&    |   T(($//r   c                 L    Uc  U R                   $ [        U R                   U5      $ r   )_end_effector_dictr   rB   s     r   get_end_effector_id_dict(RobotUrdfLoader.get_end_effector_id_dict   s&    |$$$T,,d33r   c                     U R                   $ )zReturns the unique object instance id of this loaded URDF in pybullet.

Note this is different from all other get_{}_id APIs, which returns the
joint/link id within this robot instance.

Returns:
  The object id as returned by loadURDF.
)	_robot_idr=   s    r   robot_idRobotUrdfLoader.robot_id   s     >>r   c                     U R                   $ r   )_all_joint_infor]   s    r   all_joint_infoRobotUrdfLoader.all_joint_info   s    r   c                     U R                   $ r   )
_user_dictr]   s    r   	user_dictRobotUrdfLoader.user_dict   s    ??r   c                     U R                   $ r   )r9   r]   s    r   r)   RobotUrdfLoader.motor_names   s    r   c                     U R                   $ r   r3   r]   s    r   r"    RobotUrdfLoader.constrained_base   s    !!!r   c                     [         R                  " 5       nU R                  c  SU[        '   U$ UR	                  [        U R                  U R                  5      5        U$ )aA  Builds the base joints dictionary.

In pybullet, a link's id within the robot always equal to its parent joint
id. So this base joint dict functionaly is equivalent to the base link dict.
The dictionary may only contain {ROBOT_BASE: -1} if self._base_names is
empty.

Returns:
  The base link (joint) ordered dictionary.
)r   r   r5   
ROBOT_BASEupdater   rF   )r=   	base_dicts     r   _build_base_dict RobotUrdfLoader._build_base_dict   sY     '')I i
  y!7!79I9IJKr   c                    [         R                  " 5       nU R                  c  U$ U R                  R                  5        HC  u  p#[         R                  " 5       X'   X   R	                  [        U R                  U5      5        ME     U$ )z4Builds a dictionary using user defined joint groups.)r   r   r;   itemsrp   r   rF   )r=   rf   
group_namegroup_joint_namess       r   _build_user_dict RobotUrdfLoader._build_user_dict   s{    '')I)-)9)9)?)?)A%
)557i""
D**,=
>@ *B r   c                    U R                   R                  U R                  5      n[        U5       Vs/ s H)  nU R                   R	                  U R                  U5      PM+     nnU H$  nUS   nU R                   R                  USSSS9  M&     [        R                  " 5       n[        R                  " [        S4/5      nU H6  nUS   R                  S5      nUS   nXVU'   XWUS   R                  S5      '   M8     XXg4$ s  snf )a  Extracts all joints from the URDF.

Finds all joints (fixed or movable) in the URDF and extracts the info. This
includes actuated joints (i.e. motors), and non-actuated joints, e.g. the
passive joints in Minitaur's four bar mechanism, and fixed joints connecting
the toe and the lower legs, etc.

Returns:
  number of joints, all joint information as returned by pybullet, and the
  joint_name_to_id dictionary.

r   rn   )linearDampingangularDamping   zUTF-8   )
r-   getNumJointsr\   rangegetJointInfochangeDynamicsr   r   ro   decode)	r=   
num_jointsirb   
joint_infojoint_idr   link_name_to_id
joint_names	            r   _build_all_joint_dict%RobotUrdfLoader._build_all_joint_dict   s    &&33DNNCJ z""A 	**4>>1="   %
Ah
**
Ba + ; %
 #..0!--
B/?.@AO$
a=''0jAh%-z" 9Ajn++G45 % '7HH+s   0Dc                 
   Uc  U R                   nUc  U R                  nUc  U R                  nU R                  XU5      U l        U R                  5       u  U l        U l        U l        U l	        U R                  5       U l        [        U R                  U R                  5      U l        [        U R                  U R                  5      U l        U R#                  5       U l        U R'                  X#5        U R)                  U5        g)z/Reloads the URDF and rebuilds the dictionaries.N)r4   r/   r0   
_load_urdfr\   r   _num_jointsra   rF   rJ   rr   rA   r   r9   rN   r:   rX   rx   re   reset_base_posereset_joint_angles)r=   r#   r$   r%   r(   s        r   r<   RobotUrdfLoader.load   s     $"99!33'/)-)O)O&__%:%EGDN #88:Tt+T-C	++-DO !7!79J9JKD'(>(>(,(@(@BD++-DO+N-.r   c                     U(       aE  U R                   R                  U R                  UUU R                  U R                   R                  S9$ U R                   R                  U R                  UUU R                  S9$ !   [        S5        [        S5        [        U R                  5        SSKnUR                  S5         g= f)z+Loads the URDF and returns the pybullet id.)useFixedBaseflags)r   z!!!!!!!!!!!!!!!!zError: cannot find file:r   N)r-   loadURDFr.   r3   URDF_USE_SELF_COLLISIONprintsysexit)r=   r#   r$   r%   r   s        r   r   RobotUrdfLoader._load_urdf  s    	$$--OO,//''?? . A 	A $$--OO,//	 . 
 	
&'DOO	hhqks   AA> /A> >ACjoint_anglesc                 b   U R                   c  gUc  U R                   nU R                  b  U R                  c  [        S5      eUR	                  5        HY  u  p#X0R                  U   -  U R                  U   -   nU R
                  R                  U R                  U R                  U   USS9  M[     g)a
  Resets the joint angles.

Resets the joint poses. This is instanteneously and will ignore the physics
(e.g. collisions, inertias, etc). Should only be used during the episode
reset time. Does not work for real robots (other than changing the
visualization). This API has no effect if both the input joint_angles and
the self._init_joint_angles are None.

Args:
  joint_angles: The joint angles in the robot's joint space.

Raises:
  AttributeError if the joint directions and joint offsets are not provided
  during init.
Nz;joint directions and joint offsets not provided in __init__r   )targetVelocity)	r6   r8   r7   AttributeErrorru   r-   resetJointStater\   rF   )r=   r   r   angleurdf_joint_angles        r   r   "RobotUrdfLoader.reset_joint_angles7  s      &,,l%)<)<)D
GI I *//1
!7!7
" ++J78
++
..

 
 
,
	 ,  2r   base_positionbase_orientation_quaternionc                     Uc  U R                   nUc  U R                  nU R                  R                  U R                  X5        U R                  R                  U R                  SS5        g)zResets the base position and orientation.

Instanteneously re-position the base pose of the robot. Does not work for
real robots except for the visualization.

Args:
  base_position: Base x, y, z position.
  base_orientation_quaternion: Base rotation.
Nr   r   r   )r/   r0   r-   resetBasePositionAndOrientationr\   resetBaseVelocity)r=   r   r   s      r   r   RobotUrdfLoader.reset_base_poseZ  sd     ..m"*$($J$J!99D++DNNI,57r   c                 ,    U R                   (       a  S$ S$ )Nr      rk   r]   s    r   com_dofRobotUrdfLoader.com_dofq  s    &&1-A-r   )ra   rA   r5   r3   r4   rX   r:   r0   r/   r6   r8   rF   r7   rJ   rN   r9   r   r-   r\   r.   re   r;   )FTr   NNNNNNNNNr   )NNNN)NN)$__name__
__module____qualname____firstlineno____doc__r   BulletClientr   boolr   floatr   intr>   rC   rG   rK   rO   rR   rU   rY   propertyr^   rb   rf   r)   r"   rr   rx   r   r<   r   r   r   r   __static_attributes__r   r   r   r   r   +   s;   9  %$()27;04 $-1)-*.!%(,,0K-$11K- K- 	K-
 "K-  ,K- ).eK- "'uK- +K- dEk*K- $+&K- T3YK- ;K-  +K- tU4[()K-Z,5; ,$tSy/ ,
3E$K 34c	? 3
25; 2$tSy/ 2
-E$K -4c	? - 483%*4[3<@sO3 150"'+09=dEk9J0 484%*4[4<@sO4 	 	         " "$	#IN %))-7;-1/!/  ,/ ).e	/
 dEk*/:d %*5\38<DG4!T$+-> !J %)2675\7 $)<7. . .r   r   )r   r   typingr   r   r   ginnumpynppybullet_utilsr   ro   r   r   ndarrayr   r   configurableobjectr   r   r   r   <module>r      s    H  $ $ 
  ( 
T3Y  ;+/c	?E jjE::E jjEFZZF::F jjF G.f G. G.r   