Sensors

Vortex provides several sensors for measuring distances between geometries, detecting overlaps and more.

In order to add a sensor to your content in the editor:

  1. Select Sensors in the Toolbox.
  2. Double-click the desired sensor to add it to the 3D View.
  3. Edit the name of the sensor in its Properties panel.

The following sensor extensions are available:

Distance Sensors

Geometry Distance Sensor

A Geometry Distance sensor measures the closest distance between specified collision geometries in your scene or mechanism. The sensor compares each geometry specified in the Geometries 1 group to each geometry in the Geometries 2 group, and returns the distance between the two closest geometries.

In the Properties panel, configure the following fields:

  • Active: Select this box to compute the distance between the closest collision geometry in the Geometries 1 group to the nearest collision geometry in Geometries 2. Deactivating this input stops any distance measurements, and will reset the distance information outputs.
  • Geometries 1 and Geometries 2:
    • Size: Adjust this field to specify how many collision geometries you want to include in each grouping of geometries. Use the Browse button at the end of each row to bring up a dialog box where you can select a geometry from the Explorer panel.

Once you have specified all the collision geometries in both groups, press the play button in the editor to run the simulation, and consult the following outputs:

  • Distance: Displays the minimum distance (in meters) between the geometry in the Geometries 1 group nearest to the closest geometry in Geometries 2.
  • Point 1: The position of the point on the collision geometry from Geometries 1 nearest to the closest geometry from Geometries 2.
  • Point 2: The position of the point on the collision geometry from Geometries 2 nearest to the closest geometry from Geometries 1.
  • Geometry Index 1: Indicates the row in Geometries 1 that contains the geometry nearest to the closest geometry from Geometries 2.
  • Geometry Index 2: Indicates the row in Geometries 2 that contains the geometry nearest to the closest geometry from Geometries 1.
  • Geometry Name 1: Displays the name of the collision geometry referred to in Geometry Index 1.
  • Geometry Name 2: Displays the name of the collision geometry referred to in Geometry Index 2.

Optionally, you can display a visual aid in the 3D View that draws a line connecting the two collision geometries at their closest points (see image below). To do this, right-click the eye icon next to the Geometry Distance sensor in the Explorer panel, and enable Accessory.

Part Distance Sensor

A Part Distance sensor measures the closest distance between specified Parts in your scene or mechanism.

In the Properties panel, configure the following fields:

  • Active: Select this box to compute the distance between Part 1 and Part 2. Deactivating this input stops any distance measurements, and will reset the distance information outputs.
  • Part 1: Use the Browse button at the end of this field to bring up a dialog box where you can select the first part from the Explorer panel.
  • Part 2: Use the Browse button at the end of this field to bring up a dialog box where you can select the second part from the Explorer panel.

Once you have specified the two parts, press the Play button to run the simulation, and consult the following outputs:

  • Distance: Displays the distance (in meters) between the collision geometry within Part 1 closest to the nearest collision geometry within Part 2. If a part does not contain any collision geometries, the part's origins are used.
  • Point 1: The position of the point on the collision geometry from Part 1 closest to Part 2.
  • Point 2: The position of the point on the collision geometry from Part 2 closest to Part 1.
  • Geometry Name 1: Displays the name of the collision geometry from Part 1 closest to Part 2.
  • Geometry Name 2: Displays the name of the collision geometry from Part 2 closest to Part 1.

Optionally, you can display a visual aid in the 3D View that draws a line connecting the two parts at their closest points (see image below). To do this, right-click the eye icon next to the Part Distance sensor in the Explorer panel, and enable Accessory.

Overlap Sensors

Two sensors that detect overlaps are related. These are the Intersection Sensor, which detects overlaps of pairs of geometries, and the Raycast Sensor, which detects overlaps of geometries with a specified ray. These sensors can be used in conjunction with Sensor Triggers in order to detect such overlaps. In this context, a "sensor" triggers a "sensor trigger". The following section describes these concepts in more details.

Intersection Sensor

An Intersection sensor detects when a designated sensor trigger object collides (overlaps) with a collision geometry used as a sensor. A single sensor can contain multiple objects.

