Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better stable rearrange sampling #1301

Merged
merged 11 commits into from
May 25, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(
sample_region_ratio: Optional[Dict[str, float]] = None,
nav_to_min_distance: float = -1.0,
recep_set_sample_probs: Optional[Dict[str, float]] = None,
translation_up_offset=0.08,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
translation_up_offset=0.08,
translation_up_offset : float =0.08,

) -> None:
"""
:param object_set: The set objects from which placements will be sampled.
Expand All @@ -48,10 +49,12 @@ def __init__(
:param sample_region_ratio: Defines a XZ scaling of the sample region around its center. Default no scaling. Enables shrinking aabb receptacles away from edges.
:param nav_to_min_distance: -1.0 means there will be no accessibility constraint. Positive values indicate minimum distance from sampled object to a navigable point.
:param recep_set_sample_probs: Optionally provide a non-uniform weighting for receptacle sampling.
:param translation_up_offset: Optionally offset sample points to improve likelyhood of successful placement on inflated collision shapes.
"""
self.object_set = object_set
self._allowed_recep_set_names = allowed_recep_set_names
self._recep_set_sample_probs = recep_set_sample_probs
self._translation_up_offset = translation_up_offset

self.receptacle_instances: Optional[
List[Receptacle]
Expand Down Expand Up @@ -246,8 +249,11 @@ def sample_placement(
num_placement_tries += 1

# sample the object location
target_object_position = receptacle.sample_uniform_global(
sim, self.sample_region_ratio[receptacle.name]
target_object_position = (
receptacle.sample_uniform_global(
sim, self.sample_region_ratio[receptacle.name]
)
+ self._translation_up_offset * receptacle.up
)

# instance the new potential object from the handle
Expand Down
29 changes: 16 additions & 13 deletions habitat-lab/habitat/sims/habitat_simulator/sim_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ def bb_ray_prescreen(
support_obj_ids = [-1]
lowest_key_point: mn.Vector3 = None
lowest_key_point_height = None
highest_support_impact: mn.Vector3 = None
highest_support_impact: Optional[mn.Vector3] = None
highest_support_impact_height = None
highest_support_impact_with_stage = False
highest_support_impact_id = None
raycast_results = []
gravity_dir = sim.get_gravity().normalized()
object_local_to_global = obj.transformation
bb_corners = get_bb_corners(obj.collision_shape_aabb)
bb_corners = get_bb_corners(obj.root_scene_node.cumulative_bb)
key_points = [mn.Vector3(0)] + bb_corners # [COM, c0, c1 ...]
support_impacts: Dict[int, mn.Vector3] = {} # indexed by keypoints
for ix, key_point in enumerate(key_points):
Expand All @@ -181,7 +181,7 @@ def bb_ray_prescreen(
if hit.object_id == obj.object_id:
continue
elif hit.object_id in support_obj_ids:
hit_point = ray.origin + ray.direction * hit.ray_distance
hit_point = hit.point
support_impacts[ix] = hit_point
support_impact_height = mn.math.dot(
hit_point, -gravity_dir
Expand All @@ -194,10 +194,11 @@ def bb_ray_prescreen(
):
highest_support_impact = hit_point
highest_support_impact_height = support_impact_height
highest_support_impact_with_stage = hit.object_id == -1
highest_support_impact_id = hit.object_id

# terminates at the first non-self ray hit
break

# compute the relative base height of the object from its lowest bb corner and COM
base_rel_height = (
lowest_key_point_height
Expand All @@ -206,16 +207,16 @@ def bb_ray_prescreen(

# account for the affects of stage mesh margin
# Warning: Bullet raycast on stage triangle mesh does NOT consider the margin, so explicitly consider this here.
margin_offset = (
0
if not highest_support_impact_with_stage
else sim.get_stage_initialization_template().margin
)
margin_offset = 0
if highest_support_impact_id is None:
pass
elif highest_support_impact_id == -1:
margin_offset = sim.get_stage_initialization_template().margin

surface_snap_point = (
None
if 0 not in support_impacts
else support_impacts[0]
else highest_support_impact
+ gravity_dir * (base_rel_height - margin_offset)
)

Expand Down Expand Up @@ -254,7 +255,9 @@ def snap_down(
# set default support surface to stage/ground mesh
support_obj_ids = [-1]

bb_ray_prescreen_results = bb_ray_prescreen(sim, obj, support_obj_ids)
bb_ray_prescreen_results = bb_ray_prescreen(
sim, obj, support_obj_ids, check_all_corners=False
)

if bb_ray_prescreen_results["surface_snap_point"] is None:
# no support under this object, return failure
Expand All @@ -273,7 +276,7 @@ def snap_down(
cp.object_id_a == obj.object_id
or cp.object_id_b == obj.object_id
) and (
(cp.contact_distance < -0.01)
(cp.contact_distance < -0.05)
or not (
cp.object_id_a in support_obj_ids
or cp.object_id_b in support_obj_ids
Expand Down