@@ -3714,6 +3714,89 @@ def random(cls, seed=None, **kwargs):
37143714 return oven
37153715
37163716
3717+ class DishRackAsset (TrimeshSceneAsset ):
3718+
3719+ def __init__ (
3720+ self ,
3721+ width = 0.5 ,
3722+ depth = 0.7 ,
3723+ height = 0.16 ,
3724+ thickness = 0.005 ,
3725+ wire_gap = 0.05 ,
3726+ plate_holders = True ,
3727+ plate_holders_every_nth_wire = 1 ,
3728+ plate_holders_height = None ,
3729+ plate_holders_width = None ,
3730+ plate_holders_angle = 0.0 ,
3731+ leg_height = 0.01 ,
3732+ ** kwargs ,
3733+ ):
3734+ """A dish rack asset.
3735+
3736+ .. image:: /../imgs/dish_rack_asset.png
3737+ :align: center
3738+ :width: 250px
3739+
3740+ Args:
3741+ width (float, optional): Width of the dish rack. Defaults to 0.5.
3742+ depth (float, optional): Depth of the dish rack. Defaults to 0.7.
3743+ height (float, optional): Height of the dish rack. Defaults to 0.16.
3744+ thickness (float, optional): Thickness of wires. Defaults to 0.005.
3745+ wire_gap (float, optional): Gap between wires. Defaults to 0.05.
3746+ plate_holders (bool, optional): Whether the dish rack has plate holders. Defaults to False.
3747+ plate_holders_every_nth_wire (int, optional): How many plate holders, i.e., every nth wire. Defaults to 1.
3748+ plate_holders_height (float, optional): Height of the plate holders. None means 0.3 of the dish rack width. Defaults to None.
3749+ plate_holders_width (float, optional): Width of the plate holders. None means half of the dish rack height. Defaults to None.
3750+ plate_holders_angle (float, optional): Angle of the side of the plate holders. Defaults to 0.
3751+ leg_height (float, optional): Height of the cylindrical legs. Defaults to 0.01.
3752+ """
3753+ basket_primitives = BinAsset .create_primitives (
3754+ width = width ,
3755+ depth = depth ,
3756+ height = height - leg_height ,
3757+ thickness = thickness ,
3758+ angle = 0.0 ,
3759+ wired = True ,
3760+ wire_gap = wire_gap ,
3761+ plate_holders = plate_holders ,
3762+ plate_holders_every_nth_wire = plate_holders_every_nth_wire ,
3763+ plate_holders_height = plate_holders_height ,
3764+ plate_holders_width = plate_holders_width ,
3765+ plate_holders_angle = plate_holders_angle ,
3766+ )
3767+
3768+ # add four legs
3769+ leg_primitives = []
3770+ inner_width = width - 2.0 * thickness
3771+ inner_depth = depth - 2.0 * thickness
3772+ wire_x = np .arange (- inner_width / 2.0 , inner_width / 2.0 , wire_gap )[1 :]
3773+ wire_y = np .arange (- inner_depth / 2.0 , inner_depth / 2.0 , wire_gap )[1 :]
3774+ basket_primitives .append (trimesh .primitives .Cylinder (radius = 2.0 * thickness , height = leg_height , transform = tra .translation_matrix ((wire_x [1 ], wire_y [1 ], - leg_height / 2.0 ))))
3775+ basket_primitives .append (trimesh .primitives .Cylinder (radius = 2.0 * thickness , height = leg_height , transform = tra .translation_matrix ((wire_x [1 ], wire_y [- 2 ], - leg_height / 2.0 ))))
3776+ basket_primitives .append (trimesh .primitives .Cylinder (radius = 2.0 * thickness , height = leg_height , transform = tra .translation_matrix ((wire_x [- 2 ], wire_y [- 2 ], - leg_height / 2.0 ))))
3777+ basket_primitives .append (trimesh .primitives .Cylinder (radius = 2.0 * thickness , height = leg_height , transform = tra .translation_matrix ((wire_x [- 2 ], wire_y [1 ], - leg_height / 2.0 ))))
3778+
3779+ scene = trimesh .Scene ()
3780+ for i , geometry in enumerate (basket_primitives ):
3781+ name = f"dish_rack_wire_{ i } "
3782+ scene .add_geometry (
3783+ geometry = geometry ,
3784+ geom_name = name ,
3785+ node_name = name ,
3786+ )
3787+
3788+ for i , geometry in enumerate (leg_primitives ):
3789+ name = f"dish_rack_leg_{ i } "
3790+ scene .add_geometry (
3791+ geometry = geometry ,
3792+ geom_name = name ,
3793+ node_name = name ,
3794+ )
3795+
3796+ super ().__init__ (scene = scene , ** kwargs )
3797+
3798+
3799+
37173800class DishwasherAsset (URDFAsset ):
37183801 """A dishwasher asset."""
37193802
@@ -4352,18 +4435,23 @@ def __init__(self, width=0.5,
43524435 )
43534436
43544437 @staticmethod
4355- def create_primitives (width , depth , height , thickness , angle = 0 , wired = False , wire_gap = 0.05 , wire_thickness = 0.005 ):
4438+ def create_primitives (width , depth , height , thickness , angle = 0 , wired = False , wire_gap = 0.05 , wire_thickness = 0.005 , plate_holders = False , plate_holders_every_nth_wire = 1 , plate_holders_height = None , plate_holders_width = None , plate_holders_angle = 0 ):
43564439 if angle != 0 :
43574440 raise Warning (f"BinAsset: angle is ignored since use_primitives=True" )
43584441
4442+ if not wired and plate_holders :
4443+ raise Warning ("BinAsset: Cannot create plate_holders=True if wired=False" )
4444+
4445+ if not (plate_holders_angle >= 0 and plate_holders_angle <= np .pi / 2.0 ):
4446+ raise ValueError (f"plate_holders_angle={ plate_holders_angle } must be between 0 and np.pi / 2.0." )
4447+
43594448 if not (angle > - np .pi / 2.0 and angle < np .pi / 2.0 ):
43604449 raise ValueError (f"angle={ angle } must be between -np.pi / 2.0 and np.pi / 2.0 (exclusively)." )
43614450
43624451 if wired and angle != 0 :
43634452 raise NotImplementedError ("BinAsset cannot be angled (angle={angle}) if wired=True." )
43644453
43654454 outer_hyp = height / np .cos (angle )
4366- outer_widthdepth = np .sin (angle ) * outer_hyp
43674455
43684456 inner_width = width - 2.0 * thickness
43694457 inner_depth = depth - 2.0 * thickness
@@ -4429,6 +4517,52 @@ def create_primitives(width, depth, height, thickness, angle=0, wired=False, wir
44294517 (inner_width_bottom , thickness , wire_thickness ),
44304518 transform = tra .translation_matrix ((0 , - depth / 2.0 + thickness / 2.0 , wire_z [i ]))
44314519 ))
4520+
4521+ if plate_holders :
4522+ # add structure for plate holder
4523+ if plate_holders_width is None :
4524+ plate_holders_width = 0.3 * width
4525+ if plate_holders_height is None :
4526+ plate_holders_height = 0.5 * height
4527+
4528+ if plate_holders_angle > 0 :
4529+ plate_holders_slope_width = plate_holders_height / np .tan (plate_holders_angle )
4530+ else :
4531+ plate_holders_slope_width = 0
4532+
4533+ wire_y = np .arange (- inner_depth_bottom / 2.0 , inner_depth_bottom / 2.0 , wire_gap )[1 :]
4534+ for i in range (len (wire_y )):
4535+ if i % plate_holders_every_nth_wire != 0 :
4536+ continue
4537+
4538+ # add horizontal bar
4539+ primitives .append (
4540+ trimesh .primitives .Box (
4541+ (plate_holders_width , thickness , thickness ),
4542+ transform = tra .translation_matrix ((0 , wire_y [i ], plate_holders_height )),
4543+ )
4544+ )
4545+
4546+ # add vertical prong
4547+ length = plate_holders_height
4548+ if plate_holders_slope_width > 0 :
4549+ length = np .sqrt (plate_holders_height ** 2 + plate_holders_slope_width ** 2 )
4550+ else :
4551+ length = plate_holders_height
4552+
4553+ primitives .append (
4554+ trimesh .primitives .Box (
4555+ (length , thickness , thickness ),
4556+ transform = tra .translation_matrix ((- plate_holders_width / 2.0 - plate_holders_slope_width / 2.0 , wire_y [i ], plate_holders_height / 2.0 )) @ tra .rotation_matrix (angle = plate_holders_angle + np .pi / 2.0 , direction = (0 , - 1 , 0 )),
4557+ )
4558+ )
4559+
4560+ primitives .append (
4561+ trimesh .primitives .Box (
4562+ (length , thickness , thickness ),
4563+ transform = tra .translation_matrix ((plate_holders_width / 2.0 + plate_holders_slope_width / 2.0 , wire_y [i ], plate_holders_height / 2.0 )) @ tra .rotation_matrix (angle = plate_holders_angle + np .pi / 2.0 , direction = (0 , 1 , 0 )),
4564+ )
4565+ )
44324566 else :
44334567 bin_floor = trimesh .primitives .Box ((inner_width_bottom , inner_depth_bottom , thickness ), transform = tra .translation_matrix ((0 , 0 , + thickness / 2.0 )))
44344568 bin_wall_north = trimesh .primitives .Box ((inner_width_bottom , thickness , height ), transform = tra .translation_matrix ((0 , + depth / 2.0 - thickness / 2.0 , height / 2.0 )))
0 commit comments