In the Properties panel, configure the following fields:

  • Active: Check this box to toggle whether the sensor is in effect.
  • Select Intersecting with Everything to have this sensor report intersections with everything. Leave this field deselected to have it report intersections only with objects labeled by a sensor trigger.
  • Labels: Adjust the Size field to specify the number of labels given to this sensor. In the available slots, add custom text. Matching these labels to the same labels in a sensor trigger creates an interface between the two where you can control which sensor/trigger combinations result in a positive "Has Intersected" result in the sensor's output when contact is made.
    Leaving a label blank acts as a wild card, matching this sensor with all labeled triggers, regardless of the triggers' labels.
  • Sensor Extensions: Adjust the Size field to specify the amount of objects whose interactions you want to associate to this sensor. After adding the appropriate number of extension fields, press the ellipsis button at the end of the row, then browse to and select the object you want to link to this sensor.

For example, if you wanted to detect when a car is in contact with the ground, you could add an Intersection sensor and add each wheel as a sensor extension. In the corresponding sensor trigger, you would add the terrain as a trigger extension. Finally, you would add matching labels to both the sensor and the trigger. When at least one of the four tires is in contact with the ground, the "Has Intersected" output would become true, meaning contact is made.

Raycast Sensor

A Raycast sensor detects when a designated trigger object comes into contact with an imaginary line segment of a user-defined length. Unlike the Intersection sensor, the Raycast sensor is placed at a user-defined point in space. If you want to tie the sensor to an object, you can use the Connection Editor to link its transform to those of another object.

  • Max Distance: Specifies the maximum distance ahead of the sensor beyond which an intersection is no longer detected.
  • Active: Check this box to toggle whether the trigger is in effect.
  • Select Casting Ray on Everything to have this ray report intersections with everything. Leave this field deselected to have it report intersections only with objects labeled by a sensor trigger.
  • Labels: Adjust the Size field to specify the number of labels given to this trigger. In the available slots, add custom labels. Matching these labels with the same labels you added a sensor trigger creates an interface between the two where can control which sensor/triggers combinations result in a positive "Has Intersected" result in the sensor's Properties panel's output.

For example, if you wanted to add a proximity sensor to a car to detect when it comes too close to pedestrian, you could add a Raycast sensor and, using the Connection Editor, link it to the car, pointing it ahead. Next, you would set the maximum distance past which proximity to a pedestrian is no longer a concern. In the corresponding sensor trigger, you would add the pedestrians in your scene as trigger extensions. Finally, you would add matching labels to both the sensor and the trigger. When a pedestrian comes within the range of the maximum distance, the "Has Intersected" output would become true.

Sensor Trigger

A sensor trigger detects when a designated sensor (Raycast Sensor or Intersection Sensor) intersects with it.

In the Properties panel, configure the following fields:

  • Active: Check this box to toggle whether the trigger is in effect.
  • Labels: Adjust the Size field to specify the number of labels given to this trigger. In the available slots, add custom labels. Matching these labels with the same labels you added in a sensor creates an interface between the two where you can control which sensor/triggers combinations result in a positive "Has Intersected" result in the sensor's Properties panel's output.
  • Trigger Extensions: Adjust the Size field to specify the amount of objects you want to set off a collision with the sensor. After adding the appropriate number of extension fields, press the ellipsis button at the end of the row, then browse to and select the object you want to link to this trigger.

Advanced: Creating Sensors and Triggers in Python Scripts

Raycast Sensors, Intersection Sensors and Sensor Triggers can be created directly in python. In this case, additional information can be obtained from the sensors, which is otherwise not available in the high level extensions. Among others, this includes detailed contact information such as contact positions and normals for every detected intersection.

The following example code snippets demonstrate how to create an Intersection Sensor paired with a Sensor Trigger in both Python 3 and Python 2 (legacy) scripts.

In both examples, the script requires the following parameters and outputs, which need to be added to the script manually in the editor.

Parameters:

NameTypeDescription
TriggerExtExtension Pointer

Represents the extension that will be used as sensor trigger.

Can be any object that contains geometry, such as a Part, a Collision Geometry, or even a Cable or Vehicle.

SensorExtExtension Pointer

Represents the extension that will be used as intersection sensor.

Can be any object that contains geometry, such as a Part, a Collision Geometry, or even a Cable or Vehicle.

Outputs:

NameTypeDescription
CollidingBoolean

Flag specifying whether a collision between TriggerExt and SensorExt (see above) was detected.

ContactsInteger

Number of contacts found by the intersection sensor in every step.

PenetrationDoubleSum of penetration of all contacts that were found by the intersection sensor in every step.

Python 3 example

from Vortex import *

