diff --git a/CHANGELOG.md b/CHANGELOG.md index 38eb5dfb43..8153aea1e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project are documented in this file. ### Changed - Change device jtcvc to use motor velocity and joint velocity in input to PINN models (https://github.com/ami-iit/bipedal-locomotion-framework/pull/903) +- Set the system timer resolution to the minimum value for higher precision on `Windows` (https://github.com/ami-iit/bipedal-locomotion-framework/pull/907) ### Fixed - Bug fix of `JointTorqueControlDevice` device (https://github.com/ami-iit/bipedal-locomotion-framework/pull/890) diff --git a/cmake/AddBipedalLocomotionLibrary.cmake b/cmake/AddBipedalLocomotionLibrary.cmake index 624f034157..76cf54dedf 100644 --- a/cmake/AddBipedalLocomotionLibrary.cmake +++ b/cmake/AddBipedalLocomotionLibrary.cmake @@ -12,6 +12,7 @@ function(add_bipedal_locomotion_library) PRIVATE_HEADERS PUBLIC_LINK_LIBRARIES PRIVATE_LINK_LIBRARIES + PRIVATE_WINDOWS_LINK_LIBRARIES SUBDIRECTORIES) set(prefix "bipedal_component") @@ -32,6 +33,7 @@ function(add_bipedal_locomotion_library) set(private_headers ${${prefix}_PRIVATE_HEADERS}) set(public_link_libraries ${${prefix}_PUBLIC_LINK_LIBRARIES}) set(private_link_libraries ${${prefix}_PRIVATE_LINK_LIBRARIES}) + set(private_windows_link_libraries ${${prefix}_PRIVATE_WINDOWS_LINK_LIBRARIES}) set(subdirectories ${${prefix}_SUBDIRECTORIES}) if(NOT installation_folder) @@ -76,6 +78,10 @@ function(add_bipedal_locomotion_library) target_link_libraries(${name} PUBLIC ${public_link_libraries}) target_link_libraries(${name} PRIVATE ${private_link_libraries}) + if(WIN32) + target_link_libraries(${name} PRIVATE ${private_windows_link_libraries}) + endif() + set_target_properties(${name} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}${name}" VERSION ${BipedalLocomotionFramework_VERSION} diff --git a/src/System/CMakeLists.txt b/src/System/CMakeLists.txt index dd30345c6f..74871cbb17 100644 --- a/src/System/CMakeLists.txt +++ b/src/System/CMakeLists.txt @@ -9,21 +9,22 @@ if(FRAMEWORK_COMPILE_System) # set target name add_bipedal_locomotion_library( - NAME System - PUBLIC_HEADERS ${H_PREFIX}/InputPort.h ${H_PREFIX}/OutputPort.h - ${H_PREFIX}/Advanceable.h ${H_PREFIX}/Source.h ${H_PREFIX}/Sink.h - ${H_PREFIX}/Factory.h - ${H_PREFIX}/VariablesHandler.h ${H_PREFIX}/LinearTask.h ${H_PREFIX}/ILinearTaskSolver.h ${H_PREFIX}/ILinearTaskFactory.h ${H_PREFIX}/ITaskControllerManager.h - ${H_PREFIX}/IClock.h ${H_PREFIX}/StdClock.h ${H_PREFIX}/Clock.h - ${H_PREFIX}/SharedResource.h ${H_PREFIX}/AdvanceableRunner.h - ${H_PREFIX}/QuitHandler.h - ${H_PREFIX}/Barrier.h ${H_PREFIX}/TimeProfiler.h - ${H_PREFIX}/WeightProvider.h ${H_PREFIX}/ConstantWeightProvider.h - SOURCES src/VariablesHandler.cpp src/LinearTask.cpp - src/StdClock.cpp src/Clock.cpp src/QuitHandler.cpp src/Barrier.cpp - src/ConstantWeightProvider.cpp src/TimeProfiler.cpp - PUBLIC_LINK_LIBRARIES BipedalLocomotion::ParametersHandler Eigen3::Eigen - SUBDIRECTORIES tests YarpImplementation RosImplementation + NAME System + PUBLIC_HEADERS ${H_PREFIX}/InputPort.h ${H_PREFIX}/OutputPort.h + ${H_PREFIX}/Advanceable.h ${H_PREFIX}/Source.h ${H_PREFIX}/Sink.h + ${H_PREFIX}/Factory.h + ${H_PREFIX}/VariablesHandler.h ${H_PREFIX}/LinearTask.h ${H_PREFIX}/ILinearTaskSolver.h ${H_PREFIX}/ILinearTaskFactory.h ${H_PREFIX}/ITaskControllerManager.h + ${H_PREFIX}/IClock.h ${H_PREFIX}/StdClock.h ${H_PREFIX}/Clock.h + ${H_PREFIX}/SharedResource.h ${H_PREFIX}/AdvanceableRunner.h + ${H_PREFIX}/QuitHandler.h + ${H_PREFIX}/Barrier.h ${H_PREFIX}/TimeProfiler.h + ${H_PREFIX}/WeightProvider.h ${H_PREFIX}/ConstantWeightProvider.h + SOURCES src/VariablesHandler.cpp src/LinearTask.cpp + src/StdClock.cpp src/Clock.cpp src/QuitHandler.cpp src/Barrier.cpp + src/ConstantWeightProvider.cpp src/TimeProfiler.cpp + PUBLIC_LINK_LIBRARIES BipedalLocomotion::ParametersHandler Eigen3::Eigen + PRIVATE_WINDOWS_LINK_LIBRARIES Winmm + SUBDIRECTORIES tests YarpImplementation RosImplementation ) endif() diff --git a/src/System/include/BipedalLocomotion/System/StdClock.h b/src/System/include/BipedalLocomotion/System/StdClock.h index 78ea7af9b5..23a02f1559 100644 --- a/src/System/include/BipedalLocomotion/System/StdClock.h +++ b/src/System/include/BipedalLocomotion/System/StdClock.h @@ -60,6 +60,33 @@ class StdClock final : public IClock * threads to run. */ void yield() final; + +private: + + /** + * PrecisionScheduler is a class that allows to set the system timer resolution to the minimum + * value for higher precision. This class is used only on Windows systems. + */ + struct PrecisionScheduler + { + /** + * Constructor. + * It sets the system timer resolution to the minimum value for higher precision. + * @note Only affects Windows systems. + */ + PrecisionScheduler(); + + /** + * Destructor. + * It restores the system timer resolution to the default value. + * @note Only affects Windows systems. + */ + ~PrecisionScheduler(); + }; + + PrecisionScheduler m_precisionScheduler; /**< PrecisionScheduler object. + It is used only on Windows systems. */ + }; class StdClockFactory final : public ClockFactory diff --git a/src/System/src/StdClock.cpp b/src/System/src/StdClock.cpp index c2634850e4..7ead781f23 100644 --- a/src/System/src/StdClock.cpp +++ b/src/System/src/StdClock.cpp @@ -8,6 +8,10 @@ #include #include +#if defined(_WIN32) +#include +#endif + #include using namespace BipedalLocomotion::System; @@ -32,6 +36,30 @@ void StdClock::yield() std::this_thread::yield(); } +StdClock::PrecisionScheduler::PrecisionScheduler() +{ +#if defined(_WIN32) + // Only affects Windows systems. + TIMECAPS tm; // Stores system timer capabilities. + // Get the minimum timer resolution supported by the system. + timeGetDevCaps(&tm, sizeof(TIMECAPS)); + // Set the system timer resolution to the minimum value for higher precision. + timeBeginPeriod(tm.wPeriodMin); +#endif +} + +StdClock::PrecisionScheduler::~PrecisionScheduler() +{ +#if defined(_WIN32) + // Only affects Windows systems. + TIMECAPS tm; // Stores system timer capabilities. + // Get the minimum timer resolution supported by the system. + timeGetDevCaps(&tm, sizeof(TIMECAPS)); + // Restore the system timer resolution to the default value. + timeEndPeriod(tm.wPeriodMin); +#endif +} + IClock& StdClockFactory::createClock() { // Create the singleton. Meyers' implementation. It is automatically threadsafe