Skip to content

Driving Example

Overview

The SightLab Driving Simulation is a flexible platform for building driving studies. It is located in the ExampleScripts-Driving folder and supports desktop, VR headsets, game controllers, and steering wheels. Participants drive through city streets or along a highway, with traffic and pedestrians, while SightLab records their gaze, the car's movement, and any collisions.

Driver's view from the jeep at a city intersection, with a taxi, pedestrians, and the speed and gear display

Click below to Download the latest version


Download Latest Version

Quick Start

  1. Run Driving_GUI_Main.py.
  2. In the SightLab GUI, choose your hardware (see Hardware Options). To drive somewhere else, see Changing the Environment.
  3. Press Spacebar to start the experiment, and press it again to go on to the next trial.
  4. Drive using the controls. Press r at any time to put the car back where the trial started.
  5. After the session, the data is in the data folder. Run SightLabVR_Replay.py to replay the session.

Traffic and pedestrians are on by default. Turn them off with ADD_TRAFFIC and ADD_PEDESTRIANS in Driving_Config.py, and set how many vehicles and pedestrians each trial has in the STIM file.

Features

Driving

  • Modifiable car models and environments
  • Realistic gas, brake, and steering controls, with Drive and Reverse gears
  • Acceleration, braking, and coasting set in real-world units (see Driving Feel)
  • Steering that pivots around the rear axle and eases into and out of turns
  • Solid-world collision: the car can't drive through buildings, props, or other vehicles. It uses lightweight raycasts, so no physics engine is needed (see Collision System)
  • Elevation, hill, and ramp support
  • Interactive headlights and engine audio whose pitch follows the car's speed
  • Animated MPH and RPM gauges, steering wheel, and tires
  • Controller vibration on impacts and when pulling away (see Controller Vibration)
  • HUD showing speed, gear, fixations, and timestamp
  • Multi-user driving: several drivers in the same city, each seeing the others' cars (see Multi-User)

Research and Analysis

  • Eye tracking, with fixations and dwell time on the dashboard, mirrors, traffic vehicles, traffic lights, and pedestrians
  • Car position, rotation, velocity, and average speed saved for each trial, plus any custom data you add (see Data Collected)
  • Hit counts, collision flags, and nearest-vehicle distance for traffic and pedestrians
  • Physiological data integration, including Biopac markers on collisions
  • Session replay with gaze paths and heatmaps
  • Instructor view with real-time control and monitoring

Environment

  • Day, night, and fog conditions with variable lighting
  • Traffic that follows the road, keeps its distance, obeys traffic lights, and yields to your car (see Traffic System)
  • Routes recorded in-app, so traffic can be added to any environment without a 3D tool
  • Animated pedestrians that walk the sidewalks, wait at signals, and pause when your car approaches their path (see Pedestrian System)
  • Traffic vehicle wheels that spin with speed (see Traffic Wheel Animation)
  • 360° media integration
  • Customizable obstacles

Night trial with the headlights on, recording the driver's gaze on the car radio

Included Scripts

Script What it's for
Driving_GUI_Main.py Start here. The main example. Hardware and environment are chosen in the SightLab GUI, and per-trial traffic and pedestrian settings come from Resources/stim_file.csv.
Driving_Main_noGUI.py The same experiment without the GUI. Each row of Resources/stim_file-nonGUI.csv is one trial and sets that trial's environment. See Setting Up Trials.
Driving_GUI_Traffic.py Same as Driving_GUI_Main.py, but traffic is always on, whatever ADD_TRAFFIC is set to. Kept from earlier versions, where this was the only script with traffic.
Driving_Server.py, Driving_Client.py The same experiment as a multi-user session: one server, plus a client for each driver. See Multi-User.
Driving_Config.py Car, viewpoint, collision, driving feel, vibration, and hardware settings, plus the traffic and pedestrian switches. See Driving Configuration Settings.
traffic_config.py Traffic and pedestrian settings. See Traffic Settings and Pedestrian Settings.
generate_pedestrian_routes.py Builds sidewalk routes for pedestrians from an environment's geometry. See Sidewalk Routes.
SightLabVR_Replay.py Plays back recorded sessions. See Session Replay.
modules/wheel_inspector.py Shows the axis and button IDs of a steering wheel. See Adding a Steering Wheel.

Traffic (ADD_TRAFFIC) and pedestrians (ADD_PEDESTRIANS) work in every script, together or separately.

Controls

For keys shared by all SightLab experiments, see Controls.

Keyboard Shortcuts

These keys work with any hardware:

Key Action
Spacebar Start the experiment, or go on to the next trial
b Cycle the viewpoint: in the car, third person, and closer in. On an Xbox controller, press Select.
r Reset: return the car to the position and heading it started the trial at, put the seat position back, and bring the car to a stop
i Re-center the view rotation (Driving_GUI_Main.py, Driving_Server.py, and Driving_Client.py)
v Print the current seat position, so it can be saved as the default (see Changing the View Position)
T, F, G, H, Z, X Adjust the seat position on desktop
W, A, S, D, Z, X Adjust the seat position in a VR headset

Driving Controls

Action Keyboard Xbox controller VR controllers SteamVR / Vive wands Steering wheel
Steer W, A, S, D Left stick Left stick Right trackpad (left/right) Wheel
Gas = Right trigger Right trigger (some headsets also need the right-hand B button held) Right system button Gas pedal
Brake - Left trigger Left trigger Right grip button Brake pedal
Toggle Drive / Reverse Y X Y Controller button Wheel button
Look around Mouse Right stick or mouse Headset Headset

Come to a stop before toggling between Drive and Reverse. To see or change which button does what for your hardware, see Customizing Controls.

Hardware Options

Choose one of these in the SightLab GUI. Each name maps to a vizconnect file through HARDWARE_CONFIGS in Driving_Config.py.

Type Options
Desktop Driving Desktop (keyboard and mouse), Desktop Driving Controller (Xbox controller)
Steering wheel Driving G923 Wheel, Driving Thrustmaster Wheel, Driving Wheel, Driving Vive Focus Vision G923 Wheel
Meta Driving Meta, Driving Meta Game Controller
OpenXR Driving OpenXR, Driving OpenXR No EyeTR, Driving Quest Pro, Driving Varjo, Driving Vive Focus Vision, Driving Pimax Controller
SteamVR and HP Driving SteamVR, Driving SteamVR Controller, Driving Vive, Driving Omnicept

Session Replay

After running a session, use SightLabVR_Replay.py to play it back, including the car's movement. Check Follow Mode to see the drive in first person from the car; otherwise the replay uses the default third-person view. Walk Path also shows the direction and speed of the car. Traffic vehicles and pedestrians appear in the replay as well.

