What’s New in Scenic
This page describes what new features have been added in each version of Scenic, as well as any syntax changes which break backwards compatibility. Scenic uses semantic versioning, so a program written for Scenic 2.1 should also work in Scenic 2.5, but not necessarily in Scenic 3.0. You can run scenic --version to see which version of Scenic you are using.
Scenic 3.x
The Scenic 3.x series adds native support for 3D geometry, precise modeling of the shapes of objects, and temporal requirements. It also features a new parser enabling clearer error messages, greater language extensibility, and various improvements to the syntax.
See Porting to Scenic 3 for tools to help migrate existing 2D scenarios.
Scenic 3.0.0
Backwards-incompatible syntax changes:
Objects must be explicitly created using the
new
keyword, e.g.new Object at (1, 2)
instead of the oldObject at (1, 2)
. This removes an ambiguity in the Scenic grammar, and makes non-creation uses of class names likemyClasses = [Car, Bicycle, Pedestrian]
clearer.Monitor definitions must include a parenthesized list of arguments, like behaviors: you should write
monitor MyMonitor():
for example instead of the oldmonitor MyMonitor:
. Furthermore, monitors are no longer automatically enforced in the scenario where they are defined: you must explicitly instantiate them with the newrequire monitor
statement.As the
heading
property is now derived from the 3Dorientation
(see below), it can no longer be set directly. Classes providing a default value forheading
should instead provide a default value forparentOrientation
. Code likewith heading 30 deg
should be replaced with the more idiomaticfacing 30 deg
.
Backwards-incompatible semantics changes:
Objects are no longer required to be visible from the
ego
by default. (TherequireVisible
property is nowFalse
by default.)Visibility checks take occlusion into account by default (see below). The visible regions of objects are now 3D regions.
Checking containment of objects in regions is now precise (previously, Scenic only checked if all of the corners of the object were contained in the region).
While evaluating a precondition or invariant of a behavior or scenario, code that would cause the simulation to be rejected (such as sampling from an empty list) is now considered as simply making the precondition/invariant false.
The
left of Object
specifier and its variants now correctly take into account the dimensions of both the object being created and the given object (the implementation previously did not account for the latter, despite the documentation saying otherwise).The
offset by
specifier now optionally specifiesparentOrientation
.The
visible
andnot visible
specifiers now take into account occlusion and the shapes of objects. In previous versions, they only checked whether the center of the object was visible/not visible, ignoring occlusion.
Backwards-incompatible API changes:
The maxIterations argument of
Simulator.simulate
now has default value 1, rather than 100. A default value of 1 is the most reasonable in general since it means that when a simulation is rejected, a new scene will have to be generated (instead of trying many simulations from the same starting scene, which might well fail in the same way).For simulator interface writers: the
Simulator.createSimulation
andSimulation
APIs have changed; initial creation of objects is now done automatically, and other initialization must be done in the newSimulation.setup
method. Seescenic.core.simulators
for details.
Major new features:
Scenic uses 3D geometry. Vectors now have 3 coordinates: if a third coordinate is not provided, it is assumed to be zero, so that scenarios taking place entirely in the z=0 plane will continue to work as before. Orientations of objects in space are represented by a new
orientation
property (internally a quaternion), which is computed by applying intrinsicyaw
,pitch
, androll
rotations, given by new properties by those names. These rotations are applied to the object’sparentOrientation
, which by default aligns with the Scenic global coordinate system but is optionally specified byleft of
and similar specifiers; this makes it easy to orient an object with respect to another object. See the relevant section of the tutorial for examples.Scenic models the precise shapes of objects, rather than simply using bounding boxes for collision detection and visibility checks. Objects have a new
shape
property (an instance of the Shape class) representing their shape; shapes can be created from standard 3D mesh formats such as STL.Visibility checks now take occlusion into account as well as precise shapes of objects. This is done using raytracing: the number of rays can be controlled on a per-object basis using
viewRayDensity
and related properties.The
require
statement accepts arbitrary properties in Linear Temporal Logic (not just therequire always
andrequire eventually
forms previously allowed).Sampled
Scene
objects can now be serialized to short sequences of bytes and restored later. Similarly, executedSimulation
objects can be saved and replayed. See Storing Scenes/Simulations for Later Use for details.Scenic syntax highlighters for Sublime Text, Visual Studio Code, and other TextMate-compatible editors are now available: see Getting Started with Scenic. For users of Pygments, the
scenic
package automatically installs a Pygments lexer (and associated style) for Scenic.
Minor new features:
Scenic 2.x
The Scenic 2.x series is a major new version of Scenic which adds native support for dynamic scenarios, scenario composition, and more.
Scenic 2.1.0
Major new features:
Modular scenarios and ways to compose them together, introduced as a prototype in 2.0.0, are now finalized, with many fixes and improvements. See Composing Scenarios for an overview of the new syntax.
The
record
statement for recording values at every step of dynamic simulations (or only at the start/end).A built-in Newtonian physics simulator for debugging dynamic scenarios without having to install an external simulator (see
scenic.simulators.newtonian
).The interface to the Webots simulator has been greatly generalized, and now supports dynamic scenarios (see
scenic.simulators.webots
).
Minor new features:
You can now write
require expr as name
to give a name to a requirement; similarly forrequire always
, termination conditions, etc.Compatibility with Python 3.7 is restored. Scenic 2 now supports all versions of Python from 3.7 to 3.11.
Scenic 2.0.0
Backwards-incompatible syntax changes:
The interval notation
(low, high)
for uniform distributions has been removed: useRange(low, high)
instead. As a result of this change, the usual Python syntax for tuples is now legal in Scenic.The
height
property of Object, measuring its extent along the Y axis, has been renamedlength
to better match its intended use. The nameheight
will be used again in a future version of Scenic with native support for 3D geometry.
Major new features:
Scenic now supports writing and executing dynamic scenarios, where agents take actions over time according to behaviors specified in Scenic. See Dynamic Scenarios for an overview of the new syntax.
An abstract Driving Domain allowing traffic scenarios to be written in a platform-agnostic way and executed in multiple simulators (in particular, both CARLA and LGSVL). This library includes functionality to parse road networks from standard formats (currently OpenDRIVE) and expose information about them for use in Scenic scenarios.
A much generalized and improved interface to CARLA. (Many thanks to the CARLA team for contributing this.)
An interface to the LGSVL driving simulator. (Many thanks to the LG team for helping develop this interface.)
Minor new features:
Operators and specifiers which take vectors as arguments will now accept tuples and lists of length 2; for example, you can write
Object at (1, 2)
. The old syntaxObject at 1@2
is still supported.The
model
statement allows a scenario to specify which world model it uses, while being possible to override from the command line with the--model
option.Global parameters can be overridden from the command line using the
--param
option (e.g. to specify a different map to use for a scenario).The unpacking operator
*
can now be used withUniform
to select a random element of a random list/tuple (e.g.lane = Uniform(*network.lanes); sec = Uniform(*lane.sections)
).The Python built-in function
filter
is now supported, and can be used along with unpacking as above to select a random element of a random list satisfying a given condition (see filter for an example).
(Many other minor features didn’t make it into this list.)