Compare commits
15 Commits
mjcarroll/
...
clalancett
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca852e6792 | ||
|
|
d7a0b8d995 | ||
|
|
d557c3a5aa | ||
|
|
7021e9aaf8 | ||
|
|
b611cd077a | ||
|
|
5230a99748 | ||
|
|
42b5745669 | ||
|
|
5751a54894 | ||
|
|
863970e5c1 | ||
|
|
9f2efa804d | ||
|
|
9dff67fc88 | ||
|
|
ef788db75a | ||
|
|
34dae0a8c9 | ||
|
|
7ff1b2991f | ||
|
|
c0ad535249 |
@@ -2,6 +2,11 @@
|
||||
Changelog for package rclcpp
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
0.8.4 (2020-01-17)
|
||||
------------------
|
||||
* Intra-process subscriber should use RMW actual qos (ros2`#913 <https://github.com/ros2/rclcpp/issues/913>`_) (`#914 <https://github.com/ros2/rclcpp/issues/914>`_) (`#965 <https://github.com/ros2/rclcpp/issues/965>`_)
|
||||
* Contributors: Todd Malsbary
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
endif()
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
add_compile_options(-Wall -Wextra -Wpedantic -rdynamic -g)
|
||||
endif()
|
||||
|
||||
include_directories(include)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "rclcpp/visibility_control.hpp"
|
||||
#include "rmw/types.h"
|
||||
#include "tracetools/tracetools.h"
|
||||
#include "tracetools/utils.hpp"
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
@@ -98,6 +99,21 @@ public:
|
||||
}
|
||||
TRACEPOINT(callback_end, (const void *)this);
|
||||
}
|
||||
|
||||
void register_callback_for_tracing()
|
||||
{
|
||||
if (shared_ptr_callback_) {
|
||||
TRACEPOINT(
|
||||
rclcpp_callback_register,
|
||||
(const void *)this,
|
||||
get_symbol(shared_ptr_callback_));
|
||||
} else if (shared_ptr_with_request_header_callback_) {
|
||||
TRACEPOINT(
|
||||
rclcpp_callback_register,
|
||||
(const void *)this,
|
||||
get_symbol(shared_ptr_with_request_header_callback_));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rclcpp
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#define RCLCPP__CLOCK_HPP_
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <shared_mutex> // NOLINT
|
||||
#include <unordered_map>
|
||||
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/time.hpp"
|
||||
@@ -138,6 +141,19 @@ private:
|
||||
rcl_allocator_t allocator_;
|
||||
};
|
||||
|
||||
// This code is an ABI-compatible version of the code that went in for
|
||||
// https://github.com/ros2/rclcpp/pull/999. The way that this works is to have
|
||||
// a global map of pointers to mutexes, one per clock class that is created.
|
||||
// During the rclcpp::Clock constructor, it adds a new one to this map, and
|
||||
// during the rclcpp::Clock destructor, it removes it from this map. When
|
||||
// it needs to lock it, it just looks it up in the map. The map itself has
|
||||
// to be protected when adding a new mutex, removing one, or looking it up,
|
||||
// hence the g_clock_map_mutex.
|
||||
extern std::shared_timed_mutex g_clock_map_mutex;
|
||||
extern std::unordered_map<rclcpp::Clock *, std::mutex> g_clock_mutex_map;
|
||||
|
||||
std::mutex & get_clock_mutex(rclcpp::Clock * clock);
|
||||
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__CLOCK_HPP_
|
||||
|
||||
@@ -88,8 +88,7 @@ struct function_traits<std::_Bind<ReturnTypeT(ClassT::*(FArgs ...))(Args ...)>>
|
||||
struct function_traits<std::_Bind<std::_Mem_fn<ReturnTypeT (ClassT::*)(Args ...)>(FArgs ...)>>
|
||||
#elif defined _MSC_VER // MS Visual Studio
|
||||
struct function_traits<
|
||||
std::_Binder<std::_Unforced, ReturnTypeT(__cdecl ClassT::*)(Args ...), FArgs ...>
|
||||
>
|
||||
std::_Binder<std::_Unforced, ReturnTypeT (ClassT::*)(Args ...), FArgs ...>>
|
||||
#else
|
||||
#error "Unsupported C++ compiler / standard library"
|
||||
#endif
|
||||
@@ -106,8 +105,7 @@ struct function_traits<std::_Bind<ReturnTypeT(ClassT::*(FArgs ...))(Args ...) co
|
||||
struct function_traits<std::_Bind<std::_Mem_fn<ReturnTypeT (ClassT::*)(Args ...) const>(FArgs ...)>>
|
||||
#elif defined _MSC_VER // MS Visual Studio
|
||||
struct function_traits<
|
||||
std::_Binder<std::_Unforced, ReturnTypeT(__cdecl ClassT::*)(Args ...) const, FArgs ...>
|
||||
>
|
||||
std::_Binder<std::_Unforced, ReturnTypeT (ClassT::*)(Args ...) const, FArgs ...>>
|
||||
#else
|
||||
#error "Unsupported C++ compiler / standard library"
|
||||
#endif
|
||||
@@ -121,7 +119,7 @@ struct function_traits<std::__bind<ReturnTypeT( &)(Args ...), FArgs ...>>
|
||||
#elif defined __GLIBCXX__ // glibc++ (GNU C++)
|
||||
struct function_traits<std::_Bind<ReturnTypeT(*(FArgs ...))(Args ...)>>
|
||||
#elif defined _MSC_VER // MS Visual Studio
|
||||
struct function_traits<std::_Binder<std::_Unforced, ReturnTypeT(__cdecl &)(Args ...), FArgs ...>>
|
||||
struct function_traits<std::_Binder<std::_Unforced, ReturnTypeT( &)(Args ...), FArgs ...>>
|
||||
#else
|
||||
#error "Unsupported C++ compiler / standard library"
|
||||
#endif
|
||||
|
||||
@@ -159,6 +159,7 @@ public:
|
||||
rclcpp_service_callback_added,
|
||||
(const void *)get_service_handle().get(),
|
||||
(const void *)&any_callback_);
|
||||
any_callback_.register_callback_for_tracing();
|
||||
}
|
||||
|
||||
Service(
|
||||
@@ -181,6 +182,7 @@ public:
|
||||
rclcpp_service_callback_added,
|
||||
(const void *)get_service_handle().get(),
|
||||
(const void *)&any_callback_);
|
||||
any_callback_.register_callback_for_tracing();
|
||||
}
|
||||
|
||||
Service(
|
||||
@@ -205,6 +207,7 @@ public:
|
||||
rclcpp_service_callback_added,
|
||||
(const void *)get_service_handle().get(),
|
||||
(const void *)&any_callback_);
|
||||
any_callback_.register_callback_for_tracing();
|
||||
}
|
||||
|
||||
Service() = delete;
|
||||
|
||||
@@ -124,15 +124,16 @@ public:
|
||||
using rclcpp::detail::resolve_intra_process_buffer_type;
|
||||
|
||||
// Check if the QoS is compatible with intra-process.
|
||||
if (qos.get_rmw_qos_profile().history == RMW_QOS_POLICY_HISTORY_KEEP_ALL) {
|
||||
rmw_qos_profile_t qos_profile = get_actual_qos().get_rmw_qos_profile();
|
||||
if (qos_profile.history == RMW_QOS_POLICY_HISTORY_KEEP_ALL) {
|
||||
throw std::invalid_argument(
|
||||
"intraprocess communication is not allowed with keep all history qos policy");
|
||||
}
|
||||
if (qos.get_rmw_qos_profile().depth == 0) {
|
||||
if (qos_profile.depth == 0) {
|
||||
throw std::invalid_argument(
|
||||
"intraprocess communication is not allowed with 0 depth qos policy");
|
||||
}
|
||||
if (qos.get_rmw_qos_profile().durability != RMW_QOS_POLICY_DURABILITY_VOLATILE) {
|
||||
if (qos_profile.durability != RMW_QOS_POLICY_DURABILITY_VOLATILE) {
|
||||
throw std::invalid_argument(
|
||||
"intraprocess communication allowed only with volatile durability");
|
||||
}
|
||||
@@ -149,7 +150,7 @@ public:
|
||||
options.get_allocator(),
|
||||
context,
|
||||
this->get_topic_name(), // important to get like this, as it has the fully-qualified name
|
||||
qos.get_rmw_qos_profile(),
|
||||
qos_profile,
|
||||
resolve_intra_process_buffer_type(options.intra_process_buffer_type, callback)
|
||||
);
|
||||
TRACEPOINT(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp</name>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.4</version>
|
||||
<description>The ROS client library in C++.</description>
|
||||
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -128,9 +128,9 @@ def get_rclcpp_suffix_from_features(features):
|
||||
typename ::rclcpp::Logger>::value, \
|
||||
"First argument to logging macros must be an rclcpp::Logger"); \
|
||||
@[ if 'throttle' in feature_combination]@ \
|
||||
auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
|
||||
auto get_time_point = [&c=clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
|
||||
try { \
|
||||
*time_point = clock.now().nanoseconds(); \
|
||||
*time_point = c.now().nanoseconds(); \
|
||||
} catch (...) { \
|
||||
RCUTILS_SAFE_FWRITE_TO_STDERR( \
|
||||
"[rclcpp|logging.hpp] RCLCPP_@(severity)@(suffix) could not get current time stamp\n"); \
|
||||
|
||||
@@ -12,6 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <mutex>
|
||||
#include <shared_mutex> // NOLINT
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <execinfo.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
#include "rclcpp/clock.hpp"
|
||||
|
||||
#include "rclcpp/exceptions.hpp"
|
||||
@@ -21,6 +30,93 @@
|
||||
namespace rclcpp
|
||||
{
|
||||
|
||||
std::shared_timed_mutex g_clock_map_mutex;
|
||||
std::unordered_map<rclcpp::Clock *, std::mutex> g_clock_mutex_map;
|
||||
|
||||
/** Print a demangled stack backtrace of the caller function to FILE* out. */
|
||||
void print_backtrace(FILE *out = stderr, unsigned int max_frames = 63)
|
||||
{
|
||||
fprintf(out, "stack trace:\n");
|
||||
|
||||
// storage array for stack trace address data
|
||||
void* addrlist[max_frames+1];
|
||||
|
||||
// retrieve current stack addresses
|
||||
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
|
||||
|
||||
if (addrlen == 0) {
|
||||
fprintf(out, " <empty, possibly corrupt>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve addresses into strings containing "filename(function+address)",
|
||||
// this array must be free()-ed
|
||||
char** symbollist = backtrace_symbols(addrlist, addrlen);
|
||||
|
||||
// allocate string which will be filled with the demangled function name
|
||||
size_t funcnamesize = 256;
|
||||
char* funcname = (char*)malloc(funcnamesize);
|
||||
|
||||
// iterate over the returned symbol lines. skip the first, it is the
|
||||
// address of this function.
|
||||
for (int i = 1; i < addrlen; i++) {
|
||||
char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
|
||||
|
||||
// find parentheses and +address offset surrounding the mangled name:
|
||||
// ./module(function+0x15c) [0x8048a6d]
|
||||
for (char *p = symbollist[i]; *p; ++p) {
|
||||
if (*p == '(') {
|
||||
begin_name = p;
|
||||
} else if (*p == '+') {
|
||||
begin_offset = p;
|
||||
} else if (*p == ')' && begin_offset) {
|
||||
end_offset = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (begin_name && begin_offset && end_offset && begin_name < begin_offset) {
|
||||
*begin_name++ = '\0';
|
||||
*begin_offset++ = '\0';
|
||||
*end_offset = '\0';
|
||||
|
||||
// mangled name is now in [begin_name, begin_offset) and caller
|
||||
// offset in [begin_offset, end_offset). now apply
|
||||
// __cxa_demangle():
|
||||
|
||||
int status;
|
||||
char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status);
|
||||
if (status == 0) {
|
||||
funcname = ret; // use possibly realloc()-ed string
|
||||
fprintf(out, " %s : %s+%s\n", symbollist[i], funcname, begin_offset);
|
||||
}
|
||||
else {
|
||||
// demangling failed. Output function name as a C function with
|
||||
// no arguments.
|
||||
fprintf(out, " %s : %s()+%s\n", symbollist[i], begin_name, begin_offset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// couldn't parse the line? print the whole line.
|
||||
fprintf(out, " %s\n", symbollist[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(funcname);
|
||||
free(symbollist);
|
||||
}
|
||||
|
||||
std::mutex & get_clock_mutex(rclcpp::Clock * clock)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lk(g_clock_map_mutex);
|
||||
try {
|
||||
return g_clock_mutex_map.at(clock);
|
||||
} catch (const std::out_of_range &) {
|
||||
print_backtrace();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
JumpHandler::JumpHandler(
|
||||
pre_callback_t pre_callback,
|
||||
post_callback_t post_callback,
|
||||
@@ -37,10 +133,24 @@ Clock::Clock(rcl_clock_type_t clock_type)
|
||||
if (ret != RCL_RET_OK) {
|
||||
exceptions::throw_from_rcl_error(ret, "could not get current time stamp");
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::shared_timed_mutex> lg(g_clock_map_mutex);
|
||||
// Add a new default-constructed mutex, keyed off of this pointer.
|
||||
fprintf(stderr, "Adding clock mutex for %p\n", static_cast<void *>(this));
|
||||
g_clock_mutex_map[this];
|
||||
}
|
||||
}
|
||||
|
||||
Clock::~Clock()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::shared_timed_mutex> lg(g_clock_map_mutex);
|
||||
// Remove the mutex corresponding to this clock object.
|
||||
g_clock_mutex_map.erase(this);
|
||||
fprintf(stderr, "Removed clock mutex for %p\n", static_cast<void *>(this));
|
||||
}
|
||||
|
||||
auto ret = rcl_clock_fini(&rcl_clock_);
|
||||
if (ret != RCL_RET_OK) {
|
||||
RCUTILS_LOG_ERROR("Failed to fini rcl clock.");
|
||||
@@ -118,18 +228,25 @@ Clock::create_jump_callback(
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
|
||||
// Try to add the jump callback to the clock
|
||||
rcl_ret_t ret = rcl_clock_add_jump_callback(
|
||||
&rcl_clock_, threshold, Clock::on_time_jump,
|
||||
handler.get());
|
||||
if (RCL_RET_OK != ret) {
|
||||
exceptions::throw_from_rcl_error(ret, "Failed to add time jump callback");
|
||||
{
|
||||
fprintf(stderr, "create_jump_callback() getting clock mutex for %p\n", static_cast<void *>(this));
|
||||
std::lock_guard<std::mutex> clock_guard(get_clock_mutex(this));
|
||||
// Try to add the jump callback to the clock
|
||||
rcl_ret_t ret = rcl_clock_add_jump_callback(
|
||||
&rcl_clock_, threshold, Clock::on_time_jump,
|
||||
handler.get());
|
||||
if (RCL_RET_OK != ret) {
|
||||
exceptions::throw_from_rcl_error(ret, "Failed to add time jump callback");
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
// create shared_ptr that removes the callback automatically when all copies are destructed
|
||||
// TODO(dorezyuk) UB, if the clock leaves scope before the JumpHandler
|
||||
return JumpHandler::SharedPtr(handler.release(), [this](JumpHandler * handler) noexcept {
|
||||
fprintf(stderr, "create_jump_callback release lambda getting clock mutex for %p\n", static_cast<void *>(this));
|
||||
std::lock_guard<std::mutex> clock_guard(get_clock_mutex(this));
|
||||
|
||||
rcl_ret_t ret = rcl_clock_remove_jump_callback(&rcl_clock_, Clock::on_time_jump,
|
||||
handler);
|
||||
delete handler;
|
||||
|
||||
@@ -321,9 +321,11 @@ rclcpp::Event::SharedPtr
|
||||
NodeGraph::get_graph_event()
|
||||
{
|
||||
auto event = rclcpp::Event::make_shared();
|
||||
std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
|
||||
graph_events_.push_back(event);
|
||||
graph_users_count_++;
|
||||
{
|
||||
std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
|
||||
graph_events_.push_back(event);
|
||||
graph_users_count_++;
|
||||
}
|
||||
// on first call, add node to graph_listener_
|
||||
if (should_add_to_graph_listener_.exchange(false)) {
|
||||
graph_listener_->add_node(this);
|
||||
|
||||
@@ -402,6 +402,8 @@ NodeParameters::declare_parameter(
|
||||
|
||||
// Publish if events_publisher_ is not nullptr, which may be if disabled in the constructor.
|
||||
if (nullptr != events_publisher_) {
|
||||
parameter_event.node = combined_name_;
|
||||
parameter_event.stamp = node_clock_->get_clock()->now();
|
||||
events_publisher_->publish(parameter_event);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "rclcpp/clock.hpp"
|
||||
#include "rclcpp/contexts/default_context.hpp"
|
||||
#include "rclcpp/exceptions.hpp"
|
||||
|
||||
@@ -40,11 +42,15 @@ TimerBase::TimerBase(
|
||||
timer_handle_ = std::shared_ptr<rcl_timer_t>(
|
||||
new rcl_timer_t, [ = ](rcl_timer_t * timer) mutable
|
||||
{
|
||||
if (rcl_timer_fini(timer) != RCL_RET_OK) {
|
||||
RCUTILS_LOG_ERROR_NAMED(
|
||||
"rclcpp",
|
||||
"Failed to clean up rcl timer handle: %s", rcl_get_error_string().str);
|
||||
rcl_reset_error();
|
||||
{
|
||||
fprintf(stderr, "TimerBase handle lambda getting clock mutex for %p\n", static_cast<void *>(clock.get()));
|
||||
std::lock_guard<std::mutex> clock_guard(get_clock_mutex(clock.get()));
|
||||
if (rcl_timer_fini(timer) != RCL_RET_OK) {
|
||||
RCUTILS_LOG_ERROR_NAMED(
|
||||
"rclcpp",
|
||||
"Failed to clean up rcl timer handle: %s", rcl_get_error_string().str);
|
||||
rcl_reset_error();
|
||||
}
|
||||
}
|
||||
delete timer;
|
||||
// Captured shared pointers by copy, reset to make sure timer is finalized before clock
|
||||
@@ -55,15 +61,19 @@ TimerBase::TimerBase(
|
||||
*timer_handle_.get() = rcl_get_zero_initialized_timer();
|
||||
|
||||
rcl_clock_t * clock_handle = clock_->get_clock_handle();
|
||||
if (
|
||||
rcl_timer_init(
|
||||
timer_handle_.get(), clock_handle, rcl_context.get(), period.count(), nullptr,
|
||||
rcl_get_default_allocator()) != RCL_RET_OK)
|
||||
{
|
||||
RCUTILS_LOG_ERROR_NAMED(
|
||||
"rclcpp",
|
||||
"Couldn't initialize rcl timer handle: %s\n", rcl_get_error_string().str);
|
||||
rcl_reset_error();
|
||||
fprintf(stderr, "TimerBase constructor getting clock mutex for %p\n", static_cast<void *>(this->clock_.get()));
|
||||
std::lock_guard<std::mutex> clock_guard(get_clock_mutex(this->clock_.get()));
|
||||
if (
|
||||
rcl_timer_init(
|
||||
timer_handle_.get(), clock_handle, rcl_context.get(), period.count(), nullptr,
|
||||
rcl_get_default_allocator()) != RCL_RET_OK)
|
||||
{
|
||||
RCUTILS_LOG_ERROR_NAMED(
|
||||
"rclcpp",
|
||||
"Couldn't initialize rcl timer handle: %s\n", rcl_get_error_string().str);
|
||||
rcl_reset_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,16 +77,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DummyNode
|
||||
{
|
||||
public:
|
||||
DummyNode()
|
||||
{
|
||||
clock_ = rclcpp::Clock::make_shared(RCL_ROS_TIME);
|
||||
}
|
||||
rclcpp::Clock::SharedPtr get_clock()
|
||||
{
|
||||
return clock_;
|
||||
}
|
||||
|
||||
private:
|
||||
rclcpp::Clock::SharedPtr clock_;
|
||||
};
|
||||
|
||||
TEST_F(TestLoggingMacros, test_logging_named) {
|
||||
for (int i : {1, 2, 3}) {
|
||||
RCLCPP_DEBUG(g_logger, "message %d", i);
|
||||
}
|
||||
size_t expected_location = __LINE__ - 2u;
|
||||
EXPECT_EQ(3u, g_log_calls);
|
||||
EXPECT_TRUE(g_last_log_event.location != NULL);
|
||||
if (g_last_log_event.location) {
|
||||
EXPECT_STREQ("TestBody", g_last_log_event.location->function_name);
|
||||
EXPECT_THAT(g_last_log_event.location->file_name, EndsWith("test_logging.cpp"));
|
||||
EXPECT_EQ(82u, g_last_log_event.location->line_number);
|
||||
EXPECT_EQ(expected_location, g_last_log_event.location->line_number);
|
||||
}
|
||||
EXPECT_EQ(RCUTILS_LOG_SEVERITY_DEBUG, g_last_log_event.level);
|
||||
EXPECT_EQ("name", g_last_log_event.name);
|
||||
@@ -210,6 +227,26 @@ TEST_F(TestLoggingMacros, test_throttle) {
|
||||
EXPECT_EQ(6u, g_log_calls);
|
||||
}
|
||||
}
|
||||
DummyNode node;
|
||||
rcl_clock_t * node_clock = node.get_clock()->get_clock_handle();
|
||||
ASSERT_TRUE(node_clock);
|
||||
ASSERT_EQ(RCL_RET_OK, rcl_enable_ros_time_override(node_clock));
|
||||
EXPECT_EQ(6u, g_log_calls);
|
||||
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, RCUTILS_MS_TO_NS(10)));
|
||||
for (uint64_t i = 0; i < 3; ++i) {
|
||||
RCLCPP_DEBUG_THROTTLE(g_logger, *node.get_clock(), 10, "Throttling");
|
||||
if (i == 0) {
|
||||
EXPECT_EQ(7u, g_log_calls);
|
||||
rcl_time_point_value_t clock_ns = node.get_clock()->now().nanoseconds() + RCUTILS_MS_TO_NS(5);
|
||||
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, clock_ns));
|
||||
} else if (i == 1) {
|
||||
EXPECT_EQ(7u, g_log_calls);
|
||||
rcl_time_point_value_t clock_ns = node.get_clock()->now().nanoseconds() + RCUTILS_MS_TO_NS(5);
|
||||
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, clock_ns));
|
||||
} else {
|
||||
EXPECT_EQ(8u, g_log_calls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool log_function(rclcpp::Logger logger)
|
||||
|
||||
@@ -287,10 +287,6 @@ static std::vector<TestParameters> invalid_qos_profiles()
|
||||
TestParameters(
|
||||
rclcpp::QoS(rclcpp::KeepAll()),
|
||||
"keep_all_qos"));
|
||||
parameters.push_back(
|
||||
TestParameters(
|
||||
rclcpp::QoS(rclcpp::KeepLast(0)),
|
||||
"keep_last_zero_depth_qos"));
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ Changelog for package rclcpp_action
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
0.8.4 (2020-01-17)
|
||||
------------------
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
* issue-919 Fixed "memory leak" in action clients (`#920 <https://github.com/ros2/rclcpp/issues/920>`_)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_action</name>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.4</version>
|
||||
<description>Adds action APIs for C++.</description>
|
||||
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
Changelog for package rclcpp_components
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
0.8.4 (2020-01-17)
|
||||
------------------
|
||||
* Remove absolute path from installed CMake code (`#948 <https://github.com/ros2/rclcpp/issues/948>`_) (`#950 <https://github.com/ros2/rclcpp/issues/950>`_)
|
||||
* Contributors: Jacob Perron
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_components</name>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.4</version>
|
||||
<description>Package containing tools for dynamically loadable components</description>
|
||||
<maintainer email="michael@openrobotics.org">Michael Carroll</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -25,7 +25,8 @@ macro(_rclcpp_components_register_package_hook)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set(@PROJECT_NAME@_NODE_TEMPLATE "@CMAKE_INSTALL_PREFIX@/@node_main_template_install_dir@/node_main.cpp.in")
|
||||
get_filename_component(@PROJECT_NAME@_SHARE_DIR "${@PROJECT_NAME@_DIR}" DIRECTORY)
|
||||
set(@PROJECT_NAME@_NODE_TEMPLATE "${@PROJECT_NAME@_SHARE_DIR}/node_main.cpp.in")
|
||||
|
||||
include("${rclcpp_components_DIR}/rclcpp_components_register_nodes.cmake")
|
||||
include("${rclcpp_components_DIR}/rclcpp_components_register_node.cmake")
|
||||
|
||||
@@ -3,6 +3,9 @@ Changelog for package rclcpp_lifecycle
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
0.8.4 (2020-01-17)
|
||||
------------------
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_lifecycle</name>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.4</version>
|
||||
<description>Package containing a prototype for lifecycle implementation</description>
|
||||
<maintainer email="karsten@osrfoundation.org">Karsten Knese</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
Reference in New Issue
Block a user