For more information, see Session Replay. For multi-user sessions, see Multi-User Data and Replay.

SightLabVR_Replay showing a recorded drive from inside the jeep, with the gaze ray and Replay Preferences panel

Data Collected

Data is saved in the data folder. Multi-user sessions save it on the server (see Multi-User Data and Replay).

Car and Driver Data

  • Raw trial data (every frame): Car Velocity X, Car Velocity Y, and Car Velocity Z, plus tracking columns for the car's position and rotation (my_car).
  • Average speed: Average Speed MPH for each trial, in the trial data and the experiment summary.
  • Gaze data: dwell time, view counts, and fixations on the included jeep's InstrumentPanel, Radio, RearViewMirror, and LeftMirror, plus any other gaze objects in the scene.
  • Eye tracking and physiological data: recorded as in any SightLab session, depending on your hardware (see Biopac Integration).
  • Replay: the car is recorded as the my_car scene object, so its movement appears in Session Replay.
  • Custom data: add your own columns with sightlab.setCustomTrialData(value, 'Column Name'), the way the scripts save velocity.

Traffic Data

  • Raw trial data: Nearest Vehicle Distance, the meters from your car's body to the closest traffic vehicle, every frame, and a hit by traffic_car_XX flag when a moving vehicle reaches you.
  • Experiment summary: Traffic Count, Min Vehicle Distance, and Vehicle Hits.
  • Gaze data: dwell time, view counts, and fixations for each vehicle and traffic light, like any other gaze object.

Pedestrian Data

  • Raw trial data: a hit pedestrian <name> flag on the frame your car strikes an avatar.
  • Experiment summary: Pedestrian Hits, reset to 0 at the start of each trial and written at the end of the trial.
  • Gaze data: dwell time, view counts, and fixations for each pedestrian, when PEDESTRIAN_GAZE_OBJECTS is on.

Collision Events and Biopac Markers

  • Events: TRAFFIC_HIT_EVENT (viz.getEventID('TRAFFIC_HIT')) is sent with the vehicle's name, and PEDESTRIAN_HIT_EVENT (viz.getEventID('PEDESTRIAN_HIT')) with the pedestrian's name, so a collision can end a trial or trigger a rating scale.
  • Biopac: when a Biopac is connected, each hit also inserts a vehicle hit: <name> or pedestrian hit: <name> stim marker, so collisions line up with the physiological recording. The scripts do this in markHit(), next to the vibration handlers; edit the marker text there. See Sending Events to Biopac.
  • Vibration: the controller vibrates on each hit (see Controller Vibration).

Register collision handlers once, outside the trial loop. viz.callback adds a new handler each time it is called, so registering inside the loop would run the handler once for every trial so far:

def onTrafficHit(name):
    print('Hit by', name)
viz.callback(TRAFFIC_HIT_EVENT, onTrafficHit)

Setting Up Trials

Each trial's traffic and pedestrian settings come from a STIM file in Resources, with one row per trial. Row 1 is trial 1.

  • GUI scripts read stim_file.csv. The environment, number of trials, and start and end conditions are set in the GUI.
  • Driving_Main_noGUI.py reads stim_file-nonGUI.csv, which also sets each trial's scene and the number of trials:
    • The environment column sets the scene for each trial. ENVIRONMENT_MODEL in Driving_Config.py is only used when a row has no environment.
    • The number of rows sets the number of trials.
    • Traffic and pedestrian routes follow each row's environment, so street_day.osgb loads Resources/traffic/street_day.json and street_day_pedestrians.json.
Column Meaning When missing or blank
environment Environment file for the trial (stim_file-nonGUI.csv only) ENVIRONMENT_MODEL
number of vehicles How many vehicles from the pool are active (0 to MAX_VEHICLES) DEFAULT_VEHICLES (6)
traffic speed Target speed in m/s for every lane Each lane's own speed
traffic lights on / off. With lights off, crossing lanes yield to each other at the intersection instead. LIGHTS_ENABLED (on)
yield to user car on / off. Whether traffic brakes early for your car. YIELD_TO_USER_CAR (on)
number of pedestrians Active pedestrians, limited by the pool (MAX_PEDESTRIANS). 0 means no pedestrians. DEFAULT_PEDESTRIANS (4)
pedestrian speed Walking speed in m/s, varied per pedestrian by PEDESTRIAN_SPEED_JITTER PEDESTRIAN_SPEED_MPS (1.2)

The included stim_file-nonGUI.csv:

environment,number of vehicles,traffic speed,traffic lights,yield to user car,number of pedestrians
Resources/environments/city_rtx2.osgb,15,13,on,on,8
Resources/environments/ENV_Highway.osgb,12,20,on,on,0
Resources/environments/street_day.osgb,8,10,on,on,8
Resources/environments/street__night.osgb,10,12,on,off,10

This makes traffic density and speed per-trial conditions, for example a light and a heavy trial on the same road, saved alongside the driver's gaze and velocity data. The same settings can be applied in code with traffic.configure({'number of vehicles': 4, 'traffic lights': 'off'}) before traffic.start().

Conditions can also be changed in code. For example, Driving_GUI_Main.py turns the headlights on for trials 2 and 4 (see Scripting the Car).

Customization

Changing the Environment

  1. Place the new environment file in the Resources/environments folder.
  2. Select it:

    • GUI scripts: click Modify on the GUI screen and choose the new environment.

      Environment selector in the SightLab GUI

    • Driving_Main_noGUI.py: set the file in the environment column of Resources/stim_file-nonGUI.csv.

    • Set where the car starts by adding the environment's file name to CAR_STARTING_POSITIONS in Driving_Config.py. Environments not listed there use CAR_STARTING_POSITION.
    • Optionally, record traffic routes and generate sidewalk routes for the new environment.

Changing the Vehicle

Changing the Vehicle

Change the path to your vehicle in Driving_Config.py, along with the names of the parts that can be animated (headlights, wheels, steering wheel, and MPH and RPM gauges). You can find the part names in Inspector.

CAR_MODEL = 'Resources/jeepmodel.osgb'

When swapping vehicles, also update REAR_AXLE_OFFSET in Driving_Config.py. The car rotates around this point (its rear axle) when steering, and most models do not have their origin centered on the body. To measure it, open the model in Inspector and read the rear wheel centers, or average the bounding-box centers of the two rear wheel nodes.

Regions of interest inside the vehicle

The car is non-intersectable (see Collision System), so regions of interest on items inside it are set up differently. Add a region in Inspector, right-click it in the scene graph on the left, and choose Save. Then add the saved model, parent it to the car, and register it as a gaze object. The included jeep does this for its instrument panel, radio, and mirrors:

