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.

Click below to Download the latest version
Quick Start
- Run
Driving_GUI_Main.py. - In the SightLab GUI, choose your hardware (see Hardware Options). To drive somewhere else, see Changing the Environment.
- Press Spacebar to start the experiment, and press it again to go on to the next trial.
- Drive using the controls. Press
rat any time to put the car back where the trial started. - After the session, the data is in the
datafolder. RunSightLabVR_Replay.pyto 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

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.

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, andCar Velocity Z, plus tracking columns for the car's position and rotation (my_car). - Average speed:
Average Speed MPHfor 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, andLeftMirror, 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_carscene 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 ahit by traffic_car_XXflag when a moving vehicle reaches you. - Experiment summary:
Traffic Count,Min Vehicle Distance, andVehicle 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_OBJECTSis on.
Collision Events and Biopac Markers
- Events:
TRAFFIC_HIT_EVENT(viz.getEventID('TRAFFIC_HIT')) is sent with the vehicle's name, andPEDESTRIAN_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>orpedestrian hit: <name>stim marker, so collisions line up with the physiological recording. The scripts do this inmarkHit(), 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.pyreadsstim_file-nonGUI.csv, which also sets each trial's scene and the number of trials:- The
environmentcolumn sets the scene for each trial.ENVIRONMENT_MODELinDriving_Config.pyis only used when a row has noenvironment. - The number of rows sets the number of trials.
- Traffic and pedestrian routes follow each row's environment, so
street_day.osgbloadsResources/traffic/street_day.jsonandstreet_day_pedestrians.json.
- The
| 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
- Place the new environment file in the
Resources/environmentsfolder. -
Select it:
-
GUI scripts: click Modify on the GUI screen and choose the new environment.

-
Driving_Main_noGUI.py: set the file in theenvironmentcolumn ofResources/stim_file-nonGUI.csv. - Set where the car starts by adding the environment's file name to
CAR_STARTING_POSITIONSinDriving_Config.py. Environments not listed there useCAR_STARTING_POSITION. - Optionally, record traffic routes and generate sidewalk routes for the new environment.
-
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
- 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).
- When the position looks right, press
v. The seat position is printed in the Vizard interactive window. -
Paste the position into
Driving_Config.py:PASSENGER_POSITION_TRUCK: the included jeep on desktop, steering wheels, and Meta headsetsPASSENGER_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

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:
- 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. -
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 -
Make a copy of one of the wheel vizconnect files in
vizconnect_configs, such asvizconnect_config_desktop_driving_g923.py. Change its import to your new input module, and set the button IDs for events such asSHIFT_GEAR(Drive/Reverse) andtoggleViewsunder its mappings. - Add the new configuration to
HARDWARE_CONFIGSinDriving_Config.pyso it appears in the GUI.
Contact support@worldviz.com for more information.
Customizing Controls
- Open the vizconnect file for your hardware from the example's
vizconnect_configsfolder.HARDWARE_CONFIGSinDriving_Config.pylists which file each hardware option uses. - Go to Advanced > Transports > Driving > Mappings, and to Acceleration/Deceleration under Events.
- 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 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 caron, 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:
- Set
RECORD_ROUTES = Trueintraffic_config.pyand run the demo. - Start a trial in the environment, then press F5 to open the recorder. Traffic pauses and the key list appears on screen.
- 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.
- 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.
- 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.
- 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

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_00 … traffic_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 switchADD_TRAFFICis inDriving_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

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:
- A dedicated route file,
Resources/traffic/<environment>_pedestrians.json. It uses the same lane format as the vehicle route files; only the lane waypoints andloopflag are used. Files are included forstreet_day,street__night, andcity_rtx2. - 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 = Falsetoo, as long as the vehicle route file exists. SetPEDESTRIAN_LANE_OFFSET = 0to 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.
- 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. - 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. - 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 offHAPTIC_BOUND_DEVICES_ONLY(True) — only vibrate controllers the chosen vizconnect usesHAPTIC_ENGINE_SOURCE('accel') —'accel'rumbles when the speed changes;'speed'gives a constant rumble proportional to speedHAPTIC_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 eventsHAPTIC_ACCEL_REFERENCE(6.0) — acceleration in m/s² that gives the full rumble. MatchingACCELERATION_MPS2makes a full-throttle launch peak the effect.HAPTIC_ACCEL_DEADBAND(0.12) — fraction ofHAPTIC_ACCEL_REFERENCEbelow which there is no rumble at allHAPTIC_ACCEL_SMOOTHING(0.15) — seconds of smoothing; higher is smoother but lags moreHAPTIC_ENGINE_MIN(0.02) — minimum rumble, used only whenHAPTIC_ENGINE_SOURCEis'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 vehiclesHAPTIC_TRAFFIC_HIT_STRENGTH/HAPTIC_TRAFFIC_HIT_DURATION(0.8 / 0.3 s) — being hit by traffic, and striking a pedestrianHAPTIC_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
- Run
Driving_Server.pyon the computer hosting the session, and set up the environment, trials, and start/end conditions in its GUI. - Run
Driving_Client.pyon each driver's computer, connect to the server, and choose the driving hardware (for example Driving Desktop or Driving Meta). - 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_SPACINGmeters further back, facing the same way. A client that reconnects gets its place back if it is still free, and therreset 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_MODELin its ownDriving_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-usermy_carobject 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.pyshows 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 inCAR_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
rto 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 tuneCOLLISION_UPDATE_INTERVAL. - The controller doesn't vibrate: set
HAPTIC_DEBUG = Trueto print why a device was skipped. WithHAPTIC_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>.jsonyet, 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_NAMESif 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
yaworscaleentry inVEHICLE_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, thenumber of pedestrianscolumn in the STIM file (0 means none), and theResources/pedestriansfolder. 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.
walkTodoes 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.
-
Import the car class.
car_module.pyis in the example'smodulesfolder, so keep that folder next to your script:from Driving_Config import * from modules.car_module import Car -
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 -
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) -
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) -
After the trial starts, link the car to the
drivingtransport and place it. Themain_transportis 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_Roadfolder with an endlessly stretching highway.
-
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

| 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.
Related Documentation
- Controls
- Session Replay
- Running a Session with Multi User
- Street Walking Example, which uses the same traffic and pedestrian systems
- Biopac Integration and Sending Events to Biopac
- Scene Editor – Inspector