From c8f519ec0b7db99ae45389ed42b2c79b5405bb0d Mon Sep 17 00:00:00 2001 From: Chelsea Jaggi Date: Mon, 27 Jul 2020 18:13:29 -0700 Subject: [PATCH] Smoother (autoturn) smooth turn: estimate frame rate when beginning turn (#498) * Smoother (autoturn) smooth turn: estimate frame rate when beginning turn * remove log messages and fix formatting --- src/tabcontrollers/RotationTabController.cpp | 55 +++++++++++++++++--- src/tabcontrollers/RotationTabController.h | 31 ++++++++++- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/tabcontrollers/RotationTabController.cpp b/src/tabcontrollers/RotationTabController.cpp index 5c38e02..097a1a4 100644 --- a/src/tabcontrollers/RotationTabController.cpp +++ b/src/tabcontrollers/RotationTabController.cpp @@ -196,14 +196,11 @@ void RotationTabController::doAutoTurn( && m_autoTurnLinearSmoothTurnRemaining != 0 ) { // TODO: implement angular acceleration max? - auto deltaMillis - = std::chrono::duration_cast( - currentTime - m_autoTurnLastUpdate ) - .count(); + double deltaSeconds + = FrameRates::toDoubleSeconds( m_estimatedFrameRate ); auto miniDeltaAngle = static_cast( std::abs( - ( deltaMillis * RotationTabController::autoTurnSpeed() ) - / 1000 ) + ( deltaSeconds * RotationTabController::autoTurnSpeed() ) ) * ( m_autoTurnLinearSmoothTurnRemaining < 0 ? -1 : 1 ) ); if ( std::abs( m_autoTurnLinearSmoothTurnRemaining ) < std::abs( miniDeltaAngle ) ) @@ -366,6 +363,52 @@ void RotationTabController::doAutoTurn( } while ( false ); m_autoTurnWallActive[i] = true; + auto delta = currentTime - m_autoTurnLastUpdate; + if ( delta + < ( FrameRates::RATE_144HZ + FrameRates::RATE_120HZ ) / 2 ) + { + m_estimatedFrameRate = FrameRates::RATE_144HZ; + } + else if ( ( delta >= ( FrameRates::RATE_144HZ + + FrameRates::RATE_120HZ ) + / 2 ) + && ( delta < ( FrameRates::RATE_120HZ + + FrameRates::RATE_90HZ ) + / 2 ) ) + { + m_estimatedFrameRate = FrameRates::RATE_120HZ; + } + else if ( ( delta >= ( FrameRates::RATE_120HZ + + FrameRates::RATE_90HZ ) + / 2 ) + && ( delta < ( FrameRates::RATE_90HZ + + FrameRates::RATE_72HZ ) + / 2 ) ) + { + m_estimatedFrameRate = FrameRates::RATE_90HZ; + } + else if ( ( delta + >= ( FrameRates::RATE_90HZ + FrameRates::RATE_72HZ ) + / 2 ) + && ( delta < ( FrameRates::RATE_72HZ + + FrameRates::RATE_60HZ ) + / 2 ) ) + { + m_estimatedFrameRate = FrameRates::RATE_72HZ; + } + else if ( ( delta + >= ( FrameRates::RATE_72HZ + FrameRates::RATE_60HZ ) + / 2 ) + && ( delta < ( FrameRates::RATE_60HZ + + FrameRates::RATE_45HZ ) + / 2 ) ) + { + m_estimatedFrameRate = FrameRates::RATE_60HZ; + } + else + { + m_estimatedFrameRate = FrameRates::RATE_45HZ; + } } else if ( ( chaperoneQuad.distance > ( RotationTabController::autoTurnActivationDistance() diff --git a/src/tabcontrollers/RotationTabController.h b/src/tabcontrollers/RotationTabController.h index 19117eb..df6199a 100644 --- a/src/tabcontrollers/RotationTabController.h +++ b/src/tabcontrollers/RotationTabController.h @@ -1,4 +1,3 @@ - #pragma once #include @@ -25,6 +24,35 @@ enum class AutoTurnModes LINEAR_SMOOTH_TURN }; +namespace FrameRates +{ + // Each of type std::chrono::time_point::duration + constexpr auto RATE_45HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + constexpr auto RATE_60HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + constexpr auto RATE_72HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + constexpr auto RATE_90HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + constexpr auto RATE_120HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + constexpr auto RATE_144HZ = std::chrono::duration_cast< + std::chrono::steady_clock::time_point::duration>( + std::chrono::duration>( 1 ) ); + + template double toDoubleSeconds( T duration ) + { + return ( static_cast( duration.count() ) * T::period::num ) + / T::period::den; + } +} // namespace FrameRates + class RotationTabController : public QObject { Q_OBJECT @@ -65,6 +93,7 @@ private: vr::HmdMatrix34_t m_autoTurnLastHmdUpdate; std::vector m_autoTurnChaperoneDistancesLast; double m_autoTurnRoundingError = 0.0; + std::chrono::steady_clock::time_point::duration m_estimatedFrameRate; bool m_isHMDActive = false;