Skip to content

Commit 42d3dbc

Browse files
committed
Add new RCL_RAW_STEADY_TIME changes
Signed-off-by: Sai Kishor Kothakota <[email protected]>
1 parent 2fcef70 commit 42d3dbc

File tree

9 files changed

+163
-11
lines changed

9 files changed

+163
-11
lines changed

rclcpp/include/rclcpp/timer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,8 @@ class GenericTimer : public TimerBase
338338
bool
339339
is_steady() override
340340
{
341-
return clock_->get_clock_type() == RCL_STEADY_TIME;
341+
return clock_->get_clock_type() == RCL_STEADY_TIME ||
342+
clock_->get_clock_type() == RCL_RAW_STEADY_TIME;
342343
}
343344

344345
protected:

rclcpp/src/rclcpp/clock.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ Clock::sleep_until(
120120
const std::chrono::steady_clock::time_point chrono_until =
121121
chrono_entry + std::chrono::nanoseconds(delta_t.nanoseconds());
122122

123+
// loop over spurious wakeups but notice shutdown or stop of sleep
124+
std::unique_lock lock(impl_->wait_mutex_);
125+
while (now() < until && !impl_->stop_sleeping_ && !impl_->shutdown_ && context->is_valid()) {
126+
impl_->cv_.wait_until(lock, chrono_until);
127+
}
128+
impl_->stop_sleeping_ = false;
129+
} else if (this_clock_type == RCL_RAW_STEADY_TIME) {
130+
// Synchronize because RCL steady clock epoch might differ from chrono::steady_clock epoch
131+
const Time rcl_entry = now();
132+
const std::chrono::steady_clock::time_point chrono_entry = std::chrono::steady_clock::now();
133+
const Duration delta_t = until - rcl_entry;
134+
const std::chrono::steady_clock::time_point chrono_until =
135+
chrono_entry + std::chrono::nanoseconds(delta_t.nanoseconds());
136+
123137
// loop over spurious wakeups but notice shutdown or stop of sleep
124138
std::unique_lock lock(impl_->wait_mutex_);
125139
while (now() < until && !impl_->stop_sleeping_ && !impl_->shutdown_ && context->is_valid()) {
@@ -469,6 +483,7 @@ class ClockWaiter::ClockWaiterImpl
469483
return wait_until_ros_time(lock, abs_time, pred);
470484
break;
471485
case RCL_STEADY_TIME:
486+
case RCL_RAW_STEADY_TIME:
472487
return wait_until_steady_time(lock, abs_time, pred);
473488
break;
474489
case RCL_SYSTEM_TIME:

rclcpp/test/rclcpp/test_clock_conditional.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ INSTANTIATE_TEST_SUITE_P(
136136
ClockConditionalVariable,
137137
TestClockWakeup,
138138
::testing::Values(
139-
RCL_SYSTEM_TIME, RCL_ROS_TIME, RCL_STEADY_TIME
139+
RCL_SYSTEM_TIME, RCL_ROS_TIME, RCL_STEADY_TIME, RCL_RAW_STEADY_TIME
140140
));
141141

142142
TEST_P(TestClockWakeup, wakeup_sleep) {

rclcpp/test/rclcpp/test_logging.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,41 +190,54 @@ TEST_F(TestLoggingMacros, test_throttle) {
190190
std::this_thread::sleep_for(50ms);
191191
}
192192
EXPECT_EQ(4u, g_log_calls);
193+
rclcpp::Clock raw_steady_clock(RCL_RAW_STEADY_TIME);
194+
for (uint64_t i = 0; i < 3; ++i) {
195+
RCLCPP_DEBUG_THROTTLE(g_logger, raw_steady_clock, 10000, "Throttling");
196+
}
197+
EXPECT_EQ(5u, g_log_calls);
198+
RCLCPP_DEBUG_SKIPFIRST_THROTTLE(g_logger, raw_steady_clock, 1, "Skip first throttling");
199+
EXPECT_EQ(5u, g_log_calls);
200+
for (uint64_t i = 0; i < 6; ++i) {
201+
RCLCPP_DEBUG_THROTTLE(g_logger, raw_steady_clock, 100, "Throttling");
202+
RCLCPP_DEBUG_SKIPFIRST_THROTTLE(g_logger, raw_steady_clock, 400, "Throttling");
203+
std::this_thread::sleep_for(50ms);
204+
}
205+
EXPECT_EQ(8u, g_log_calls);
193206
rclcpp::Clock ros_clock(RCL_ROS_TIME);
194207
ASSERT_EQ(RCL_RET_OK, rcl_enable_ros_time_override(ros_clock.get_clock_handle()));
195208
RCLCPP_DEBUG_THROTTLE(g_logger, ros_clock, 10000, "Throttling");
196209
rcl_clock_t * clock = ros_clock.get_clock_handle();
197210
ASSERT_TRUE(clock);
198-
EXPECT_EQ(4u, g_log_calls);
211+
EXPECT_EQ(8u, g_log_calls);
199212
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(clock, RCUTILS_MS_TO_NS(10)));
200213
for (uint64_t i = 0; i < 2; ++i) {
201214
RCLCPP_DEBUG_THROTTLE(g_logger, ros_clock, 10, "Throttling");
202215
if (i == 0) {
203-
EXPECT_EQ(5u, g_log_calls);
216+
EXPECT_EQ(9u, g_log_calls);
204217
rcl_time_point_value_t clock_ns = ros_clock.now().nanoseconds() + RCUTILS_MS_TO_NS(10);
205218
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(clock, clock_ns));
206219
} else {
207-
EXPECT_EQ(6u, g_log_calls);
220+
EXPECT_EQ(10u, g_log_calls);
208221
}
209222
}
210223
DummyNode node;
211224
rcl_clock_t * node_clock = node.get_clock()->get_clock_handle();
212225
ASSERT_TRUE(node_clock);
213226
ASSERT_EQ(RCL_RET_OK, rcl_enable_ros_time_override(node_clock));
214-
EXPECT_EQ(6u, g_log_calls);
227+
EXPECT_EQ(10u, g_log_calls);
215228
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, RCUTILS_MS_TO_NS(10)));
216229
for (uint64_t i = 0; i < 3; ++i) {
217230
RCLCPP_DEBUG_THROTTLE(g_logger, *node.get_clock(), 10, "Throttling");
218231
if (i == 0) {
219-
EXPECT_EQ(7u, g_log_calls);
232+
EXPECT_EQ(11u, g_log_calls);
220233
rcl_time_point_value_t clock_ns = node.get_clock()->now().nanoseconds() + RCUTILS_MS_TO_NS(5);
221234
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, clock_ns));
222235
} else if (i == 1) {
223-
EXPECT_EQ(7u, g_log_calls);
236+
EXPECT_EQ(11u, g_log_calls);
224237
rcl_time_point_value_t clock_ns = node.get_clock()->now().nanoseconds() + RCUTILS_MS_TO_NS(5);
225238
EXPECT_EQ(RCL_RET_OK, rcl_set_ros_time_override(node_clock, clock_ns));
226239
} else {
227-
EXPECT_EQ(8u, g_log_calls);
240+
EXPECT_EQ(12u, g_log_calls);
228241
}
229242
}
230243
}

