Program Listing for File timer.h
↰ Return to documentation for file (/tmp/ws/src/marti_common/swri_roscpp/include/swri_roscpp/timer.h
)
// *****************************************************************************
//
// 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 <chrono>
#include <rclcpp/rclcpp.hpp>
#include <diagnostic_updater/diagnostic_status_wrapper.hpp>
#include <swri_roscpp/timer_impl.h>
namespace swri
{
class Timer
{
private:
std::shared_ptr<TimerImpl> impl_;
public:
Timer();
template<class T>
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<TimerImpl>(new TimerImpl());
}
template<class T>
inline
Timer::Timer(rclcpp::Node &nh,
rclcpp::Duration period,
void(T::*callback)(),
T *obj)
{
impl_ = std::shared_ptr<TimerImpl>(
new TypedTimerImpl<T>(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_