├── ch7 ├── vendor_pkgs │ ├── COLCON_IGNORE │ ├── grpc_vendor │ │ ├── package.xml │ │ └── CMakeLists.txt │ ├── mpg123_vendor │ │ ├── package.xml │ │ └── CMakeLists.txt │ └── opencv_vendor │ │ ├── package.xml │ │ └── CMakeLists.txt ├── sensor │ ├── ch7_msgfltr_py │ │ ├── ch7_msgfltr_py │ │ │ └── __init__.py │ │ ├── resource │ │ │ └── ch7_msgfltr_py │ │ ├── setup.cfg │ │ ├── package.xml │ │ ├── setup.py │ │ └── test │ │ │ ├── test_copyright.py │ │ │ ├── test_pep257.py │ │ │ └── test_flake8.py │ └── ch7_msgfltr_cpp │ │ ├── package.xml │ │ └── CMakeLists.txt └── diagnostics │ └── ch7_diagnostics_cpp │ ├── param │ └── updater.yaml │ ├── package.xml │ ├── CMakeLists.txt │ ├── launch │ └── temp_analysis.launch.py │ └── src │ └── freq_checker.cpp ├── ch2 ├── node │ ├── ch2_node_py │ │ ├── resource │ │ │ └── ch2_node_py │ │ ├── ch2_node_py │ │ │ ├── __init__.py │ │ │ ├── node2gons.py │ │ │ └── node2go.py │ │ ├── setup.cfg │ │ ├── package.xml │ │ ├── setup.py │ │ └── test │ │ │ ├── test_pep257.py │ │ │ ├── test_flake8.py │ │ │ └── test_copyright.py │ └── ch2_node_cpp │ │ ├── package.xml │ │ ├── src │ │ ├── main.cpp │ │ ├── main2.cpp │ │ ├── node2go.cpp │ │ ├── getid.cpp │ │ ├── global_arg.cpp │ │ ├── multinode.cpp │ │ ├── lifecyclenode2go.cpp │ │ └── multilifecyclenode.cpp │ │ ├── include │ │ └── ch2_node_cpp │ │ │ ├── node2go.hpp │ │ │ └── lifecyclenode2go.hpp │ │ └── CMakeLists.txt └── package │ ├── ch2_pkg_py │ ├── resource │ │ └── ch2_pkg_py │ ├── ch2_pkg_py │ │ ├── __init__.py │ │ └── pkg2go.py │ ├── setup.cfg │ ├── package.xml │ ├── setup.py │ └── test │ │ ├── test_pep257.py │ │ ├── test_flake8.py │ │ └── test_copyright.py │ └── ch2_pkg_cpp │ ├── package.xml │ ├── src │ ├── main.cpp │ └── pkg2go.cpp │ ├── include │ └── ch2_pkg_cpp │ │ └── pkg2go.hpp │ └── CMakeLists.txt ├── ch3 ├── param │ ├── ch3_param_py │ │ ├── ch3_param_py │ │ │ ├── __init__.py │ │ │ └── soliloquist.py │ │ ├── resource │ │ │ └── ch3_param_py │ │ ├── setup.cfg │ │ ├── param │ │ │ └── earth_param.yaml │ │ ├── package.xml │ │ ├── test │ │ │ ├── test_copyright.py │ │ │ ├── test_pep257.py │ │ │ └── test_flake8.py │ │ └── setup.py │ ├── ch3_param_bringup │ │ ├── ch3_param_bringup │ │ │ └── __init__.py │ │ ├── resource │ │ │ └── ch3_param_bringup │ │ ├── setup.cfg │ │ ├── param │ │ │ └── default_param.yaml │ │ ├── package.xml │ │ ├── test │ │ │ ├── test_copyright.py │ │ │ ├── test_pep257.py │ │ │ └── test_flake8.py │ │ ├── setup.py │ │ └── launch │ │ │ └── bringup.launch.py │ └── ch3_param_cpp │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ └── soliloquist.cpp ├── logging │ ├── ch3_logging_py │ │ ├── ch3_logging_py │ │ │ ├── __init__.py │ │ │ └── logger_test.py │ │ ├── resource │ │ │ └── ch3_logging_py │ │ ├── setup.cfg │ │ ├── package.xml │ │ ├── setup.py │ │ └── test │ │ │ ├── test_pep257.py │ │ │ ├── test_flake8.py │ │ │ └── test_copyright.py │ └── ch3_logging_cpp │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ ├── stuck_logger.cpp │ │ └── logger_test.cpp ├── plugin │ ├── ch3_plugin_beta │ │ ├── beta_defines.xml │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ │ └── pluginbeta.cpp │ ├── ch3_plugin_alpha │ │ ├── alpha_defines.xml │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ │ └── pluginalpha.cpp │ ├── ch3_plugin_base │ │ ├── CMakeLists.txt │ │ ├── package.xml │ │ └── include │ │ │ └── ch3_plugin_base │ │ │ └── pluginbase.hpp │ └── ch3_plugin_main │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ ├── withnode.cpp │ │ └── withoutnode.cpp ├── launch │ └── ch3_launch │ │ ├── CMakeLists.txt │ │ ├── package.xml │ │ └── launch │ │ ├── multi_pkg.launch.py │ │ ├── singlexec.launch.py │ │ ├── changed.singlexec.launch.py │ │ ├── multi_exec.launch.py │ │ └── mixed.launch.py └── component │ └── ch3_component │ ├── package.xml │ ├── CMakeLists.txt │ ├── src │ ├── com2.cpp │ └── com1.cpp │ └── launch │ └── composition.launch.py ├── ch4 ├── topic │ ├── ch4_topic_py │ │ ├── ch4_topic_py │ │ │ ├── __init__.py │ │ │ └── self_node.py │ │ ├── resource │ │ │ └── ch4_topic_py │ │ ├── setup.cfg │ │ ├── package.xml │ │ ├── setup.py │ │ └── test │ │ │ ├── test_copyright.py │ │ │ ├── test_pep257.py │ │ │ └── test_flake8.py │ └── ch4_topic_cpp │ │ ├── package.xml │ │ ├── src │ │ ├── sub_node.cpp │ │ ├── sub_statistics.cpp │ │ ├── loan_pub.cpp │ │ ├── pub_node.cpp │ │ ├── self_node.cpp │ │ └── intra_nodes.cpp │ │ └── CMakeLists.txt └── service │ ├── ch4_service_py │ ├── ch4_service_py │ │ ├── __init__.py │ │ └── self_service.py │ ├── resource │ │ └── ch4_service_py │ ├── setup.cfg │ ├── package.xml │ ├── setup.py │ └── test │ │ ├── test_pep257.py │ │ ├── test_flake8.py │ │ └── test_copyright.py │ └── ch4_service_cpp │ ├── package.xml │ ├── CMakeLists.txt │ └── src │ └── single_node.cpp ├── ch5 ├── action │ ├── ch5_action_py │ │ ├── resource │ │ │ └── ch5_action_py │ │ ├── ch5_action_py │ │ │ ├── __init__.py │ │ │ └── self_node.py │ │ ├── setup.cfg │ │ ├── setup.py │ │ ├── package.xml │ │ └── test │ │ │ ├── test_copyright.py │ │ │ ├── test_pep257.py │ │ │ └── test_flake8.py │ ├── ch5_action_interfaces │ │ ├── action │ │ │ └── Count.action │ │ ├── CMakeLists.txt │ │ └── package.xml │ └── ch5_action_cpp │ │ ├── package.xml │ │ ├── CMakeLists.txt │ │ └── src │ │ └── wrapped_action.cpp ├── interface │ └── ch5_v_interfaces │ │ ├── srv │ │ ├── GetVelocity.srv │ │ └── SetVelocityLimit.srv │ │ ├── action │ │ └── SpeedUpTo.action │ │ ├── msg │ │ └── SE3Velocity.msg │ │ ├── CMakeLists.txt │ │ └── package.xml └── tf2 │ └── ch5_tf2_cpp │ ├── package.xml │ ├── CMakeLists.txt │ └── src │ ├── dynamic_transform.cpp │ └── static_transform.cpp ├── .gitignore ├── doc ├── cover.jpg └── cover_theme.jpg ├── ch6 ├── decom.yaml ├── ch6_debug_cpp │ ├── package.xml │ ├── CMakeLists.txt │ ├── launch │ │ └── debug.py │ └── src │ │ └── faultcode.cpp ├── ch6_unittest_cpp │ ├── package.xml │ ├── include │ │ └── ch6_unittest_cpp │ │ │ └── monkey.hpp │ ├── CMakeLists.txt │ ├── src │ │ └── monkey.cpp │ └── test │ │ └── monkey_test.cpp └── ch6_bag_cpp │ ├── package.xml │ ├── CMakeLists.txt │ └── src │ └── pubdata.cpp ├── depends.repos └── .github └── workflows └── ci.yml /ch7/vendor_pkgs/COLCON_IGNORE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/resource/ch2_node_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/resource/ch2_pkg_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/ch2_node_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/ch2_pkg_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/ch3_param_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/resource/ch3_param_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/ch4_topic_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/resource/ch4_topic_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/resource/ch5_action_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/ch3_logging_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/resource/ch3_logging_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/ch4_service_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/resource/ch4_service_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/ch5_action_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/ch7_msgfltr_py/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/resource/ch7_msgfltr_py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/ch3_param_bringup/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/resource/ch3_param_bringup: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | install 3 | log 4 | .vscode 5 | .pyc 6 | __pycache__ 7 | -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/srv/GetVelocity.srv: -------------------------------------------------------------------------------- 1 | --- 2 | SE3Velocity velocity 3 | -------------------------------------------------------------------------------- /doc/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homalozoa/ros2_for_beginners_code/HEAD/doc/cover.jpg -------------------------------------------------------------------------------- /doc/cover_theme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homalozoa/ros2_for_beginners_code/HEAD/doc/cover_theme.jpg -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/srv/SetVelocityLimit.srv: -------------------------------------------------------------------------------- 1 | SE3Velocity max_velocity 2 | --- 3 | bool succeed 4 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch2_node_py 3 | [install] 4 | install_scripts=$base/lib/ch2_node_py 5 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch2_pkg_py 3 | [install] 4 | install_scripts=$base/lib/ch2_pkg_py 5 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_interfaces/action/Count.action: -------------------------------------------------------------------------------- 1 | uint32 goal_count 2 | --- 3 | uint32 global_count 4 | --- 5 | uint32 local_count 6 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch3_param_py 3 | [install] 4 | install_scripts=$base/lib/ch3_param_py 5 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch4_topic_py 3 | [install] 4 | install_scripts=$base/lib/ch4_topic_py 5 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch5_action_py 3 | [install] 4 | install_scripts=$base/lib/ch5_action_py 5 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch7_msgfltr_py 3 | [install] 4 | install_scripts=$base/lib/ch7_msgfltr_py 5 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch3_logging_py 3 | [install] 4 | install_scripts=$base/lib/ch3_logging_py 5 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch4_service_py 3 | [install] 4 | install_scripts=$base/lib/ch4_service_py 5 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/ch3_param_bringup 3 | [install] 4 | install_scripts=$base/lib/ch3_param_bringup 5 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/param/earth_param.yaml: -------------------------------------------------------------------------------- 1 | py_soliloquist: 2 | ros__parameters: 3 | time_cycle_s: 1.5 4 | output_str: "Hello earth" 5 | -------------------------------------------------------------------------------- /ch6/decom.yaml: -------------------------------------------------------------------------------- 1 | output_bags: 2 | - uri: compressed 3 | storage_id: sqlite3 4 | all: true 5 | compression_mode: file 6 | compression_format: zstd 7 | -------------------------------------------------------------------------------- /depends.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | depends/diagnostics: 3 | type: git 4 | url: https://github.com/ros/diagnostics.git 5 | version: ros2-devel 6 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/param/default_param.yaml: -------------------------------------------------------------------------------- 1 | py_soliloquist: 2 | ros__parameters: 3 | time_cycle_s: 3.0 4 | output_str: "Hello Moon" 5 | -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/action/SpeedUpTo.action: -------------------------------------------------------------------------------- 1 | SE3Velocity goal_velocity 2 | --- 3 | SE3Velocity final_velocity 4 | --- 5 | SE3Velocity current_velocity 6 | -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/msg/SE3Velocity.msg: -------------------------------------------------------------------------------- 1 | # SE3 velocity 2 | # 3 | float64 linear_x 4 | float64 linear_y 5 | float64 linear_z 6 | # 7 | float64 angular_x 8 | float64 angular_y 9 | float64 angular_z 10 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_beta/beta_defines.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Beta test plugin 4 | 5 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_interfaces/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch5_action_interfaces) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(rosidl_default_generators REQUIRED) 6 | 7 | rosidl_generate_interfaces(${PROJECT_NAME} 8 | "action/Count.action") 9 | 10 | ament_export_dependencies(rosidl_default_runtime) 11 | ament_package() 12 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_alpha/alpha_defines.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Alpha A plugin 4 | 5 | 6 | Alpha B plugin 7 | 8 | -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch5_v_interfaces) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(rosidl_default_generators REQUIRED) 6 | 7 | rosidl_generate_interfaces(${PROJECT_NAME} 8 | "msg/SE3Velocity.msg" 9 | "srv/GetVelocity.srv" 10 | "srv/SetVelocityLimit.srv" 11 | "action/SpeedUpTo.action") 12 | 13 | ament_export_dependencies(rosidl_default_runtime) 14 | ament_package() 15 | -------------------------------------------------------------------------------- /ch7/diagnostics/ch7_diagnostics_cpp/param/updater.yaml: -------------------------------------------------------------------------------- 1 | analyzers: 2 | ros__parameters: 3 | path: TemperatureSensor 4 | pub_rate: 2.0 5 | other_as_errors: false 6 | standalone_sensors: 7 | type: diagnostic_aggregator/GenericAnalyzer 8 | path: SensorStandalone 9 | contains: [ '/standalone' ] 10 | num_items: 1 11 | in_class_sensors: 12 | type: diagnostic_aggregator/GenericAnalyzer 13 | path: SensorInClass 14 | contains: [ '/class' ] 15 | num_items: 2 16 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_launch) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | 11 | install(DIRECTORY launch 12 | DESTINATION share/${PROJECT_NAME}/ 13 | ) 14 | 15 | if(BUILD_TESTING) 16 | find_package(ament_lint_auto REQUIRED) 17 | ament_lint_auto_find_test_dependencies() 18 | endif() 19 | 20 | ament_package() 21 | -------------------------------------------------------------------------------- /ch6/ch6_debug_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch6_debug_cpp 5 | 0.0.1 6 | Debug demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch2_pkg_cpp 5 | 0.0.1 6 | C++ ament package demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_plugin_base) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | 21 | include_directories(include) 22 | 23 | install(DIRECTORY include/ 24 | DESTINATION include/ 25 | ) 26 | 27 | ament_export_include_directories(include) 28 | ament_package() 29 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_base/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_plugin_base 5 | 0.0.1 6 | Base package for testing plugin 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/grpc_vendor/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | grpc_vendor 5 | 0.0.1 6 | Vendor library for GRPC of ROS 2. 7 | homalozoa 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/mpg123_vendor/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | mpg123_vendor 5 | 0.0.1 6 | Vendor library for mpg123 of ROS 2. 7 | homalozoa 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/opencv_vendor/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | opencv_vendor 5 | 0.0.1 6 | Vendor library for OpenCV of CyberDog. 7 | homalozoa 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | 12 | ament_lint_auto 13 | ament_lint_common 14 | 15 | 16 | ament_cmake 17 | 18 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_logging_py 5 | 0.0.1 6 | Python logging demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_param_py 5 | 0.0.1 6 | Package for testing parameters in Node 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch4_topic_cpp 5 | 0.0.1 6 | ROS 2 topic demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch6/ch6_unittest_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch6_unittest_cpp 5 | 0.0.1 6 | Unit test demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_param_cpp 5 | 0.0.1 6 | Package for testing parameters in Node 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch2_node_py 5 | 0.0.1 6 | Python node demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | rclpy 11 | 12 | ament_copyright 13 | ament_flake8 14 | ament_pep257 15 | python3-pytest 16 | 17 | 18 | ament_python 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_logging_cpp 5 | 0.0.1 6 | ROS 2 logging demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_param_bringup 5 | 0.0.1 6 | Package for testing parameters in Launch 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch4_service_cpp 5 | 0.0.1 6 | ROS 2 service demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch7_msgfltr_py 5 | 0.0.1 6 | ROS 2 message filters demo wroten in Python. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch2_node_cpp 5 | 0.0.1 6 | C++ node demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | rclcpp_lifecycle 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | 22 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch2_pkg_py 5 | 0.0.1 6 | Python ament package demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ch2_pkg_cpp 11 | 12 | ament_copyright 13 | ament_flake8 14 | ament_pep257 15 | python3-pytest 16 | 17 | 18 | ament_python 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch3/component/ch3_component/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_component 5 | 0.0.1 6 | Component demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | rclcpp_components 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | 22 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch7_msgfltr_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='ROS 2 message filters demo wroten in Python.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | ], 24 | }, 25 | ) 26 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch4_service_py 5 | 0.0.1 6 | ROS 2 service demo wroten in Python. 7 | homalozoa 8 | Apache-2.0 9 | 10 | rclpy 11 | 12 | ament_copyright 13 | ament_flake8 14 | ament_pep257 15 | python3-pytest 16 | 17 | 18 | ament_python 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch4_topic_py 5 | 0.0.1 6 | ROS 2 topic demo wroten in Python. 7 | homalozoa 8 | Apache-2.0 9 | 10 | rclpy 11 | 12 | ament_copyright 13 | ament_flake8 14 | ament_pep257 15 | python3-pytest 16 | 17 | 18 | ament_python 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch2_pkg_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='Python ament package demo.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'pkg2go = ch2_pkg_py.pkg2go:main', 24 | ], 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch3_logging_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='Python logging demo.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'logger_test=ch3_logging_py.logger_test:main' 24 | ], 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_beta/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_plugin_beta 5 | 0.0.1 6 | Plugin package for testing plugin 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ch3_plugin_base 13 | rclcpp 14 | pluginlib 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch4_topic_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='ROS 2 topic demo wroten in Python.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'topic_pub_py = ch4_topic_py.self_node:main', 24 | ], 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_alpha/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_plugin_alpha 5 | 0.0.1 6 | Plugin package for testing plugin 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ch3_plugin_base 13 | rclcpp 14 | pluginlib 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch5_action_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='ROS 2 action demo wroten in Python.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'self_action_py = ch5_action_py.self_node:main', 24 | ], 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /ch6/ch6_bag_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch6_bag_cpp 5 | 0.0.1 6 | Using rosbag2 API demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | rcpputils 14 | rcutils 15 | rosbag2_cpp 16 | 17 | ament_lint_auto 18 | ament_lint_common 19 | 20 | 21 | ament_cmake 22 | 23 | 24 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch4_service_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='ROS 2 service demo wroten in Python.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'self_service = ch4_service_py.self_service:main', 24 | ], 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch5_action_cpp 5 | 0.0.1 6 | ROS 2 action demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | rclcpp_action 14 | ch5_action_interfaces 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch5_action_py 5 | 0.0.1 6 | ROS 2 action demo wroten in Python. 7 | homalozoa 8 | Apache-2.0 9 | 10 | rclpy 11 | ch5_action_interfaces 12 | 13 | ament_copyright 14 | ament_flake8 15 | ament_pep257 16 | python3-pytest 17 | 18 | 19 | ament_python 20 | 21 | 22 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch7_msgfltr_cpp 5 | 0.0.1 6 | ROS 2 message filters demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | sensor_msgs 14 | message_filters 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_launch 5 | 0.0.1 6 | ROS 2 launch demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ch2_node_cpp 13 | ch3_logging_cpp 14 | ch3_logging_py 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch5/tf2/ch5_tf2_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch5_tf2_cpp 5 | 0.0.1 6 | ROS 2 tf2 demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | geometry_msgs 13 | rclcpp 14 | tf2 15 | tf2_ros 16 | 17 | 18 | ament_lint_auto 19 | ament_lint_common 20 | 21 | 22 | ament_cmake 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | package_name = 'ch2_node_py' 4 | 5 | setup( 6 | name=package_name, 7 | version='0.0.1', 8 | packages=[package_name], 9 | data_files=[ 10 | ('share/ament_index/resource_index/packages', 11 | ['resource/' + package_name]), 12 | ('share/' + package_name, ['package.xml']), 13 | ], 14 | install_requires=['setuptools'], 15 | zip_safe=True, 16 | maintainer='homalozoa', 17 | maintainer_email='nx.tardis@gmail.com', 18 | description='Python node demo.', 19 | license='Apache-2.0', 20 | tests_require=['pytest'], 21 | entry_points={ 22 | 'console_scripts': [ 23 | 'node2go=ch2_node_py.node2go:main', 24 | 'node2gons=ch2_node_py.node2gons:main' 25 | ], 26 | }, 27 | ) 28 | -------------------------------------------------------------------------------- /ch7/diagnostics/ch7_diagnostics_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch7_diagnostics_cpp 5 | 0.0.1 6 | ROS 2 diagnostics system demo wroten in C++. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | rclcpp 13 | diagnostic_updater 14 | sensor_msgs 15 | 16 | ament_lint_auto 17 | ament_lint_common 18 | 19 | 20 | ament_cmake 21 | 22 | 23 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/grpc_vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(grpc_vendor) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(Protobuf QUIET) 6 | find_package(gRPC CONFIG QUIET) 7 | 8 | if(Protobuf_FOUND AND gRPC_FOUND) 9 | message("protobuf & gRPC found, skip building from source") 10 | return() 11 | endif() 12 | 13 | set(EXTPRJ_NAME grpc) 14 | set(GIT_URL "https://github.com/grpc/grpc.git") 15 | set(PKG_VER "v1.36.3") 16 | 17 | include(ExternalProject) 18 | 19 | externalproject_add( 20 | ${EXTPRJ_NAME} 21 | PREFIX ${EXTPRJ_NAME} 22 | GIT_REPOSITORY ${GIT_URL} 23 | GIT_TAG ${PKG_VER} 24 | CMAKE_ARGS 25 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 26 | -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} 27 | INSTALL_DIR ${CMAKE_INSTALL_PREFIX} 28 | TIMEOUT 1200 29 | ) 30 | 31 | ament_package() -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | paths-ignore: 4 | - '**.md' 5 | push: 6 | paths-ignore: 7 | - '**.md' 8 | 9 | jobs: 10 | ci: 11 | runs-on: ${{ matrix.os }} 12 | container: 13 | image: osrf/ros:${{ matrix.ros_distribution }}-desktop 14 | strategy: 15 | matrix: 16 | os: [ubuntu-22.04] 17 | ros_distribution: [foxy, galactic, humble, rolling] 18 | fail-fast: false 19 | steps: 20 | - name: add more dependencies 21 | run: | 22 | sudo apt-get update 23 | sudo apt-get install -y python3-colcon-coveragepy-result 24 | sudo apt-get install -y ros-${{ matrix.ros_distribution }}-diagnostic-updater 25 | - name: build and test 26 | uses: ros-tooling/action-ros-ci@v0.2 27 | with: 28 | target-ros2-distro: ${{ matrix.ros_distribution }} 29 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_main/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch3_plugin_main 5 | 0.0.1 6 | Main package for testing plugin 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | 12 | ch3_plugin_alpha 13 | ch3_plugin_base 14 | ch3_plugin_beta 15 | rclcpp 16 | pluginlib 17 | 18 | ament_lint_auto 19 | ament_lint_common 20 | 21 | 22 | ament_cmake 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/setup.py: -------------------------------------------------------------------------------- 1 | from glob import glob 2 | 3 | import os 4 | 5 | from setuptools import setup 6 | 7 | package_name = 'ch3_param_py' 8 | 9 | setup( 10 | name=package_name, 11 | version='0.0.1', 12 | packages=[package_name], 13 | data_files=[ 14 | ('share/ament_index/resource_index/packages', 15 | ['resource/' + package_name]), 16 | ('share/' + package_name, ['package.xml']), 17 | (os.path.join('share', package_name, 'param'), glob('param/*.yaml')) 18 | ], 19 | install_requires=['setuptools'], 20 | zip_safe=True, 21 | maintainer='homalohzoa', 22 | maintainer_email='nx.tardis@gmail.com', 23 | description='Package for testing parameters in Node', 24 | license='Apache-2.0', 25 | tests_require=['pytest'], 26 | entry_points={ 27 | 'console_scripts': [ 28 | 'soliloquist = ch3_param_py.soliloquist:main', 29 | ], 30 | }, 31 | ) 32 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_interfaces/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch5_action_interfaces 5 | 0.0.1 6 | ROS 2 action interface demo. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | action_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | ament_lint_auto 18 | ament_lint_common 19 | 20 | rosidl_interface_packages 21 | 22 | ament_cmake 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_cpp/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | 17 | #include "ch2_pkg_cpp/pkg2go.hpp" 18 | 19 | int main(int argc, char ** argv) 20 | { 21 | (void)argc; 22 | (void)argv; 23 | auto pkg2go = ros_beginner::Pkg2Go("Hello ROS 2."); 24 | std::cout << pkg2go.get_pkg2go_name() << std::endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | 17 | #include "ch2_node_cpp/node2go.hpp" 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | int main(int argc, char ** argv) 21 | { 22 | rclcpp::init(argc, argv); 23 | rclcpp::spin(std::make_shared("cpp_node")); 24 | rclcpp::shutdown(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch5/interface/ch5_v_interfaces/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ch5_v_interfaces 5 | 0.0.1 6 | ROS 2 interfaces demo. Including description of velocity in SE3. 7 | homalozoa 8 | Apache-2.0 9 | 10 | ament_cmake 11 | rosidl_default_generators 12 | 13 | action_msgs 14 | 15 | rosidl_default_runtime 16 | 17 | ament_lint_auto 18 | ament_lint_common 19 | 20 | rosidl_interface_packages 21 | 22 | ament_cmake 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch7_msgfltr_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | find_package(sensor_msgs REQUIRED) 12 | find_package(message_filters REQUIRED) 13 | 14 | 15 | set(executable_fltr selfilter) 16 | set(dependencies 17 | rclcpp 18 | sensor_msgs 19 | message_filters 20 | ) 21 | 22 | add_executable(${executable_fltr} 23 | src/selfilter.cpp 24 | ) 25 | 26 | ament_target_dependencies(${executable_fltr} 27 | ${dependencies} 28 | ) 29 | 30 | install( 31 | TARGETS ${executable_fltr} 32 | DESTINATION lib/${PROJECT_NAME} 33 | ) 34 | 35 | if(BUILD_TESTING) 36 | find_package(ament_lint_auto REQUIRED) 37 | ament_lint_auto_find_test_dependencies() 38 | endif() 39 | 40 | ament_package() 41 | -------------------------------------------------------------------------------- /ch6/ch6_debug_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch6_debug_cpp) 3 | 4 | # set(CMAKE_BUILD_TYPE "Debug") 5 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 6 | add_compile_options(-Wall -Wextra -Wpedantic -g -ggdb3) 7 | endif() 8 | 9 | # find dependencies 10 | find_package(ament_cmake REQUIRED) 11 | find_package(rclcpp REQUIRED) 12 | 13 | set(executable_debug tracetest) 14 | 15 | set(dependencies 16 | rclcpp 17 | ) 18 | 19 | add_executable(${executable_debug} 20 | src/faultcode.cpp 21 | ) 22 | 23 | ament_target_dependencies(${executable_debug} 24 | ${dependencies} 25 | ) 26 | 27 | install( 28 | TARGETS ${executable_debug} 29 | DESTINATION lib/${PROJECT_NAME} 30 | ) 31 | 32 | install( 33 | DIRECTORY launch 34 | DESTINATION share/${PROJECT_NAME}/ 35 | ) 36 | 37 | if(BUILD_TESTING) 38 | find_package(ament_lint_auto REQUIRED) 39 | ament_lint_auto_find_test_dependencies() 40 | endif() 41 | 42 | ament_package() 43 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/setup.py: -------------------------------------------------------------------------------- 1 | from glob import glob 2 | 3 | import os 4 | 5 | from setuptools import setup 6 | 7 | package_name = 'ch3_param_bringup' 8 | 9 | setup( 10 | name=package_name, 11 | version='0.0.1', 12 | packages=[package_name], 13 | data_files=[ 14 | ('share/ament_index/resource_index/packages', 15 | ['resource/' + package_name]), 16 | ('share/' + package_name, ['package.xml']), 17 | (os.path.join('share', package_name, 'param'), glob('param/*.yaml')), 18 | (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')) 19 | ], 20 | install_requires=['setuptools'], 21 | zip_safe=True, 22 | maintainer='homalozoa', 23 | maintainer_email='nx.tardis@gmail.com', 24 | description='Package for testing parameters in Launch', 25 | license='Apache-2.0', 26 | tests_require=['pytest'], 27 | entry_points={ 28 | 'console_scripts': [ 29 | ], 30 | }, 31 | ) 32 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/ch2_pkg_py/pkg2go.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | 16 | class Pkg2Go(): 17 | 18 | def __init__(self, name): 19 | self.name = name 20 | 21 | def get_pkg2go_name(self): 22 | return self.name 23 | 24 | 25 | def main(args=None): 26 | pkg2go = Pkg2Go('Bye ROS 2.') 27 | print(pkg2go.get_pkg2go_name()) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch7/sensor/ch7_msgfltr_py/test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 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 | from ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /ch6/ch6_debug_cpp/launch/debug.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | import launch_ros 17 | 18 | 19 | def generate_launch_description(): 20 | debug_exec = launch_ros.actions.Node( 21 | package='ch6_debug_cpp', 22 | executable='tracetest', 23 | prefix=['xterm -e gdb -ex run --args'], 24 | output='screen') 25 | 26 | return launch.LaunchDescription([ 27 | debug_exec, 28 | ]) 29 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_cpp/src/pkg2go.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | 17 | #include "ch2_pkg_cpp/pkg2go.hpp" 18 | 19 | namespace ros_beginner 20 | { 21 | Pkg2Go::Pkg2Go(const std::string & pkg2go_name) 22 | { 23 | this->pkg2go_name_ = pkg2go_name; 24 | } 25 | 26 | Pkg2Go::~Pkg2Go() 27 | {} 28 | 29 | std::string Pkg2Go::get_pkg2go_name() const 30 | { 31 | return this->pkg2go_name_; 32 | } 33 | } // namespace ros_beginner 34 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_logging_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | 12 | set(executable_test logger_test) 13 | set(executable_stuck stuck_logger) 14 | set(dependencies 15 | rclcpp 16 | ) 17 | 18 | add_executable(${executable_test} 19 | src/logger_test.cpp 20 | ) 21 | add_executable(${executable_stuck} 22 | src/stuck_logger.cpp 23 | ) 24 | 25 | ament_target_dependencies(${executable_test} 26 | ${dependencies} 27 | ) 28 | ament_target_dependencies(${executable_stuck} 29 | ${dependencies} 30 | ) 31 | 32 | install( 33 | TARGETS ${executable_test} 34 | TARGETS ${executable_stuck} 35 | DESTINATION lib/${PROJECT_NAME} 36 | ) 37 | 38 | if(BUILD_TESTING) 39 | find_package(ament_lint_auto REQUIRED) 40 | ament_lint_auto_find_test_dependencies() 41 | endif() 42 | 43 | ament_package() 44 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 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 | from ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | # Remove the `skip` decorator once the source file(s) have a copyright header 20 | @pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') 21 | @pytest.mark.copyright 22 | @pytest.mark.linter 23 | def test_copyright(): 24 | rc = main(argv=['.', 'test']) 25 | assert rc == 0, 'Found errors' 26 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/ch2_node_py/node2gons.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import rclpy 16 | from rclpy.node import Node 17 | 18 | 19 | class Node2Go(Node): 20 | 21 | def __init__(self, name): 22 | self.name = name 23 | super().__init__(self.name) 24 | 25 | 26 | def main(args=None): 27 | rclpy.init(args=args) 28 | node = Node2Go('py_node') 29 | print(node.get_namespace() + '/' + node.get_name()) 30 | rclpy.shutdown() 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/main2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | 17 | #include "ch2_node_cpp/node2go.hpp" 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | int main(int argc, char ** argv) 21 | { 22 | rclcpp::init(argc, argv); 23 | rclcpp::executors::SingleThreadedExecutor executor; 24 | auto node2go = std::make_shared("cpp_node"); 25 | executor.add_node(node2go->get_node_base_interface()); 26 | executor.spin(); 27 | rclcpp::shutdown(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_cpp/include/ch2_pkg_cpp/pkg2go.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 CH2_PKG_CPP__PKG2GO_HPP_ 16 | #define CH2_PKG_CPP__PKG2GO_HPP_ 17 | 18 | #include 19 | 20 | namespace ros_beginner 21 | { 22 | class Pkg2Go 23 | { 24 | public: 25 | explicit Pkg2Go(const std::string & pkg2go_name); 26 | ~Pkg2Go(); 27 | std::string get_pkg2go_name() const; 28 | 29 | private: 30 | std::string pkg2go_name_; 31 | }; 32 | } // namespace ros_beginner 33 | #endif // CH2_PKG_CPP__PKG2GO_HPP_ 34 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_param_cpp) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(rclcpp REQUIRED) 21 | 22 | set(executable soliloquist) 23 | set(dependencies 24 | rclcpp 25 | ) 26 | 27 | add_executable(${executable} 28 | src/soliloquist.cpp 29 | ) 30 | 31 | ament_target_dependencies(${executable} 32 | ${dependencies} 33 | ) 34 | 35 | install( 36 | TARGETS ${executable} 37 | DESTINATION lib/${PROJECT_NAME} 38 | ) 39 | 40 | if(BUILD_TESTING) 41 | find_package(ament_lint_auto REQUIRED) 42 | set(ament_cmake_copyright_FOUND TRUE) 43 | set(ament_cmake_cpplint_FOUND TRUE) 44 | ament_lint_auto_find_test_dependencies() 45 | endif() 46 | 47 | ament_package() 48 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch4_service_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | 12 | set(executable_selfservice self_exec) 13 | set(executable_selfnode self_node) 14 | 15 | set(dependencies 16 | rclcpp 17 | ) 18 | 19 | add_executable(${executable_selfservice} 20 | src/self_service.cpp 21 | ) 22 | 23 | add_executable(${executable_selfnode} 24 | src/single_node.cpp 25 | ) 26 | 27 | ament_target_dependencies( 28 | ${executable_selfservice} 29 | ${dependencies} 30 | ) 31 | 32 | ament_target_dependencies( 33 | ${executable_selfnode} 34 | ${dependencies} 35 | ) 36 | 37 | install( 38 | TARGETS ${executable_selfservice} 39 | TARGETS ${executable_selfnode} 40 | RUNTIME DESTINATION lib/${PROJECT_NAME} 41 | ) 42 | 43 | if(BUILD_TESTING) 44 | find_package(ament_lint_auto REQUIRED) 45 | ament_lint_auto_find_test_dependencies() 46 | endif() 47 | 48 | ament_package() 49 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/include/ch2_node_cpp/node2go.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 CH2_NODE_CPP__NODE2GO_HPP_ 16 | #define CH2_NODE_CPP__NODE2GO_HPP_ 17 | 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | namespace ros_beginner 23 | { 24 | class Node2Go : public rclcpp::Node 25 | { 26 | public: 27 | explicit Node2Go(const std::string & node_name); 28 | ~Node2Go(); 29 | 30 | private: 31 | rclcpp::TimerBase::SharedPtr printimer_; 32 | }; 33 | } // namespace ros_beginner 34 | #endif // CH2_NODE_CPP__NODE2GO_HPP_ 35 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_py/ch2_node_py/node2go.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import rclpy 16 | from rclpy.node import Node 17 | 18 | 19 | class Node2Go(Node): 20 | 21 | def __init__(self, name): 22 | super().__init__(name) 23 | self.create_timer(0.5, self.timer_callback) 24 | 25 | def timer_callback(self): 26 | print(self.get_name()) 27 | 28 | 29 | def main(args=None): 30 | rclpy.init(args=args) 31 | node = Node2Go('py_node') 32 | rclpy.spin(node) 33 | rclpy.shutdown() 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/node2go.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "ch2_node_cpp/node2go.hpp" 19 | 20 | namespace ros_beginner 21 | { 22 | using namespace std::chrono_literals; 23 | Node2Go::Node2Go(const std::string & node_name) 24 | : rclcpp::Node(node_name) 25 | { 26 | auto printimer_callback = 27 | [&]() -> void { 28 | std::cout << this->get_name() << std::endl; 29 | }; 30 | printimer_ = this->create_wall_timer(500ms, printimer_callback); 31 | } 32 | 33 | Node2Go::~Node2Go() 34 | {} 35 | } // namespace ros_beginner 36 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/launch/multi_pkg.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | import launch_ros 17 | 18 | 19 | def generate_launch_description(): 20 | exec_cpp = launch_ros.actions.Node( 21 | package='ch3_logging_cpp', 22 | executable='logger_test', 23 | name='log_in_cpp', 24 | output='screen') 25 | exec_py = launch_ros.actions.Node( 26 | package='ch3_logging_py', 27 | executable='logger_test', 28 | name='log_in_py', 29 | output='screen') 30 | 31 | return launch.LaunchDescription([ 32 | exec_cpp, 33 | exec_py 34 | ]) 35 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_base/include/ch3_plugin_base/pluginbase.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 CH3_PLUGIN_BASE__PLUGINBASE_HPP_ 16 | #define CH3_PLUGIN_BASE__PLUGINBASE_HPP_ 17 | 18 | #include 19 | 20 | namespace ch3 21 | { 22 | namespace plugin 23 | { 24 | class PluginBase 25 | { 26 | public: 27 | ~PluginBase() {} 28 | virtual void say_hello(const int32_t & times) = 0; 29 | virtual bool say_something(const std::string & something) = 0; 30 | 31 | protected: 32 | PluginBase() = default; 33 | }; 34 | } // namespace plugin 35 | } // namespace ch3 36 | #endif // CH3_PLUGIN_BASE__PLUGINBASE_HPP_ 37 | -------------------------------------------------------------------------------- /ch6/ch6_unittest_cpp/include/ch6_unittest_cpp/monkey.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 CH6_UNITTEST_CPP__MONKEY_HPP_ 16 | #define CH6_UNITTEST_CPP__MONKEY_HPP_ 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | namespace zoo 23 | { 24 | class MonkeyNode : public rclcpp::Node 25 | { 26 | public: 27 | explicit MonkeyNode(const std::string & node_name, const int32_t count_init = 0); 28 | bool add_bananas(const int32_t & bananas); 29 | bool eat_bananas(const int32_t & bananas); 30 | int32_t check_bananas(); 31 | 32 | private: 33 | int32_t count_bananas_; 34 | }; 35 | } // namespace zoo 36 | #endif // CH6_UNITTEST_CPP__MONKEY_HPP_ 37 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_beta/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_plugin_beta) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(ch3_plugin_base REQUIRED) 21 | find_package(pluginlib REQUIRED) 22 | find_package(rclcpp REQUIRED) 23 | 24 | set(lib_beta plugins_beta) 25 | set(dependencies 26 | ch3_plugin_base 27 | pluginlib 28 | rclcpp 29 | ) 30 | 31 | add_library(${lib_beta} SHARED 32 | src/pluginbeta.cpp) 33 | 34 | ament_target_dependencies(${lib_beta} 35 | ${dependencies} 36 | ) 37 | 38 | if(BUILD_TESTING) 39 | find_package(ament_lint_auto REQUIRED) 40 | ament_lint_auto_find_test_dependencies() 41 | endif() 42 | 43 | install( 44 | TARGETS ${lib_beta} 45 | LIBRARY DESTINATION lib 46 | ) 47 | 48 | ament_export_libraries(${lib_beta}) 49 | ament_export_dependencies(${dependencies}) 50 | pluginlib_export_plugin_description_file(ch3_plugin_base beta_defines.xml) 51 | ament_package() 52 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_alpha/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_plugin_alpha) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(ch3_plugin_base REQUIRED) 21 | find_package(pluginlib REQUIRED) 22 | find_package(rclcpp REQUIRED) 23 | 24 | set(lib_alpha plugins_alpha) 25 | set(dependencies 26 | ch3_plugin_base 27 | pluginlib 28 | rclcpp 29 | ) 30 | 31 | add_library(${lib_alpha} SHARED 32 | src/pluginalpha.cpp 33 | ) 34 | 35 | ament_target_dependencies(${lib_alpha} 36 | ${dependencies} 37 | ) 38 | 39 | install( 40 | TARGETS ${lib_alpha} 41 | LIBRARY DESTINATION lib 42 | ) 43 | 44 | if(BUILD_TESTING) 45 | find_package(ament_lint_auto REQUIRED) 46 | ament_lint_auto_find_test_dependencies() 47 | endif() 48 | 49 | ament_export_libraries(${lib_alpha}) 50 | ament_export_dependencies(${dependencies}) 51 | pluginlib_export_plugin_description_file(ch3_plugin_base alpha_defines.xml) 52 | ament_package() 53 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_plugin_main) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(ch3_plugin_base REQUIRED) 21 | find_package(pluginlib REQUIRED) 22 | find_package(rclcpp REQUIRED) 23 | 24 | set(exec_withoutnode run_plugin_withoutnode) 25 | set(exec_withnode run_plugin_withnode) 26 | 27 | add_executable(${exec_withoutnode} src/withoutnode.cpp) 28 | add_executable(${exec_withnode} src/withnode.cpp) 29 | 30 | ament_target_dependencies(${exec_withoutnode} 31 | ch3_plugin_base 32 | pluginlib 33 | rclcpp 34 | ) 35 | ament_target_dependencies(${exec_withnode} 36 | ch3_plugin_base 37 | pluginlib 38 | rclcpp 39 | ) 40 | 41 | install( 42 | TARGETS ${exec_withoutnode} 43 | TARGETS ${exec_withnode} 44 | RUNTIME DESTINATION lib/${PROJECT_NAME} 45 | ) 46 | 47 | if(BUILD_TESTING) 48 | find_package(ament_lint_auto REQUIRED) 49 | ament_lint_auto_find_test_dependencies() 50 | endif() 51 | 52 | ament_package() 53 | -------------------------------------------------------------------------------- /ch6/ch6_unittest_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch6_unittest_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | 12 | set(lib_monkey monkey) 13 | set(test_monkey monkeytest) 14 | 15 | set(dependencies 16 | rclcpp 17 | ) 18 | 19 | include_directories(include) 20 | 21 | add_library(${lib_monkey} SHARED 22 | src/monkey.cpp 23 | ) 24 | 25 | ament_target_dependencies(${lib_monkey} 26 | ${dependencies} 27 | ) 28 | 29 | install( 30 | TARGETS ${lib_monkey} 31 | ARCHIVE DESTINATION lib 32 | LIBRARY DESTINATION lib 33 | RUNTIME DESTINATION bin 34 | ) 35 | 36 | if(BUILD_TESTING) 37 | find_package(ament_lint_auto REQUIRED) 38 | ament_lint_auto_find_test_dependencies() 39 | find_package(ament_cmake_gtest REQUIRED) 40 | ament_add_gtest(${test_monkey} 41 | test/monkey_test.cpp 42 | TIMEOUT 20 43 | ) 44 | ament_target_dependencies(${test_monkey} 45 | ${dependencies} 46 | ) 47 | target_link_libraries(${test_monkey} 48 | ${lib_monkey} 49 | ) 50 | endif() 51 | 52 | ament_export_include_directories(include) 53 | ament_export_libraries(${lib_monkey}) 54 | ament_export_dependencies(${dependencies}) 55 | ament_package() 56 | -------------------------------------------------------------------------------- /ch6/ch6_debug_cpp/src/faultcode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | int main(int argc, char ** argv) 21 | { 22 | rclcpp::init(argc, argv); 23 | using namespace std::chrono_literals; 24 | auto node_a = std::make_shared("TestNode"); 25 | auto executor = std::make_unique(); 26 | int * int_ptr; 27 | auto timer_cb = [&]() -> void { 28 | RCLCPP_INFO_STREAM(rclcpp::get_logger("DebugTest"), std::to_string(*int_ptr)); 29 | }; 30 | auto timer_ = node_a->create_wall_timer(1s, timer_cb); 31 | executor->add_node(node_a->get_node_base_interface()); 32 | executor->spin(); 33 | rclcpp::shutdown(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/getid.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "ch2_node_cpp/node2go.hpp" 21 | #include "sys/types.h" 22 | 23 | namespace ros_beginner 24 | { 25 | using namespace std::chrono_literals; 26 | Node2Go::Node2Go(const std::string & node_name) 27 | : rclcpp::Node(node_name) 28 | { 29 | auto printimer_callback = 30 | [&]() -> void { 31 | pid_t pid = getpid(); 32 | std::cout << this->get_name() << ": pid is " << pid << ", thread id is " << 33 | std::this_thread::get_id() << std::endl; 34 | }; 35 | printimer_ = this->create_wall_timer(500ms, printimer_callback); 36 | } 37 | 38 | Node2Go::~Node2Go() 39 | {} 40 | } // namespace ros_beginner 41 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_py/ch3_logging_py/logger_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import rclpy 16 | from rclpy.node import Node 17 | 18 | 19 | class LoggerTest(Node): 20 | 21 | def __init__(self, name): 22 | super().__init__(name) 23 | self.get_logger().debug('Init node [' + self.get_name() + ']') 24 | self.get_logger().info('Init node [' + self.get_name() + ']') 25 | self.get_logger().warn('Init node [' + self.get_name() + ']') 26 | self.get_logger().error('Init node [' + self.get_name() + ']') 27 | self.get_logger().fatal('Init node [' + self.get_name() + ']') 28 | 29 | 30 | def main(args=None): 31 | rclpy.init(args=args) 32 | LoggerTest('py_log_test') 33 | rclpy.shutdown() 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/mpg123_vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(mpg123_vendor) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | set(EXTPRJ_NAME mpg123) 7 | set(PREFIX_DIR "${CMAKE_CURRENT_BINARY_DIR}/${EXTPRJ_NAME}/src/${EXTPRJ_NAME}") 8 | set(OUT_DIR "${CMAKE_BINARY_DIR}/install") 9 | 10 | include(ExternalProject) 11 | 12 | externalproject_add( 13 | ${EXTPRJ_NAME} 14 | PREFIX ${EXTPRJ_NAME} 15 | URL https://www.mpg123.de/download/mpg123-1.29.2.tar.bz2 16 | URL_MD5 05137a60b40d66bc185b1e106815aec7 17 | CONFIGURE_COMMAND eval ${PREFIX_DIR}/configure --prefix=${OUT_DIR} 18 | BUILD_COMMAND "make" 19 | INSTALL_DIR ${OUT_DIR} 20 | TIMEOUT 1200 21 | ) 22 | 23 | set(mpg123_libs 24 | mpg123 25 | out123 26 | syn123 27 | ) 28 | 29 | install(DIRECTORY ${OUT_DIR}/bin/ 30 | DESTINATION bin/ 31 | PATTERN "*" 32 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ 33 | GROUP_EXECUTE GROUP_READ 34 | ) 35 | 36 | install(DIRECTORY ${OUT_DIR}/include/ 37 | DESTINATION include/${EXTPRJ_NAME} 38 | ) 39 | 40 | install(DIRECTORY ${OUT_DIR}/lib/ 41 | DESTINATION lib/ 42 | REGEX ".?so.?" 43 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ 44 | GROUP_EXECUTE GROUP_READ 45 | ) 46 | 47 | install(DIRECTORY ${OUT_DIR}/share/ 48 | DESTINATION share/${PROJECT_NAME} 49 | ) 50 | 51 | ament_export_include_directories(include) 52 | ament_export_libraries(${mpg123_libs}) 53 | ament_package() -------------------------------------------------------------------------------- /ch2/package/ch2_pkg_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch2_pkg_cpp) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | 21 | set(executable_pkg2go pkg2go) 22 | set(library_pkg2go ${executable_pkg2go}_core) 23 | include_directories(include) 24 | 25 | add_library(${library_pkg2go} SHARED 26 | src/pkg2go.cpp 27 | ) 28 | 29 | add_executable(${executable_pkg2go} 30 | src/main.cpp 31 | ) 32 | 33 | target_link_libraries(${executable_pkg2go} 34 | ${library_pkg2go} 35 | ) 36 | 37 | install(TARGETS 38 | ${library_pkg2go} 39 | ARCHIVE DESTINATION lib 40 | LIBRARY DESTINATION lib 41 | RUNTIME DESTINATION bin 42 | ) 43 | 44 | install(TARGETS ${executable_pkg2go} 45 | RUNTIME DESTINATION lib/${PROJECT_NAME} 46 | ) 47 | 48 | install(DIRECTORY include/ 49 | DESTINATION include/ 50 | ) 51 | 52 | if(BUILD_TESTING) 53 | find_package(ament_lint_auto REQUIRED) 54 | ament_lint_auto_find_test_dependencies() 55 | endif() 56 | 57 | ament_export_include_directories(include) 58 | ament_export_libraries(${library_pkg2go}) 59 | ament_package() 60 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch5_action_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | find_package(rclcpp_action REQUIRED) 12 | find_package(ch5_action_interfaces REQUIRED) 13 | 14 | set(ROS_DISTRO $ENV{ROS_DISTRO}) 15 | if(${ROS_DISTRO} STREQUAL "foxy") 16 | add_compile_definitions(FOXY_ACTION_API) 17 | endif() 18 | 19 | set(executable_self self_action) 20 | set(executable_wrapped wrapped_action) 21 | 22 | set(dependencies 23 | rclcpp 24 | rclcpp_action 25 | ch5_action_interfaces 26 | ) 27 | 28 | include_directories(include) 29 | 30 | add_executable(${executable_self} 31 | src/self_action.cpp 32 | ) 33 | 34 | add_executable(${executable_wrapped} 35 | src/wrapped_action.cpp 36 | ) 37 | 38 | ament_target_dependencies( 39 | ${executable_self} 40 | ${dependencies} 41 | ) 42 | 43 | ament_target_dependencies( 44 | ${executable_wrapped} 45 | ${dependencies} 46 | ) 47 | 48 | install( 49 | TARGETS ${executable_self} 50 | TARGETS ${executable_wrapped} 51 | RUNTIME DESTINATION lib/${PROJECT_NAME} 52 | ) 53 | 54 | if(BUILD_TESTING) 55 | find_package(ament_lint_auto REQUIRED) 56 | ament_lint_auto_find_test_dependencies() 57 | endif() 58 | 59 | ament_package() 60 | -------------------------------------------------------------------------------- /ch6/ch6_unittest_cpp/src/monkey.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "ch6_unittest_cpp/monkey.hpp" 19 | 20 | namespace zoo 21 | { 22 | MonkeyNode::MonkeyNode(const std::string & node_name, const int32_t count_init) 23 | : Node(node_name) 24 | { 25 | count_bananas_ = count_init; 26 | } 27 | 28 | bool MonkeyNode::add_bananas(const int32_t & bananas) 29 | { 30 | count_bananas_ += bananas; 31 | return true; 32 | } 33 | 34 | bool MonkeyNode::eat_bananas(const int32_t & bananas) 35 | { 36 | bool rtn; 37 | if (count_bananas_ - bananas >= 0) { 38 | count_bananas_ -= bananas; 39 | rtn = true; 40 | } else { 41 | rtn = false; 42 | } 43 | return rtn; 44 | } 45 | 46 | int32_t MonkeyNode::check_bananas() 47 | { 48 | return count_bananas_; 49 | } 50 | } // namespace zoo 51 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/launch/singlexec.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | import launch_ros 17 | 18 | 19 | def generate_launch_description(): 20 | argument_node_count = launch.actions.DeclareLaunchArgument( 21 | 'node_count', default_value='1') 22 | argument_executor_type = launch.actions.DeclareLaunchArgument( 23 | 'executor_type', default_value='s') 24 | exec__multi_node = launch_ros.actions.Node( 25 | package='ch2_node_cpp', 26 | executable='multinode', 27 | arguments=[ 28 | launch.substitutions.LaunchConfiguration('node_count'), 29 | launch.substitutions.LaunchConfiguration('executor_type')], 30 | output='screen') 31 | 32 | return launch.LaunchDescription([ 33 | argument_node_count, 34 | argument_executor_type, 35 | exec__multi_node, 36 | ]) 37 | -------------------------------------------------------------------------------- /ch6/ch6_bag_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch6_bag_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | find_package(rcpputils REQUIRED) 12 | find_package(rcutils REQUIRED) 13 | find_package(rosbag2_cpp REQUIRED) 14 | 15 | set(ROS_DISTRO $ENV{ROS_DISTRO}) 16 | if(${ROS_DISTRO} STREQUAL "foxy") 17 | add_compile_definitions(FOXY_BAG_API) 18 | endif() 19 | if(${ROS_DISTRO} STREQUAL "foxy" OR ${ROS_DISTRO} STREQUAL "galactic") 20 | add_compile_definitions(DEPRECATED_BAG_API) 21 | endif() 22 | 23 | set(executable_data pubdata) 24 | set(executable_bag operatebag) 25 | 26 | set(dependencies 27 | rclcpp 28 | rcpputils 29 | rcutils 30 | rosbag2_cpp 31 | ) 32 | 33 | add_executable(${executable_data} 34 | src/pubdata.cpp 35 | ) 36 | 37 | add_executable(${executable_bag} 38 | src/operatebag.cpp 39 | ) 40 | 41 | ament_target_dependencies(${executable_data} 42 | ${dependencies} 43 | ) 44 | 45 | ament_target_dependencies(${executable_bag} 46 | ${dependencies} 47 | ) 48 | 49 | install( 50 | TARGETS ${executable_data} 51 | TARGETS ${executable_bag} 52 | DESTINATION lib/${PROJECT_NAME} 53 | ) 54 | 55 | if(BUILD_TESTING) 56 | find_package(ament_lint_auto REQUIRED) 57 | ament_lint_auto_find_test_dependencies() 58 | endif() 59 | 60 | ament_package() 61 | -------------------------------------------------------------------------------- /ch7/diagnostics/ch7_diagnostics_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch7_diagnostics_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | find_package(rclcpp_lifecycle REQUIRED) 12 | find_package(diagnostic_updater REQUIRED) 13 | find_package(sensor_msgs REQUIRED) 14 | 15 | set(executable_simpleupdater simple_updater) 16 | set(executable_freqchecker freq_checker) 17 | 18 | set(dependencies 19 | rclcpp 20 | diagnostic_updater 21 | sensor_msgs 22 | ) 23 | 24 | add_executable(${executable_simpleupdater} 25 | src/simple_updater.cpp 26 | ) 27 | add_executable(${executable_freqchecker} 28 | src/freq_checker.cpp 29 | ) 30 | 31 | 32 | ament_target_dependencies(${executable_simpleupdater} 33 | ${dependencies} 34 | ) 35 | ament_target_dependencies(${executable_freqchecker} 36 | ${dependencies} 37 | ) 38 | 39 | install( 40 | TARGETS ${executable_simpleupdater} 41 | TARGETS ${executable_freqchecker} 42 | DESTINATION lib/${PROJECT_NAME} 43 | ) 44 | 45 | install( 46 | DIRECTORY launch/ 47 | DESTINATION share/${PROJECT_NAME}/param/ 48 | ) 49 | 50 | install( 51 | DIRECTORY param/ 52 | DESTINATION share/${PROJECT_NAME}/param/ 53 | ) 54 | 55 | if(BUILD_TESTING) 56 | find_package(ament_lint_auto REQUIRED) 57 | ament_lint_auto_find_test_dependencies() 58 | endif() 59 | 60 | ament_package() 61 | -------------------------------------------------------------------------------- /ch5/tf2/ch5_tf2_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch5_tf2_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(geometry_msgs REQUIRED) 11 | find_package(rclcpp REQUIRED) 12 | find_package(tf2 REQUIRED) 13 | find_package(tf2_ros REQUIRED) 14 | 15 | set(executable_static static_transform) 16 | set(executable_dynamic dynamic_transform) 17 | set(executable_listener transform_listener) 18 | 19 | set(dependencies 20 | geometry_msgs 21 | rclcpp 22 | tf2 23 | tf2_ros 24 | ) 25 | 26 | add_executable(${executable_static} 27 | src/static_transform.cpp 28 | ) 29 | 30 | add_executable(${executable_dynamic} 31 | src/dynamic_transform.cpp 32 | ) 33 | 34 | add_executable(${executable_listener} 35 | src/transform_listener.cpp 36 | ) 37 | 38 | ament_target_dependencies( 39 | ${executable_static} 40 | ${dependencies} 41 | ) 42 | 43 | ament_target_dependencies( 44 | ${executable_dynamic} 45 | ${dependencies} 46 | ) 47 | 48 | ament_target_dependencies( 49 | ${executable_listener} 50 | ${dependencies} 51 | ) 52 | 53 | install( 54 | TARGETS ${executable_static} 55 | TARGETS ${executable_dynamic} 56 | TARGETS ${executable_listener} 57 | DESTINATION lib/${PROJECT_NAME} 58 | ) 59 | 60 | if(BUILD_TESTING) 61 | find_package(ament_lint_auto REQUIRED) 62 | ament_lint_auto_find_test_dependencies() 63 | endif() 64 | 65 | ament_package() 66 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/launch/changed.singlexec.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | import launch_ros 17 | 18 | 19 | def generate_launch_description(): 20 | argument_node_count = launch.actions.DeclareLaunchArgument( 21 | 'node_count', default_value='1') 22 | argument_executor_type = launch.actions.DeclareLaunchArgument( 23 | 'executor_type', default_value='s') 24 | exec__multi_node = launch_ros.actions.Node( 25 | package='ch2_node_cpp', 26 | executable='multinode', 27 | name='another_multi_node', 28 | namespace='new_ns', 29 | exec_name='changed_multinode', 30 | arguments=[ 31 | launch.substitutions.LaunchConfiguration('node_count'), 32 | launch.substitutions.LaunchConfiguration('executor_type')], 33 | output='screen') 34 | 35 | return launch.LaunchDescription([ 36 | argument_node_count, 37 | argument_executor_type, 38 | exec__multi_node, 39 | ]) 40 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_beta/src/pluginbeta.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "ch3_plugin_base/pluginbase.hpp" 19 | #include "pluginlib/class_list_macros.hpp" 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | namespace ch3 23 | { 24 | namespace plugin 25 | { 26 | class PluginBeta : public PluginBase 27 | { 28 | public: 29 | PluginBeta() {} 30 | void say_hello(const int32_t & times) override 31 | { 32 | auto times_(times); 33 | while (--times_ >= 0) { 34 | RCLCPP_INFO(rclcpp::get_logger("PluginBeta"), "Hello beta"); 35 | } 36 | } 37 | bool say_something(const std::string & something) override 38 | { 39 | if (something.size() == 0) { 40 | return false; 41 | } else { 42 | RCLCPP_INFO_STREAM(rclcpp::get_logger("PluginBeta"), something); 43 | return true; 44 | } 45 | } 46 | }; 47 | } // namespace plugin 48 | } // namespace ch3 49 | 50 | PLUGINLIB_EXPORT_CLASS(ch3::plugin::PluginBeta, ch3::plugin::PluginBase) 51 | -------------------------------------------------------------------------------- /ch7/vendor_pkgs/opencv_vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(opencv_vendor) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(OpenCV QUIET) 6 | 7 | if(OpenCV_FOUND) 8 | message("OpenCV ${OpenCV_VERSION} found, skip building ${PROJECT_NAME}") 9 | return() 10 | endif() 11 | 12 | set(EXTPRJ_NAME opencv) 13 | set(EXTPRJ_DEP opencv-contrib) 14 | set(PKG_VER "4.2.0") 15 | set(EXTERNAL_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}/Download) 16 | 17 | include(ExternalProject) 18 | 19 | externalproject_add(${EXTPRJ_DEP} 20 | URL https://github.com/opencv/opencv_contrib/archive/refs/tags/${PKG_VER}.tar.gz 21 | URL_MD5 7f8111deb2ce3ed6c87ede8b3bf82031 22 | SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv-contrib" 23 | CONFIGURE_COMMAND "" 24 | BUILD_COMMAND "" 25 | INSTALL_COMMAND "" 26 | ) 27 | 28 | externalproject_add( 29 | ${EXTPRJ_NAME} 30 | PREFIX ${EXTPRJ_NAME} 31 | URL https://github.com/opencv/opencv/archive/refs/tags/${PKG_VER}.tar.gz 32 | URL_MD5 e8cb208ce2723481408b604b480183b6 33 | SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv" 34 | CMAKE_ARGS 35 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 36 | -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} 37 | -DBUILD_DOCS:BOOL=OFF 38 | -DBUILD_EXAMPLES:BOOL=OFF 39 | -DBUILD_PACKAGE:BOOL=OFF 40 | -DBUILD_SHARED_LIBS:BOOL=ON 41 | -DBUILD_TESTS:BOOL=OFF 42 | -DOPENCV_EXTRA_MODULES_PATH=${EXTERNAL_DOWNLOAD_LOCATION}/opencv-contrib/modules 43 | INSTALL_DIR ${CMAKE_INSTALL_PREFIX} 44 | TIMEOUT 1200 45 | ) 46 | add_dependencies(${EXTPRJ_NAME} ${EXTPRJ_DEP}) 47 | 48 | ament_package() 49 | -------------------------------------------------------------------------------- /ch3/component/ch3_component/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch3_component) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | find_package(rclcpp_components REQUIRED) 12 | 13 | set(library_components component_test) 14 | set(dependencies 15 | rclcpp 16 | rclcpp_components 17 | ) 18 | 19 | add_library(${library_components} SHARED 20 | src/com1.cpp 21 | src/com2.cpp 22 | ) 23 | 24 | ament_target_dependencies(${library_components} 25 | ${dependencies} 26 | ) 27 | 28 | rclcpp_components_register_node(${library_components} 29 | PLUGIN "ros_beginner::Component1" 30 | EXECUTABLE componentest1) 31 | 32 | rclcpp_components_register_node(${library_components} 33 | PLUGIN "ros_beginner::Component2" 34 | EXECUTABLE componentest2) 35 | 36 | rclcpp_components_register_node(${library_components} 37 | PLUGIN "ros_beginner::Component3" 38 | EXECUTABLE componentest3) 39 | 40 | # rclcpp_components_register_nodes(${library_components} 41 | # "ros_beginner::Component1" 42 | # "ros_beginner::Component2" 43 | # "ros_beginner::Component3") 44 | 45 | install(TARGETS ${library_components} 46 | ARCHIVE DESTINATION lib 47 | LIBRARY DESTINATION lib 48 | RUNTIME DESTINATION bin 49 | ) 50 | 51 | install(DIRECTORY launch 52 | DESTINATION share/${PROJECT_NAME}/ 53 | ) 54 | 55 | if(BUILD_TESTING) 56 | find_package(ament_lint_auto REQUIRED) 57 | ament_lint_auto_find_test_dependencies() 58 | endif() 59 | 60 | ament_package() 61 | -------------------------------------------------------------------------------- /ch3/component/ch3_component/src/com2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | #include "rclcpp_components/register_node_macro.hpp" 22 | #include "sys/types.h" 23 | 24 | namespace ros_beginner 25 | { 26 | using namespace std::chrono_literals; 27 | 28 | class Component2 : public rclcpp::Node 29 | { 30 | public: 31 | explicit Component2(const rclcpp::NodeOptions & node_options) 32 | : Node("component_2", node_options) 33 | { 34 | auto printimer_cb = 35 | [&]() -> void { 36 | pid_t pid = getpid(); 37 | RCLCPP_INFO_STREAM( 38 | this->get_logger(), 39 | this->get_name() << ": pid is " << pid << ", thread id is " << 40 | std::this_thread::get_id()); 41 | }; 42 | printimer_ = this->create_wall_timer(500ms, printimer_cb); 43 | } 44 | 45 | private: 46 | rclcpp::TimerBase::SharedPtr printimer_; 47 | }; 48 | } // namespace ros_beginner 49 | 50 | RCLCPP_COMPONENTS_REGISTER_NODE(ros_beginner::Component2) 51 | -------------------------------------------------------------------------------- /ch7/diagnostics/ch7_diagnostics_cpp/launch/temp_analysis.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | import launch 20 | import launch_ros.actions 21 | 22 | prj_dir = get_package_share_directory('ch7_diagnostics_cpp') 23 | 24 | 25 | def generate_launch_description(): 26 | aggregator = launch_ros.actions.Node( 27 | package='diagnostic_aggregator', 28 | executable='aggregator_node', 29 | output='screen', 30 | parameters=[os.path.join( 31 | prj_dir, 'param', 32 | 'updater.yaml')]) 33 | temp_updater = launch_ros.actions.Node( 34 | package='ch7_diagnostics_cpp', 35 | executable='simple_updater') 36 | return launch.LaunchDescription([ 37 | aggregator, 38 | temp_updater, 39 | launch.actions.RegisterEventHandler( 40 | event_handler=launch.event_handlers.OnProcessExit( 41 | target_action=aggregator, 42 | on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())], 43 | )), 44 | ]) 45 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/global_arg.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | class NodeWithOption : public rclcpp::Node 22 | { 23 | public: 24 | NodeWithOption(const std::string & node_name, const rclcpp::NodeOptions & options) 25 | : rclcpp::Node(node_name, options) 26 | { 27 | if (options.use_global_arguments()) { 28 | RCLCPP_INFO_STREAM(this->get_logger(), std::string("Using global arguments")); 29 | } else { 30 | RCLCPP_INFO_STREAM(this->get_logger(), std::string("Not using global arguments")); 31 | } 32 | RCLCPP_INFO_STREAM(this->get_logger(), this->get_namespace()); 33 | } 34 | }; 35 | 36 | int main(int argc, char ** argv) 37 | { 38 | rclcpp::init(argc, argv); 39 | auto exec = rclcpp::executors::SingleThreadedExecutor(); 40 | auto options = rclcpp::NodeOptions(); 41 | options.use_global_arguments(atoi(argv[2])); 42 | 43 | auto node = std::make_shared(argv[1], options); 44 | exec.add_node(node->get_node_base_interface()); 45 | exec.spin_once(); 46 | 47 | rclcpp::shutdown(); 48 | } 49 | -------------------------------------------------------------------------------- /ch3/component/ch3_component/launch/composition.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | from launch_ros.actions import ComposableNodeContainer 17 | from launch_ros.descriptions import ComposableNode 18 | 19 | 20 | def generate_launch_description(): 21 | """Generate launch description with multiple components.""" 22 | container = ComposableNodeContainer( 23 | name='CompositionDemo', 24 | namespace='', 25 | package='rclcpp_components', 26 | executable='component_container', 27 | composable_node_descriptions=[ 28 | ComposableNode( 29 | package='ch3_component', 30 | plugin='ros_beginner::Component1', 31 | name='c1'), 32 | ComposableNode( 33 | package='ch3_component', 34 | plugin='ros_beginner::Component2', 35 | name='c2'), 36 | ComposableNode( 37 | package='ch3_component', 38 | plugin='ros_beginner::Component3', 39 | name='c3') 40 | ], 41 | output='screen', 42 | ) 43 | 44 | return launch.LaunchDescription([container]) 45 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_bringup/launch/bringup.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | import launch 20 | import launch_ros.actions 21 | 22 | 23 | def generate_launch_description(): 24 | bringup_dir = get_package_share_directory('ch3_param_bringup') 25 | ld = launch.LaunchDescription() 26 | 27 | set_parameter_cmd = launch.actions.DeclareLaunchArgument( 28 | 'params_file', 29 | default_value=os.path.join( 30 | bringup_dir, 'param', 31 | 'default_param.yaml'), 32 | description='Path to paramaters YAML file') 33 | set_namespace_cmd = launch.actions.DeclareLaunchArgument( 34 | 'namespace_ext', default_value='') 35 | params_file = launch.substitutions.LaunchConfiguration('params_file') 36 | namespace_ext = launch.substitutions.LaunchConfiguration('namespace_ext') 37 | ld.add_action(set_parameter_cmd) 38 | ld.add_action(set_namespace_cmd) 39 | ld.add_action(launch_ros.actions.Node( 40 | package='ch3_param_py', 41 | executable='soliloquist', 42 | namespace=namespace_ext, 43 | parameters=[params_file], 44 | output='screen')) 45 | 46 | return ld 47 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/include/ch2_node_cpp/lifecyclenode2go.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 CH2_NODE_CPP__LIFECYCLENODE2GO_HPP_ 16 | #define CH2_NODE_CPP__LIFECYCLENODE2GO_HPP_ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include "lifecycle_msgs/msg/state.hpp" 23 | #include "rclcpp/rclcpp.hpp" 24 | #include "rclcpp_lifecycle/lifecycle_node.hpp" 25 | #include "sys/types.h" 26 | 27 | namespace ros_beginner 28 | { 29 | using CallbackReturn_T = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn; 30 | class LifecycleNode2Go : public rclcpp_lifecycle::LifecycleNode 31 | { 32 | public: 33 | explicit LifecycleNode2Go(const std::string & node_name); 34 | ~LifecycleNode2Go(); 35 | 36 | // Lifecycle functions 37 | CallbackReturn_T on_configure(const rclcpp_lifecycle::State &) override; 38 | // CallbackReturn_T on_activate(const rclcpp_lifecycle::State &); 39 | // CallbackReturn_T on_deactivate(const rclcpp_lifecycle::State &); 40 | CallbackReturn_T on_cleanup(const rclcpp_lifecycle::State &) override; 41 | CallbackReturn_T on_shutdown(const rclcpp_lifecycle::State &); 42 | 43 | private: 44 | rclcpp::TimerBase::SharedPtr printimer_; 45 | }; 46 | } // namespace ros_beginner 47 | #endif // CH2_NODE_CPP__LIFECYCLENODE2GO_HPP_ 48 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/launch/multi_exec.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import launch 16 | import launch_ros 17 | 18 | 19 | def generate_launch_description(): 20 | argument_node_count = launch.actions.DeclareLaunchArgument( 21 | 'node_count', default_value='1') 22 | argument_executor_type = launch.actions.DeclareLaunchArgument( 23 | 'executor_type', default_value='s') 24 | exec_multi_1 = launch_ros.actions.Node( 25 | package='ch2_node_cpp', 26 | executable='multinode', 27 | name='multi_1', 28 | exec_name='multi_first', 29 | arguments=[ 30 | launch.substitutions.LaunchConfiguration('node_count'), 31 | launch.substitutions.LaunchConfiguration('executor_type')], 32 | output='screen') 33 | exec_multi_2 = launch_ros.actions.Node( 34 | package='ch2_node_cpp', 35 | executable='multinode', 36 | name='multi_2', 37 | exec_name='multi_second', 38 | arguments=[ 39 | launch.substitutions.LaunchConfiguration('node_count'), 40 | launch.substitutions.LaunchConfiguration('executor_type')], 41 | output='screen') 42 | 43 | return launch.LaunchDescription([ 44 | argument_node_count, 45 | argument_executor_type, 46 | exec_multi_1, 47 | exec_multi_2 48 | ]) 49 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/sub_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | class SubNode : public rclcpp::Node 21 | { 22 | public: 23 | explicit SubNode(const std::string & node_name) 24 | : Node(node_name) 25 | { 26 | subsciber_ = this->create_subscription( 27 | "current_time", 28 | // rclcpp::SystemDefaultsQoS(), 29 | rclcpp::QoS(0).keep_all().transient_local().reliable(), 30 | std::bind(&SubNode::count_sub_callback, this, std::placeholders::_1)); 31 | } 32 | 33 | private: 34 | rclcpp::Subscription::SharedPtr subsciber_; 35 | void count_sub_callback(const std::shared_ptr msg) 36 | { 37 | RCLCPP_INFO_STREAM( 38 | this->get_logger(), 39 | "Sub: Current timestamp is : " << 40 | std::to_string(msg->sec) << 41 | " seconds, " << 42 | std::to_string(msg->nanosec) << 43 | " nanoseconds."); 44 | } 45 | }; 46 | 47 | int main(int argc, char ** argv) 48 | { 49 | rclcpp::init(argc, argv); 50 | auto node_ = std::make_shared("topic_sub"); 51 | rclcpp::executors::SingleThreadedExecutor executor_; 52 | 53 | executor_.add_node(node_); 54 | executor_.spin(); 55 | 56 | rclcpp::shutdown(); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch4_topic_cpp) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | # find dependencies 9 | find_package(ament_cmake REQUIRED) 10 | find_package(rclcpp REQUIRED) 11 | 12 | set(executable_pub pub_node) 13 | set(executable_sub sub_node) 14 | set(executable_self self_node) 15 | set(executable_intra intra_nodes) 16 | set(executable_loanp loan_pub) 17 | set(executable_stat stat_sub) 18 | 19 | set(dependencies 20 | rclcpp 21 | ) 22 | 23 | add_executable(${executable_pub} 24 | src/pub_node.cpp 25 | ) 26 | 27 | add_executable(${executable_sub} 28 | src/sub_node.cpp 29 | ) 30 | 31 | add_executable(${executable_self} 32 | src/self_node.cpp 33 | ) 34 | 35 | add_executable(${executable_intra} 36 | src/intra_nodes.cpp 37 | ) 38 | 39 | add_executable(${executable_loanp} 40 | src/loan_pub.cpp 41 | ) 42 | 43 | add_executable(${executable_stat} 44 | src/sub_statistics.cpp 45 | ) 46 | 47 | ament_target_dependencies(${executable_pub} 48 | ${dependencies} 49 | ) 50 | 51 | ament_target_dependencies(${executable_sub} 52 | ${dependencies} 53 | ) 54 | 55 | ament_target_dependencies(${executable_self} 56 | ${dependencies} 57 | ) 58 | 59 | ament_target_dependencies(${executable_intra} 60 | ${dependencies} 61 | ) 62 | 63 | ament_target_dependencies(${executable_loanp} 64 | ${dependencies} 65 | ) 66 | 67 | ament_target_dependencies(${executable_stat} 68 | ${dependencies} 69 | ) 70 | 71 | install( 72 | TARGETS ${executable_pub} 73 | TARGETS ${executable_sub} 74 | TARGETS ${executable_self} 75 | TARGETS ${executable_intra} 76 | TARGETS ${executable_loanp} 77 | TARGETS ${executable_stat} 78 | RUNTIME DESTINATION lib/${PROJECT_NAME} 79 | ) 80 | 81 | if(BUILD_TESTING) 82 | find_package(ament_lint_auto REQUIRED) 83 | ament_lint_auto_find_test_dependencies() 84 | endif() 85 | 86 | ament_package() 87 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_cpp/src/stuck_logger.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "rclcpp/rclcpp.hpp" 22 | #include "sys/types.h" 23 | 24 | namespace ros_beginner 25 | { 26 | using namespace std::chrono_literals; 27 | 28 | class LoggerTest : public rclcpp::Node 29 | { 30 | public: 31 | explicit LoggerTest(const std::string & node_name) 32 | : Node(node_name) 33 | { 34 | auto printimer_cb = 35 | [&]() -> void { 36 | pid_t pid = getpid(); 37 | std::cout << "missing log"; // << std::flush; 38 | RCLCPP_INFO_STREAM( 39 | this->get_logger(), "pid is " << pid << ", thread id is " << 40 | std::this_thread::get_id()); 41 | }; 42 | printimer_ = this->create_wall_timer(500ms, printimer_cb); 43 | } 44 | 45 | private: 46 | rclcpp::TimerBase::SharedPtr printimer_; 47 | }; 48 | } // namespace ros_beginner 49 | 50 | int main(int argc, char ** argv) 51 | { 52 | // setvbuf(stdout, NULL, _IONBF, BUFSIZ); 53 | rclcpp::init(argc, argv); 54 | auto logger_test = std::make_shared("cpp_log_test"); 55 | auto executor = std::make_unique(); 56 | executor->add_node(logger_test); 57 | executor->spin(); 58 | rclcpp::shutdown(); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_py/ch3_param_py/soliloquist.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | from rcl_interfaces.msg import SetParametersResult 16 | 17 | import rclpy 18 | 19 | from rclpy.node import Node 20 | from rclpy.parameter import Parameter 21 | 22 | 23 | class Soliloquist(Node): 24 | 25 | def __init__(self, name): 26 | super().__init__(name) 27 | self.declare_parameter(name='time_cycle_s', value=0.5) 28 | time_cycle = self.get_parameter('time_cycle_s') 29 | self.declare_parameter('output_str', 'hello world') 30 | self.output_str = self.get_parameter('output_str') 31 | self.timer_handler = self.create_timer(time_cycle.value, self.timer_callback) 32 | self.add_on_set_parameters_callback(self.param_callback) 33 | 34 | def timer_callback(self): 35 | self.get_logger().info(self.output_str.value) 36 | 37 | def param_callback(self, data): 38 | for parameter in data: 39 | if parameter.name == 'output_str': 40 | if parameter.type_ == Parameter.Type.STRING: 41 | self.output_str = parameter 42 | return SetParametersResult(successful=True) 43 | 44 | 45 | def main(args=None): 46 | rclpy.init(args=args) 47 | node = Soliloquist('py_soliloquist') 48 | executor = rclpy.executors.SingleThreadedExecutor() 49 | executor.add_node(node) 50 | executor.spin() 51 | rclpy.shutdown() 52 | 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_py/ch4_topic_py/self_node.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | from builtin_interfaces.msg import Time 16 | 17 | import rclpy 18 | 19 | from rclpy.node import Node 20 | 21 | 22 | class PubNodePy(Node): 23 | 24 | def __init__(self, name): 25 | super().__init__(name) 26 | self.publisher_ = self.create_publisher(Time, '_current_time', 10) 27 | self.publisher_.get_subscription_count() 28 | self.subscription_ = self.create_subscription( 29 | Time, '_current_time', self.sub_callback, 10) 30 | timer_period = 0.5 31 | self.timer = self.create_timer(timer_period, self.timer_callback) 32 | 33 | def timer_callback(self): 34 | msg = self.get_clock().now().to_msg() 35 | self.publisher_.publish(msg) 36 | self.get_logger().info( 37 | 'pub: Current timestamp is : ' + 38 | str(msg.sec) + 39 | ' seconds, ' + 40 | str(msg.nanosec) + 41 | ' nanoseconds.') 42 | 43 | def sub_callback(self, msg): 44 | self.get_logger().info( 45 | 'sub: Current timestamp is : ' + 46 | str(msg.sec) + 47 | ' seconds, ' + 48 | str(msg.nanosec) + 49 | ' nanoseconds.') 50 | 51 | 52 | def main(args=None): 53 | rclpy.init(args=args) 54 | node = PubNodePy('selftalk') 55 | executor = rclpy.executors.SingleThreadedExecutor() 56 | executor.add_node(node) 57 | executor.spin() 58 | rclpy.shutdown() 59 | 60 | 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /ch3/launch/ch3_launch/launch/mixed.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import os 16 | 17 | import ament_index_python 18 | import launch 19 | 20 | from launch.event_handlers.on_shutdown import OnShutdown 21 | from launch.launch_description_sources import PythonLaunchDescriptionSource 22 | from launch.substitutions import PathJoinSubstitution 23 | 24 | from launch_ros.substitutions import FindPackageShare 25 | 26 | 27 | def generate_launch_description(): 28 | ld = launch.LaunchDescription() 29 | 30 | ld.add_action(launch.actions.LogInfo(msg='Hi!')) 31 | node_count = launch.actions.DeclareLaunchArgument('node_count', default_value='100') 32 | ld.add_action(node_count) 33 | ld.add_action(launch.actions.DeclareLaunchArgument( 34 | 'executor_type', default_value='s')) 35 | ld.add_action(launch.actions.SetLaunchConfiguration('node_count', '1')) 36 | ld.add_action(launch.actions.SetEnvironmentVariable('ROS_DOMAIN_ID', '100')) 37 | ld.add_action(launch.actions.RegisterEventHandler( 38 | OnShutdown(on_shutdown=[launch.actions.LogInfo(msg='ROS Apps is exiting.')]))) 39 | 40 | ld.add_action(launch.actions.IncludeLaunchDescription( 41 | PythonLaunchDescriptionSource([os.path.join( 42 | ament_index_python.packages.get_package_share_directory('ch3_launch'), 'launch'), 43 | '/singlexec.launch.py']))) 44 | ld.add_action(launch.actions.IncludeLaunchDescription( 45 | PythonLaunchDescriptionSource(PathJoinSubstitution([ 46 | FindPackageShare('ch3_launch'), 'launch', 'multi_pkg.launch.py'])))) 47 | 48 | return ld 49 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/sub_statistics.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | class SubNode : public rclcpp::Node 22 | { 23 | public: 24 | explicit SubNode(const std::string & node_name) 25 | : Node(node_name) 26 | { 27 | auto sub_options = rclcpp::SubscriptionOptions(); 28 | sub_options.topic_stats_options.state = rclcpp::TopicStatisticsState::Enable; 29 | sub_options.topic_stats_options.publish_period = std::chrono::seconds(10); 30 | subsciber_ = this->create_subscription( 31 | "current_time", 32 | rclcpp::SystemDefaultsQoS(), 33 | std::bind(&SubNode::count_sub_callback, this, std::placeholders::_1), 34 | sub_options); 35 | } 36 | 37 | private: 38 | rclcpp::Subscription::SharedPtr subsciber_; 39 | void count_sub_callback(const std::shared_ptr msg) 40 | { 41 | RCLCPP_INFO_STREAM( 42 | this->get_logger(), 43 | "Sub: Current timestamp is : " << 44 | std::to_string(msg->sec) << 45 | " seconds, " << 46 | std::to_string(msg->nanosec) << 47 | " nanoseconds."); 48 | } 49 | }; 50 | 51 | int main(int argc, char ** argv) 52 | { 53 | rclcpp::init(argc, argv); 54 | auto node_ = std::make_shared("statistic_sub"); 55 | rclcpp::executors::SingleThreadedExecutor executor_; 56 | 57 | executor_.add_node(node_); 58 | executor_.spin(); 59 | 60 | rclcpp::shutdown(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /ch6/ch6_unittest_cpp/test/monkey_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | 17 | #include "ch6_unittest_cpp/monkey.hpp" 18 | #include "gtest/gtest.h" 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | class TestNode : public ::testing::Test 22 | { 23 | protected: 24 | static void SetUpTestCase() 25 | { 26 | rclcpp::init(0, nullptr); 27 | } 28 | 29 | static void TearDownTestCase() 30 | { 31 | rclcpp::shutdown(); 32 | } 33 | }; 34 | 35 | TEST(MonkeyRawTest, initBananas) 36 | { 37 | rclcpp::init(0, nullptr); 38 | auto monkey_raw = std::make_shared("first_monkey", 100); 39 | ASSERT_EQ(monkey_raw->check_bananas(), 100); 40 | ASSERT_STREQ(monkey_raw->get_name(), "first_monkey"); 41 | rclcpp::shutdown(); 42 | } 43 | 44 | TEST(MonkeyRawTest, faileInitMonkey) 45 | { 46 | ASSERT_THROW(std::make_shared("another_monkey"), rclcpp::exceptions::RCLError); 47 | } 48 | 49 | TEST_F(TestNode, setBananas) 50 | { 51 | auto monkey_raw = std::make_unique("second_monkey"); 52 | EXPECT_TRUE(monkey_raw->add_bananas(99)); 53 | ASSERT_EQ(monkey_raw->check_bananas(), 99); 54 | } 55 | 56 | TEST_F(TestNode, eatAfterInitAndSet) 57 | { 58 | auto monkey_raw = std::make_unique("third_monkey", 10); 59 | EXPECT_TRUE(monkey_raw->add_bananas(20)); 60 | EXPECT_FALSE(monkey_raw->eat_bananas(100)); 61 | EXPECT_EQ(monkey_raw->check_bananas(), 30); 62 | EXPECT_TRUE(monkey_raw->eat_bananas(15)); 63 | ASSERT_EQ(monkey_raw->check_bananas(), 15); 64 | } 65 | 66 | int main(int argc, char ** argv) 67 | { 68 | testing::InitGoogleTest(&argc, argv); 69 | return RUN_ALL_TESTS(); 70 | } 71 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_main/src/withnode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "pluginlib/class_loader.hpp" 20 | #include "ch3_plugin_base/pluginbase.hpp" 21 | #include "rclcpp/rclcpp.hpp" 22 | 23 | class TestNode : public rclcpp::Node 24 | { 25 | public: 26 | explicit TestNode(const std::string & node_name) 27 | : Node(node_name) 28 | { 29 | using namespace std::chrono_literals; 30 | this->declare_parameter("plugin_name", "AlphaB"); 31 | loader = std::make_shared>( 32 | "ch3_plugin_base", 33 | "ch3::plugin::PluginBase"); 34 | auto printimer_callback = 35 | [&]() -> void { 36 | auto plugin_name = this->get_parameter("plugin_name").as_string(); 37 | try { 38 | auto plugin_instance = loader->createUniqueInstance(plugin_name); 39 | plugin_instance->say_hello(1); 40 | } catch (pluginlib::PluginlibException & ex) { 41 | printf("Failed to load PluginBeta. Error: %s\n", ex.what()); 42 | } 43 | }; 44 | timer_ = this->create_wall_timer(500ms, printimer_callback); 45 | } 46 | 47 | private: 48 | rclcpp::TimerBase::SharedPtr timer_; 49 | std::shared_ptr> loader; 50 | }; 51 | 52 | int main(int argc, char ** argv) 53 | { 54 | rclcpp::init(argc, argv); 55 | auto node_ = std::make_shared("plugin_test_node"); 56 | rclcpp::executors::SingleThreadedExecutor executor_; 57 | 58 | executor_.add_node(node_); 59 | executor_.spin(); 60 | 61 | rclcpp::shutdown(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_alpha/src/pluginalpha.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "ch3_plugin_base/pluginbase.hpp" 19 | #include "pluginlib/class_list_macros.hpp" 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | namespace ch3 23 | { 24 | namespace plugin 25 | { 26 | class PluginAlphaA : public PluginBase 27 | { 28 | public: 29 | PluginAlphaA() {} 30 | void say_hello(const int32_t & times) override 31 | { 32 | auto times_(times); 33 | while (--times_ >= 0) { 34 | RCLCPP_INFO(rclcpp::get_logger("PluginAlphaA"), "Hello A alpha"); 35 | } 36 | } 37 | bool say_something(const std::string & something) override 38 | { 39 | if (something.size() == 0) { 40 | return false; 41 | } else { 42 | RCLCPP_INFO_STREAM(rclcpp::get_logger("PluginAlphaA"), something); 43 | return true; 44 | } 45 | } 46 | }; 47 | 48 | class PluginAlphaB : public PluginBase 49 | { 50 | public: 51 | PluginAlphaB() {} 52 | void say_hello(const int32_t & times) override 53 | { 54 | auto times_(times); 55 | while (--times_ >= 0) { 56 | RCLCPP_INFO(rclcpp::get_logger("PluginAlphaB"), "Hello B alpha"); 57 | } 58 | } 59 | bool say_something(const std::string & something) override 60 | { 61 | if (something.size() == 0) { 62 | return false; 63 | } else { 64 | RCLCPP_INFO_STREAM(rclcpp::get_logger("PluginAlphaB"), something); 65 | return true; 66 | } 67 | } 68 | }; 69 | } // namespace plugin 70 | } // namespace ch3 71 | 72 | PLUGINLIB_EXPORT_CLASS(ch3::plugin::PluginAlphaA, ch3::plugin::PluginBase) 73 | PLUGINLIB_EXPORT_CLASS(ch3::plugin::PluginAlphaB, ch3::plugin::PluginBase) 74 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/multinode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "ch2_node_cpp/node2go.hpp" 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | int main(int argc, char ** argv) 23 | { 24 | rclcpp::init(argc, argv); 25 | uint32_t node_count(0); 26 | bool is_multi(false); 27 | std::vector> node_vector; 28 | rclcpp::executors::SingleThreadedExecutor executor_s; 29 | rclcpp::executors::MultiThreadedExecutor executor_m; 30 | 31 | if (argc >= 3) { 32 | int input_count = atoi(argv[1]); 33 | node_count = input_count > 0 ? input_count : 0; 34 | node_vector.reserve(node_count); 35 | std::string multi_flag = static_cast(argv[2]); 36 | if (multi_flag == std::string("m")) { 37 | is_multi = true; 38 | } else if (multi_flag == std::string("s")) { 39 | is_multi = false; 40 | } else { 41 | std::cout << "Example: ros2 run ch2_node_cpp getid s/m" << std::endl; 42 | return 0; 43 | } 44 | } else { 45 | std::cout << "Example: ros2 run ch2_node_cpp getid s/m" << std::endl; 46 | return 0; 47 | } 48 | 49 | for (int i = node_count; i--; ) { 50 | node_vector.push_back( 51 | std::make_shared( 52 | "cpp_node_a_" + 53 | std::to_string(i))); 54 | if (is_multi) {executor_m.add_node(node_vector.back()->get_node_base_interface());} else { 55 | executor_s.add_node(node_vector.back()->get_node_base_interface()); 56 | } 57 | } 58 | if (is_multi) {executor_m.spin();} else {executor_s.spin();} 59 | 60 | rclcpp::shutdown(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/lifecyclenode2go.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "ch2_node_cpp/lifecyclenode2go.hpp" 20 | 21 | namespace ros_beginner 22 | { 23 | using namespace std::chrono_literals; 24 | LifecycleNode2Go::LifecycleNode2Go(const std::string & node_name) 25 | : rclcpp_lifecycle::LifecycleNode(node_name) 26 | {} 27 | 28 | LifecycleNode2Go::~LifecycleNode2Go() 29 | {} 30 | 31 | CallbackReturn_T LifecycleNode2Go::on_configure(const rclcpp_lifecycle::State &) 32 | { 33 | std::cout << "Configuring node [" << this->get_name() << "]." << std::endl; 34 | auto printimer_callback = 35 | [&]() -> void { 36 | if (this->get_current_state().id() == lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) { 37 | pid_t pid = getpid(); 38 | std::cout << this->get_name() << ": pid is " << pid << ", thread id is " << 39 | std::this_thread::get_id() << std::endl; 40 | } 41 | }; 42 | printimer_ = this->create_wall_timer(500ms, printimer_callback); 43 | return CallbackReturn_T::SUCCESS; 44 | } 45 | 46 | CallbackReturn_T LifecycleNode2Go::on_cleanup(const rclcpp_lifecycle::State &) 47 | { 48 | std::cout << "Cleaning up node [" << this->get_name() << "]." << std::endl; 49 | printimer_->cancel(); 50 | return CallbackReturn_T::SUCCESS; 51 | } 52 | 53 | CallbackReturn_T LifecycleNode2Go::on_shutdown(const rclcpp_lifecycle::State &) 54 | { 55 | std::cout << "Shutting down node [" << this->get_name() << "]." << std::endl; 56 | if (!printimer_->is_canceled()) { 57 | printimer_->cancel(); 58 | } 59 | printimer_->reset(); 60 | return CallbackReturn_T::SUCCESS; 61 | } 62 | 63 | } // namespace ros_beginner 64 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/loan_pub.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | class PubNode : public rclcpp::Node 22 | { 23 | public: 24 | explicit PubNode(const std::string & node_name) 25 | : Node(node_name) 26 | { 27 | using namespace std::chrono_literals; 28 | publisher_ = this->create_publisher( 29 | "current_time", 30 | rclcpp::SystemDefaultsQoS()); 31 | auto topictimer_callback = 32 | [&]() -> void { 33 | auto loan_time_ = publisher_->borrow_loaned_message(); 34 | loan_time_.get() = this->get_clock()->now(); 35 | RCLCPP_INFO_STREAM( 36 | this->get_logger(), 37 | "pub: Current timestamp is : " << 38 | std::to_string(loan_time_.get().sec) << 39 | " seconds, " << 40 | std::to_string(loan_time_.get().nanosec) << 41 | " nanoseconds."); 42 | publisher_->publish(std::move(loan_time_)); 43 | }; 44 | timer_ = this->create_wall_timer(500ms, topictimer_callback); 45 | } 46 | 47 | private: 48 | rclcpp::TimerBase::SharedPtr timer_; 49 | rclcpp::Publisher::SharedPtr publisher_; 50 | }; 51 | 52 | int main(int argc, char ** argv) 53 | { 54 | rclcpp::init(argc, argv); 55 | auto node_ = std::make_shared("topic_pub"); 56 | rclcpp::executors::SingleThreadedExecutor executor_; 57 | rclcpp::NodeOptions options; 58 | auto context_ = std::make_shared(); 59 | options.context(context_); 60 | 61 | 62 | executor_.add_node(node_); 63 | executor_.spin(); 64 | 65 | rclcpp::shutdown(); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/pub_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | class PubNode : public rclcpp::Node 21 | { 22 | public: 23 | explicit PubNode(const std::string & node_name) 24 | : Node(node_name) 25 | { 26 | using namespace std::chrono_literals; 27 | publisher_ = this->create_publisher( 28 | "current_time", 29 | // rclcpp::SystemDefaultsQoS()); 30 | rclcpp::QoS(0).keep_all().transient_local().reliable()); 31 | auto topictimer_callback = 32 | [&]() -> void { 33 | timestamp_ = this->get_clock()->now(); 34 | RCLCPP_INFO_STREAM( 35 | this->get_logger(), 36 | "pub: Current timestamp is : " << 37 | std::to_string(timestamp_.sec) << 38 | " seconds, " << 39 | std::to_string(timestamp_.nanosec) << 40 | " nanoseconds."); 41 | publisher_->publish(timestamp_); 42 | }; 43 | timer_ = this->create_wall_timer(500ms, topictimer_callback); 44 | } 45 | 46 | private: 47 | builtin_interfaces::msg::Time timestamp_; 48 | rclcpp::TimerBase::SharedPtr timer_; 49 | rclcpp::Publisher::SharedPtr publisher_; 50 | }; 51 | 52 | int main(int argc, char ** argv) 53 | { 54 | rclcpp::init(argc, argv); 55 | auto node_ = std::make_shared("topic_pub"); 56 | rclcpp::executors::SingleThreadedExecutor executor_; 57 | rclcpp::NodeOptions options; 58 | auto context_ = std::make_shared(); 59 | options.context(context_); 60 | 61 | 62 | executor_.add_node(node_); 63 | executor_.spin(); 64 | 65 | rclcpp::shutdown(); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /ch3/component/ch3_component/src/com1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | #include "rclcpp_components/register_node_macro.hpp" 22 | #include "sys/types.h" 23 | 24 | namespace ros_beginner 25 | { 26 | using namespace std::chrono_literals; 27 | 28 | class Component1 : public rclcpp::Node 29 | { 30 | public: 31 | explicit Component1(const rclcpp::NodeOptions & node_options) 32 | : Node("component_1", node_options) 33 | { 34 | auto printimer_cb = 35 | [&]() -> void { 36 | pid_t pid = getpid(); 37 | RCLCPP_INFO_STREAM( 38 | this->get_logger(), 39 | this->get_name() << ": pid is " << pid << ", thread id is " << 40 | std::this_thread::get_id()); 41 | }; 42 | printimer_ = this->create_wall_timer(500ms, printimer_cb); 43 | } 44 | 45 | private: 46 | rclcpp::TimerBase::SharedPtr printimer_; 47 | }; 48 | class Component3 : public rclcpp::Node 49 | { 50 | public: 51 | explicit Component3(const rclcpp::NodeOptions & node_options) 52 | : Node("component_3", node_options) 53 | { 54 | auto printimer_cb = 55 | [&]() -> void { 56 | pid_t pid = getpid(); 57 | RCLCPP_INFO_STREAM( 58 | this->get_logger(), 59 | this->get_name() << ": pid is " << pid << ", thread id is " << 60 | std::this_thread::get_id()); 61 | }; 62 | printimer_ = this->create_wall_timer(500ms, printimer_cb); 63 | } 64 | 65 | private: 66 | rclcpp::TimerBase::SharedPtr printimer_; 67 | }; 68 | } // namespace ros_beginner 69 | 70 | RCLCPP_COMPONENTS_REGISTER_NODE(ros_beginner::Component1) 71 | RCLCPP_COMPONENTS_REGISTER_NODE(ros_beginner::Component3) 72 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/src/multilifecyclenode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "ch2_node_cpp/lifecyclenode2go.hpp" 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | int main(int argc, char ** argv) 23 | { 24 | rclcpp::init(argc, argv); 25 | uint32_t node_count(0); 26 | bool is_multi(false); 27 | std::vector> node_vector; 28 | rclcpp::executors::SingleThreadedExecutor executor_s; 29 | rclcpp::executors::MultiThreadedExecutor executor_m; 30 | 31 | if (argc >= 3) { 32 | int input_count = atoi(argv[1]); 33 | node_count = input_count > 0 ? input_count : 0; 34 | node_vector.reserve(node_count); 35 | std::string multi_flag = static_cast(argv[2]); 36 | if (multi_flag == std::string("m")) { 37 | is_multi = true; 38 | } else if (multi_flag == std::string("s")) { 39 | is_multi = false; 40 | } else { 41 | std::cout << "Example: ros2 run ch2_node_cpp multilifecyclenode s/m" << 42 | std::endl; 43 | return 0; 44 | } 45 | } else { 46 | std::cout << "Example: ros2 run ch2_node_cpp multilifecyclenode s/m" << std::endl; 47 | return 0; 48 | } 49 | 50 | for (int i = node_count; i--; ) { 51 | node_vector.push_back( 52 | std::make_shared( 53 | "cpp_node_a_" + 54 | std::to_string(i))); 55 | if (is_multi) {executor_m.add_node(node_vector.back()->get_node_base_interface());} else { 56 | executor_s.add_node(node_vector.back()->get_node_base_interface()); 57 | } 58 | } 59 | if (is_multi) {executor_m.spin();} else {executor_s.spin();} 60 | 61 | rclcpp::shutdown(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /ch3/plugin/ch3_plugin_main/src/withoutnode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "pluginlib/class_loader.hpp" 19 | #include "ch3_plugin_base/pluginbase.hpp" 20 | 21 | int main(int argc, char ** argv) 22 | { 23 | (void) argc; 24 | (void) argv; 25 | 26 | pluginlib::ClassLoader loader( 27 | "ch3_plugin_base", 28 | "ch3::plugin::PluginBase"); 29 | // for (const auto & xml_path : loader.getPluginXmlPaths()) { 30 | // std::cout << "xml path : " << xml_path << std::endl; 31 | // } 32 | // if (loader.isClassAvailable("ch3::plugin::PluginAlphaA")) { 33 | // std::cout << "Ready to load 'ch3::plugin::PluginAlphaA'" << std::endl; 34 | // loader.loadLibraryForClass("ch3::plugin::PluginAlphaA"); 35 | // } 36 | // std::cout << "Load plugin " 37 | // << loader.isClassAvailable("ch3::plugin::PluginAlphaA") << std::endl; 38 | 39 | try { 40 | auto alpha_a = loader.createUniqueInstance("ch3::plugin::PluginAlphaA"); 41 | auto alpha_b = loader.createUniqueInstance("AlphaB"); 42 | 43 | alpha_a->say_hello(2); 44 | alpha_b->say_hello(1); 45 | } catch (pluginlib::PluginlibException & ex) { 46 | printf("Failed to load PluginAlpha. Error: %s\n", ex.what()); 47 | } 48 | 49 | try { 50 | auto beta_name = loader.createUniqueInstance("BetaPluginNewName"); 51 | beta_name->say_something("using plugin name"); 52 | } catch (pluginlib::PluginlibException & ex) { 53 | printf("Failed to load PluginBeta. Error: %s\n", ex.what()); 54 | } 55 | 56 | try { 57 | auto gamma = loader.createUniqueInstance("ch3::plugin::PluginGamma"); 58 | gamma->say_hello(1); 59 | } catch (pluginlib::PluginlibException & ex) { 60 | printf("Failed to load PluginGamma. Error: %s\n", ex.what()); 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /ch5/tf2/ch5_tf2_cpp/src/dynamic_transform.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "geometry_msgs/msg/pose_stamped.hpp" 20 | #include "geometry_msgs/msg/transform_stamped.hpp" 21 | #include "rclcpp/rclcpp.hpp" 22 | #include "tf2/LinearMath/Quaternion.h" 23 | #include "tf2_ros/buffer.h" 24 | #include "tf2_ros/transform_broadcaster.h" 25 | #include "tf2_ros/transform_listener.h" 26 | 27 | class DynamicTransform : public rclcpp::Node 28 | { 29 | public: 30 | explicit DynamicTransform(const std::string & node_name) 31 | : Node(node_name) 32 | { 33 | using namespace std::chrono_literals; 34 | delta_ = 0.0; 35 | tf_publisher_ = std::make_shared(this); 36 | tf_timer_ = 37 | this->create_wall_timer(30ms, std::bind(&DynamicTransform::update_transform, this)); 38 | } 39 | 40 | private: 41 | void update_transform() 42 | { 43 | rclcpp::Time now = this->get_clock()->now(); 44 | geometry_msgs::msg::TransformStamped trans; 45 | tf2::Quaternion quat; 46 | 47 | trans.header.stamp = now; 48 | trans.header.frame_id = "map"; 49 | trans.child_frame_id = "robot"; 50 | trans.transform.translation.x = delta_; 51 | trans.transform.translation.y = 0; 52 | trans.transform.translation.z = 0; 53 | quat.setRPY(0, 0, 0); 54 | trans.transform.rotation.x = quat.x(); 55 | trans.transform.rotation.y = quat.y(); 56 | trans.transform.rotation.z = quat.z(); 57 | trans.transform.rotation.w = quat.w(); 58 | 59 | tf_publisher_->sendTransform(trans); 60 | delta_ += 0.01; 61 | } 62 | std::shared_ptr tf_publisher_; 63 | rclcpp::TimerBase::SharedPtr tf_timer_; 64 | double delta_; 65 | }; 66 | 67 | int main(int argc, char ** argv) 68 | { 69 | rclcpp::init(argc, argv); 70 | rclcpp::spin(std::make_shared("dynamic_tf_node")); 71 | rclcpp::shutdown(); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /ch6/ch6_bag_cpp/src/pubdata.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | class PubNode : public rclcpp::Node 22 | { 23 | public: 24 | explicit PubNode(const std::string & node_name) 25 | : Node(node_name) 26 | { 27 | using namespace std::chrono_literals; 28 | time_publisher_ = this->create_publisher( 29 | "current_time", 30 | rclcpp::SystemDefaultsQoS()); 31 | duration_publisher_ = this->create_publisher( 32 | "current_duration", 33 | rclcpp::SystemDefaultsQoS()); 34 | ts_init_ = this->get_clock()->now(); 35 | auto topictimer_callback = 36 | [&]() -> void { 37 | auto timestamp = std::make_unique(this->get_clock()->now()); 38 | auto duration = std::make_unique(); 39 | duration->sec = timestamp->sec - ts_init_.seconds(); 40 | duration->nanosec = timestamp->nanosec - ts_init_.nanoseconds(); 41 | time_publisher_->publish(std::move(timestamp)); 42 | duration_publisher_->publish(std::move(duration)); 43 | }; 44 | timer_ = this->create_wall_timer(500ms, topictimer_callback); 45 | } 46 | 47 | private: 48 | rclcpp::TimerBase::SharedPtr timer_; 49 | rclcpp::Time ts_init_; 50 | rclcpp::Publisher::SharedPtr time_publisher_; 51 | rclcpp::Publisher::SharedPtr duration_publisher_; 52 | }; 53 | 54 | int main(int argc, char ** argv) 55 | { 56 | rclcpp::init(argc, argv); 57 | auto node = std::make_shared("topic_pub"); 58 | auto executor_ = std::make_unique(); 59 | auto current_time = node->get_clock()->now(); 60 | executor_->add_node(node); 61 | RCLCPP_INFO(node->get_logger(), "Begin."); 62 | while (node->get_clock()->now() - current_time <= std::chrono::milliseconds(10'000)) { 63 | executor_->spin_some(); 64 | } 65 | RCLCPP_INFO(node->get_logger(), "End."); 66 | rclcpp::shutdown(); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_py/ch4_service_py/self_service.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import rclpy 16 | import rclpy.executors 17 | 18 | from rclpy.node import Node 19 | from rcl_interfaces.msg import Parameter 20 | from rcl_interfaces.srv import GetParameters 21 | 22 | 23 | class ServerNode(Node): 24 | 25 | def __init__(self, name): 26 | super().__init__(name) 27 | self.callback_group = rclpy.callback_groups.ReentrantCallbackGroup() 28 | self.serv_ = self.create_service(GetParameters, 'get_para', self.srv_callback, 29 | callback_group=self.callback_group) 30 | 31 | def srv_callback(self, request, response): 32 | para_ = Parameter() 33 | para_.value.bool_value = bool(request.names) 34 | self.get_logger().info('Request: ' + request.names[0]) 35 | response.values.append(para_.value) 36 | return response 37 | 38 | 39 | class ClientNode(Node): 40 | 41 | def __init__(self, name): 42 | super().__init__(name) 43 | self.callback_group = rclpy.callback_groups.ReentrantCallbackGroup() 44 | self.client_ = self.create_client(GetParameters, 'get_para') 45 | self.create_timer(0.5, self.clientimer_callback, self.callback_group) 46 | 47 | def clientimer_callback(self): 48 | request_ = GetParameters.Request() 49 | now_sec, _ = self.get_clock().now().seconds_nanoseconds() 50 | self.get_logger().info('Ready to send req') 51 | request_.names.append(str(now_sec)) 52 | future_ = self.client_.call(request_) 53 | self.get_logger().info('Sent req') 54 | 55 | response_value_ = future_.values[0] 56 | if bool(response_value_.bool_value): 57 | self.get_logger().info('Got response succeed') 58 | 59 | 60 | def main(args=None): 61 | rclpy.init(args=args) 62 | srv_node = ServerNode('service_server') 63 | cli_node = ClientNode('service_client') 64 | executor = rclpy.executors.MultiThreadedExecutor() 65 | executor.add_node(srv_node) 66 | executor.add_node(cli_node) 67 | executor.spin() 68 | rclpy.shutdown() 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/self_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | class SelfNode : public rclcpp::Node 21 | { 22 | public: 23 | explicit SelfNode(const std::string & node_name) 24 | : Node(node_name) 25 | { 26 | using namespace std::chrono_literals; 27 | subsciber_ = this->create_subscription( 28 | "current_time", 29 | rclcpp::SystemDefaultsQoS(), 30 | std::bind(&SelfNode::count_sub_callback, this, std::placeholders::_1)); 31 | publisher_ = this->create_publisher( 32 | "current_time", 33 | rclcpp::SystemDefaultsQoS()); 34 | auto topictimer_callback = 35 | [&]() -> void { 36 | timestamp_ = this->get_clock()->now(); 37 | RCLCPP_INFO_STREAM( 38 | this->get_logger(), 39 | "pub: Current timestamp is : " << 40 | std::to_string(timestamp_.sec) << 41 | " second, " << 42 | std::to_string(timestamp_.nanosec) << 43 | " nanosecond."); 44 | publisher_->publish(timestamp_); 45 | }; 46 | timer_ = this->create_wall_timer(1s, topictimer_callback); 47 | } 48 | 49 | private: 50 | builtin_interfaces::msg::Time timestamp_; 51 | rclcpp::TimerBase::SharedPtr timer_; 52 | rclcpp::Publisher::SharedPtr publisher_; 53 | rclcpp::Subscription::SharedPtr subsciber_; 54 | void count_sub_callback(const std::shared_ptr msg) 55 | { 56 | RCLCPP_INFO_STREAM( 57 | this->get_logger(), 58 | "Sub: Current timestamp is : " << 59 | std::to_string(msg->sec) << 60 | " second, " << 61 | std::to_string(msg->nanosec) << 62 | " nanosecond."); 63 | } 64 | }; 65 | 66 | int main(int argc, char ** argv) 67 | { 68 | rclcpp::init(argc, argv); 69 | auto node_ = std::make_shared("topic_self"); 70 | rclcpp::executors::SingleThreadedExecutor executor_; 71 | 72 | executor_.add_node(node_); 73 | executor_.spin(); 74 | 75 | rclcpp::shutdown(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /ch7/diagnostics/ch7_diagnostics_cpp/src/freq_checker.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | #include "diagnostic_updater/diagnostic_updater.hpp" 20 | #include "diagnostic_updater/publisher.hpp" 21 | #include "diagnostic_updater/update_functions.hpp" 22 | #include "sensor_msgs/msg/range.hpp" 23 | 24 | void tick_freq(diagnostic_updater::DiagnosticStatusWrapper & stat) 25 | { 26 | stat.summary(diagnostic_msgs::msg::DiagnosticStatus::OK, "Tick tick"); 27 | } 28 | 29 | int main(int argc, char ** argv) 30 | { 31 | rclcpp::init(argc, argv); 32 | auto node_n = rclcpp::Node::make_shared("n_node"); 33 | auto exec = std::make_unique(); 34 | 35 | diagnostic_updater::Updater updater_n(node_n); 36 | updater_n.setHardwareID("normal"); 37 | double min_freq(29.0); 38 | double max_freq(31.0); 39 | diagnostic_updater::HeaderlessTopicDiagnostic hdls_freq_checker( 40 | "rate_freq_1", updater_n, 41 | diagnostic_updater::FrequencyStatusParam(&min_freq, &max_freq, 0.1, 10)); 42 | diagnostic_updater::FunctionDiagnosticTask freq_task( 43 | "Tick frequncy checker task", std::bind(&tick_freq, std::placeholders::_1)); 44 | hdls_freq_checker.addTask(&freq_task); 45 | 46 | diagnostic_updater::FrequencyStatusParam freq_param(&min_freq, &max_freq); 47 | diagnostic_updater::TimeStampStatusParam ts_param(-1.0, 3.0); 48 | diagnostic_updater::TopicDiagnostic freq_checker("rate_freq_2", updater_n, freq_param, ts_param); 49 | 50 | auto range_pub = 51 | node_n->create_publisher("range", rclcpp::SystemDefaultsQoS()); 52 | diagnostic_updater::DiagnosedPublisher diag_pub(range_pub, updater_n, 53 | freq_param, ts_param); 54 | sensor_msgs::msg::Range range; 55 | 56 | exec->add_node(node_n); 57 | rclcpp::Rate r(30); 58 | while (rclcpp::ok()) { 59 | exec->spin_some(); 60 | hdls_freq_checker.tick(); 61 | // range.header.stamp = node_n->get_clock()->now(); 62 | // freq_checker.tick(range.header.stamp); 63 | // diag_pub.publish(range); 64 | r.sleep(); 65 | } 66 | rclcpp::shutdown(); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /ch3/logging/ch3_logging_cpp/src/logger_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "rclcpp/rclcpp.hpp" 22 | #include "sys/types.h" 23 | 24 | namespace ros_beginner 25 | { 26 | using namespace std::chrono_literals; 27 | 28 | class LoggerTest : public rclcpp::Node 29 | { 30 | public: 31 | explicit LoggerTest(const std::string & node_name) 32 | : Node(node_name) 33 | { 34 | auto printimer_cb = 35 | [&]() -> void { 36 | pid_t pid = getpid(); 37 | std::cout << this->get_name() << ": pid is " << pid << ", thread id is " << 38 | std::this_thread::get_id() << std::endl; 39 | }; 40 | printimer_ = this->create_wall_timer(500ms, printimer_cb); 41 | auto condition_func = 42 | [&](const bool cond) -> bool { 43 | return cond; 44 | }; 45 | std::function condition_func_true = std::bind(condition_func, true); 46 | std::function condition_func_false = std::bind(condition_func, false); 47 | RCLCPP_INFO(this->get_logger(), "[info] inside log [%s]", this->get_name()); 48 | RCLCPP_INFO_STREAM(this->get_logger(), "[info-stream] inside log [" << this->get_name() << "]"); 49 | RCLCPP_INFO_FUNCTION( 50 | this->get_logger(), 51 | &condition_func_true, 52 | "[info-func] func log true output"); 53 | RCLCPP_INFO_FUNCTION( 54 | this->get_logger(), 55 | &condition_func_false, 56 | "[info-func] func log false output"); 57 | } 58 | 59 | private: 60 | rclcpp::TimerBase::SharedPtr printimer_; 61 | }; 62 | } // namespace ros_beginner 63 | 64 | int main(int argc, char ** argv) 65 | { 66 | rclcpp::init(argc, argv); 67 | auto logger_test = std::make_shared("cpp_log_test"); 68 | for (int i = 0; i < 5; i++) { 69 | RCLCPP_INFO_STREAM_ONCE( 70 | logger_test->get_logger(), "[info-once] outside log, flag: " << std::to_string(i)); 71 | RCLCPP_INFO_STREAM( 72 | logger_test->get_logger(), 73 | "[info-stream] outside log, flag: " << std::to_string(i)); 74 | RCLCPP_INFO_STREAM_SKIPFIRST( 75 | logger_test->get_logger(), 76 | "[info-stream-skipfirst] outside log, flag: " << std::to_string(i)); 77 | } 78 | rclcpp::shutdown(); 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /ch3/param/ch3_param_cpp/src/soliloquist.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "rclcpp/rclcpp.hpp" 19 | 20 | namespace ros_beginner 21 | { 22 | 23 | class Soliloquist : public rclcpp::Node 24 | { 25 | public: 26 | explicit Soliloquist() 27 | : Node("cpp_soliloquist") 28 | { 29 | this->declare_parameter("time_cycle_ms", 500); 30 | this->declare_parameter("output_str", "hello_world"); 31 | time_cycle_ms_ = this->get_parameter("time_cycle_ms").as_int(); 32 | output_str_ = std::make_shared(this->get_parameter("output_str").as_string()); 33 | auto printimer_cb = 34 | [&]() -> void { 35 | RCLCPP_INFO_STREAM(this->get_logger(), *output_str_); 36 | }; 37 | auto param_cb = 38 | [&](const std::vector & parameters) -> rcl_interfaces::msg:: 39 | SetParametersResult { 40 | rcl_interfaces::msg::SetParametersResult result; 41 | result.successful = false; 42 | result.reason = "nothing changed"; 43 | 44 | for (const auto & para : parameters) { 45 | RCLCPP_INFO_STREAM(this->get_logger(), para.get_name()); 46 | if (para.get_name().compare("output_str") == 0) { 47 | if (!para.as_string().empty() && para.as_string().compare(*output_str_)) { 48 | output_str_ = std::make_shared(para.as_string()); 49 | RCLCPP_WARN_STREAM(this->get_logger(), "Output string changed."); 50 | result.successful = true; 51 | result.reason = "success"; 52 | } 53 | } 54 | } 55 | 56 | return result; 57 | }; 58 | printimer_ = this->create_wall_timer(std::chrono::milliseconds(time_cycle_ms_), printimer_cb); 59 | paramhandle_ = this->add_on_set_parameters_callback(param_cb); 60 | } 61 | 62 | private: 63 | int time_cycle_ms_; 64 | std::shared_ptr output_str_; 65 | rclcpp::TimerBase::SharedPtr printimer_; 66 | OnSetParametersCallbackHandle::SharedPtr paramhandle_; 67 | }; 68 | } // namespace ros_beginner 69 | 70 | int main(int argc, char ** argv) 71 | { 72 | rclcpp::init(argc, argv); 73 | auto node_ = std::make_shared(); 74 | auto exec_ = std::make_shared(); 75 | exec_->add_node(node_->get_node_base_interface()); 76 | exec_->spin(); 77 | rclcpp::shutdown(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_py/ch5_action_py/self_node.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Homalozoa 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 | import time 16 | 17 | from ch5_action_interfaces.action import Count 18 | 19 | import rclpy 20 | import rclpy.action 21 | import rclpy.callback_groups 22 | import rclpy.executors 23 | 24 | from rclpy.node import Node 25 | 26 | 27 | class ActionNodePy(Node): 28 | 29 | def __init__(self, name): 30 | super().__init__(name) 31 | self.global_count_ = 0 32 | self.callback_group = rclpy.callback_groups.ReentrantCallbackGroup() 33 | self.server_ = rclpy.action.ActionServer(self, Count, 'sec_count', self.count_callback, 34 | callback_group=self.callback_group, 35 | cancel_callback=self.cancel_callback) 36 | self.client_ = rclpy.action.ActionClient(self, Count, 'sec_count') 37 | timer_period = 9 38 | self.timer = self.create_timer(timer_period, self.timer_callback) 39 | 40 | def timer_callback(self): 41 | goal = Count.Goal() 42 | goal.goal_count = 3 43 | self.client_.send_goal_async(goal) 44 | self.get_logger().info('Send goal: ' + str(goal.goal_count)) 45 | 46 | def cancel_callback(self, goal_handle): 47 | self.get_logger().info('Received cancel request') 48 | return rclpy.action.CancelResponse.ACCEPT 49 | 50 | def count_callback(self, goal_handle): 51 | result = Count.Result() 52 | feedback = Count.Feedback() 53 | goal = goal_handle.request.goal_count 54 | local_count = 0 55 | self.get_logger().info('Got goal: ' + str(goal)) 56 | while (local_count < goal): 57 | if goal_handle.is_cancel_requested: 58 | break 59 | feedback.local_count = local_count 60 | goal_handle.publish_feedback(feedback) 61 | self.get_logger().info('Publish feedback: ' + str(local_count)) 62 | local_count += 1 63 | time.sleep(1) 64 | goal_handle.succeed() 65 | self.global_count_ += local_count 66 | result.global_count = self.global_count_ 67 | self.get_logger().info('Return result: ' + str(self.global_count_)) 68 | return result 69 | 70 | 71 | def main(args=None): 72 | rclpy.init(args=args) 73 | node = ActionNodePy('self_action') 74 | executor = rclpy.executors.MultiThreadedExecutor() 75 | executor.add_node(node) 76 | executor.spin() 77 | rclpy.shutdown() 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | -------------------------------------------------------------------------------- /ch5/tf2/ch5_tf2_cpp/src/static_transform.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | 18 | #include "geometry_msgs/msg/transform_stamped.hpp" 19 | #include "rclcpp/rclcpp.hpp" 20 | #include "tf2/LinearMath/Quaternion.h" 21 | #include "tf2_ros/static_transform_broadcaster.h" 22 | 23 | class StaticTransform : public rclcpp::Node 24 | { 25 | public: 26 | explicit StaticTransform(const std::string & node_name) 27 | // explicit StaticTransform(const std::string & node_name, char ** argv) 28 | : Node(node_name) 29 | { 30 | tf_publisher_ = std::make_shared(this); 31 | this->set_transform( 32 | "world", "map", // frame ids 33 | 1, 1, 1, // translation 34 | 0, 0, 0); // rotation 35 | // this->set_transform( 36 | // argv[1], argv[2], // frame ids 37 | // atof(argv[3]), atof(argv[4]), atof(argv[5]), // translation 38 | // atof(argv[6]), atof(argv[7]), atof(argv[8])); // rotation 39 | } 40 | 41 | private: 42 | void set_transform( 43 | const std::string & source_frame, 44 | const std::string & target_frame, 45 | const double & trans_x, 46 | const double & trans_y, 47 | const double & trans_z, 48 | const double & rot_roll, 49 | const double & rot_pitch, 50 | const double & rot_yaw) 51 | { 52 | rclcpp::Time now = this->get_clock()->now(); 53 | geometry_msgs::msg::TransformStamped trans; 54 | tf2::Quaternion quat; 55 | 56 | trans.header.stamp = now; 57 | trans.header.frame_id = source_frame; 58 | trans.child_frame_id = target_frame; 59 | trans.transform.translation.x = trans_x; 60 | trans.transform.translation.y = trans_y; 61 | trans.transform.translation.z = trans_z; 62 | quat.setRPY(rot_roll, rot_pitch, rot_yaw); 63 | trans.transform.rotation.x = quat.x(); 64 | trans.transform.rotation.y = quat.y(); 65 | trans.transform.rotation.z = quat.z(); 66 | trans.transform.rotation.w = quat.w(); 67 | 68 | tf_publisher_->sendTransform(trans); 69 | } 70 | std::shared_ptr tf_publisher_; 71 | }; 72 | 73 | int main(int argc, char ** argv) 74 | { 75 | // if (argc != 9) { 76 | // RCLCPP_ERROR( 77 | // rclcpp::get_logger("Notice"), 78 | // "Usage: ros2 run ch5_tf2_cpp static_transform header_frame child_frame x y z r p y"); 79 | // return 1; 80 | // } 81 | rclcpp::init(argc, argv); 82 | // rclcpp::spin(std::make_shared("static_tf_node", argv)); 83 | rclcpp::spin(std::make_shared("static_tf_node")); 84 | rclcpp::shutdown(); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /ch5/action/ch5_action_cpp/src/wrapped_action.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | #include "rclcpp_action/rclcpp_action.hpp" 22 | 23 | #include "ch5_action_interfaces/action/count.hpp" 24 | #include "ch5_action_cpp/action_server.hpp" 25 | 26 | class SingleNode : public rclcpp::Node 27 | { 28 | using CountT = ch5_action_interfaces::action::Count; 29 | 30 | public: 31 | explicit SingleNode(const std::string & node_name) 32 | : Node(node_name) 33 | { 34 | using namespace std::chrono_literals; 35 | global_count_ = 0; 36 | cb_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant); 37 | client_ = rclcpp_action::create_client(this, "sec_count"); 38 | auto clientimer_callback = 39 | [&]() -> void { 40 | auto goal = CountT::Goal(); 41 | goal.goal_count = 3; 42 | client_->async_send_goal(std::move(goal)); 43 | }; 44 | clientimer_ = this->create_wall_timer(9s, clientimer_callback); 45 | this->server_ = std::make_unique>( 46 | this->shared_from_this(), 47 | "sec_count", 48 | std::bind(&SingleNode::execution_cb, this)); 49 | } 50 | 51 | private: 52 | rclcpp::TimerBase::SharedPtr clientimer_; 53 | std::unique_ptr> server_; 54 | rclcpp_action::Client::SharedPtr client_; 55 | rclcpp::CallbackGroup::SharedPtr cb_group_; 56 | uint32_t global_count_; 57 | void execution_cb() 58 | { 59 | auto result = std::make_shared(); 60 | auto feedback = std::make_shared(); 61 | const auto goal = server_->get_current_goal(); 62 | rclcpp::Rate loop_rate(1); 63 | uint32_t local_count = 0; 64 | RCLCPP_INFO_STREAM( 65 | this->get_logger(), 66 | "Got goal: " << std::to_string(goal->goal_count)); 67 | while (local_count < goal->goal_count) { 68 | if (server_->is_cancel_requested()) { 69 | break; 70 | } 71 | feedback->local_count = local_count; 72 | server_->publish_feedback(feedback); 73 | local_count += 1; 74 | loop_rate.sleep(); 75 | } 76 | global_count_ += local_count; 77 | result->global_count = global_count_; 78 | server_->succeeded_current(result); 79 | } 80 | }; 81 | 82 | int main(int argc, char ** argv) 83 | { 84 | rclcpp::init(argc, argv); 85 | auto srv_node_ = std::make_shared("self_action"); 86 | rclcpp::executors::MultiThreadedExecutor executor_; 87 | 88 | executor_.add_node(srv_node_); 89 | executor_.spin(); 90 | 91 | rclcpp::shutdown(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /ch4/service/ch4_service_cpp/src/single_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | class SingleNode : public rclcpp::Node 23 | { 24 | public: 25 | explicit SingleNode(const std::string & node_name) 26 | : Node(node_name) 27 | { 28 | using namespace std::chrono_literals; 29 | cb_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant); 30 | client_ = this->create_client("get_para"); 31 | auto clientimer_callback = 32 | [&]() -> void { 33 | auto req = std::make_unique(); 34 | req->names.push_back("abc"); 35 | RCLCPP_INFO_STREAM(this->get_logger(), "Ready to send req"); 36 | client_->async_send_request(std::move(req)); 37 | RCLCPP_INFO_STREAM(this->get_logger(), "Sent req"); 38 | }; 39 | clientimer_ = this->create_wall_timer(500ms, clientimer_callback); 40 | auto logtimer_callback = 41 | [&]() -> void { 42 | RCLCPP_INFO_STREAM(this->get_logger(), "Hello earth"); 43 | }; 44 | logtimer_ = this->create_wall_timer(500ms, logtimer_callback); 45 | server_ = this->create_service( 46 | "get_para", 47 | std::bind(&SingleNode::service_callback, this, std::placeholders::_1, std::placeholders::_2), 48 | rmw_qos_profile_services_default, 49 | cb_group_); 50 | } 51 | 52 | private: 53 | rclcpp::TimerBase::SharedPtr clientimer_; 54 | rclcpp::TimerBase::SharedPtr logtimer_; 55 | rclcpp::Service::SharedPtr server_; 56 | rclcpp::Client::SharedPtr client_; 57 | rclcpp::CallbackGroup::SharedPtr cb_group_; 58 | void service_callback( 59 | const std::shared_ptr request, 60 | std::shared_ptr response) 61 | { 62 | rcl_interfaces::msg::Parameter para_; 63 | para_.value.bool_value = !request->names.empty(); 64 | response->values.push_back(para_.value); 65 | std::this_thread::sleep_for(std::chrono::seconds(3)); 66 | RCLCPP_INFO_STREAM( 67 | this->get_logger(), 68 | "Response: " << std::to_string(response->values[0].bool_value)); 69 | } 70 | }; 71 | 72 | int main(int argc, char ** argv) 73 | { 74 | rclcpp::init(argc, argv); 75 | auto srv_node_ = std::make_shared("srv_self"); 76 | rclcpp::executors::MultiThreadedExecutor executor_; 77 | 78 | executor_.add_node(srv_node_); 79 | executor_.spin(); 80 | 81 | rclcpp::shutdown(); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /ch4/topic/ch4_topic_cpp/src/intra_nodes.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Homalozoa 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 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | class PubNode : public rclcpp::Node 23 | { 24 | public: 25 | explicit PubNode(const std::string & node_name) 26 | : Node(node_name) 27 | { 28 | using namespace std::chrono_literals; 29 | auto pub_options = rclcpp::PublisherOptions(); 30 | pub_options.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable; 31 | publisher_ = this->create_publisher( 32 | "current_time", 33 | 10, 34 | pub_options); 35 | auto topictimer_callback = 36 | [&]() -> void { 37 | builtin_interfaces::msg::Time::UniquePtr timestamp_ = 38 | std::make_unique(this->get_clock()->now()); 39 | RCLCPP_INFO_STREAM( 40 | this->get_logger(), 41 | "pub: Addr is :" << 42 | reinterpret_cast(timestamp_.get())); 43 | publisher_->publish(std::move(timestamp_)); 44 | }; 45 | timer_ = this->create_wall_timer(500ms, topictimer_callback); 46 | } 47 | 48 | private: 49 | rclcpp::TimerBase::SharedPtr timer_; 50 | rclcpp::Publisher::SharedPtr publisher_; 51 | }; 52 | 53 | class SubNode : public rclcpp::Node 54 | { 55 | public: 56 | explicit SubNode(const std::string & node_name) 57 | : Node(node_name) 58 | { 59 | auto sub_options = rclcpp::SubscriptionOptions(); 60 | sub_options.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable; 61 | subsciber_ = this->create_subscription( 62 | "current_time", 63 | 10, 64 | std::bind(&SubNode::count_sub_callback, this, std::placeholders::_1), 65 | sub_options); 66 | } 67 | 68 | private: 69 | rclcpp::Subscription::SharedPtr subsciber_; 70 | void count_sub_callback(const builtin_interfaces::msg::Time::UniquePtr msg) 71 | { 72 | RCLCPP_INFO_STREAM( 73 | this->get_logger(), 74 | "sub: Addr is :" << 75 | reinterpret_cast(msg.get())); 76 | } 77 | }; 78 | 79 | void another_executor() 80 | { 81 | rclcpp::executors::SingleThreadedExecutor executor_; 82 | auto sub_node_ = std::make_shared("topic_sub"); 83 | executor_.add_node(sub_node_); 84 | executor_.spin(); 85 | } 86 | 87 | int main(int argc, char ** argv) 88 | { 89 | rclcpp::init(argc, argv); 90 | auto pub_node_ = std::make_shared("topic_pub"); 91 | rclcpp::executors::SingleThreadedExecutor executor_; 92 | 93 | std::thread another(another_executor); 94 | 95 | executor_.add_node(pub_node_); 96 | executor_.spin(); 97 | 98 | another.join(); 99 | rclcpp::shutdown(); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /ch2/node/ch2_node_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ch2_node_cpp) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++17 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 17) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(rclcpp REQUIRED) 21 | find_package(rclcpp_lifecycle REQUIRED) 22 | 23 | set(executable_node2go node2go) 24 | set(executable_node2go2 node2go2) 25 | set(executable_multinode multinode) 26 | set(executable_multilifecyclenode multilifecyclenode) 27 | set(executable_global_arg globalarg) 28 | set(library_node2go nodelib) 29 | set(library_getid getid) 30 | set(library_lifecyclenode lifecyclenode2go) 31 | set(dependencies 32 | rclcpp 33 | rclcpp_lifecycle 34 | ) 35 | 36 | include_directories(include) 37 | 38 | add_library(${library_node2go} SHARED 39 | src/node2go.cpp 40 | ) 41 | add_library(${library_getid} SHARED 42 | src/getid.cpp 43 | ) 44 | add_library(${library_lifecyclenode} SHARED 45 | src/lifecyclenode2go.cpp 46 | ) 47 | 48 | add_executable(${executable_node2go} 49 | src/main.cpp 50 | ) 51 | add_executable(${executable_node2go2} 52 | src/main2.cpp 53 | ) 54 | add_executable(${executable_multinode} 55 | src/multinode.cpp 56 | ) 57 | add_executable(${executable_multilifecyclenode} 58 | src/multilifecyclenode.cpp 59 | ) 60 | add_executable(${executable_global_arg} 61 | src/global_arg.cpp 62 | ) 63 | 64 | ament_target_dependencies(${library_node2go} 65 | ${dependencies} 66 | ) 67 | ament_target_dependencies(${library_getid} 68 | ${dependencies} 69 | ) 70 | ament_target_dependencies(${library_lifecyclenode} 71 | ${dependencies} 72 | ) 73 | ament_target_dependencies(${executable_node2go} 74 | ${dependencies} 75 | ) 76 | ament_target_dependencies(${executable_node2go2} 77 | ${dependencies} 78 | ) 79 | ament_target_dependencies(${executable_multinode} 80 | ${dependencies} 81 | ) 82 | ament_target_dependencies(${executable_multilifecyclenode} 83 | ${dependencies} 84 | ) 85 | ament_target_dependencies(${executable_global_arg} 86 | ${dependencies} 87 | ) 88 | 89 | target_link_libraries(${executable_node2go} 90 | ${library_node2go} 91 | ) 92 | target_link_libraries(${executable_node2go2} 93 | ${library_node2go} 94 | ) 95 | target_link_libraries(${executable_multinode} 96 | ${library_getid} 97 | ) 98 | target_link_libraries(${executable_multilifecyclenode} 99 | ${library_lifecyclenode} 100 | ) 101 | 102 | install(TARGETS 103 | ${library_node2go} 104 | ${library_getid} 105 | ${library_lifecyclenode} 106 | ARCHIVE DESTINATION lib 107 | LIBRARY DESTINATION lib 108 | RUNTIME DESTINATION bin 109 | ) 110 | 111 | install( 112 | TARGETS ${executable_node2go} 113 | TARGETS ${executable_node2go2} 114 | TARGETS ${executable_multinode} 115 | TARGETS ${executable_multilifecyclenode} 116 | TARGETS ${executable_global_arg} 117 | RUNTIME DESTINATION lib/${PROJECT_NAME} 118 | ) 119 | 120 | install(DIRECTORY include/ 121 | DESTINATION include/ 122 | ) 123 | 124 | if(BUILD_TESTING) 125 | find_package(ament_lint_auto REQUIRED) 126 | ament_lint_auto_find_test_dependencies() 127 | endif() 128 | 129 | ament_export_include_directories(include) 130 | ament_export_libraries(${library_node2go} ${library_getid} ${library_lifecyclenode}) 131 | ament_export_dependencies(${dependencies}) 132 | ament_package() 133 | --------------------------------------------------------------------------------