instrumentPanel = vizfx.addChild('Resources/InstrumentPanel.osgb')
instrumentPanel.setParent(car)
sightlab.addSceneObject("InstrumentPanel", instrumentPanel, gaze=True)

In multi-user sessions, each driver's car is painted in their assigned color. See CAR_PAINT_NAME_MATCH under Multi-User Settings.

Changing the View Position

  1. Run the script from the Vizard editor, and move the viewpoint with T F G H and Z X (desktop) or W A S D and Z X (headset).
  2. When the position looks right, press v. The seat position is printed in the Vizard interactive window.
  3. Paste the position into Driving_Config.py:

    • PASSENGER_POSITION_TRUCK: the included jeep on desktop, steering wheels, and Meta headsets
    • PASSENGER_POSITION: other car models on desktop and Meta headsets

    SteamVR, Vive, and OpenXR headsets use seat positions set in the script itself. Edit those directly:

    if sightlab.getConfig() in ['Driving SteamVR']:
        transportNode2.setPosition([0.188, 1.1, 0.868])
    

transportNode2 is the seat inside the car, and transportNode moves the car itself. THIRD_PERSON_VIEW and CLOSER_IN_VIEW set the other two viewpoints that b cycles through.

Adding a Steering Wheel

Adding a steering wheel

Configurations are included for the Logitech G923 Wheel (Driving G923 Wheel and Driving Vive Focus Vision G923 Wheel) and Thrustmaster wheels (Driving Thrustmaster Wheel). The wheel turns the car, the pedals are gas and brake, and buttons on the wheel toggle Drive/Reverse and the viewpoint.

To add another wheel:

  1. Run modules/wheel_inspector.py. Turn the wheel, press each pedal, and press each button to see which axis or button ID it uses. The Windows Set up USB game controllers panel shows the same information.
  2. Make a copy of an included input module, such as modules/g923_input.py, and change the axis IDs to match your wheel:

    # Top of the file
    THROTTLE_PEDAL = 1   # Throttle pedal: 1.0 when not pressed, -1.0 when fully pressed
    BRAKE_PEDAL = 2      # Brake pedal: 1.0 when not pressed, -1.0 when fully pressed
    CLUTCH_PEDAL = 3     # Clutch pedal: 1.0 when not pressed, varies when pressed
    
    # In __init__
    self.wheel_axis = 0  # Steering wheel: -1 to +1
    
  3. Make a copy of one of the wheel vizconnect files in vizconnect_configs, such as vizconnect_config_desktop_driving_g923.py. Change its import to your new input module, and set the button IDs for events such as SHIFT_GEAR (Drive/Reverse) and toggleViews under its mappings.

  4. Add the new configuration to HARDWARE_CONFIGS in Driving_Config.py so it appears in the GUI.

Contact support@worldviz.com for more information.

Customizing Controls

  1. Open the vizconnect file for your hardware from the example's vizconnect_configs folder. HARDWARE_CONFIGS in Driving_Config.py lists which file each hardware option uses.
  2. Go to Advanced > Transports > Driving > Mappings, and to Acceleration/Deceleration under Events.
  3. Modify the mappings as needed.

How quickly the car speeds up and slows down is set in Driving_Config.py (see Driving Feel).

Traffic System

Traffic vehicles and traffic lights at a city intersection, seen from above

Traffic comes from a reusable, self-contained package (modules/traffic/, configured in traffic_config.py). Vehicles follow the road, keep their distance from each other, obey traffic lights, react to your car, and can't drive through walls, each other, or you. It works in any environment without a 3D modeling tool, because routes are recorded from the driver's seat while the demo runs.

Traffic is turned on with ADD_TRAFFIC = True in Driving_Config.py and works in all of the scripts. Everything else is set in traffic_config.py, and the number and speed of vehicles for each trial are set in the STIM file. Recorded traffic data is listed under Traffic Data.

How It Works

The system is kinematic (no physics engine), so it stays fast even with a dozen vehicles in a large city model:

  • Routes, not physics — each lane is a line recorded along the road and saved as Resources/traffic/<environment>.json. When a trial starts, the lane is smoothed, resampled every meter, and each sample is snapped to the ground with a single downward ray. Vehicles then follow that path, so they stay on the road surface across grades, curves, and overpasses without casting ground rays every frame.
  • Car following — vehicles in the same lane keep a speed-dependent gap (Intelligent Driver Model) and can never overlap. Vehicles crossing or merging from another lane ahead are treated as obstacles too.
  • Traffic lights — a stop line on a lane belongs to a signal group of an intersection, and each intersection cycles its groups through green, yellow, and all-red while vehicles queue behind the line on red. Lights are built procedurally (no model needed) and registered as gaze objects, so looks at a signal are recorded. Highway lanes have no signals: they are open roads, and vehicles respawn at the start.
  • Bumper rays — the same slope-aware sweep used for your own car (see Collision System) runs ahead of every traffic vehicle along its lane. If a wall or prop is in the way, for example because a route was recorded slightly off the road, the vehicle brakes instead of passing through it, and a console warning names whatever blocked it.
  • Your car — traffic treats it as a solid obstacle of its real length and width, not as a point. With yield to user car on, vehicles brake early and queue behind you at an intersection. With it off, they keep their speed but are still stopped on contact, so traffic never drives through you. Your own bumper collision already stops you from driving into them, so the block works in both directions.

Included Routes

Environment Traffic
street_day.osgb, street__night.osgb Signalized four-way intersection: one lane each way on the boulevard (signal group A) and on the cross street (group B)
city_rtx2.osgb Boulevard with two lanes each way, plus the hill street the car starts on, meeting at a signalized intersection
ENV_Highway.osgb Three lanes in your direction along 533 m of the main carriageway, following its curve and grade, plus two lanes of oncoming traffic on the carriageway across the median
chicago2.osgb (expanded download) The avenue the car starts on, one lane each way, crossed by two cross streets at signalized intersections. The car starts at a red light while cross traffic goes first.

A route is tied to real coordinates, so the car's starting position is set per environment in Driving_Config.py. That puts the car on the road the route was drawn for, in its lane, and behind the stop line where there is one:

CAR_STARTING_POSITIONS = {'street_day.osgb': [0.25, 0, -3.5], 'street__night.osgb': [0.25, 0, -3.5],
                          'city_rtx2.osgb': [2.5, 0, -30.0],
                          'ENV_Highway.osgb': [-41.5, 0, -120.0],
                          'chicago2.osgb': [0.33, 0, 97.0]}

Any environment without a route file runs with no traffic and prints a message saying so.

Recording Routes for a New Environment

