Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): head prediction scaler #2568

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions alvr/client_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
pub tracking_sender: Mutex<Option<StreamSender<Tracking>>>,
pub statistics_sender: Mutex<Option<StreamSender<ClientStatistics>>>,
pub statistics_manager: Mutex<Option<StatisticsManager>>,
pub decoder_callback: Mutex<Option<Box<dyn FnMut(Duration, &[u8]) -> bool + Send>>>,

Check warning on line 65 in alvr/client_core/src/connection.rs

View workflow job for this annotation

GitHub Actions / check-linux

warning: very complex type used. Consider factoring parts into `type` definitions --> alvr/client_core/src/connection.rs:65:27 | 65 | pub decoder_callback: Mutex<Option<Box<dyn FnMut(Duration, &[u8]) -> bool + Send>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity = note: `#[warn(clippy::type_complexity)]` on by default

Check warning on line 65 in alvr/client_core/src/connection.rs

View workflow job for this annotation

GitHub Actions / check-windows

warning: very complex type used. Consider factoring parts into `type` definitions --> alvr\client_core\src\connection.rs:65:27 | 65 | pub decoder_callback: Mutex<Option<Box<dyn FnMut(Duration, &[u8]) -> bool + Send>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity = note: `#[warn(clippy::type_complexity)]` on by default
pub head_pose_queue: RwLock<VecDeque<(Duration, Pose)>>,
pub last_good_head_pose: RwLock<Pose>,
pub view_params: RwLock<[ViewParams; 2]>,
Expand Down Expand Up @@ -209,6 +209,7 @@
} else {
0.0
},
settings.headset.head_prediction_scaler,
));

let (mut control_sender, mut control_receiver) = proto_control_socket
Expand Down
22 changes: 16 additions & 6 deletions alvr/client_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,16 +234,24 @@
) {
dbg_client_core!("send_tracking");

let target_timestamp =
let (target_timestamp, head_predilection_factor) =
if let Some(stats) = &*self.connection_context.statistics_manager.lock() {
poll_timestamp + stats.average_total_pipeline_latency()
(
poll_timestamp + stats.average_total_pipeline_latency(),
stats.get_head_predilection_scaler(),
)
} else {
poll_timestamp
(poll_timestamp, 1.0)
};

for (id, motion) in &mut device_motions {
if *id == *HEAD_ID {
*motion = predict_motion(target_timestamp, poll_timestamp, *motion);
*motion = predict_motion(
target_timestamp,
poll_timestamp,
head_predilection_factor,
*motion,
);

let mut head_pose_queue = self.connection_context.head_pose_queue.write();

Expand All @@ -260,7 +268,7 @@
} else if let Some(stats) = &*self.connection_context.statistics_manager.lock() {
let tracker_timestamp = poll_timestamp + stats.tracker_prediction_offset();

*motion = predict_motion(tracker_timestamp, poll_timestamp, *motion);
*motion = predict_motion(tracker_timestamp, poll_timestamp, 1.0, *motion);
}
}

Expand Down Expand Up @@ -309,7 +317,7 @@
/// The callback should return true if the frame was successfully submitted to the decoder
pub fn set_decoder_input_callback(
&self,
callback: Box<dyn FnMut(Duration, &[u8]) -> bool + Send>,

Check warning on line 320 in alvr/client_core/src/lib.rs

View workflow job for this annotation

GitHub Actions / check-linux

warning: very complex type used. Consider factoring parts into `type` definitions --> alvr/client_core/src/lib.rs:320:19 | 320 | callback: Box<dyn FnMut(Duration, &[u8]) -> bool + Send>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
) {
dbg_client_core!("set_decoder_input_callback");

Expand Down Expand Up @@ -361,7 +369,7 @@
},
];

view_params

Check warning on line 372 in alvr/client_core/src/lib.rs

View workflow job for this annotation

GitHub Actions / check-linux

warning: returning the result of a `let` binding from a block --> alvr/client_core/src/lib.rs:372:9 | 361 | / let view_params = [ 362 | | ViewParams { 363 | | pose: head_pose * view_params[0].pose, 364 | | fov: view_params[0].fov, ... | 369 | | }, 370 | | ]; | |__________- unnecessary `let` binding 371 | 372 | view_params | ^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return = note: `#[warn(clippy::let_and_return)]` on by default help: return the expression directly | 361 ~ 362 | 363 ~ [ 364 + ViewParams { 365 + pose: head_pose * view_params[0].pose, 366 + fov: view_params[0].fov, 367 + }, 368 + ViewParams { 369 + pose: head_pose * view_params[1].pose, 370 + fov: view_params[1].fov, 371 + }, 372 + ] |
}

pub fn report_submit(&self, timestamp: Duration, vsync_queue: Duration) {
Expand Down Expand Up @@ -399,11 +407,13 @@
pub fn predict_motion(
target_timestamp: Duration,
current_timestamp: Duration,
predict_factor: f32,
motion: DeviceMotion,
) -> DeviceMotion {
let delta_time_s = target_timestamp
.saturating_sub(current_timestamp)
.as_secs_f32();
.as_secs_f32()
* predict_factor;

let delta_position = motion.linear_velocity * delta_time_s;
let delta_orientation = Quat::from_scaled_axis(motion.angular_velocity * delta_time_s);
Expand Down
7 changes: 7 additions & 0 deletions alvr/client_core/src/statistics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ pub struct StatisticsManager {
prev_vsync: Instant,
total_pipeline_latency_average: SlidingWindowAverage<Duration>,
steamvr_pipeline_latency: Duration,
head_prediction_scaler: f32,
}

impl StatisticsManager {
pub fn new(
max_history_size: usize,
nominal_server_frame_interval: Duration,
steamvr_pipeline_frames: f32,
head_prediction_scaler: f32,
) -> Self {
Self {
max_history_size,
Expand All @@ -36,6 +38,7 @@ impl StatisticsManager {
steamvr_pipeline_latency: Duration::from_secs_f32(
steamvr_pipeline_frames * nominal_server_frame_interval.as_secs_f32(),
),
head_prediction_scaler,
}
}

Expand Down Expand Up @@ -139,4 +142,8 @@ impl StatisticsManager {
.get_average()
.saturating_sub(self.steamvr_pipeline_latency)
}

pub fn get_head_predilection_scaler(&self) -> f32 {
self.head_prediction_scaler
}
}
4 changes: 4 additions & 0 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@ Tilted: the world gets tilted when long pressing the oculus button. This is usef
#[schema(flag = "real-time")]
pub rotation_recentering_mode: RotationRecenteringMode,

#[schema(gui(slider(min = 0.0, max = 1.0, step = 0.01)))]
pub head_prediction_scaler: f32,

#[schema(flag = "steamvr-restart")]
pub controllers: Switch<ControllersConfig>,

Expand Down Expand Up @@ -1782,6 +1785,7 @@ pub fn session_settings_default() -> SettingsDefault {
rotation_recentering_mode: RotationRecenteringModeDefault {
variant: RotationRecenteringModeDefaultVariant::Yaw,
},
head_prediction_scaler: 1.0,
},
connection: ConnectionConfigDefault {
stream_protocol: SocketProtocolDefault {
Expand Down
Loading