rclcpp/test/rclcpp/test_node.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,29 @@ TEST_F(TestNode, construction_and_destruction) {
165165
"my_node", "/ns",
166166
options), std::invalid_argument);
167167
}
168+
169+
{
170+
rclcpp::NodeOptions options;
171+
options.clock_type(RCL_RAW_STEADY_TIME);
172+
ASSERT_NO_THROW(
173+
{
174+
const auto node = std::make_shared<rclcpp::Node>("my_node", "/ns", options);
175+
EXPECT_EQ(RCL_RAW_STEADY_TIME, node->get_clock()->get_clock_type());
176+
});
177+
}
178+
179+
{
180+
rclcpp::NodeOptions options;
181+
options.parameter_overrides(
182+
{
183+
{"use_sim_time", true},
184+
});
185+
options.clock_type(RCL_RAW_STEADY_TIME);
186+
ASSERT_THROW(
187+
const auto node = std::make_shared<rclcpp::Node>(
188+
"my_node", "/ns",
189+
options), std::invalid_argument);
190+
}
168191
}
169192

170193
/*

rclcpp/test/rclcpp/test_node_options.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,6 @@ TEST(TestNodeOptions, clock_type) {
382382
EXPECT_EQ(RCL_SYSTEM_TIME, options.clock_type());
383383
options.clock_type(RCL_STEADY_TIME);
384384
EXPECT_EQ(RCL_STEADY_TIME, options.clock_type());
385+
options.clock_type(RCL_RAW_STEADY_TIME);
386+
EXPECT_EQ(RCL_RAW_STEADY_TIME, options.clock_type());
385387
}

rclcpp/test/rclcpp/test_rate.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ TEST_F(TestRate, clock_types) {
146146
rclcpp::Rate rate(1.0, std::make_shared<rclcpp::Clock>(RCL_STEADY_TIME));
147147
EXPECT_EQ(RCL_STEADY_TIME, rate.get_type());
148148
}
149+
{
150+
rclcpp::Rate rate(1.0, std::make_shared<rclcpp::Clock>(RCL_RAW_STEADY_TIME));
151+
EXPECT_EQ(RCL_RAW_STEADY_TIME, rate.get_type());
152+
}
149153
{
150154
rclcpp::Rate rate(1.0, std::make_shared<rclcpp::Clock>(RCL_ROS_TIME));
151155
EXPECT_EQ(RCL_ROS_TIME, rate.get_type());

rclcpp/test/rclcpp/test_time.cpp

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ TEST_F(TestTime, clock_type_access) {
6363

6464
rclcpp::Clock steady_clock(RCL_STEADY_TIME);
6565
EXPECT_EQ(RCL_STEADY_TIME, steady_clock.get_clock_type());
66+
67+
rclcpp::Clock raw_steady_clock(RCL_RAW_STEADY_TIME);
68+
EXPECT_EQ(RCL_RAW_STEADY_TIME, raw_steady_clock.get_clock_type());
6669
}
6770

6871
// Check that the clock may go out of the scope before the jump callback without leading in UB.
@@ -93,6 +96,11 @@ TEST_F(TestTime, time_sources) {
9396
Time steady_now = steady_clock.now();
9497
EXPECT_NE(0, steady_now.sec);
9598
EXPECT_NE(0u, steady_now.nanosec);
99+
100+
rclcpp::Clock raw_steady_clock(RCL_RAW_STEADY_TIME);
101+
Time raw_steady_now = raw_steady_clock.now();
102+
EXPECT_NE(0, raw_steady_now.sec);
103+
EXPECT_NE(0u, raw_steady_now.nanosec);
96104
}
97105

98106
static const int64_t HALF_SEC_IN_NS = RCUTILS_MS_TO_NS(500);
@@ -193,30 +201,47 @@ TEST_F(TestTime, operators) {
193201

194202
rclcpp::Time system_time(0, 0, RCL_SYSTEM_TIME);
195203
rclcpp::Time steady_time(0, 0, RCL_STEADY_TIME);
204+
rclcpp::Time raw_steady_time(0, 0, RCL_RAW_STEADY_TIME);
196205

197206
EXPECT_ANY_THROW((void)(system_time == steady_time));
207+
EXPECT_ANY_THROW((void)(system_time == raw_steady_time));
198208
EXPECT_ANY_THROW((void)(system_time != steady_time));
209+
EXPECT_ANY_THROW((void)(system_time != raw_steady_time));
199210
EXPECT_ANY_THROW((void)(system_time <= steady_time));
211+
EXPECT_ANY_THROW((void)(system_time <= raw_steady_time));
200212
EXPECT_ANY_THROW((void)(system_time >= steady_time));
213+
EXPECT_ANY_THROW((void)(system_time >= raw_steady_time));
201214
EXPECT_ANY_THROW((void)(system_time < steady_time));
215+
EXPECT_ANY_THROW((void)(system_time < raw_steady_time));
202216
EXPECT_ANY_THROW((void)(system_time > steady_time));
217+
EXPECT_ANY_THROW((void)(system_time > raw_steady_time));
203218
EXPECT_ANY_THROW((void)(system_time - steady_time));
219+
EXPECT_ANY_THROW((void)(system_time - raw_steady_time));
204220

205221
rclcpp::Clock system_clock(RCL_SYSTEM_TIME);
206222
rclcpp::Clock steady_clock(RCL_STEADY_TIME);
223+
rclcpp::Clock raw_steady_clock(RCL_RAW_STEADY_TIME);
207224

208225
rclcpp::Time now = system_clock.now();
209226
rclcpp::Time later = steady_clock.now();
227+
rclcpp::Time raw_later = raw_steady_clock.now();
210228

211229
EXPECT_ANY_THROW((void)(now == later));
230+
EXPECT_ANY_THROW((void)(now == raw_later));
212231
EXPECT_ANY_THROW((void)(now != later));
232+
EXPECT_ANY_THROW((void)(now != raw_later));
213233
EXPECT_ANY_THROW((void)(now <= later));
234+
EXPECT_ANY_THROW((void)(now <= raw_later));
214235
EXPECT_ANY_THROW((void)(now >= later));
236+
EXPECT_ANY_THROW((void)(now >= raw_later));
215237
EXPECT_ANY_THROW((void)(now < later));
238+
EXPECT_ANY_THROW((void)(now < raw_later));
216239
EXPECT_ANY_THROW((void)(now > later));
240+
EXPECT_ANY_THROW((void)(now > raw_later));
217241
EXPECT_ANY_THROW((void)(now - later));
242+
EXPECT_ANY_THROW((void)(now - raw_later));
218243

219-
for (auto time_source : {RCL_ROS_TIME, RCL_SYSTEM_TIME, RCL_STEADY_TIME}) {
244+
for (auto time_source : {RCL_ROS_TIME, RCL_SYSTEM_TIME, RCL_STEADY_TIME, RCL_RAW_STEADY_TIME}) {
220245
rclcpp::Time time = rclcpp::Time(0, 0, time_source);
221246
rclcpp::Time copy_constructor_time(time);
222247
rclcpp::Time assignment_op_time = rclcpp::Time(1, 0, time_source);
@@ -312,7 +337,7 @@ TEST_F(TestTime, seconds) {
312337
TEST_F(TestTime, test_max) {
313338
// Same clock types
314339
for (rcl_clock_type_t type = RCL_ROS_TIME;
315-
type != RCL_STEADY_TIME; type = static_cast<rcl_clock_type_t>(type + 1))
340+
type != RCL_RAW_STEADY_TIME; type = static_cast<rcl_clock_type_t>(type + 1))
316341
{
317342
const rclcpp::Time time_max = rclcpp::Time::max(type);
318343
const rclcpp::Time max_time(std::numeric_limits<int32_t>::max(), 999999999, type);
@@ -323,13 +348,22 @@ TEST_F(TestTime, test_max) {
323348
{
324349
const rclcpp::Time time_max = rclcpp::Time::max(RCL_ROS_TIME);
325350
const rclcpp::Time max_time(std::numeric_limits<int32_t>::max(), 999999999, RCL_STEADY_TIME);
351+
const rclcpp::Time raw_max_time(
352+
std::numeric_limits<int32_t>::max(), 999999999, RCL_RAW_STEADY_TIME);
326353
EXPECT_ANY_THROW((void)(time_max == max_time));
354+
EXPECT_ANY_THROW((void)(time_max == raw_max_time));
327355
EXPECT_ANY_THROW((void)(time_max != max_time));
356+
EXPECT_ANY_THROW((void)(time_max != raw_max_time));
328357
EXPECT_ANY_THROW((void)(time_max <= max_time));
358+
EXPECT_ANY_THROW((void)(time_max <= raw_max_time));
329359
EXPECT_ANY_THROW((void)(time_max >= max_time));
360+
EXPECT_ANY_THROW((void)(time_max >= raw_max_time));
330361
EXPECT_ANY_THROW((void)(time_max < max_time));
362+
EXPECT_ANY_THROW((void)(time_max < raw_max_time));
331363
EXPECT_ANY_THROW((void)(time_max > max_time));
364+
EXPECT_ANY_THROW((void)(time_max > raw_max_time));
332365
EXPECT_ANY_THROW((void)(time_max - max_time));
366+
EXPECT_ANY_THROW((void)(time_max - raw_max_time));
333367
}
334368
}
335369

@@ -433,6 +467,11 @@ TEST_F(TestClockSleep, bad_clock_type) {
433467
RCLCPP_EXPECT_THROW_EQ(
434468
clock.sleep_until(ros_until),
435469
std::runtime_error("until's clock type does not match this clock's type"));
470+
471+
rclcpp::Time raw_steady_until(54321, 0, RCL_RAW_STEADY_TIME);
472+
RCLCPP_EXPECT_THROW_EQ(
473+
clock.sleep_until(raw_steady_until),
474+
std::runtime_error("until's clock type does not match this clock's type"));
436475
}
437476

438477
TEST_F(TestClockSleep, sleep_until_invalid_context) {
@@ -493,13 +532,34 @@ TEST_F(TestClockSleep, sleep_until_basic_steady) {
493532
EXPECT_GE(steady_end - steady_start, std::chrono::milliseconds(milliseconds));
494533
}
495534

535+
TEST_F(TestClockSleep, sleep_until_basic_raw_steady) {
536+
const auto milliseconds = 300;
537+
rclcpp::Clock clock(RCL_RAW_STEADY_TIME);
538+
auto delay = rclcpp::Duration(0, RCUTILS_MS_TO_NS(milliseconds));
539+
auto sleep_until = clock.now() + delay;
540+
541+
auto steady_start = std::chrono::steady_clock::now();
542+
ASSERT_TRUE(clock.sleep_until(sleep_until));
543+
auto steady_end = std::chrono::steady_clock::now();
544+
545+
EXPECT_GE(clock.now(), sleep_until);
546+
EXPECT_GE(steady_end - steady_start, std::chrono::milliseconds(milliseconds));
547+
}
548+
496549
TEST_F(TestClockSleep, sleep_until_steady_past_returns_immediately) {
497550
rclcpp::Clock clock(RCL_STEADY_TIME);
498551
auto until = clock.now() - rclcpp::Duration(1000, 0);
499552
// This should return immediately, other possible behavior might be sleep forever and timeout
500553
ASSERT_TRUE(clock.sleep_until(until));
501554
}
502555

556+
TEST_F(TestClockSleep, sleep_until_raw_steady_past_returns_immediately) {
557+
rclcpp::Clock clock(RCL_RAW_STEADY_TIME);
558+
auto until = clock.now() - rclcpp::Duration(1000, 0);
559+
// This should return immediately, other possible behavior might be sleep forever and timeout
560+
ASSERT_TRUE(clock.sleep_until(until));
561+
}
562+
503563
TEST_F(TestClockSleep, sleep_until_system_past_returns_immediately) {
504564
rclcpp::Clock clock(RCL_SYSTEM_TIME);
505565
auto until = clock.now() - rclcpp::Duration(1000, 0);
@@ -660,6 +720,25 @@ TEST_F(TestClockSleep, sleep_for_basic_system) {
660720
EXPECT_GE(end - start, std::chrono::milliseconds(milliseconds));
661721
}
662722

723+
TEST_F(TestClockSleep, sleep_for_basic_raw_steady) {
724+
const auto milliseconds = 300;
725+
rclcpp::Clock clock(RCL_RAW_STEADY_TIME);
726+
auto rel_time = rclcpp::Duration(0, RCUTILS_MS_TO_NS(milliseconds));
727+
728+
auto steady_start = std::chrono::steady_clock::now();
729+
ASSERT_TRUE(clock.sleep_for(rel_time));
730+
auto steady_end = std::chrono::steady_clock::now();
731+
732+
EXPECT_GE(steady_end - steady_start, std::chrono::milliseconds(milliseconds));
733+
}
734+
735+
TEST_F(TestClockSleep, sleep_for_raw_steady_past_returns_immediately) {
736+
rclcpp::Clock clock(RCL_RAW_STEADY_TIME);
737+
auto rel_time = rclcpp::Duration(-1000, 0);
738+
// This should return immediately
739+
ASSERT_TRUE(clock.sleep_for(rel_time));
740+
}
741+
663742
TEST_F(TestClockSleep, sleep_for_basic_steady) {
664743
const auto milliseconds = 300;
665744
rclcpp::Clock clock(RCL_STEADY_TIME);

rclcpp/test/rclcpp/test_time_source.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,21 @@ TEST(TimeSource, invalid_clock_type_for_sim_time)
299299
rclcpp::shutdown();
300300
}
301301

302+
TEST(TimeSource, invalid_raw_steady_clock_type_for_sim_time)
303+
{
304+
rclcpp::init(0, nullptr);
305+
306+
rclcpp::NodeOptions options;
307+
options.clock_type(RCL_RAW_STEADY_TIME);
308+
auto node = std::make_shared<rclcpp::Node>("my_node", options);
309+
EXPECT_FALSE(
310+
node->set_parameter(
311+
rclcpp::Parameter(
312+
"use_sim_time", rclcpp::ParameterValue(
313+
true))).successful);
314+
rclcpp::shutdown();
315+
}
316+
302317
TEST_F(TestTimeSource, clock) {
303318
rclcpp::TimeSource ts(node);
304319
auto ros_clock = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);

0 commit comments

Comments
 (0)