Routes are created in-app with the route recorder, by driving the road you want traffic on:

  1. Set RECORD_ROUTES = True in traffic_config.py and run the demo.
  2. Start a trial in the environment, then press F5 to open the recorder. Traffic pauses and the key list appears on screen.
  3. Drive along a lane in the direction cars should travel with F4 (auto-drop) on, which drops a ground-snapped waypoint every few meters. F6 drops one by hand at a bend.
  4. Press F9 to finish the lane as an open road (vehicles respawn at its start), or F8 to close it as a loop. Repeat for each lane, including the oncoming ones.
  5. Where cars should stop, press F10. A stop line is added to the last lane, and a traffic light is placed at the curb facing the approaching traffic. PAGE DOWN cycles the signal group (A, B, C, D) so crossing streets get different groups, and INSERT starts a new intersection centered on your position.
  6. Press F12 to save. The file is written, and traffic restarts on the new routes immediately.
Key Action
F5 Show / hide the recorder
F6 Drop a waypoint at your position
F4 Toggle automatic waypoint dropping while driving
F7 Undo the last waypoint
PAGE UP Delete the waypoint nearest to you
F8 / F9 Finish the lane as a loop / as an open road
F10 Add a stop line and traffic light to the last lane
INSERT Start a new intersection at your position
PAGE DOWN Cycle the signal group for the next stop line
END / HOME Raise / lower the last lane's speed by 1 m/s
DELETE Delete the last lane
F11 (twice within 3 s) Clear everything and start over
F12 Save and reload

All keys can be changed in RECORDER_KEYS in traffic_config.py. The on-screen key list can be resized or moved with RECORDER_TEXT_SCALE, RECORDER_TEXT_POSITION, and RECORDER_TEXT_ALIGN; it defaults to the top-right corner, clear of SightLab's dwell readout and trial timer. Auto-drop uses F4 here rather than the t key used in the Street Walking Example, because t is already a viewpoint key while driving.

Route files are plain JSON and can be edited by hand. Waypoint heights are snapped to the ground again every time a file loads, so routes survive small changes to the environment. Set DEBUG_DRAW_ROUTES = True to draw the loaded lanes, stop lines, and intersections during a normal run.

Vehicle Models

Traffic vehicle models, including a black sedan and a taxi, stopped at a crosswalk

Every .osgb, .osg, or .ive model in Resources/vehicles/ is used as a traffic vehicle. The pool (MAX_VEHICLES, 15 by default) cycles through the files in alphabetical order, so adding a model is a matter of dropping it in the folder. The included models are Black-Sedan.osgb, car2.osgb, car3.osgb, and Taxi.osgb.

Models are re-centered and turned to face the road automatically. If one drives backwards or is the wrong size, add an override with yaw and/or scale:

VEHICLE_MODEL_OVERRIDES = {'car3.osgb': {'yaw': 180}, 'Taxi.osgb': {'yaw': 180}}

Set TINT_VEHICLES = True to tint each vehicle a random color from VEHICLE_TINTS.

Vehicles are registered as gaze objects (traffic_car_00traffic_car_14), so dwell time and fixations are recorded per vehicle, and they appear in Session Replay.

Traffic Wheel Animation

Traffic wheels spin according to each vehicle's current speed and stop when it is stationary. Configure the wheel node names for each model in traffic_config.py. The included mappings are:

VEHICLE_WHEEL_NODES = {
    'car2.osgb': {'nodes': ['Steer_FL', 'Steer_FR', 'Steer_RL', 'Steer_RR'], 'sign': -1},
    'car3.osgb': {'nodes': ['Steer_FL', 'Steer_FR', 'Steer_RL', 'Steer_RR'], 'axis': 'roll'},
    'Taxi.osgb': {'nodes': ['enhanced_wheel_FL_steer', 'enhanced_wheel_FR_steer',
                            'enhanced_wheel_RL_steer', 'enhanced_wheel_RR_steer'],
                  'axis': 'roll'},
    'car2_pbr.osgb': {'nodes': ['Steer_FL', 'Steer_FR', 'Steer_RL', 'Steer_RR'], 'sign': -1},
    'Black-Sedan.osgb': {'nodes': ['Steer_FL', 'Steer_FR', 'Steer_RL', 'Steer_RR'], 'sign': -1}
}
VEHICLE_WHEEL_RADIUS = 0.33     # wheel radius in meters
VEHICLE_WHEEL_SPIN_SIGN = 1.0   # default rotation direction

To animate another traffic model, look up its wheel node names and add an entry keyed by its file name. An entry can be a list of node names (using the defaults), or a dictionary with nodes, radius, sign, and axis. The default axis is pitch; use roll or yaw to match the model's local rotation axis. Set sign to -1 if the wheels spin backward, and adjust radius if the rotation rate does not match the road speed. Keep the existing entries when adding models.

Models without a mapping still drive normally, but their wheels do not spin. Missing node names are skipped; if none of the configured nodes are found, the console reports it. These settings apply to the traffic vehicles; your own car's wheel names are set in Driving_Config.py.

Traffic Settings

The most useful options in traffic_config.py:

  • RECORD_ROUTES, DEBUG_DRAW_ROUTES — route recorder and route drawing. The master switch ADD_TRAFFIC is in Driving_Config.py.
  • MAX_VEHICLES (15), DEFAULT_VEHICLES (6), DEFAULT_SPEED_MPS (13), SPEED_JITTER — pool size, and speeds when the STIM file does not specify them.
  • MIN_GAP, TIME_HEADWAY, MAX_ACCEL, COMFORT_DECEL, EMERGENCY_DECEL, CROSS_TRAFFIC_RANGE — car-following behavior.
  • GREEN_TIME (12 s), YELLOW_TIME (3 s), ALL_RED_TIME (1.5 s), STOP_LINE_MARGIN — signal timing. A route file can override the timing per intersection.
  • CONFLICT_ZONE_RADIUS — with lights off, how close another lane's car must be to the intersection before a vehicle yields.
  • PEDESTRIAN_LOOKAHEAD, CORRIDOR_HALF_WIDTH, HIT_RADIUS, HIT_COOLDOWN, HIT_SOUND — how far ahead traffic looks for your car, and what counts as a hit.
  • BLOCK_AT_CONTACT, CONTACT_MARGIN — the hard block that stops a non-yielding vehicle when it reaches your car. It is on here, because the car is solid, and off in the walking example, where a non-yielding vehicle is meant to register a hit on the pedestrian.
  • SPAWN_CLEAR_RADIUS — how much room is left around your car when vehicles are placed at the start of a trial.
  • BUMPER_HEIGHT, BUMPER_RANGE, SLOPE_LIMIT, RAYCAST_EVERY_N_FRAMES, BUMPER_EXCLUDE_NODE_NAMES — the traffic vehicles' own bumper rays. Invisible gaze-catcher and occluder geometry is excluded by name so it never blocks traffic.
  • LIGHTS_AS_GAZE_OBJECTS, LOG_NEAREST_VEHICLE — record gaze on traffic lights, and the per-frame nearest-vehicle distance.
  • RANDOM_SEED (42) — fixed, so every run, and every computer in a multi-user session, gets the same vehicle layout.

