.. _program_listing_file__tmp_ws_src_marti_common_swri_roscpp_include_swri_roscpp_timer.h: Program Listing for File timer.h ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/marti_common/swri_roscpp/include/swri_roscpp/timer.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // ***************************************************************************** // // Copyright (c) 2015, Southwest Research Institute® (SwRI®) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of Southwest Research Institute® (SwRI®) nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL SOUTHWEST RESEARCH INSTITUTE BE LIABLE FOR ANY // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // ***************************************************************************** #ifndef SWRI_ROSCPP_TIMER_H_ #define SWRI_ROSCPP_TIMER_H_ #include #include #include #include namespace swri { class Timer { private: std::shared_ptr impl_; public: Timer(); template Timer(rclcpp::Node& nh, rclcpp::Duration period, void(T::*callback)(), T *obj); Timer& operator=(const Timer &other); rclcpp::Duration desiredPeriod() const; double desiredFrequency() const; void resetStatistics(); // The number of times the timer callback has been called. size_t ticks() const; // Frequency/Period of the timer callbacks. double meanFrequencyHz() const; rclcpp::Duration meanPeriod() const; rclcpp::Duration minPeriod() const; rclcpp::Duration maxPeriod() const; double meanPeriodMilliseconds() const; double minPeriodMilliseconds() const; double maxPeriodMilliseconds() const; // Average duration of the timer callback. These are tracked as // wall durations because they are typically used as a rough profile // of how long the callback takes to execute which is independent of // simulated time. std::chrono::nanoseconds meanDuration() const; std::chrono::nanoseconds minDuration() const; std::chrono::nanoseconds maxDuration() const; double meanDurationMicroseconds() const; double minDurationMicroseconds() const; double maxDurationMicroseconds() const; enum DIAGNOSTIC_FLAGS { DIAG_COUNT = 1 << 0, DIAG_RATE = 1 << 1, DIAG_DURATION = 1 << 2, DIAG_ALL = ~0, DIAG_MOST = DIAG_ALL ^ DIAG_COUNT }; void appendDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &status, const std::string &name, const int flags); }; // class Timer inline Timer::Timer() { // Setup an empty implementation so that we can assume impl_ is // non-null and avoid a lot of unnecessary NULL checks. impl_ = std::shared_ptr(new TimerImpl()); } template inline Timer::Timer(rclcpp::Node &nh, rclcpp::Duration period, void(T::*callback)(), T *obj) { impl_ = std::shared_ptr( new TypedTimerImpl(nh, period, callback, obj)); } inline Timer& Timer::operator=(const Timer &other) { impl_ = other.impl_; return *this; } inline rclcpp::Duration Timer::desiredPeriod() const { return impl_->desiredPeriod(); } inline double Timer::desiredFrequency() const { return 1.0 / desiredPeriod().seconds(); } inline void Timer::resetStatistics() { return impl_->resetStatistics(); } inline size_t Timer::ticks() const { return impl_->ticks(); } inline double Timer::meanFrequencyHz() const { return impl_->meanFrequencyHz(); } inline rclcpp::Duration Timer::meanPeriod() const { return impl_->meanPeriod(); } inline rclcpp::Duration Timer::minPeriod() const { return impl_->minPeriod(); } inline rclcpp::Duration Timer::maxPeriod() const { return impl_->maxPeriod(); } inline double Timer::meanPeriodMilliseconds() const { return impl_->meanPeriod().nanoseconds() / 1000000.0; } inline double Timer::minPeriodMilliseconds() const { return impl_->minPeriod().nanoseconds() / 1000000.0; } inline double Timer::maxPeriodMilliseconds() const { return impl_->maxPeriod().nanoseconds() / 1000000.0; } inline std::chrono::nanoseconds Timer::meanDuration() const { return impl_->meanDuration(); } inline std::chrono::nanoseconds Timer::minDuration() const { return impl_->minDuration(); } inline std::chrono::nanoseconds Timer::maxDuration() const { return impl_->maxDuration(); } inline double Timer::meanDurationMicroseconds() const { return impl_->meanDuration().count() / 1000.0; } inline double Timer::minDurationMicroseconds() const { return impl_->minDuration().count() / 1000.0; } inline double Timer::maxDurationMicroseconds() const { return impl_->maxDuration().count() / 1000.0; } inline void Timer::appendDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &status, const std::string &name, int flags) { // Alias a type for easier access to DiagnosticStatus enumerations. // typedef diagnostic_msgs::DiagnosticStatus DS; // todo(anyone): Add an optional limit to set a warning or error // some critical measurement crosses as threshold. Big ones are // probably frequency dropping too low and duration getting too // large. if (flags & DIAG_COUNT) { status.addf(name + " ticks", "%d", ticks()); } if (flags & DIAG_RATE) { if (ticks() < 2) { status.add( name + " rates", "min period: N/A ms, mean frequency: N/A hz, max period: N/A ms"); } else { status.addf( name + " rates", "min period: %.2f ms, mean frequency: %.2f hz, max period: %.2f ms", minPeriodMilliseconds(), meanFrequencyHz(), maxPeriodMilliseconds()); } } if (flags & DIAG_DURATION) { if (ticks() < 1) { status.add(name + " duration", "min: N/A us, mean: N/A us, max: N/A us"); } else { status.addf(name + " duration", "min: %.2f us, mean: %.2f us, max: %.2f us", minDurationMicroseconds(), meanDurationMicroseconds(), maxDurationMicroseconds()); } } } } // namespace swri #endif // SWRI_ROSCPP_TIMER_H_