[ROS2] Tutorial Intermediate - Composing multiple nodes in a single process
Composing multiple nodes in a single process
Run the demos
Discover available components
어떤 components가 등록되어있고 사용가능한지 알려면 아래의 코드를 사용하면 된다.
ros2 component types
Run-time composition using ROS services with a publisher and subscriber
먼저 component container를 실행하고
ros2 run rclcpp_components component_container
두번째 shell에서 ros2 command line tool을 통해 실행중인 container를 확인하자.
ros2 component list
두번째 shell에서 talker component를 실행해보자.
ros2 component load /ComponentManager composition composition::Talker
이제 첫번째 shell은 component가 로드됐음을 보여줄 것이다.
두번째 shell에 다른 command로 listener component를 실행해보자.
ros2 component load /ComponentManager composition composition::Listener
ros2 command line은 아래로 확인할 수 있다.
ros2 component list
Run-time composition using ROS services with a server and client
첫번째 shell
ros2 run rclcpp_components component_container
두번째 shell
ros2 component load /ComponentManager composition composition::Server
ros2 component load /ComponentManager composition composition::Client
client가 server에 request를 보내고 server는 request를 생성하고 응답한다.
client는 이 reponse를 받아 출력한다.
Compile-time composition with hardcoded nodes
같은 공유 라이브러리는 ROS interface없이 재사용하여 여러 component를 실행하는 단일 실행파일을 compile 할 수 있다.
실행파일은 4개의 component를 포함한다.(talker, listener, server, client)
ros2 run composition manual_composition
각 쌍(talker, listener와 server, client)의 message를 보여준다.
Run-time composition using dlopen
generic container 과정을 생성하고 ROS interface없이 라이브러리를 사용함으로써 run-time composition을 대체한다.
각 라이브러리를 열고 각 rclpp::Node instance를 생성한다.
ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so
이로써 shell은 각각 보내고 받는 메세지의 반복되는 출력을 보여준다.
Composition using launch actions
command line tool이 디버깅하고 진단하는데 유용하지만 component 세트를 실행하는 것이 더 편리하다.
이를 자동화하기 위해 launch file을 사용한다.
ros2 launch composition composition_demo.launch.py
Advanced Topics
Unloading components
첫번째 shell, component container를 시작하고
ros2 run rclcpp_components component_container
ros2 command line tool를 통해 container 를 실행하자.
ros2 component list
두번째 shell
ros2 component load /ComponentManager composition composition::Talker
ros2 component load /ComponentManager composition composition::Listener
component container로부터 node가 unload되도록 특정 ID를 사용해야 한다.
ros2 component unload /ComponentManager 1 2
Remapping container name and namespace
component maner name과 namespace는 standard command line argument로 재정의할 수 있다.
ros2 run rclcpp_components component_container --ros-args -r __node:=MyContainer -r __ns:=/ns
두번째 shell
ros2 component load /ns/MyContainer composition composition::Listener
Remap component names and namespaces
첫번째 shell
ros2 run rclcpp_components component_container
node name 재설정
ros2 component load /ComponentManager composition composition::Talker --node-name talker2
namespace 재설정
ros2 component load /ComponentManager composition composition::Talker --node-namespace /ns
node name, namespace 둘다 재설정
ros2 component load /ComponentManager composition composition::Talker --node-name talker3 --node-namespace /ns2
ros2를 실행해보면 바뀐 것을 볼 수 있다.
ros2 component list
Passing parameter values into components
ros2 component load command line은 임의의 파라미터가 노드를 통과하는 것을 도와준다.
ros2 component load /ComponentManager image_tools image_tools::Cam2Image -p burger_mode:=true
Passing additional arguments into components
ros2 component load command line은 특정 옵션이 component manager를 통과하는 것을 도와준다. command line 옵션은 node를 인스턴스화하는 것이다.
ros2 component load /ComponentManager composition composition::Talker -e use_intra_process_comms:=true
Composable nodes as shared libraries
패키지로부터 공유 라이브러리로써 노드를 내보내고 다른 패키지에서 노드를 사용하고 싶다면 downstream package에 있는 실제 target을 import하는 CMake file에 코드를 추가해야 한다.
그 후 생성된 파일을 install하고 생성된 파일을 추출한다.
Composing Non-Node Derived components
ROS2에서 component를 통해 system resource를 더 효과적으로 사용하고 특정 노드에 연결되지 않은 재사용 가능한 기능을 만드는 강력한 feature를 제공할 수 있다.
component를 사용하는 장점 중 하나는 필요에 따라 ROS 시스템에 로드할 수 있는 실행파일 또는 공유 라이브러리로 non-node를 생성할 수 있다는 것이다.
노드로부터 파생되지 않은 component를 만들기 위해서는 아래의 가이드라인을 따르면 된다.
1. argument로 const rclcpp::NodeOptions& 를 사용하는 constructor를 구현 한다.
2. NodeBaseInterface::SharedPtr를 return하는 get_node_base_interface() 방법을 구현한다.
interface를 제공하기 위해 constructor에서 생성한 get_node_base_interface()방법을 사용할 수 있다.
ROS2_Humble Documentation : https://docs.ros.org/en/humble/Tutorials/Intermediate.html