Pedestrian System

A pedestrian avatar at a crosswalk, with a taxi and other pedestrians in the background

Pedestrians are turned on with ADD_PEDESTRIANS = True in Driving_Config.py and work in all of the scripts, with or without vehicle traffic (ADD_TRAFFIC). The pedestrian system (modules/traffic/pedestrians.py) loads animated avatars from Resources/pedestrians/, places them along sidewalk routes at the start of each trial, and stops and hides them at the end. Recorded pedestrian data is listed under Pedestrian Data.

Walking and Yielding

Pedestrians walk between ground-snapped waypoints using vizact.walkTo. They follow closed loops continuously, or turn around at the ends of open paths. When your car is close to a pedestrian and their walking path, they pause and play their idle animation, then continue once the path has stayed clear for PEDESTRIAN_RESUME_DELAY (1 second by default). Pedestrians already in the roadway keep walking to clear it. If a pedestrian gets stuck while walking, they turn around.

When traffic is on, pedestrians also wait at the roadside before crossing a lane whose vehicle light is green or yellow (PEDESTRIAN_OBEY_SIGNALS).

The STIM column yield to user car controls whether traffic vehicles brake early for your car, not pedestrian behavior. Whether pedestrians stop for your car is set with the PEDESTRIAN_YIELD_* settings below.

Sidewalk Routes

The system looks for sidewalk routes in this order:

  1. A dedicated route file, Resources/traffic/<environment>_pedestrians.json. It uses the same lane format as the vehicle route files; only the lane waypoints and loop flag are used. Files are included for street_day, street__night, and city_rtx2.
  2. Sidewalks derived from the vehicle routes while the experiment runs. The system offsets points to the right of each lane's direction of travel, searches outward for curbs, snaps points to the ground, and checks clearance from walls and the roadway. This works with ADD_TRAFFIC = False too, as long as the vehicle route file exists. Set PEDESTRIAN_LANE_OFFSET = 0 to turn this off.

Without usable routes, no pedestrians walk in that environment.

Generating a route file. Derived sidewalks are only a fallback and can leave few usable paths on narrow streets. To create a dedicated route file, add the environment's name to the ENVIRONMENTS list at the top of generate_pedestrian_routes.py and run the script with Vizard. The environment needs a vehicle route file in Resources/traffic and its model in Resources/environments. The script scans the ground on either side of each road for walkable sidewalk, runs a path down the middle of it, and cuts the path wherever something blocks it. Run it again whenever the environment model changes.

Pedestrian Avatars

Place animated avatar models, such as .cfg or .osgb files, in Resources/pedestrians/. Five RocketBox avatars plus vcc_female.cfg and vcc_male.cfg are included. The pool (MAX_PEDESTRIANS) cycles through the folder, so a count above the number of files reuses avatars.

Set each model's idle and walk animation IDs in PEDESTRIAN_ANIMATIONS in traffic_config.py. Models that aren't listed use PEDESTRIAN_DEFAULT_ANIMATIONS (idle: 1, walk: 2); the included RocketBox avatars use idle 1 and walk 5. PEDESTRIAN_MODEL_OVERRIDES supports per-model scale adjustments.

Pedestrians are registered as avatar scene objects (pedestrian_00, and so on) for recording and replay. PEDESTRIAN_GAZE_OBJECTS = True records pedestrian dwell and fixation data in single-user sessions; this is automatically turned off in multi-user sessions.

Pedestrian Settings

Useful settings in traffic_config.py:

  • MAX_PEDESTRIANS (15), DEFAULT_PEDESTRIANS (4), PEDESTRIAN_SPEED_MPS (1.2), PEDESTRIAN_SPEED_JITTER, PEDESTRIAN_TURN_SPEED — pool size, walking speed, and turning.
  • PEDESTRIAN_YIELD_DISTANCE (12 m), PEDESTRIAN_YIELD_CLEARANCE (2.5 m), PEDESTRIAN_RESUME_DELAY — when avatars stop for your car and when they continue.
  • PEDESTRIAN_OBEY_SIGNALS (True), PEDESTRIAN_SIGNAL_MARGIN, PEDESTRIAN_SIGNAL_RANGE — waiting at signalized crossings.
  • PEDESTRIAN_LANE_OFFSET, PEDESTRIAN_CURB_SEARCH, PEDESTRIAN_SIDEWALK_MARGIN, PEDESTRIAN_WALL_CLEARANCE, PEDESTRIAN_ROAD_HALF_WIDTH, PEDESTRIAN_MIN_ROUTE_LENGTH — placement of derived sidewalk paths.
  • PEDESTRIAN_SPAWN_CLEAR_RADIUS, PEDESTRIAN_SPAWN_NEAR_CAR, PEDESTRIAN_SPAWN_SEPARATION — initial clearance from the car and spacing between avatars.
  • PEDESTRIAN_STUCK_TIME, PEDESTRIAN_STUCK_SPEED — recovery when an avatar cannot make progress.
  • PEDESTRIAN_HIT_RADIUS (1 m), PEDESTRIAN_HIT_COOLDOWN (2 s), PEDESTRIAN_HIT_SOUND (none) — what counts as striking a pedestrian, how long before the same avatar can register another hit, and an optional impact sound. The radius is measured from the avatar to the nearest point of your car, after subtracting the car's half width, so lower it if near misses are being counted.
  • PEDESTRIAN_DISABLE_LIGHTING — on by default, to keep avatars from rendering too dark.

Driving Behavior

Driving Feel

Speed and braking

These settings in Driving_Config.py use real-world units, and the HUD shows the car's true speed:

  • MAX_SPEED (27.5) — top speed in m/s. 27.5 m/s is about 61.5 mph.
  • ACCELERATION_MPS2 (6.0) — full-throttle acceleration in m/s². 6.0 is 0–60 mph in about 4.5 s; 3.4 (about 7.9 s) matches a real Jeep Wrangler.
  • BRAKING_MPS2 (8.3) — full-brake deceleration in m/s². 8.3 (0.85 g) is about the limit of a real vehicle on dry asphalt, 60–0 mph in about 43 m.
  • COAST_RATE (1.2) — deceleration in m/s² when the throttle is released. 1.2 matches a real car's drag and engine braking; higher stops sooner.

Steering

