Skip to content

Commit 58ae127

Browse files
committed
(dev) composition over inheritance
1 parent 1a592d6 commit 58ae127

File tree

6 files changed

+84
-30
lines changed

6 files changed

+84
-30
lines changed

rclcpp_lifecycle/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ macro(targets)
5656
"rclcpp${target_suffix}"
5757
"std_msgs")
5858

59-
install(TARGETS rclcpp_lifecycle${target_suffix} lifecycle_talker${target_suffix}
59+
install(TARGETS
60+
rclcpp_lifecycle${target_suffix}
61+
lifecycle_talker${target_suffix}
6062
ARCHIVE DESTINATION lib
6163
LIBRARY DESTINATION lib
6264
RUNTIME DESTINATION bin

rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_manager.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,19 @@ class LIFECYCLE_EXPORT LifecycleManager : public LifecycleManagerInterface
6363
{
6464
public:
6565
using NodeInterfacePtr = std::shared_ptr<node::lifecycle::LifecycleNodeInterface>;
66+
using NodePtr = std::shared_ptr<node::lifecycle::LifecycleNode>;
6667

6768
LifecycleManager();
6869
~LifecycleManager();
6970

7071
void
71-
add_node_interface(const NodeInterfacePtr & node_interface);
72+
add_node_interface(const NodePtr & node);
7273

7374
void
74-
add_node_interface(const NodeInterfacePtr & node_interface,
75+
add_node_interface(const std::string & node_name, const NodeInterfacePtr & node_interface);
76+
77+
void
78+
add_node_interface(const std::string & node_name, const NodeInterfacePtr & node_interface,
7579
rcl_state_machine_t custom_state_machine);
7680

7781
template<typename T>

rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,35 +60,49 @@ class LifecycleNodeInterface
6060
virtual bool on_activate() {return true; }
6161
virtual bool on_deactivate() {return true; }
6262
virtual bool on_error() {return true; }
63-
// hardcoded mock
64-
// as we don't have a node base class yet
65-
virtual std::string get_name()
66-
{
67-
static auto counter = 0;
68-
std::string tmp_name = "my_node" + std::to_string(++counter);
69-
return tmp_name;
70-
}
7163
};
7264

7365
/**
7466
* @brief LifecycleNode as child class of rclcpp Node
7567
* has lifecycle nodeinterface for configuring this node.
7668
*/
77-
class LifecycleNode : public rclcpp::node::Node, public lifecycle::LifecycleNodeInterface
69+
class LifecycleNode : public lifecycle::LifecycleNodeInterface
7870
{
7971
public:
8072
using LifecyclePublisherWeakPtr =
8173
std::weak_ptr<rclcpp::publisher::lifecycle_interface::PublisherInterface>;
8274

8375
LIFECYCLE_EXPORT
8476
explicit LifecycleNode(const std::string & node_name, bool use_intra_process_comms = false)
85-
: Node(node_name, use_intra_process_comms)
86-
{
87-
}
77+
: base_interface_(std::make_shared<rclcpp::node::Node>(node_name, use_intra_process_comms)),
78+
communication_interface_(base_interface_) // MOCK as base/comms interface not done yet
79+
{}
8880

8981
LIFECYCLE_EXPORT
9082
~LifecycleNode() {}
9183

84+
// MOCK typedefs as node refactor not done yet
85+
using BaseInterface = rclcpp::node::Node;
86+
std::shared_ptr<BaseInterface>
87+
get_base_interface()
88+
{
89+
return base_interface_;
90+
}
91+
92+
// MOCK typedefs as node refactor not done yet
93+
using CommunicationInterface = rclcpp::node::Node;
94+
std::shared_ptr<CommunicationInterface>
95+
get_communication_interface()
96+
{
97+
return communication_interface_;
98+
}
99+
100+
std::string
101+
get_name()
102+
{
103+
return base_interface_->get_name();
104+
}
105+
92106
/**
93107
* @brief same API for creating publisher as regular Node
94108
*/
@@ -100,7 +114,7 @@ class LifecycleNode : public rclcpp::node::Node, public lifecycle::LifecycleNode
100114
std::shared_ptr<Alloc> allocator = nullptr)
101115
{
102116
// create regular publisher in rclcpp::Node
103-
auto pub = rclcpp::node::Node::create_publisher<MessageT, Alloc,
117+
auto pub = communication_interface_->create_publisher<MessageT, Alloc,
104118
rclcpp::publisher::LifecyclePublisher<MessageT, Alloc>>(
105119
topic_name, qos_profile, allocator);
106120

@@ -109,6 +123,16 @@ class LifecycleNode : public rclcpp::node::Node, public lifecycle::LifecycleNode
109123
return pub;
110124
}
111125

126+
template<typename CallbackType>
127+
typename rclcpp::timer::WallTimer<CallbackType>::SharedPtr
128+
create_wall_timer(
129+
std::chrono::nanoseconds period,
130+
CallbackType callback,
131+
rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr)
132+
{
133+
return communication_interface_->create_wall_timer(period, callback, group);
134+
}
135+
112136
LIFECYCLE_EXPORT
113137
virtual bool
114138
disable_communication()
@@ -138,6 +162,8 @@ class LifecycleNode : public rclcpp::node::Node, public lifecycle::LifecycleNode
138162
}
139163

140164
private:
165+
std::shared_ptr<BaseInterface> base_interface_;
166+
std::shared_ptr<CommunicationInterface> communication_interface_;
141167
// Placeholder for all pub/sub/srv/clients
142168
std::vector<LifecyclePublisherWeakPtr> weak_pubs_;
143169
};

rclcpp_lifecycle/src/rclcpp_lifecycle/lifecycle_manager.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,24 @@ LifecycleManager::LifecycleManager()
3030
LifecycleManager::~LifecycleManager() = default;
3131

3232
void
33-
LifecycleManager::add_node_interface(const NodeInterfacePtr & node_interface)
33+
LifecycleManager::add_node_interface(const NodePtr & node)
3434
{
35-
impl_->add_node_interface(node_interface);
35+
add_node_interface(node->get_base_interface()->get_name(), node);
3636
}
3737

3838
void
39-
LifecycleManager::add_node_interface(const NodeInterfacePtr & node_interface,
39+
LifecycleManager::add_node_interface(const std::string & node_name,
40+
const NodeInterfacePtr & node_interface)
41+
{
42+
impl_->add_node_interface(node_name, node_interface);
43+
}
44+
45+
void
46+
LifecycleManager::add_node_interface(const std::string & node_name,
47+
const NodeInterfacePtr & node_interface,
4048
rcl_state_machine_t custom_state_machine)
4149
{
42-
impl_->add_node_interface(node_interface, custom_state_machine);
50+
impl_->add_node_interface(node_name, node_interface, custom_state_machine);
4351
}
4452

4553
bool

rclcpp_lifecycle/src/rclcpp_lifecycle/lifecycle_manager_impl.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ class LIFECYCLE_EXPORT LifecycleManager::LifecycleManagerImpl
5050
~LifecycleManagerImpl() = default;
5151

5252
void
53-
add_node_interface(const NodeInterfacePtr & node_interface)
53+
add_node_interface(const std::string & node_name, const NodeInterfacePtr & node_interface)
5454
{
5555
rcl_state_machine_t state_machine = rcl_get_default_state_machine();
56-
add_node_interface(node_interface, state_machine);
56+
add_node_interface(node_name, node_interface, state_machine);
5757
}
5858

5959
void
60-
add_node_interface(const NodeInterfacePtr & node_interface,
60+
add_node_interface(const std::string & node_name, const NodeInterfacePtr & node_interface,
6161
rcl_state_machine_t custom_state_machine)
6262
{
6363
NodeStateMachine node_state_machine;
@@ -86,8 +86,7 @@ class LIFECYCLE_EXPORT LifecycleManager::LifecycleManagerImpl
8686
node_state_machine.cb_map[LifecycleTransitionsT::DEACTIVATING] = cb_deactivating;
8787
node_state_machine.cb_map[LifecycleTransitionsT::ERRORPROCESSING] = cb_error;
8888

89-
// TODO(karsten1987): clarify what do if node already exists
90-
auto node_name = node_interface->get_name();
89+
// TODO(karsten1987): clarify what do if node already exists;
9190
node_handle_map_[node_name] = node_state_machine;
9291
}
9392

rclcpp_lifecycle/src/rclcpp_lifecycle/lifecycle_talker.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#include "std_msgs/msg/string.hpp"
2727

28+
#define STRICTLY_DRY 0
29+
2830
class MyLifecycleNode : public rclcpp::node::lifecycle::LifecycleNode
2931
{
3032
public:
@@ -33,9 +35,16 @@ class MyLifecycleNode : public rclcpp::node::lifecycle::LifecycleNode
3335
{
3436
msg_ = std::make_shared<std_msgs::msg::String>();
3537

38+
#if STRICTLY_DRY
39+
// Version 1
40+
pub_ = this->get_communication_interface()->create_publisher<std_msgs::msg::String>("chatter");
41+
timer_ = this->get_communication_interface()->create_wall_timer(
42+
1_s, std::bind(&MyLifecycleNode::publish, this));
43+
#else
44+
// Version 2
3645
pub_ = this->create_publisher<std_msgs::msg::String>("chatter");
37-
3846
timer_ = this->create_wall_timer(1_s, std::bind(&MyLifecycleNode::publish, this));
47+
#endif
3948
}
4049

4150
void publish()
@@ -81,10 +90,16 @@ int main(int argc, char * argv[])
8190

8291
std::shared_ptr<MyLifecycleNode> lc_node = std::make_shared<MyLifecycleNode>("lc_talker");
8392

93+
#if STRICTLY_DRY
94+
auto node_name = lc_node->get_base_interface()->get_name();
95+
#else
96+
auto node_name = lc_node->get_name();
97+
#endif
98+
8499
rclcpp::lifecycle::LifecycleManager lm;
85100
lm.add_node_interface(lc_node);
86101

87-
exe.add_node(lc_node);
102+
exe.add_node(lc_node->get_communication_interface());
88103

89104
auto time_out_lambda = []() -> int {
90105
std::this_thread::sleep_for(std::chrono::seconds(10));
@@ -93,15 +108,15 @@ int main(int argc, char * argv[])
93108

94109
// configure
95110
// dummy mockup for now!
96-
lm.configure("my_node1");
111+
lm.configure(node_name);
97112
std::shared_future<int> time_out = std::async(std::launch::async, time_out_lambda);
98113
exe.spin_until_future_complete(time_out);
99114

100-
lm.activate("my_node1");
115+
lm.activate(node_name);
101116
time_out = std::async(std::launch::async, time_out_lambda);
102117
exe.spin_until_future_complete(time_out);
103118

104-
lm.deactivate("my_node1");
119+
lm.deactivate(node_name);
105120
time_out = std::async(std::launch::async, time_out_lambda);
106121
exe.spin_until_future_complete(time_out);
107122

0 commit comments

Comments
 (0)