def handler2(self, *args): if needs_sampling(self): return VectorOperatorDistribution(op, self, args) elif any(needs_sampling(arg) for arg in args): return VectorMethodDistribution(method, self, args, {}) elif any(needs_lazy_evaluation(arg) for arg in args): # see analogous comment in distributionFunction return makeDelayedFunctionCall(handler2, args, {}) else: return method(self, *args)
def constructScenarioFrom(namespace, verbosity=0): """Build a Scenario object from an executed Scenic module.""" # Extract workspace, if one is specified if 'workspace' in namespace: workspace = namespace['workspace'] if not isinstance(workspace, Region): raise InvalidScenarioError(f'workspace {workspace} is not a Workspace') if needs_sampling(workspace): raise InvalidScenarioError('workspace must be a fixed region') if needs_lazy_evaluation(workspace): raise InvalidScenarioError('workspace uses value undefined ' 'outside of object definition') else: workspace = None # Create Scenario object scenario = Scenario(workspace, namespace['_objects'], namespace['_params'], namespace['_requirements'], namespace['_requirementDeps']) # Prune infeasible parts of the space if usePruning: pruning.prune(scenario, verbosity=verbosity) return scenario
def evaluator(): result = req() assert not needs_sampling(result) if needs_lazy_evaluation(result): raise InvalidScenarioError(f'requirement on line {line} uses value' ' undefined outside of object definition') return result
def try_sample(dependencies, objects, workspace, active_reqs): try: sample = sample_all(dependencies) except RejectionException as e: return None, e obj_samples = [sample[o] for o in objects] ns = [needs_sampling(o) for o in obj_samples] assert not any(ns) collidable = [o for o in obj_samples if not o.allowCollisions] for o in obj_samples: if not contains(workspace, o): return None, 'object containment' if any( cuboids_intersect(vi, vj) for (i, vi) in enumerate(collidable) for vj in collidable[:i]): return None, 'object intersection' for (i, req) in enumerate(active_reqs): if not req(sample): return None, f'user-specified requirement {i}' return sample, None
def store_scenario_state_in(namespace, requirement_syntax, filename, v_state: VeneerState, c_objs: List[Constructible]): """Post-process an executed Scenic module, extracting state from the veneer.""" # Extract created Objects # namespace['_objects'] = tuple(v_state.allObjects) namespace['_objects'] = c_objs # Extract global parameters namespace['_params'] = v_state.globalParameters for name, value in v_state.globalParameters.items(): if needs_lazy_evaluation(value): raise InvalidScenarioError(f'parameter {name} uses value {value}' ' undefined outside of object definition') # Extract requirements, scan for relations used for pruning, and create closures requirements = v_state.pendingRequirements final_reqs = [] requirement_deps = set() # things needing to be sampled to evaluate the requirements namespace['_requirements'] = final_reqs namespace['_requirementDeps'] = requirement_deps def makeClosure(req, bindings, line): """Create a closure testing the requirement in the correct runtime state.""" def evaluator(): result = req() assert not needs_sampling(result) if needs_lazy_evaluation(result): raise InvalidScenarioError(f'requirement on line {line} uses value' ' undefined outside of object definition') return result def closure(values): # rebind any names referring to sampled objects for name, value in bindings.items(): if value in values: namespace[name] = values[value] # evaluate requirement condition, reporting errors on the correct line try: v_state.evaluatingRequirement = True result = execute_python_function(evaluator, filename) finally: v_state.evaluatingRequirement = False return result return closure for reqID, (req, bindings, line, prob) in requirements.items(): reqNode = requirement_syntax[reqID] # Gather dependencies of the requirement for value in bindings.values(): if needs_sampling(value): requirement_deps.add(value) if needs_lazy_evaluation(value): raise InvalidScenarioError(f'requirement on line {line} uses value {value}' ' undefined outside of object definition') # Construct closure final_reqs.append((makeClosure(req, bindings, line), prob))
def helper(self, *args, **kwargs): from probRobScene.core.sampling import needs_sampling if any(needs_sampling(arg) for arg in itertools.chain(args, kwargs.values())): return VectorMethodDistribution(method, self, args, kwargs) elif any(needs_lazy_evaluation(arg) for arg in itertools.chain(args, kwargs.values())): # see analogous comment in distributionFunction return makeDelayedFunctionCall(helper, (self,) + args, kwargs) else: return method(self, *args, **kwargs)
def show_3d(o: Object, ax, highlight=False): if needs_sampling(o): raise RuntimeError('tried to show_3d() symbolic Object') color = o.color if hasattr(o, 'color') else (1, 0, 0) draw_cube(ax, np.array([*o.position]), np.array([o.width, o.length, o.height]), np.array([*o.orientation]), color=color) ax.quiver(o.position[0], o.position[1], o.position[2], o.forward[0], o.forward[1], o.forward[2], length=0.2, normalize=True)
def validate(self): """Make some simple static checks for inconsistent built-in requirements.""" objects = self.objects static_bounds = [has_static_bounds(obj) for obj in objects] for i in range(len(objects)): oi = objects[i] # skip objects with unknown positions or bounding boxes if not static_bounds[i]: continue # Require object to be contained in the workspace/valid region container = self.workspace if not needs_sampling(container) and not contains(container, oi): contains(container, oi) raise InvalidScenarioError( f'Object at {oi.position} does not fit in container') for j in range(i): oj = objects[j] if not static_bounds[j]: continue if cuboids_intersect(oi, oj): raise InvalidScenarioError( f'Object at {oi.position} intersects' f' object at {oj.position}')
def scenario_test(self, f_path: str): scenario = scenario_from_file(f_path) ex_world, used_its = scenario.generate(verbosity=2) for o in ex_world.objects: self.assertFalse(needs_sampling(o))
def handler2(self, *args, **kwargs): if any(needs_sampling(arg) for arg in itertools.chain(args, kwargs.values())): return MethodDistribution(method, self, args, kwargs) else: return method(self, *args, **kwargs)
def dependencies(self) -> List: return [x for x in (self.obj, *self.args, *self.kwargs.values()) if needs_sampling(x) or needs_lazy_evaluation(x)]
def has_static_bounds(obj) -> bool: static_pos = not needs_sampling(obj.position) static_corners = [not needs_sampling(corner) for corner in obj.corners] return static_pos and all(static_corners)
def dependencies(self) -> List: return [ getattr(self, p) for p in self.properties if needs_sampling(getattr(self, p)) ]