Steering rotates the car around its rear axle (REAR_AXLE_OFFSET in Driving_Config.py) rather than the transport origin, and the turn rate is smoothed so the car swings into and out of turns instead of snapping. Turning follows the car's actual velocity, so the car keeps turning while coasting, and steering reverses when backing up. Turn rate also depends on speed: full steering below about 15% of top speed, tapering to 40% above about 75%.

Tuning (in modules/dynamic_driving.py):

  • _steer_engage_tau (0.20) — seconds to swing into a turn; lower is snappier
  • _steer_release_tau (0.35) — seconds to straighten out after releasing; lower means less carry
  • _low_speed_yaw_ref (0.25) — how quickly full turn authority builds with speed
  • Speed thresholds and reduction are set in _calculateSpeedAdjustedTurnMag

Collision System

The demo uses three complementary, raycast-based collision systems. There's no physics engine, so frame rate stays high even in large city models.

  1. Elevation / ground clamping (USE_COLLISION, modules/collision.py) — casts a downward ray to keep the car on the ground, letting it drive up ramps, hills, and curbs, and fall with gravity off edges.
  2. Bumper collision (USE_BUILDING_COLLISION, modules/vehicle_collision.py) — sweeps the car's movement each frame with three horizontal rays (center plus both bumper corners) in the direction of travel. If a wall, prop, or another vehicle is hit, the car is stopped flush against it and a crash sound plays. Reversing away always works, since the rays follow the actual direction of movement. This blocks the car from driving through any intersectable geometry without needing collision shapes on the environment.
  3. Traffic vehicles — the moving traffic is fed to the bumper system, so you are stopped when you drive into a traffic car, plus a proximity check so a moving car hitting a stationary player still registers. The traffic system applies the same block in reverse, so no vehicle can drive through you. See Traffic System.

Settings in Driving_Config.py:

  • BUMPER_HEIGHT (0.8) — height of the bumper rays. Anything lower than this (curbs, low guard rails, medians) can be driven over; anything taller blocks. Keep it matched to the elevation system's step height (0.8) and below traffic-car hood height (about 1.0).
  • SLOPE_LIMIT (60) — surfaces inclined less than this many degrees are treated as drivable (hills, ramps) and ignored by the bumper rays; steeper surfaces block (walls are 90°). Raise it (for example to 75) if steep drivable hills are being treated as walls.
  • COLLISION_LOOKAHEAD (2.4) — distance from the transport pivot to the bumper, which is how far ahead of the pivot the car stops. Increase it if the car's nose clips into walls, and decrease it if the car stops too early.
  • CAR_HALF_WIDTH (0.85) — sideways offset of the corner rays; match it to half your car model's width.
  • COLLISION_EXCLUDE_NODE_NAMES (['crate.osgb']) — environment nodes the bumper rays ignore, such as invisible geometry used only for eye tracking.
  • CRASH_SOUND / CRASH_COOLDOWN (1.0) — impact sound and the minimum seconds between plays.
  • TRAFFIC_HIT_DISTANCE (3.0) — center-to-center distance for the traffic proximity check.
  • COLLISION__UPDATE_TYPE ("update") / COLLISION_UPDATE_INTERVAL (0.07) — how the elevation system updates. "update" is smoothest; use "timer", with the interval in seconds, if the frame rate drops.

Settings can also be changed per trial while the experiment runs, for example to allow steeper hills on only one trial:

if sightlab.getTrialNumber() == 2:
    building_collision.setSlopeLimit(75)   # allow extra-steep hills
else:
    building_collision.setSlopeLimit(SLOPE_LIMIT)

setBumperHeight(), setLookahead(), and setEnabled() are available as well.

Teleporting the car

The bumper system is created or reset immediately after the car is moved to its starting position each trial. If you add code that moves the transport during a trial, call building_collision.reset() right afterwards so the jump isn't treated as movement to collision-test. The r reset key already does this.

The car ignores its own geometry

The car is kept non-intersectable (viz.INTERSECTION disabled) so the elevation and bumper rays never hit the car's own geometry. If you attach new geometry that should ride along with the car, parent it to the car so it is automatically excluded from collision rays.

Controller Vibration

The controller vibrates on impacts and when the car changes speed. It is handled by modules/haptics.py and configured in Driving_Config.py. Devices that can't vibrate are ignored, so the feature is safe to leave on with any hardware.

  • Impacts use full strength: hitting a wall, building, or parked vehicle; being hit by moving traffic; or striking a pedestrian.
  • Speed changes give a lighter rumble when you pull away from a stop, move off in reverse, or brake hard. A steady cruise is silent.

Which controller vibrates is decided by the hardware option you select, not by what is plugged into the computer. The devices are the ones the chosen vizconnect uses: the Xbox controller on Desktop Driving Controller, the Touch controllers on the Meta options, and the hand controllers on the OpenXR ones. A controller left connected during a VR session stays quiet, and a keyboard-only option such as Driving Desktop produces no vibration at all. Set HAPTIC_BOUND_DEVICES_ONLY = False to vibrate any connected Xbox controller regardless of the hardware option.

Settings in Driving_Config.py:

  • USE_HAPTICS (True) — turn the whole feature off
  • HAPTIC_BOUND_DEVICES_ONLY (True) — only vibrate controllers the chosen vizconnect uses
  • HAPTIC_ENGINE_SOURCE ('accel') — 'accel' rumbles when the speed changes; 'speed' gives a constant rumble proportional to speed
  • HAPTIC_ENGINE_MAX (0.05) — strength when pulling away or braking hard. Keep it well below the impact strengths so hits stand out.
  • HAPTIC_ENGINE_FLOOR (0.0) — constant level while moving; 0 is silent between events
  • HAPTIC_ACCEL_REFERENCE (6.0) — acceleration in m/s² that gives the full rumble. Matching ACCELERATION_MPS2 makes a full-throttle launch peak the effect.
  • HAPTIC_ACCEL_DEADBAND (0.12) — fraction of HAPTIC_ACCEL_REFERENCE below which there is no rumble at all
  • HAPTIC_ACCEL_SMOOTHING (0.15) — seconds of smoothing; higher is smoother but lags more
  • HAPTIC_ENGINE_MIN (0.02) — minimum rumble, used only when HAPTIC_ENGINE_SOURCE is 'speed'
  • HAPTIC_ENGINE_MOTOR ('high') — 'low' is the heavy rumble motor, 'high' the finer buzz, or 'both'. Xbox controller only; impacts always use both motors.
  • HAPTIC_CRASH_STRENGTH / HAPTIC_CRASH_DURATION (1.0 / 0.4 s) — walls, buildings, and parked vehicles
  • HAPTIC_TRAFFIC_HIT_STRENGTH / HAPTIC_TRAFFIC_HIT_DURATION (0.8 / 0.3 s) — being hit by traffic, and striking a pedestrian
  • HAPTIC_DEBUG (False) — print why a device was skipped or a call failed