def on_simulation_start(extension):
	extension.trigger = SensorTrigger()
	extension.trigger.setTriggerExtension(self.parameters.TriggerExt.value)
	extension.trigger.addLabel('Blue')
	extension.sensor = IntersectionSensor()
	extension.sensor.setSensorExtension(self.parameters.SensorExt.value)
	extension.sensor.setCollectingIntersections(True)
	extension.sensor.addLabel('Blue')

def on_simulation_stop(extension):
	extension.sensor = None
	extension.trigger = None

def post_step(extension):
	total_pen = 0
	total_con = 0
	for i in extension.sensor.getIntersections():
		total_con += len(i.contacts)
		for c in i.contacts:
			total_pen += c.penetration
	extension.outputs.Colliding.value = extension.sensor.hasIntersected()
	extension.outputs.Contacts.value = total_con
	extension.outputs.Penetration.value = total_pen

Python 2 example

from VxSim import *

def on_add_to_universe(self, universe):
	self.trigger = SensorTrigger(universe)
	self.trigger.setTriggerExtension(self.parameters.TriggerExt.value)
	self.trigger.addLabel('Blue')
	self.sensor = IntersectionSensor(universe)
	self.sensor.setSensorExtension(self.parameters.SensorExt.value)
	self.sensor.setCollectingIntersections(True)
	self.sensor.addLabel('Blue')

def on_remove_from_universe(self, universe):
	self.sensor = None
	self.trigger = None

def post_step(self):
	total_pen = 0
	total_con = 0
	for i in self.sensor.getIntersections():
		total_con += len(i.contacts)
		for c in i.contacts:
			total_pen += c.penetration
	self.outputs.Colliding.value = self.sensor.hasIntersected()
	self.outputs.Contacts.value = total_con
	self.outputs.Penetration.value = total_pen

Depth Sensor

The Depth sensor allows you to position a sensor in your simulation that opens a picture-in-picture window displaying the distances of objects within its view according to a grayscale. Objects closer to the Depth sensor are lighter gray, while objects farther away are darker.

Note The usage of this extension is not yet finalized for this version but it is included here as a technical preview.

This extension contains the following sub-extensions in its Explorer panel: Depth, Sensor, Output, HUD, Monitor.

In many cases, simply placing the Depth sensor would be sufficient, but there exist inputs and parameters you could set in Depth sensor's sub-extensions to suit your particular needs.

In the Properties panel, configure the sub-extensions:

  • Depth: In this sub-extension, select Visible to turn on the Depth sensor in the picture-in-picture window. Also, Camera Name comes preset with the name of the related monitor used for the Depth sensor.
  • Sensor: See Perspective camera for information about this sub-extension's inputs and parameters. In addition, the Near and Far inputs determine the range (in meters) from the sensor that the depth will be analyzed (this affect the grayscale).
  • Output: See Textures for information about this sub-extension's inputs and parameters.
  • HUD: See HUD Images for information about this sub-extension's inputs and parameters.
  • Monitor: See Monitor for information about this sub-extension's inputs and parameters.

Moving and Attaching the Depth Sensor

By default, the Depth sensor is created at the origin of the world, but you can move it using the Transform toolbar or the transforms in its Properties panel.

You can connect a Depth sensor to an object by linking the Parent Transform input of the Sensor sub-extension to the World Transform output of the object using the Connection Editor.

Running the Depth Sensor Fullscreen Mode

Optionally, you can run the Depth sensor in fullscreen mode.

To run the Depth sensor in fullscreen mode:

  1. In the Explorer panel, right-click the Depth sensor's Sensor sub-extension and select Activate Camera. Doing so will view the scene from the Depth sensor's perspective.
  2. Still in the Explorer panel, select the Depth sub-extension to open its Properties panel. Clear the Camera Name field.
  3. Select the HUD sub-extension in the Explorer panel. Deselect the Visible input to remove the low-resolution overlay.

The Depth sensor will take up the entire 3D View.

Taking a Screenshot

You can also save a screenshot of the Depth sensor by adding a Python script extension. After adding the script, add a boolean input named "saveImage" in the resulting dialog window, then click Ok. In your Python script file, enter the following code:

import Vortex

def pre_step(extension):
    if extension.inputs.saveImage:
        Vortex.Window.getFirstWindow().takeScreenshot("my_filename.png")

When running in a SimApp, you can modify the SimApp setup document (*.vxc) and dedicate an offscreen (invisible) window with a specific resolution to receive the Depth buffer render.The larger the resolution of the Depth sensor, the longer it takes to retrieve the image. You can configure your viewport for typical sensor resolutions (160x60 pixels, for example).