Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 37 additions & 22 deletions tests/syntax/test_pruning.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import math
import random

import pytest

from scenic.core.errors import InconsistentScenarioError
from scenic.core.vectors import Vector
from scenic.core.regions import PointInRegionDistribution
from scenic.core.vectors import Vector, VectorOperatorDistribution
from tests.utils import compileScenic, sampleEgo, sampleParamP


Expand Down Expand Up @@ -164,21 +162,38 @@ def test_visibility_pruning():
"""Test visibility pruning in general.

The following scenarios are equivalent except for how they specify that foo
must be visible from ego. The size of the workspace and the visibleDistance
of ego are chosen such that without pruning the chance of sampling a valid
scene over 100 tries is 1-(1-(3.14*2**2)/(1e10**2))**100 = ~1e-18.
Assuming the approximately buffered volume of the viewRegion has a 50% chance of
rejecting (i.e. it is twice as large as the true buffered viewRegion, which testing
indicates in this case has about a 10% increase in volume for this case), the chance
of not finding a sample in 100 iterations is 1e-31.

We also want to confirm that we aren't pruning too much, i.e. placing the position
in the viewRegion instead of at any point where the object intersects the view region.
Because of this, we want to see at least one sample where the position is outside
the viewRegion but the object intersects the viewRegion. The chance of this happening
per sample is ((1 / 2)**2), so by repeating the process 30 times we have
~1e-19 chance of not getting a single point in this zone.
must be visible from ego. Without visibility pruning, sampling a valid scene
would be extremely unlikely because the workspace is enormous compared to ego's
visible region.

We check two things. First, sampled positions must remain within distance 2 of
ego, which is the maximum distance at which the spheroid can still intersect
ego's visible region. Second, to ensure pruning is not too aggressive, we check
the conditioned/pruned region directly and verify that it still extends beyond
distance 1 from ego, so the outer band where the object intersects the view
region is still available.
"""

def assert_pruned_region_reaches_outer_band(scenario):
foo = scenario.objects[1]
conditioned = foo.position._conditioned

if isinstance(conditioned, PointInRegionDistribution):
base = conditioned.region
offset = Vector(0, 0, 0)
else:
assert isinstance(conditioned, VectorOperatorDistribution)
base = conditioned.object.region
offset = conditioned.operands[0]

max_dist = max(
(Vector(x, y, base.z) + offset).distanceTo(Vector(0, 0, 0))
for poly in base.polygons.geoms
for x, y in poly.exterior.coords
)
assert max_dist <= 2 + 1e-6
assert max_dist > 1 + 1e-6

# requireVisible
scenario = compileScenic(
"""
Expand All @@ -193,7 +208,7 @@ def test_visibility_pruning():
)
positions = [sampleParamP(scenario, maxIterations=100) for i in range(30)]
assert all(pos.distanceTo(Vector(0, 0, 0)) <= 2 for pos in positions)
assert any(pos.distanceTo(Vector(0, 0, 0)) >= 1 for pos in positions)
assert_pruned_region_reaches_outer_band(scenario)

# visible
scenario = compileScenic(
Expand All @@ -208,7 +223,7 @@ def test_visibility_pruning():
)
positions = [sampleParamP(scenario, maxIterations=100) for i in range(30)]
assert all(pos.distanceTo(Vector(0, 0, 0)) <= 2 for pos in positions)
assert any(pos.distanceTo(Vector(0, 0, 0)) >= 1 for pos in positions)
assert_pruned_region_reaches_outer_band(scenario)

# requireVisible with offset
baseOffsetVal = 0.0001
Expand All @@ -226,7 +241,7 @@ def test_visibility_pruning():
)
positions = [sampleParamP(scenario, maxIterations=100) for i in range(30)]
assert all(pos.distanceTo(Vector(0, 0, 0)) <= 2 for pos in positions)
assert any(pos.distanceTo(Vector(0, 0, 0)) >= 1 for pos in positions)
assert_pruned_region_reaches_outer_band(scenario)
assert all(pos.z == -baseOffsetVal for pos in positions)

# visible with offset
Expand All @@ -243,7 +258,7 @@ def test_visibility_pruning():
)
positions = [sampleParamP(scenario, maxIterations=100) for i in range(30)]
assert all(pos.distanceTo(Vector(0, 0, 0)) <= 2 for pos in positions)
assert any(pos.distanceTo(Vector(0, 0, 0)) >= 1 for pos in positions)
assert_pruned_region_reaches_outer_band(scenario)
assert all(pos.z == -baseOffsetVal for pos in positions)


Expand Down
Loading