If the vibration feels too heavy

A controller motor has a minimum spin-up, so very small values are not a lighter buzz; they are the same buzz at a lower duty cycle. Reduce HAPTIC_ENGINE_MAX or raise HAPTIC_ACCEL_DEADBAND rather than lowering HAPTIC_ENGINE_FLOOR toward a trickle.

How the vibration works

Vibration follows acceleration rather than speed, which is how driving games normally do it. A constant speed-proportional rumble is quickly tuned out by the driver and masks the impacts, which are the events worth feeling.

Hitting a wall, building, or parked vehicle uses the bumper collision's crash callback. Being hit by moving traffic uses TRAFFIC_HIT_EVENT, and striking a pedestrian uses PEDESTRIAN_HIT_EVENT.

The two device families behave differently, and the module adapts to each. The Xbox controller takes setVibration([left, right]) and holds it until changed, so it has two motors and HAPTIC_ENGINE_MOTOR applies. VR controllers take setVibration(duration, frequency, amplitude), stop on their own when the duration expires, and have a single amplitude, so they are refreshed while a rumble lasts and HAPTIC_ENGINE_MOTOR has no effect on them.

The haptics module never imports a VR plug-in of its own. Importing openxr opens an OpenXR session, which takes ownership of the headset and prevents configurations that open it another way (the Meta ones use oculus.dle) from connecting at all.

Multi-User

Several people can drive the same city at once, each on their own computer. Every driver sees the other drivers' cars, and the server sees all of them. Each car, including the one you drive, is shown in the color SightLab assigns that client, the same one used for its gaze point.

Running a Multi-User Session

  1. Run Driving_Server.py on the computer hosting the session, and set up the environment, trials, and start/end conditions in its GUI.
  2. Run Driving_Client.py on each driver's computer, connect to the server, and choose the driving hardware (for example Driving Desktop or Driving Meta).
  3. Once every client shows as ready on the server, click Continue and start the trials from the server.

Connecting clients works the same as in any SightLab multi-user session; see Running a Session with Multi User. The server doesn't drive: it runs a desktop configuration with its own car hidden, and watches the drivers. Run one client per computer, because SightLab tells clients apart by computer name. A client can run on the same computer as the server.

Driving Together

  • Starting positions: drivers line up instead of starting on top of each other. The first client to connect starts at the environment's usual start position, and each later client starts CLIENT_CAR_SPACING meters further back, facing the same way. A client that reconnects gets its place back if it is still free, and the r reset returns each driver to their own place in line.
  • Collisions: you can't drive through another driver's car. You stop and hear the crash sound, the same as with traffic. If two cars do end up overlapping, for example after a reset onto a spot someone is parked on, either car can drive out.
  • Different cars: each client can drive its own car by setting CAR_MODEL in its own Driving_Config.py, and the other computers load that model for its car. As with any multi-user resource, the model needs to exist at the same path on the server and every client; a computer that doesn't have it shows its own car model instead.

Multi-User Data and Replay

  • Each client's trial data and experiment summary are saved on the server with a _client_<number> suffix.
  • Every driver's car is recorded as a separate object named car_<computer name>. The single-user my_car object is not recorded in multi-user sessions.
  • Other drivers' cars are not gaze objects on the clients, so looks at another driver's car are not recorded.
  • SightLabVR_Replay.py shows every driver's car and avatar. Traffic and pedestrians differ between clients, so they are shown for one client: the lowest-numbered client when Client ID is set to All, or the client you select. Cars keep their colors in replay: each client records them as a replay flag, and the replay script applies them.

Multi-User Settings

In Driving_Config.py:

  • ADD_CLIENT_CARS (True) — adds the other drivers' cars. Keep it on for any session with more than one driver: it also stops clients overwriting each other's traffic and cockpit objects, which would otherwise show in both the view and the recorded data.
  • CLIENT_CAR_COLORS (True) — paints each driver's car in their assigned color, on every computer and in replay. Turn it off to keep every car in its model's own colors, for example when each client drives a different car.
  • CLIENT_CAR_SPACING (8.0) — meters between drivers at the start. Lower it if later drivers start off the end of the road. The start position itself is set per environment in CAR_STARTING_POSITIONS.
  • CAR_PAINT_NAME_MATCH ('paint') — on each client, only nodes of your own car whose names contain this text take your color, so the dashboard, glass, and mirrors keep theirs. The included jeep's outside paint nodes are named ..._paint_.... If another car model has no matching names, the whole car is tinted and the console says so.

The multi-user car code is in modules/multiuser_cars.py.

Troubleshooting

Driving and Collisions

  • The car is stuck or off the road: press r to return to the trial's starting position.
  • The car's nose clips into walls, or it stops too early: adjust COLLISION_LOOKAHEAD.
  • A steep drivable hill blocks the car like a wall: raise SLOPE_LIMIT, for every trial or for one trial.
  • Something invisible blocks the car: add the node's name to COLLISION_EXCLUDE_NODE_NAMES.
  • The frame rate drops in a large environment: set COLLISION__UPDATE_TYPE = "timer" and tune COLLISION_UPDATE_INTERVAL.
  • The controller doesn't vibrate: set HAPTIC_DEBUG = True to print why a device was skipped. With HAPTIC_BOUND_DEVICES_ONLY = True, only controllers used by the chosen hardware option vibrate.
  • Gaze isn't recorded on parts inside the car: the car is non-intersectable, so add those parts as separate models parented to the car (see Changing the Vehicle).

Traffic

  • "no route file … set RECORD_ROUTES = True" — that environment has no Resources/traffic/<name>.json yet, so traffic is disabled for the trial. Record one as described in Recording Routes for a New Environment.
  • "… has been blocked for 5 s by …" — a vehicle's bumper rays are hitting scene geometry. Move the route away from the object, or add the node name to BUMPER_EXCLUDE_NODE_NAMES if it is invisible helper geometry. Parked vehicles and other props are easy to miss when recording, because they sit alongside a road that looks clear from above.
  • A vehicle drives backwards or floats: add a yaw or scale entry in VEHICLE_MODEL_OVERRIDES.
  • Vehicles tilt the wrong way on slopes: flip PITCH_SIGN.
  • Traffic queues up behind you and never passes: that is the block working while the car is stopped in a live lane. Drive on, or move the start position out of the lane.

