Skip to content

Commit 0fb8046

Browse files
Add ConditionWaitReturnCode for spin_until_complete
Signed-off-by: Christophe Bedard <[email protected]>
1 parent 36d56c5 commit 0fb8046

File tree

8 files changed

+121
-32
lines changed

8 files changed

+121
-32
lines changed

rclcpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(${PROJECT_NAME}_SRCS
4343
src/rclcpp/callback_group.cpp
4444
src/rclcpp/client.cpp
4545
src/rclcpp/clock.cpp
46+
src/rclcpp/condition_wait_return_code.cpp
4647
src/rclcpp/context.cpp
4748
src/rclcpp/contexts/default_context.cpp
4849
src/rclcpp/create_generic_client.cpp
@@ -73,7 +74,6 @@ set(${PROJECT_NAME}_SRCS
7374
src/rclcpp/expand_topic_or_service_name.cpp
7475
src/rclcpp/experimental/executors/events_executor/events_executor.cpp
7576
src/rclcpp/experimental/timers_manager.cpp
76-
src/rclcpp/future_return_code.cpp
7777
src/rclcpp/generic_client.cpp
7878
src/rclcpp/generic_publisher.cpp
7979
src/rclcpp/generic_subscription.cpp
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2014 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef RCLCPP__CONDITION_WAIT_RETURN_CODE_HPP_
16+
#define RCLCPP__CONDITION_WAIT_RETURN_CODE_HPP_
17+
18+
#include <iostream>
19+
#include <string>
20+
21+
#include "rclcpp/visibility_control.hpp"
22+
23+
namespace rclcpp
24+
{
25+
26+
/// Return codes to be used with spin_until_complete.
27+
/**
28+
* SUCCESS: The condition wait is complete. This does not indicate that the operation succeeded.
29+
* INTERRUPTED: The condition wait is not complete, spinning was interrupted by Ctrl-C or another
30+
* error.
31+
* TIMEOUT: Spinning timed out.
32+
*/
33+
enum class ConditionWaitReturnCode {SUCCESS, INTERRUPTED, TIMEOUT};
34+
35+
/// Stream operator for ConditionWaitReturnCode.
36+
RCLCPP_PUBLIC
37+
std::ostream &
38+
operator<<(std::ostream & os, const ConditionWaitReturnCode & condition_wait_return_code);
39+
40+
/// String conversion function for ConditionWaitReturnCode.
41+
RCLCPP_PUBLIC
42+
std::string
43+
to_string(const ConditionWaitReturnCode & condition_wait_return_code);
44+
45+
} // namespace rclcpp
46+
47+
#endif // RCLCPP__CONDITION_WAIT_RETURN_CODE_HPP_

rclcpp/include/rclcpp/executor.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "rclcpp/executors/executor_notify_waitable.hpp"
3333
#include "rcpputils/scope_exit.hpp"
3434

35+
#include "rclcpp/condition_wait_return_code.hpp"
3536
#include "rclcpp/context.hpp"
3637
#include "rclcpp/contexts/default_context.hpp"
3738
#include "rclcpp/guard_condition.hpp"
@@ -361,7 +362,7 @@ class Executor
361362
* \return The return code, one of `SUCCESS`, `INTERRUPTED`, or `TIMEOUT`.
362363
*/
363364
template<typename TimeRepT = int64_t, typename TimeT = std::milli>
364-
FutureReturnCode
365+
ConditionWaitReturnCode
365366
spin_until_complete(
366367
const std::function<bool(void)> & condition,
367368
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
@@ -376,7 +377,7 @@ class Executor
376377

377378
// Preliminary check, finish if condition is done already.
378379
if (condition()) {
379-
return FutureReturnCode::SUCCESS;
380+
return ConditionWaitReturnCode::SUCCESS;
380381
}
381382

382383
if (spinning.exchange(true)) {
@@ -388,7 +389,7 @@ class Executor
388389
spin_once_impl(timeout_left);
389390

390391
if (condition()) {
391-
return FutureReturnCode::SUCCESS;
392+
return ConditionWaitReturnCode::SUCCESS;
392393
}
393394
// If the original timeout is < 0, then this is blocking, never TIMEOUT.
394395
if (timeout_ns < std::chrono::nanoseconds::zero()) {
@@ -397,14 +398,14 @@ class Executor
397398
// Otherwise check if we still have time to wait, return TIMEOUT if not.
398399
auto now = std::chrono::steady_clock::now();
399400
if (now >= end_time) {
400-
return FutureReturnCode::TIMEOUT;
401+
return ConditionWaitReturnCode::TIMEOUT;
401402
}
402403
// Subtract the elapsed time from the original timeout.
403404
timeout_left = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - now);
404405
}
405406

406407
// The condition did not pass before ok() returned false, return INTERRUPTED.
407-
return FutureReturnCode::INTERRUPTED;
408+
return ConditionWaitReturnCode::INTERRUPTED;
408409
}
409410

410411
/// Spin (blocking) for at least the given amount of duration.
@@ -413,7 +414,7 @@ class Executor
413414
*/
414415
template<typename TimeRepT = int64_t, typename TimeT = std::milli>
415416
void
416-
spin_for(std::chrono::duration<TimeRepT, TimeT> timeout duration)
417+
spin_for(std::chrono::duration<TimeRepT, TimeT> duration)
417418
{
418419
(void)spin_until_complete([]() {return false;}, duration);
419420
}

rclcpp/include/rclcpp/executors.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#include <future>
1919
#include <memory>
2020

21+
#include "rclcpp/condition_wait_return_code.hpp"
2122
#include "rclcpp/executors/multi_threaded_executor.hpp"
2223
#include "rclcpp/executors/single_threaded_executor.hpp"
2324
#include "rclcpp/executors/static_single_threaded_executor.hpp"
2425
#include "rclcpp/experimental/executors/events_executor/events_executor.hpp"
26+
#include "rclcpp/future_return_code.hpp"
2527
#include "rclcpp/node.hpp"
2628
#include "rclcpp/utilities.hpp"
2729
#include "rclcpp/visibility_control.hpp"
@@ -79,7 +81,7 @@ using rclcpp::executors::SingleThreadedExecutor;
7981
* \return The return code, one of `SUCCESS`, `INTERRUPTED`, or `TIMEOUT`.
8082
*/
8183
template<typename TimeRepT = int64_t, typename TimeT = std::milli>
82-
rclcpp::FutureReturnCode
84+
rclcpp::ConditionWaitReturnCode
8385
spin_node_until_complete(
8486
rclcpp::Executor & executor,
8587
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
@@ -95,7 +97,7 @@ spin_node_until_complete(
9597
}
9698

9799
template<typename NodeT = rclcpp::Node, typename TimeRepT = int64_t, typename TimeT = std::milli>
98-
rclcpp::FutureReturnCode
100+
rclcpp::ConditionWaitReturnCode
99101
spin_node_until_complete(
100102
rclcpp::Executor & executor,
101103
std::shared_ptr<NodeT> node_ptr,
@@ -156,7 +158,7 @@ spin_node_until_future_complete(
156158
} // namespace executors
157159

158160
template<typename TimeRepT = int64_t, typename TimeT = std::milli>
159-
rclcpp::FutureReturnCode
161+
rclcpp::ConditionWaitReturnCode
160162
spin_until_complete(
161163
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
162164
const std::function<bool(void)> & condition,
@@ -167,7 +169,7 @@ spin_until_complete(
167169
}
168170

169171
template<typename NodeT = rclcpp::Node, typename TimeRepT = int64_t, typename TimeT = std::milli>
170-
rclcpp::FutureReturnCode
172+
rclcpp::ConditionWaitReturnCode
171173
spin_until_complete(
172174
std::shared_ptr<NodeT> node_ptr,
173175
const std::function<bool(void)> & condition,

rclcpp/include/rclcpp/future_return_code.hpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <iostream>
1919
#include <string>
2020

21+
#include "rclcpp/condition_wait_return_code.hpp"
2122
#include "rclcpp/visibility_control.hpp"
2223

2324
namespace rclcpp
@@ -30,17 +31,7 @@ namespace rclcpp
3031
* INTERRUPTED: The future is not complete, spinning was interrupted by Ctrl-C or another error.
3132
* TIMEOUT: Spinning timed out.
3233
*/
33-
enum class FutureReturnCode {SUCCESS, INTERRUPTED, TIMEOUT};
34-
35-
/// Stream operator for FutureReturnCode.
36-
RCLCPP_PUBLIC
37-
std::ostream &
38-
operator<<(std::ostream & os, const FutureReturnCode & future_return_code);
39-
40-
/// String conversion function for FutureReturnCode.
41-
RCLCPP_PUBLIC
42-
std::string
43-
to_string(const FutureReturnCode & future_return_code);
34+
using FutureReturnCode = ConditionWaitReturnCode;
4435

4536
} // namespace rclcpp
4637

rclcpp/src/rclcpp/future_return_code.cpp renamed to rclcpp/src/rclcpp/condition_wait_return_code.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,31 @@
1616
#include <string>
1717
#include <type_traits>
1818

19-
#include "rclcpp/future_return_code.hpp"
19+
#include "rclcpp/condition_wait_return_code.hpp"
2020

2121
namespace rclcpp
2222
{
2323

2424
std::ostream &
25-
operator<<(std::ostream & os, const rclcpp::FutureReturnCode & future_return_code)
25+
operator<<(std::ostream & os, const rclcpp::ConditionWaitReturnCode & condition_wait_return_code)
2626
{
27-
return os << to_string(future_return_code);
27+
return os << to_string(condition_wait_return_code);
2828
}
2929

3030
std::string
31-
to_string(const rclcpp::FutureReturnCode & future_return_code)
31+
to_string(const rclcpp::ConditionWaitReturnCode & condition_wait_return_code)
3232
{
33-
using enum_type = std::underlying_type<FutureReturnCode>::type;
33+
using enum_type = std::underlying_type<ConditionWaitReturnCode>::type;
3434
std::string prefix = "Unknown enum value (";
35-
std::string ret_as_string = std::to_string(static_cast<enum_type>(future_return_code));
36-
switch (future_return_code) {
37-
case FutureReturnCode::SUCCESS:
35+
std::string ret_as_string = std::to_string(static_cast<enum_type>(condition_wait_return_code));
36+
switch (condition_wait_return_code) {
37+
case ConditionWaitReturnCode::SUCCESS:
3838
prefix = "SUCCESS (";
3939
break;
40-
case FutureReturnCode::INTERRUPTED:
40+
case ConditionWaitReturnCode::INTERRUPTED:
4141
prefix = "INTERRUPTED (";
4242
break;
43-
case FutureReturnCode::TIMEOUT:
43+
case ConditionWaitReturnCode::TIMEOUT:
4444
prefix = "TIMEOUT (";
4545
break;
4646
}

rclcpp/test/rclcpp/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ ament_add_gtest(test_function_traits test_function_traits.cpp)
109109
if(TARGET test_function_traits)
110110
target_link_libraries(test_function_traits ${PROJECT_NAME})
111111
endif()
112+
ament_add_gtest(
113+
test_condition_wait_return_code
114+
test_condition_wait_return_code.cpp)
115+
if(TARGET test_condition_wait_return_code)
116+
target_link_libraries(test_condition_wait_return_code ${PROJECT_NAME})
117+
endif()
112118
ament_add_gtest(
113119
test_future_return_code
114120
test_future_return_code.cpp)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2024 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <gtest/gtest.h>
16+
17+
#include <sstream>
18+
#include <string>
19+
20+
#include "rclcpp/condition_wait_return_code.hpp"
21+
22+
TEST(TestConditionWaitReturnCode, to_string) {
23+
EXPECT_EQ(
24+
"Unknown enum value (-1)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode(-1)));
25+
EXPECT_EQ(
26+
"SUCCESS (0)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode::SUCCESS));
27+
EXPECT_EQ(
28+
"INTERRUPTED (1)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode::INTERRUPTED));
29+
EXPECT_EQ(
30+
"TIMEOUT (2)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode::TIMEOUT));
31+
EXPECT_EQ(
32+
"Unknown enum value (3)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode(3)));
33+
EXPECT_EQ(
34+
"Unknown enum value (100)", rclcpp::to_string(rclcpp::ConditionWaitReturnCode(100)));
35+
}
36+
37+
TEST(TestConditionWaitReturnCode, ostream) {
38+
std::ostringstream ostream;
39+
40+
ostream << rclcpp::ConditionWaitReturnCode::SUCCESS;
41+
ASSERT_EQ("SUCCESS (0)", ostream.str());
42+
}

0 commit comments

Comments
 (0)