see also Virte4Dataset.
The Virte3 application creates app log files (sub####__cond#__APP__YYYY_MM_DD__HH_MM_SS.txt). Each log contains one row per frame. The frame-rate of the Virte3 application varies, but it is usually about 40 fps in the 3 virtual conditions and upwards of 400 fps in the 2 real-world conditions. For purposes of log playback, the data is filtered and resampled to 30 fps.
Virte3 app-logs live in //focus-cs.cs.unc.edu/raid/virte/virte123_applogs/virte3_logs.
As far as I can tell, the matlab data-set comes from the app logs rather than the vrpn logs, and the vrpn logs no longer exist. However, the app logs that we have sitting on our servers right now have rather low frame rates in the VR cases (~40 fps), yet the raw data in the matlab data-sets discussed below have sample rates between 300 and 600 fps. This is good, since it means we’re working with densely-sampled data, but it is a mystery where the matlab data came from if not from the app logs. —Jeff
There are several versions of the Virte3 data set:
virte3data_raw.mat
virte3data_filtered.mat
virte3data_short.mat
virte3data_filtered.mat. Path data such as position, velocity, tau, etc are down-sampled to 200 samples per path so that the data-set can be loaded and manipulated more easily.../analysis_2004/v3data_original.mat
v3data_raw.mat, with the exception of the view direction (which we don’t use in the matlab analysis).Each file has two data-sets
v3t—Virte3 Targets (visual targets)v3c—Virte3 CornersEach is a 1xN array of structs with the following fields: (Not all versions of the data-set have all of the fields)
.subjectID: 3001—3032.cond: 0—4.condStr: ‘REAL WALK’, ‘COWL’, ‘HMD_WALK’, ‘JOYSTICK’, ‘WIP’.targetNum:
v3t has targets 2,3,4,8,9,10v3c has corners 12,13,14,16,17,18.raw: Unfiltered data, straight from the Virte3 Application logs. The sample rate varies, but it is roughly 400Hz.
.raw.pos3: Unfiltered position data in 3-space. 3xN array..raw.look: View direction. 3xN array.raw.time: Time associated with the samples. 1xN array.raw.n: Number of samples, N. Length of the above arrays..comp: Filtered data, which is computed from the .raw fields.
.comp.n: Number of samples, N. All of the following arrays have size 1xN..comp.pos1: Filtered position data, projected onto an axis orthogonal to the TargetPlane. 0 is the TargetPlane, -totalPathLength is the StartingPoint..comp.vel1: Velocity, first forward-difference of pos1..comp.acc1: Acceleration, first forward-difference of vel1..comp.jer1: Jerk, first forward-difference of acc1..comp.distPct: Percent-Distance. Distance from TargetPlane divided by the total path length (the distance between StartingPoint and TargetPlane) times 100. 0 is the TargetPlane, 100 is the StartingPoint..comp.timePct: Percentage of the time elapsed between crossing the StartingPoint and reaching the StoppingPoint. Counts up from 0 to 100..comp.tau: Distance to StoppingPoint divided by velocity. (See Tau.).comp.taudot: First temporal derivative of Tau..comp.time: Sample times. Starts negative and counts upward towards 0, which occurs at the stopping point..stats: The per-path measures
.stats.peakvel_*: Info about the PeakVelocity critical point.
.stats.peakvel_vel: Velocity at the moment of peak velocity.stats.peakvel_time: Time of peak velocity..stats.peakvel_dist: Distance-from-target-plane of peak velocity..stats.peakvel_timePct: Percent time at which peak velocity occurs..stats.peakvel_distPct: Percent distance at which peak velocity occurs..stats.peakvel_tau: Tau at the moment of peak velocity..stats.peakvel_taudot: Derivative of Tau at the moment of peak velocity..stats.peakdecel_*: Info about the PeakDeceleration critical point.
.stats.peakdecel_acc: Acceleration at the moment of peak deceleration. (negative).stats.peakdecel_time: Time of peak deceleration..stats.peakdecel_dist: Distance-from-target-plane of peak deceleration..stats.peakdecel_timePct: Percent time at which peak deceleration occurs..stats.peakdecel_distPct: Percent distance at which peak deceleration occurs..stats.peakdecel_tau: Tau at the moment of peak deceleration..stats.peakdecel_taudot: Derivative of tau at the moment of peak deceleration..stats.taumin_*: Info about the TauMin critical point.
.stats.taumin_tau: Minimum Tau value acheived..stats.taumin_time: Time of minimum tau..stats.taumin_dist: Distance-from-target-plane of minimum tau..stats.taumin_timePct: Percent time at which minimum tau occurs..stats.taumin_distPct: Percent distance at which minimum tau occurs..stats.stop_dist: Distance between the StoppingPoint and the TargetPlane..stats.transit_dist: Distance between StartingPoint and StoppingPoint. This varies from subject to subject since StoppingPoint varies..stats.transit_time: Time elapsed between crossing the StartingPoint and reaching the StoppingPoint..stats.vel_mean: Average velocity during this approach. .transit_dist divided by .transit_time..stats.taudot_mean: Average value of the derivative of Tau..indices: Set of indices into the .comp.* arrays marking the location of the critical points. E.g., p.comp.tau(p.indices.peakdecel) == p.stats.peakdecel_tau.
.indices.peakvel: Index at which the PeakVelocity critical point occurs..indices.peakdecel: Index at which the PeakDeceleration critical point occurs.v3data_filtered.matThe fields of v3data_filtered.mat are created as follows:
>> cd virte\analysis_2005\make-v3-data >> load ..\virte3data_raw.mat >> v3targets = createV3FilteredData(v3targets_raw) >> v3corners = createV3FilteredData(v3corners_raw) >> v3targets = makeStatFields(v3targets) >> v3corners = makeStatFields(v3corners) >> save ..\virte3data_filtered.mat v3targets v3corners >> v3t = makeShortDataset(v3targets); >> v3c = makeShortDataset(v3corners); >> save ..\virte3data_short.mat v3t v3c >> writeStatsToCSV([v3targets,v3corners],'../per-path-stats/virte3stats.csv')
What’s happening:
virte3data_raw.mat, which has the identification fields (see above) and the .raw fields. The targets are in the variable v3targets_raw, and the corners are in the variable v3corners_raw.createV3FilteredData.m adds the .comp fields to the data-set by resampling/filtering the data in the .raw fields and cropping down to the apporpriate part of each path (that between the StartingPoint and the StoppingPoint). It then removes the .raw fields.makeStatFields.m adds the .stats and .indices fields..comp, .stats, and .indices fields are added and the .raw fields removed, the data-set is saved into v3data_filtered.mat.makeShortDataset.m resamples the data in the .comp fields so that the path has exactly 200 samples. This makes it easier to work with when generating plots and doing other operations that do not require high precision. The resulting data-set is saved in v3data_short.mat.writeStatsToCSV.m creates a comma-separated-value file of all the PerPathMeasures.virte3stats.csv is a comma-separated-value file of the PerPathMeasures for the virte3 data. It is located in virte\analysis_2005\per-path-stats\virte3stats.csv. It is generated by virte\analysis_2005\make-v3-data\writeStatsToCSV.m.
The first three columns are target, condition, and subject. Each row contains the per-path-measures for one path. The paths are sorted by the values of the first three columns.
Missing trials (for which there are no data) are marked by “XX” accross all the columns (besides the first 3) where the measures would be.
The Virte1 matlab data-set has these two position fields: tipOfHeadset and collisionPoint. These are, respectively, the tip of the headset in the real-world and the tip of the headset in the virtual world. In the joystick case they are different. In all other cases they are nearly the same. The difference between equivalent rows of these structs have a minimum of 0.86803cm, maximum of 1.19500cm, mean of 1.13422cm, and median of 1.13686cm. Almost all of the values are clustered around the median, with a few outliers. These values are within the margin of error expected of the tip-of-headset measurements and the error between real and virtual walls. So we can effectively the difference.
In all cases we use the collisionPoint field to form the .raw.pos3 field and, subsequently, all the .comp fields.
There are two constants defined for the X-location of the target plane: REAL_WALL_X = 5.51m and VIRTUAL_WALL_X = 5.516m. The 6mm difference is within the margin of error, and the mean of these two values, 5.513 is taken to be the target position in all cases, both real and virtual.
The Virte1 data was originally extracted (by Sharif?) into virte\virte1_analysis\matlab_code\AllSubjectsTrials.mat. The script virte\analysis_2005\make-v1-data\ImportOldV1DataFormat.m brings the data into the new format, similar to what’s being used for the Virte3 data.
There are some numbering oddities in the virte1 dataset. After extracting the virte1data_raw.mat dataset, several bad trials were removed and the trial numbers were adjusted. Details of this are described in Virte1BadTrials.
There are two path lengths in the Virte1 experiment. The shorter path (2.5m) is labelled target 1, and the longer path (3.0m) is labelled target 2.
The trials in virte1 were labelled from 1 to 6 (sometimes up to 8, so as to include the reject trials). The trial number range includes both short and long paths (targets 1 and 2, respectively). I re-numbered the trials so that target and trial numbers are orthogonal. I.e. target 1 had trials 1—3 and target 2 has trials 1—3.
v1data_filtered.matThe fields of v1data_filtered.mat are created as follows:
>> cd virte\analysis_2005\make-v1-data >> load ..\virte1data_raw.mat >> v1data = createV1FilteredData(v1data_raw) >> v1data = makeStatFields(v1data) >> save ..\virte1data_filtered.mat v1data >> writeStatsToCSV(v1data,'../per-path-stats/virte1stats.csv')
The raw data, v1data_raw comes from virte1data_raw.mat.
The filtered ata, v1data comes from virte1data_filtered.mat.
The variables have the following fields:
.subjectID: 1001—1021.cond: 0—3.condStr: ‘REAL WALK’, ‘COWL’, ‘HMD_WALK’, ‘JOYSTICK’.targetNum:
.raw: same as the .raw fields for Virte3..comp: same as the .comp fields for Virte3.