Pedestrians

  • No pedestrians appear: check ADD_PEDESTRIANS, the number of pedestrians column in the STIM file (0 means none), and the Resources/pedestrians folder. Confirm that the environment has a pedestrian route file, or a vehicle route file that sidewalks can be derived from.
  • Pedestrians walk in the street or near walls: tune the sidewalk and clearance settings, or generate a dedicated route file. walkTo does not provide general obstacle avoidance.
  • An avatar slides or plays the wrong animation: check its idle and walk IDs in PEDESTRIAN_ANIMATIONS.

Scripting the Car

Tip

The quickest way to build a custom driving experiment is to copy Driving_GUI_Main.py and edit it. The steps below show the minimum needed to add the car to your own script. Copy the rest of the trial loop from Driving_GUI_Main.py for collision, traffic, and the r reset.

  1. Import the car class. car_module.py is in the example's modules folder, so keep that folder next to your script:

    from Driving_Config import *
    from modules.car_module import Car
    
  2. After creating the SightLab instance, create the car using the part names from Driving_Config.py. The steering wheel and individual wheel names are only needed if you want a steering wheel that turns and tires that spin.

    my_car = Car(model_path=CAR_MODEL, use_headlights=True, steering_wheel_name=STEERING_WHEEL_NAME, engine_audio=ENGINE_AUDIO,
                 front_left_wheel=FRONT_LEFT_WHEEL, front_right_wheel=FRONT_RIGHT_WHEEL,
                 back_left_wheel=BACK_LEFT_WHEEL, back_right_wheel=BACK_RIGHT_WHEEL,
                 mph_gauge=MPH_GAUGE, rpm_gauge=RPM_GAUGE, sightlab_instance=sightlab)
    car = my_car.car    # the underlying Vizard node
    
  3. Register the car so it is recorded in the trial data and shown in Session Replay:

    sightlab.addSceneObject("my_car", car)
    sightlab.addTrackingTrialDataColumn("my_car", car)
    
  4. In the experiment function, set per-trial conditions such as headlights, and start the engine sound once the trial starts:

    def sightLabExperiment():
        yield viztask.waitEvent(EXPERIMENT_START)
        my_car.create_hud(sightlab.overlayWindow)
        for i in range(sightlab.getTrialCount()):
            if sightlab.getTrialNumber() == 2:
                my_car.toggle_headlights(True)    # night trial
            yield viztask.waitEvent(TRIAL_START)
            my_car.start_engine_sound(volume=ENGINE_VOLUME)
            # link the car to the transport here (step 5)
            yield viztask.waitEvent(TRIAL_END)
    
    viztask.schedule(sightlab.runExperiment)
    viztask.schedule(sightLabExperiment)
    
  5. After the trial starts, link the car to the driving transport and place it. The main_transport is the seat position inside the car:

    transportNode = vizconnect.getTransport('driving').getNode3d()          # moves the car
    my_car.link_to_transport(transportNode)
    transportNode.setPosition(CAR_STARTING_POSITION)
    
    transportNode2 = vizconnect.getTransport('main_transport').getNode3d()  # seat position in the car
    transportNode2.setPosition(PASSENGER_POSITION)
    

Driving Configuration Settings

Driving_Config.py settings, with their default values. Driving feel, collision, vibration, and multi-user settings are listed in their own sections: Driving Feel, Collision System, Controller Vibration, and Multi-User Settings. Traffic and pedestrian settings are in traffic_config.py (see Traffic Settings and Pedestrian Settings).

Car model and parts

Setting Default What it does
CAR_MODEL 'Resources/jeepmodel.osgb' The car model. Resources/bmw.osgb and sightlab_resources/objects/car.osgb are included as commented-out alternatives.
CAR_TYPE 'Car' 'Car' or 'Truck'; chooses which seat positions are used. The scripts switch to 'Truck' automatically for the jeep.
STEERING_WHEEL_NAME 'Steering_Real Car 22_Body_0' Steering wheel node that turns with steering
FRONT_LEFT_WHEEL, FRONT_RIGHT_WHEEL, BACK_LEFT_WHEEL, BACK_RIGHT_WHEEL 'FL_Real Car 22_Body_0', etc. Tire nodes that spin
MPH_GAUGE, RPM_GAUGE 'mph_gauge', 'Dok 1_Real Car 22_Body_0' Gauge needle nodes
REAR_AXLE_OFFSET [0.46, 0, -0.78] Steering pivot, measured from the rear wheel centers. Measure it again when changing CAR_MODEL.
ENGINE_AUDIO, ENGINE_VOLUME 'Resources/engine_sound8.wav', 0.2 Engine sound and its volume

Viewpoints and starting positions

Setting Default What it does
PASSENGER_POSITION_TRUCK [0.263, 0.556, 0.318] Seat position for 'Truck' (the jeep) on desktop, steering wheels, and Meta headsets; also the in-car view b returns to
PASSENGER_POSITION [-0.084, -0.233, 0.142] Seat position for 'Car' on desktop and Meta headsets
THIRD_PERSON_VIEW [0.683, 1.527, -3.218] Third-person viewpoint in the b cycle
CLOSER_IN_VIEW [0.264, 0.556, 0.528] Closer-in viewpoint in the b cycle
CAR_STARTING_POSITION [0.25, 0, 0.35] Where the car starts in environments not listed in CAR_STARTING_POSITIONS
CAR_STARTING_POSITIONS See Included Routes Where the car starts, per environment file name
ENVIRONMENT_MODEL 'Resources/environments/street_day.osgb' Fallback environment for Driving_Main_noGUI.py when a STIM row has no environment

Features and hardware

Setting Default What it does
ADD_TRAFFIC True Turns on the Traffic System
ADD_PEDESTRIANS True Turns on the Pedestrian System
HARDWARE_CONFIGS See Hardware Options Maps each hardware option in the GUI to its vizconnect file

Additional Versions

Expanded Download

The download at the top of this page adds more city maps and features, including:

  • A Longer_Road folder with an endlessly stretching highway.

    The SightLab GUI with the Longer_Road highway environment loaded

  • Driving_Simulator_360, which uses a 360 video to simulate driving in New York.

Available on Request

Contact sales@worldviz.com for information on these versions:

  • 360 video driving simulator combining 3D models and 360 video (see 360 Driving Simulator)
  • Flying simulator

360 Driving Simulator

Session replay of the 360 driving simulator, with a 3D car interior over 360 video of a New York street and a fixation heatmap on the dashboard

Key Action
R Reset position
Spacebar Start / stop the simulation
V Pause the video
B Reset the video
F Fast forward
T Get the current position
H Toggle overlays
P Toggle the gaze point
/ Take a screenshot

Note

The 360 simulator may require the K-Lite Codec Pack. To set the viewpoint, press T to get the current position, then use it with transportNode2.setPosition.