Program Listing for File rtt_executor.hpp
↰ Return to documentation for file (/tmp/ws/src/demos/pendulum_control/include/pendulum_control/rtt_executor.hpp
)
// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PENDULUM_CONTROL__RTT_EXECUTOR_HPP_
#define PENDULUM_CONTROL__RTT_EXECUTOR_HPP_
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <vector>
#include "rttest/rttest.h"
#include "rttest/utils.hpp"
#include "rmw/rmw.h"
#include "rclcpp/executor.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/memory_strategies.hpp"
namespace pendulum_control
{
class RttExecutor : public rclcpp::Executor
{
public:
RttExecutor(
const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions())
: rclcpp::Executor(options), running(false)
{
rttest_ready = rttest_running();
memset(&start_time_, 0, sizeof(timespec));
}
virtual ~RttExecutor() {}
// \return True if rclcpp is running and if the "running" boolean is set to true.
bool is_running() const
{
return rclcpp::ok() && running;
}
// \param[out] msg The message to fill out.
bool set_rtt_results_message(pendulum_msgs::msg::RttestResults & msg) const
{
if (!results_available) {
return false;
}
msg.cur_latency = last_sample;
msg.mean_latency = results.mean_latency;
assert(results.min_latency >= 0);
assert(results.max_latency >= 0);
msg.min_latency = results.min_latency;
msg.max_latency = results.max_latency;
msg.minor_pagefaults = results.minor_pagefaults;
msg.major_pagefaults = results.major_pagefaults;
timespec curtime;
clock_gettime(CLOCK_MONOTONIC, &curtime);
msg.stamp.sec = curtime.tv_sec;
msg.stamp.nanosec = curtime.tv_nsec;
return true;
}
// Do all the work available to the executor for as many iterations specified by rttest.
void spin()
{
// This call will block until rttest is finished, calling loop_callback at periodic intervals
// specified on the command line.
rttest_spin(RttExecutor::loop_callback, static_cast<void *>(this));
// Clean up state and write results after rttest has finished spinning.
running = false;
rttest_write_results();
if (rttest_running()) {
rttest_finish();
}
rttest_ready = rttest_running();
}
// \param[in] Anonymous argument, will be cast as a pointer to an RttExecutor.
static void * loop_callback(void * arg)
{
// Cast the argument so that we can access the executor's state.
RttExecutor * executor = static_cast<RttExecutor *>(arg);
// If the input pointer was NULL or invalid, or if rclcpp has stopped, signal rttest to stop.
if (!executor || !rclcpp::ok()) {
rttest_finish();
return 0;
}
// Single-threaded spin_some: do as much work as we have available.
executor->spin_some();
// Retrieve rttest statistics accumulated so far and store them in the executor.
if (rttest_get_statistics(&executor->results) >= 0) {
executor->results_available = true;
}
rttest_get_sample_at(executor->results.iteration, &executor->last_sample);
// In case this boolean wasn't set, notify that we've recently run the callback.
executor->running = true;
return 0;
}
rttest_results results;
bool results_available{false};
bool running;
bool rttest_ready;
int64_t last_sample;
protected:
timespec start_time_;
private:
RCLCPP_DISABLE_COPY(RttExecutor)
};
} // namespace pendulum_control
#endif // PENDULUM_CONTROL__RTT_EXECUTOR_HPP_