Skip to content

Commit

Permalink
Merge pull request #184 from BerkeleyLearnVerify/OnDocsUpdate
Browse files Browse the repository at this point in the history
Updated Documentation/Type Checking for On Specifier
  • Loading branch information
dfremont authored Oct 12, 2023
2 parents 4bd4eb7 + 7c5db2d commit 1b878bc
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 15 deletions.
13 changes: 7 additions & 6 deletions docs/reference/specifiers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,13 @@ contained in *region*
Like :sampref:`in {region}`, but also enforces that the object be entirely contained in the given `Region`.

.. _on {region}:
.. _on ({region} | {Object}):
.. _on ({region} | {Object} | {vector}):
.. _on {vector}:
.. _on:

on *region*
-----------
on (*region* | *Object* | *vector*)
-----------------------------------

**Specifies**:

Expand All @@ -110,12 +113,10 @@ on *region*

**Dependencies**: :prop:`baseOffset` • :prop:`contactTolerance` • :prop:`onDirection`

If :prop:`position` is not already specified with priority 1, positions the *base* of the object uniformly at random in the given `Region`, offset by :prop:`contactTolerance` (to avoid a collision).
If :prop:`position` is not already specified with priority 1, positions the *base* of the object uniformly at random in the given `Region`, on the :prop:`onSurface` of the given `Object`, or with the base of the object at the given vector. The position is always offset by half of :prop:`contactTolerance` (to avoid a collision).
The base of the object is determined by adding the object's :prop:`baseOffset` to its :prop:`position`.

Note that while :specifier:`on` can be used with `Region`, `Object` and `Vector`, it cannot be used with a distribution containing anything other than `Region`. When used with an object the base of the object being placed is placed on the target object's `onSurface` and when used with a vector the base of the object being placed is set to that position.

If instead :prop:`position` has already been specified with priority 1, then its value is modified by projecting it onto the given region.
If instead :prop:`position` has already been specified with priority 1, then its value is modified by projecting it onto the given region (or the :prop:`onSurface` of the given object). Note that this modifying version of the specifier does not accept a vector.
More precisely, we find the closest point in the region along :prop:`onDirection` (or its negation [1]_), and place the base of the object at that point. If :prop:`onDirection` is not specified, a default value is inferred from the region. A region can either specify a default value to be used, or for volumes straight up is used and for surfaces the mean of the face normal values is used (weighted by the area of the faces).

If the region has a :term:`preferred orientation` (a vector field), :prop:`parentOrientation` is specified to be equal to that orientation at the object’s :prop:`position` (whether or not this specifier is being used as a modifying specifier).
Expand Down
6 changes: 4 additions & 2 deletions docs/syntax_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ Additional specifiers for the :prop:`position` and :prop:`orientation` propertie
- Positions the object uniformly at random in the given Region
* - :sampref:`contained in {region}`
- Positions the object uniformly at random entirely contained in the given Region
* - :sampref:`on {region}`
- Positions the base of the object uniformly at random in the given Region, or modifies the position so that the base is in the Region.
* - :sampref:`on {vector}`
- Positions the base of the object at the given global coordinates
* - :sampref:`on ({region} | {Object})`
- Positions the object uniformly at random or modifies the position so that base of the Object is in the given Region/on the given Object.
* - :sampref:`offset by {vector}`
- Positions the object at the given coordinates in the local coordinate system of ego (which must already be defined)
* - :sampref:`offset along {direction} by {vector}`
Expand Down
4 changes: 2 additions & 2 deletions src/scenic/core/type_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ def canCoerceType(typeA, typeB):
return issubclass(typeA, typeB)


def canCoerce(thing, ty):
def canCoerce(thing, ty, exact=False):
"""Can this value be coerced into the given type?"""
tt = underlyingType(thing)
if canCoerceType(tt, ty):
return True
elif isinstance(thing, Distribution):
elif (not exact) and isinstance(thing, Distribution):
return True # fall back on type-checking at runtime
else:
return False
Expand Down
10 changes: 5 additions & 5 deletions src/scenic/syntax/veneer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1439,15 +1439,15 @@ def On(thing):
if isA(thing, Object):
# Target is an Object: use its onSurface.
target = thing.onSurface
elif canCoerce(thing, Vector, exact=True):
# Target is a vector
target = toVector(thing)
elif canCoerce(thing, Region):
# Target is a region (or could theoretically be coerced to one),
# so we can use it as a target.
target = thing
target = toType(thing, Region)
else:
# Target is a vector, so we can use it as a target.
target = toType(
thing, Vector, 'specifier "on R" with R not a Region, Object, or Vector'
)
raise TypeError('specifier "on R" with R not a Region, Object, or Vector')

props = {"position": 1}

Expand Down

0 comments on commit 1b878bc

Please sign in to comment.