Skip to content

feat(autoware_node): remove the lifecycle dependency #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions common/autoware_node/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ if(BUILD_TESTING)
target_include_directories(${TEST_NAME} PRIVATE src/include)
target_link_libraries(${TEST_NAME} ${PROJECT_NAME})
ament_target_dependencies(${TEST_NAME}
rclcpp
rclcpp_lifecycle)
rclcpp)
endforeach()
endif()

Expand Down
9 changes: 0 additions & 9 deletions common/autoware_node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,7 @@

AN is an `autoware.core` package designed to provide a base class for all future nodes in the
system.
It also inherits all lifecycle control capabilities of the base
class [LifecycleNode](https://docs.ros2.org/latest/api/rclcpp_lifecycle/classrclcpp__lifecycle_1_1LifecycleNode.html)

## Usage

Check the [autoware_test_node](../../demos/autoware_test_node/README.md) package for an example of how to use `autoware::Node`.

## Design

### Lifecycle

AN inherits from ROS 2 [rclcpp_lifecycle::LifecycleNode](https://design.ros2.org/articles/node_lifecycle.html) and has
all the basic functions of it.
9 changes: 2 additions & 7 deletions common/autoware_node/include/autoware/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,19 @@

#include "autoware/node/visibility_control.hpp"

#include <rclcpp_lifecycle/lifecycle_node.hpp>
#include <rclcpp/node.hpp>

#include <string>

namespace autoware::node
{
using CallbackReturn = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;

class Node : public rclcpp_lifecycle::LifecycleNode
class Node : public rclcpp::Node

Check warning on line 26 in common/autoware_node/include/autoware/node/node.hpp

View check run for this annotation

Codecov / codecov/patch

common/autoware_node/include/autoware/node/node.hpp#L26

Added line #L26 was not covered by tests
{
public:
AUTOWARE_NODE_PUBLIC
explicit Node(
const std::string & node_name, const std::string & ns = "",
const rclcpp::NodeOptions & options = rclcpp::NodeOptions());

protected:
CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
};
} // namespace autoware::node

Expand Down
4 changes: 2 additions & 2 deletions common/autoware_node/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<name>autoware_node</name>
<version>0.2.0</version>
<description>Autoware Node is an Autoware.Core package designed to provide a base class for all nodes in the system.</description>
<maintainer email="mfc@autoware.org">M. Fatih Cırıt</maintainer>
<maintainer email="mfc@autoware.org">Mete Fatih Cırıt</maintainer>
<license>Apache-2.0</license>

<buildtool_depend>ament_cmake_auto</buildtool_depend>
<buildtool_depend>autoware_cmake</buildtool_depend>

<depend>rclcpp_lifecycle</depend>
<depend>rclcpp</depend>

<test_depend>ament_cmake_ros</test_depend>
<test_depend>autoware_lint_common</test_depend>
Expand Down
12 changes: 2 additions & 10 deletions common/autoware_node/src/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,18 @@
// limitations under the License.

#include <autoware/node/node.hpp>
#include <rclcpp/rclcpp.hpp>
#include <rclcpp/node.hpp>

#include <string>

namespace autoware::node
{
Node::Node(
const std::string & node_name, const std::string & ns, const rclcpp::NodeOptions & options)
: LifecycleNode(node_name, ns, options)
: rclcpp::Node(node_name, ns, options)
{
RCLCPP_DEBUG(
get_logger(), "Node %s constructor was called.",
get_node_base_interface()->get_fully_qualified_name());
}

CallbackReturn Node::on_shutdown(const rclcpp_lifecycle::State & state)
{
RCLCPP_DEBUG(
get_logger(), "Node %s shutdown was called with state %s.",
get_node_base_interface()->get_fully_qualified_name(), state.label().c_str());
return CallbackReturn::SUCCESS;
}
} // namespace autoware::node
49 changes: 31 additions & 18 deletions common/autoware_node/test/test_an_init_shutdown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
#include <autoware/node/node.hpp>
#include <rclcpp/rclcpp.hpp>

#include <lifecycle_msgs/msg/state.hpp>

#include <gtest/gtest.h>

#include <memory>
#include <string>

class AutowareNodeInitShutdown : public ::testing::Test
{
Expand All @@ -31,30 +30,44 @@ class AutowareNodeInitShutdown : public ::testing::Test
rclcpp::NodeOptions node_options_an_;
};

// Helper function to wait until the executor starts spinning with a timeout.
bool wait_for_executor_spinning(
const std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> & executor,
std::chrono::milliseconds timeout)
{
auto start_time = std::chrono::steady_clock::now();
while (!executor->is_spinning()) {
if (std::chrono::steady_clock::now() - start_time > timeout) {
return false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return true;
}

TEST_F(AutowareNodeInitShutdown, NodeInitShutdown)
{
autoware::node::Node::SharedPtr autoware_node =
std::make_shared<autoware::node::Node>("test_node", "test_ns", node_options_an_);
const std::string node_name = "test_node";
const std::string node_ns = "test_ns";

auto autoware_node = std::make_shared<autoware::node::Node>(node_name, node_ns, node_options_an_);

auto executor = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
executor->add_node(autoware_node->get_node_base_interface());

std::thread thread_spin = std::thread([&executor]() { executor->spin(); });

ASSERT_EQ(
autoware_node->get_current_state().id(),
lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED);
// Start the executor in a separate thread.
std::thread executor_thread([executor]() { executor->spin(); });

auto state = autoware_node->shutdown();
ASSERT_EQ(autoware_node->get_fully_qualified_name(), "/" + node_ns + "/" + node_name);

ASSERT_EQ(state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_FINALIZED);
// Wait until the executor starts spinning (timeout after 2 seconds).
ASSERT_TRUE(wait_for_executor_spinning(executor, std::chrono::milliseconds(2000)))
<< "Executor did not start spinning within the expected timeout.";

// wait until executor is spinning
while (!executor->is_spinning()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
executor->cancel(); // make sure cancel is called after spin
if (thread_spin.joinable()) {
thread_spin.join();
executor->cancel();
if (executor_thread.joinable()) {
executor_thread.join();
}

ASSERT_FALSE(executor->is_spinning());
}
44 changes: 0 additions & 44 deletions demos/autoware_test_node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,3 @@ This package contains a simple example of how to use `autoware::Node`.
```bash
ros2 launch autoware_test_node autoware_test_node.launch.xml
```

### Lifecycle control

Information on Lifecycle nodes can be found [here](https://design.ros2.org/articles/node_lifecycle.html).

Output a list of nodes with lifecycle:

```console
$ ros2 lifecycle nodes
/test_ns1/test_node1
```

Get the current state of a node:

```console
$ ros2 lifecycle get /test_ns1/test_node1
unconfigured [1]
```

List the available transitions for the node:

```console
$ ros2 lifecycle list /test_ns1/test_node1
- configure [1]
Start: unconfigured
Goal: configuring
- shutdown [5]
Start: unconfigured
Goal: shuttingdown
```

Shutdown the node:

```console
$ ros2 lifecycle set /test_ns1/test_node1 shutdown
Transitioning successful
```

```console
$ ros2 lifecycle get /test_ns1/test_node1
finalized [4]
```

The node will remain alive in the `finalized` state until it is killed by the user.
3 changes: 1 addition & 2 deletions demos/autoware_test_node/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<name>autoware_test_node</name>
<version>0.2.0</version>
<description>Test package for Autoware Node.</description>
<maintainer email="mfc@autoware.org">M. Fatih Cırıt</maintainer>
<maintainer email="mfc@autoware.org">Mete Fatih Cırıt</maintainer>
<license>Apache-2.0</license>

<buildtool_depend>ament_cmake_auto</buildtool_depend>
Expand All @@ -13,7 +13,6 @@
<depend>autoware_node</depend>
<depend>rclcpp</depend>
<depend>rclcpp_components</depend>
<depend>rclcpp_lifecycle</depend>

<export>
<build_type>ament_cmake</build_type>
Expand Down
1 change: 0 additions & 1 deletion demos/autoware_test_node/src/include/test_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#define TEST_NODE_HPP_

#include <autoware/node/node.hpp>
#include <rclcpp_lifecycle/lifecycle_node.hpp>

namespace autoware::test_node
{
Expand Down
Loading