@@ -43,15 +43,19 @@ def __init__(
43
43
self .verbose = verbose
44
44
self .position = position
45
45
self .orientation = orientation
46
- self .randomize_pose = randomize_pose # TODO: This isn't set up anymore... fix
46
+ self .randomize_pose = randomize_pose # TODO: This isn't set up anymore... fix
47
47
self .init_joint_angles = (
48
- - np .pi / 2 ,
49
- - np .pi * 2 / 3 ,
50
- np .pi * 2 / 3 ,
51
- - np .pi ,
52
- - np .pi / 2 ,
53
- np .pi ,
54
- ) if init_joint_angles is None else init_joint_angles
48
+ (
49
+ - np .pi / 2 ,
50
+ - np .pi * 2 / 3 ,
51
+ np .pi * 2 / 3 ,
52
+ - np .pi ,
53
+ - np .pi / 2 ,
54
+ np .pi ,
55
+ )
56
+ if init_joint_angles is None
57
+ else init_joint_angles
58
+ )
55
59
56
60
# Robot setup
57
61
self .robot = None
@@ -61,13 +65,13 @@ def __init__(
61
65
self ._setup_robot ()
62
66
self .num_joints = self .pbclient .getNumJoints (self .robot )
63
67
self .robot_stack : list = self .robot_conf ["robot_stack" ]
64
-
68
+
65
69
# Links
66
70
self .links = self ._get_links ()
67
71
self .robot_collision_filter_idxs = self ._assign_collision_links ()
68
72
self .set_collision_filter (self .robot_collision_filter_idxs )
69
73
self .tool0_link_idx = self ._get_tool0_link_idx ()
70
-
74
+
71
75
# Joints
72
76
self .joints = self ._get_joints ()
73
77
self .control_joints , self .control_joint_idxs = self ._assign_control_joints (self .joints )
@@ -183,7 +187,7 @@ def _assign_control_joints(self, joints: dict) -> list:
183
187
control_joints = []
184
188
control_joint_idxs = []
185
189
for joint , joint_info in joints .items ():
186
- if joint_info ["type" ] == 0 : # TODO: Check if this works for prismatic joints or just revolute
190
+ if joint_info ["type" ] == 0 : # TODO: Check if this works for prismatic joints or just revolute
187
191
control_joints .append (joint )
188
192
control_joint_idxs .append (joint_info ["id" ])
189
193
return control_joints , control_joint_idxs
@@ -194,13 +198,13 @@ def _get_links(self) -> dict:
194
198
info = self .pbclient .getJointInfo (self .robot , i )
195
199
# log.debug(info)
196
200
child_link_name = info [12 ].decode ("utf-8" )
197
- links .update ({child_link_name : {'id' : i , "tf_from_parent" : info [14 ]}})
201
+ links .update ({child_link_name : {"id" : i , "tf_from_parent" : info [14 ]}})
198
202
return links
199
203
200
204
def _assign_collision_links (self ) -> list :
201
205
"""Find tool0/base pairs, add to collision filter list.
202
206
Requires that the robot part is ordered from base to tool0.
203
-
207
+
204
208
TODO: Clean this up, there must be a better way.
205
209
"""
206
210
robot_collision_filter_idxs = []
@@ -215,15 +219,15 @@ def _assign_collision_links(self) -> list:
215
219
):
216
220
robot_collision_filter_idxs .append (
217
221
(
218
- self .links [robot_part + "__base" ]['id' ],
219
- self .links [self .robot_conf ["robot_stack" ][i - 1 ] + "__tool0" ]['id' ],
222
+ self .links [robot_part + "__base" ]["id" ],
223
+ self .links [self .robot_conf ["robot_stack" ][i - 1 ] + "__tool0" ]["id" ],
220
224
)
221
225
)
222
226
return robot_collision_filter_idxs
223
227
224
228
def _get_tool0_link_idx (self ):
225
229
"""TODO: Clean up, find a better way?"""
226
- return self .links [self .robot_conf ["robot_stack" ][- 1 ] + "__tool0" ]['id' ]
230
+ return self .links [self .robot_conf ["robot_stack" ][- 1 ] + "__tool0" ]["id" ]
227
231
228
232
def _get_sensors (self ) -> dict :
229
233
"""Get sensors on robot based on runtime config files"""
@@ -251,19 +255,23 @@ def _get_sensors(self) -> dict:
251
255
robot_part + "__" + metadata ["tf_frame" ]
252
256
) # TODO: find a better way to get the prefix. If
253
257
# from robot_conf, need standard for all robots TODO: log an error if robot_part doesn't have all the right frames. Xacro utils?
254
- sensors [sensor_name ].tf_id = self .links [sensors [sensor_name ].tf_frame ]['id' ]
255
- sensors [sensor_name ].tf_from_parent = self .links [sensors [sensor_name ].tf_frame ][' tf_from_parent' ]
256
- sensors [sensor_name ].pan = metadata ["pan" ] # TODO: Are these only for cameras/toFs? If so, needs reorg
258
+ sensors [sensor_name ].tf_id = self .links [sensors [sensor_name ].tf_frame ]["id" ]
259
+ sensors [sensor_name ].tf_from_parent = self .links [sensors [sensor_name ].tf_frame ][" tf_from_parent" ]
260
+ sensors [sensor_name ].pan = metadata ["pan" ] # TODO: Are these only for cameras/toFs? If so, needs reorg
257
261
sensors [sensor_name ].tilt = metadata ["tilt" ]
258
262
# for key, value in yamlcontent.items():
259
263
# sensors.update({Path(file).stem: yamlcontent})
260
264
return sensors
261
-
265
+
262
266
def _get_sensor_attributes (self ) -> dict :
263
267
"""TODO: Delete? This is not used"""
264
268
sensor_attributes = {}
265
269
# Cameras
266
- camera_configs_path = os .path .join (CONFIG_PATH , "description" , "camera" ,)
270
+ camera_configs_path = os .path .join (
271
+ CONFIG_PATH ,
272
+ "description" ,
273
+ "camera" ,
274
+ )
267
275
camera_configs_files = glob .glob (os .path .join (camera_configs_path , "*.yaml" ))
268
276
for file in camera_configs_files :
269
277
yamlcontent = yutils .load_yaml (file )
@@ -432,7 +440,6 @@ def calculate_joint_velocities_from_ee_velocity_dls(self, end_effector_velocity,
432
440
def create_camera_transform (self , world_position , world_orientation , camera : Camera | None ) -> np .ndarray :
433
441
"""Create rotation matrix for camera"""
434
442
base_offset_tf = np .identity (4 )
435
-
436
443
437
444
ee_transform = np .identity (4 )
438
445
ee_rot_mat = np .array (self .pbclient .getMatrixFromQuaternion (world_orientation )).reshape (3 , 3 )
@@ -450,20 +457,15 @@ def create_camera_transform(self, world_position, world_orientation, camera: Cam
450
457
pan = camera .tilt
451
458
base_offset_tf [:3 , 3 ] = camera .xyz_offset
452
459
453
- tilt_rot = np .array (
454
- [[1 , 0 , 0 ], [0 , np .cos (tilt ), - np .sin (tilt )], [0 , np .sin (tilt ), np .cos (tilt )]]
455
- )
460
+ tilt_rot = np .array ([[1 , 0 , 0 ], [0 , np .cos (tilt ), - np .sin (tilt )], [0 , np .sin (tilt ), np .cos (tilt )]])
456
461
tilt_tf [:3 , :3 ] = tilt_rot
457
462
458
- pan_rot = np .array (
459
- [[np .cos (pan ), 0 , np .sin (pan )], [0 , 1 , 0 ], [- np .sin (pan ), 0 , np .cos (pan )]]
460
- )
463
+ pan_rot = np .array ([[np .cos (pan ), 0 , np .sin (pan )], [0 , 1 , 0 ], [- np .sin (pan ), 0 , np .cos (pan )]])
461
464
pan_tf [:3 , :3 ] = pan_rot
462
-
463
-
465
+
464
466
tf = ee_transform @ pan_tf @ tilt_tf @ base_offset_tf
465
467
return tf
466
-
468
+
467
469
def set_collision_filter (self , robot_collision_filter_idxs ) -> None :
468
470
"""Disable collision between pruner and arm"""
469
471
for i in robot_collision_filter_idxs :
@@ -582,7 +584,7 @@ def get_view_mat_at_curr_pose(self, camera: Camera | TimeOfFlight) -> np.ndarray
582
584
cameraUpVector = up_vector ,
583
585
)
584
586
return view_matrix
585
-
587
+
586
588
def get_view_mat_by_id_at_curr_pose (self , id ) -> np .ndarray :
587
589
pos , orientation = self .get_current_pose (id )
588
590
camera_tf = self .create_camera_transform (pos , orientation , camera = None )
@@ -591,18 +593,18 @@ def get_view_mat_by_id_at_curr_pose(self, id) -> np.ndarray:
591
593
# Initial vectors
592
594
camera_vector = np .array ([0 , 0 , 1 ]) @ camera_tf [:3 , :3 ].T
593
595
up_vector = np .array ([0 , 1 , 0 ]) @ camera_tf [:3 , :3 ].T
594
-
596
+
595
597
# log.debug(f"camera_vector: {camera_vector}")
596
598
# log.debug(f"up_vector: {up_vector}")
597
-
599
+
598
600
view_matrix = self .pbclient .computeViewMatrix (
599
601
cameraEyePosition = camera_tf [:3 , 3 ],
600
602
cameraTargetPosition = camera_tf [:3 , 3 ] + 0.1 * camera_vector ,
601
603
cameraUpVector = up_vector ,
602
604
)
603
605
# log.warn(np.asarray(view_matrix).reshape((4,4), order="F"))
604
606
return view_matrix
605
-
607
+
606
608
def get_rgbd_at_cur_pose (self , camera , type , view_matrix ) -> Tuple :
607
609
"""Get RGBD image at current pose
608
610
@param camera (Camera): Camera object
@@ -623,7 +625,7 @@ def get_rgbd_at_cur_pose(self, camera, type, view_matrix) -> Tuple:
623
625
# log.debug(f"depth_after_lin: {depth}")
624
626
625
627
return rgb , depth
626
-
628
+
627
629
def get_image_at_curr_pose (self , camera , type , view_matrix = None ) -> list :
628
630
"""Take the current pose of the sensor and capture an image
629
631
TODO: Add support for different types of sensors? For now, full rgbd
@@ -661,7 +663,7 @@ def get_image_at_curr_pose(self, camera, type, view_matrix=None) -> list:
661
663
# return camera_tf
662
664
663
665
# Collision checking
664
- #
666
+ #
665
667
def deproject_pixels_to_points (
666
668
self , sensor , data : np .ndarray , view_matrix : np .ndarray , return_frame : str = "world" , debug = False
667
669
) -> np .ndarray :
@@ -701,16 +703,22 @@ def deproject_pixels_to_points(
701
703
702
704
# Get camera coordinates from film-plane coordinates. Scale, add z (depth), then homogenize the matrix.
703
705
sensor_coords = np .divide (np .multiply (sensor .depth_film_coords , data ), [fx , fy ])
704
- sensor_coords = np .concatenate ((sensor_coords , data , np .ones ((sensor .depth_width * sensor .depth_height , 1 ))), axis = 1 )
706
+ sensor_coords = np .concatenate (
707
+ (sensor_coords , data , np .ones ((sensor .depth_width * sensor .depth_height , 1 ))), axis = 1
708
+ )
705
709
706
710
return_frame = return_frame .strip ().lower ()
707
711
if return_frame == "sensor" :
708
712
return sensor_coords
709
713
elif return_frame == "world" :
710
- world_coords = (mr .TransInv (view_matrix ) @ sensor_coords .T ).T
714
+ world_coords = (mr .TransInv (view_matrix ) @ sensor_coords .T ).T
711
715
if debug :
712
716
plot .debug_deproject_pixels_to_points (
713
- sensor = sensor , data = data , cam_coords = sensor_coords , world_coords = world_coords , view_matrix = view_matrix
717
+ sensor = sensor ,
718
+ data = data ,
719
+ cam_coords = sensor_coords ,
720
+ world_coords = world_coords ,
721
+ view_matrix = view_matrix ,
714
722
)
715
723
return world_coords
716
724
else :
@@ -780,65 +788,77 @@ def compute_deprojected_point_mask(self):
780
788
781
789
def get_key_move_action (self , keys_pressed : list ) -> np .ndarray :
782
790
"""Return an action based on the keys pressed."""
783
- action = np .zeros ((6 ,1 ), dtype = float )
791
+ action = np .zeros ((6 , 1 ), dtype = float )
784
792
if keys_pressed :
785
793
if ord ("a" ) in keys_pressed :
786
- action [0 ,0 ] += 0.01
794
+ action [0 , 0 ] += 0.01
787
795
if ord ("d" ) in keys_pressed :
788
- action [0 ,0 ] += - 0.01
796
+ action [0 , 0 ] += - 0.01
789
797
if ord ("s" ) in keys_pressed :
790
- action [1 ,0 ] += 0.01
798
+ action [1 , 0 ] += 0.01
791
799
if ord ("w" ) in keys_pressed :
792
- action [1 ,0 ] += - 0.01
800
+ action [1 , 0 ] += - 0.01
793
801
if ord ("q" ) in keys_pressed :
794
- action [2 ,0 ] += 0.01
802
+ action [2 , 0 ] += 0.01
795
803
if ord ("e" ) in keys_pressed :
796
- action [2 ,0 ] += - 0.01
804
+ action [2 , 0 ] += - 0.01
797
805
if ord ("z" ) in keys_pressed :
798
- action [3 ,0 ] += 0.01
806
+ action [3 , 0 ] += 0.01
799
807
if ord ("c" ) in keys_pressed :
800
- action [3 ,0 ] += - 0.01
808
+ action [3 , 0 ] += - 0.01
801
809
if ord ("x" ) in keys_pressed :
802
- action [4 ,0 ] += 0.01
810
+ action [4 , 0 ] += 0.01
803
811
if ord ("v" ) in keys_pressed :
804
- action [4 ,0 ] += - 0.01
812
+ action [4 , 0 ] += - 0.01
805
813
if ord ("r" ) in keys_pressed :
806
- action [5 ,0 ] += 0.05
814
+ action [5 , 0 ] += 0.05
807
815
if ord ("f" ) in keys_pressed :
808
- action [5 ,0 ] += - 0.05
816
+ action [5 , 0 ] += - 0.05
809
817
return action
810
-
818
+
811
819
def get_key_sensor_action (self , keys_pressed : list ) -> dict | None :
812
820
if keys_pressed :
813
- if ord ('p' ) in keys_pressed :
821
+ if ord ("p" ) in keys_pressed :
814
822
if time .time () - self .debounce_time > 0.1 :
815
823
sensor_data = {}
816
824
for sensor_name , sensor in self .sensors .items ():
817
- if sensor_name .startswith (' tof' ):
825
+ if sensor_name .startswith (" tof" ):
818
826
view_matrix = self .get_view_mat_at_curr_pose (camera = sensor )
819
- rgb , depth = self .get_rgbd_at_cur_pose (camera = sensor , type = 'sensor' , view_matrix = view_matrix )
827
+ rgb , depth = self .get_rgbd_at_cur_pose (
828
+ camera = sensor , type = "sensor" , view_matrix = view_matrix
829
+ )
820
830
view_matrix = np .asarray (view_matrix ).reshape ([4 , 4 ], order = "F" )
821
831
depth = depth .reshape ((sensor .depth_width * sensor .depth_height , 1 ), order = "F" )
822
-
823
- camera_points = self .deproject_pixels_to_points (sensor = sensor , data = depth , view_matrix = view_matrix , return_frame = 'sensor' )
824
-
825
- sensor_data .update ({sensor_name : {'data' : camera_points , 'tf_frame' : sensor .tf_frame , 'view_matrix' : view_matrix , 'sensor' : sensor }})
832
+
833
+ camera_points = self .deproject_pixels_to_points (
834
+ sensor = sensor , data = depth , view_matrix = view_matrix , return_frame = "sensor"
835
+ )
836
+
837
+ sensor_data .update (
838
+ {
839
+ sensor_name : {
840
+ "data" : camera_points ,
841
+ "tf_frame" : sensor .tf_frame ,
842
+ "view_matrix" : view_matrix ,
843
+ "sensor" : sensor ,
844
+ }
845
+ }
846
+ )
826
847
# plot.debug_sensor_world_data(sensor_data)
827
848
self .debounce_time = time .time ()
828
849
return sensor_data
829
850
else :
830
851
return
831
852
return
832
-
833
853
834
-
835
854
def get_key_action (self , keys_pressed : list ):
836
855
move_action = self .get_key_move_action (keys_pressed = keys_pressed )
837
856
sensor_data = self .get_key_sensor_action (keys_pressed = keys_pressed )
838
857
# controller_action = self.get_key_controller_action(keys_pressed=keys_pressed)
839
-
858
+
840
859
return
841
860
861
+
842
862
def main ():
843
863
from pybullet_tree_sim .utils .pyb_utils import PyBUtils
844
864
import time
0 commit comments