Skip to content

Commit 63a6766

Browse files
authored
Initial commit
0 parents  commit 63a6766

10 files changed

Lines changed: 285 additions & 0 deletions

File tree

.clang-format

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
Language: Cpp
3+
BasedOnStyle: Google
4+
5+
TabWidth: 2
6+
IndentWidth: 4
7+
AccessModifierOffset: -4
8+
BraceWrapping:
9+
AfterCaseLabel: false
10+
AfterClass: false
11+
AfterControlStatement: "false"
12+
AfterEnum: false
13+
AfterFunction: false
14+
AfterNamespace: false
15+
AfterObjCDeclaration: false
16+
AfterStruct: false
17+
AfterUnion: false
18+
AfterExternBlock: false
19+
BeforeCatch: false
20+
BeforeElse: false
21+
IndentBraces: false
22+
BreakBeforeBraces: Custom
23+
ColumnLimit: 120
24+
DerivePointerAlignment: false
25+
PointerAlignment: Left
26+
ReflowComments: false
27+
...

.github/workflows/main.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: CI
2+
3+
on: [ push, pull_request ]
4+
5+
jobs:
6+
industrial_ci:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
env:
11+
- { ROS_DISTRO: humble, ROS_REPO: testing }
12+
- { ROS_DISTRO: humble, ROS_REPO: main }
13+
name: ROS ${{ matrix.ROS_DISTRO }} (${{ matrix.ROS_REPO }})
14+
steps:
15+
- uses: actions/checkout@v3
16+
- uses: 'ros-industrial/industrial_ci@master'
17+
env: ${{ matrix.env }}
18+

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
log
2+
build
3+
install
4+
.vscode
5+
.cache
6+
compile_commands.json

CMakeLists.txt

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(TODO_PACKAGE_NAME)
3+
include(FetchContent)
4+
5+
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
6+
add_compile_options(-Wall -Wextra -Wpedantic)
7+
endif ()
8+
9+
# find dependencies
10+
find_package(ament_cmake REQUIRED)
11+
find_package(rclcpp REQUIRED)
12+
# Messages TODO_EXTRA
13+
find_package(ackermann_msgs REQUIRED)
14+
find_package(sensor_msgs REQUIRED)
15+
find_package(std_msgs REQUIRED)
16+
# OpenCV TODO_EXTRA
17+
find_package(cv_bridge REQUIRED)
18+
find_package(OpenCV 4.2.0 REQUIRED)
19+
20+
# Add source for node executable (link non-ros dependencies here)
21+
add_executable(TODO_PACKAGE_NAME src/TODO_NODE_NAME.cpp src/TODO_NODE_NAME_node.cpp)
22+
target_include_directories(TODO_PACKAGE_NAME PUBLIC
23+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
24+
$<INSTALL_INTERFACE:include>)
25+
target_compile_features(TODO_PACKAGE_NAME PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
26+
27+
# Make ros deps a variable so they get linked to tests as well
28+
set(dependencies
29+
rclcpp
30+
# Messages TODO_EXTRA
31+
ackermann_msgs
32+
sensor_msgs
33+
std_msgs
34+
# OpenCv TODO_EXTRA
35+
cv_bridge
36+
OpenCV
37+
)
38+
39+
# Link ros dependencies
40+
ament_target_dependencies(
41+
TODO_PACKAGE_NAME
42+
${dependencies}
43+
)
44+
45+
install(TARGETS TODO_PACKAGE_NAME
46+
DESTINATION lib/${PROJECT_NAME})
47+
48+
# Uncomment below to make launch files available if created
49+
#install(
50+
# DIRECTORY launch config
51+
# DESTINATION share/${PROJECT_NAME}/
52+
#)
53+
54+
if (BUILD_TESTING)
55+
# Manually invoke clang format so it actually uses our file
56+
find_package(ament_cmake_clang_format REQUIRED)
57+
ament_clang_format(CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/.clang-format)
58+
59+
find_package(ament_cmake_gtest REQUIRED)
60+
61+
# Add unit tests
62+
ament_add_gtest(${PROJECT_NAME}-test
63+
tests/unit.cpp
64+
# Remember to add node source files
65+
src/TODO_NODE_NAME_node.cpp
66+
)
67+
ament_target_dependencies(${PROJECT_NAME}-test ${dependencies})
68+
target_include_directories(${PROJECT_NAME}-test PUBLIC
69+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
70+
$<INSTALL_INTERFACE:include>)
71+
endif ()
72+
73+
ament_package()

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
An opinionated ROS2 C++ node template, optimised for ISC.
2+
3+
# Instructions
4+
5+
1. Clone repo inside your workspaces src directory (Ex. phnx_ws/src)
6+
2. `rosdep install --from-paths . --ignore-src -r -y` to install deps
7+
3. `colcon build` to make sure the repo builds before you mess with it
8+
4. Replace the following in both file names and code exactly and consistently.
9+
1. TODO_PACKAGE_NAME: Replace with the package name. Use snake case. Ex. `data_logger`
10+
2. TODO_NODE_NAME: Replace with the node name. Use Pascal case. Ex. `DataLogger`
11+
5. `colcon build` again. If it builds, you are done
12+
6. Rename outer folder
13+
7. Review the optional dependencies, and remove what you do not need
14+
15+
# Dependencies
16+
Some common extra dependencies are included. Review them and remove what you don't need.
17+
These are marked with TODO_EXTRA.
18+
19+
# Features
20+
21+
- Unit tests
22+
- ROS-Industrial github CI (will test units and lints)
23+
- C++ formatting via clangformat
24+
- A selection of sane lints
25+
- A single node setup in a multithreaded executor
26+
27+
# File structure
28+
29+
```
30+
.
31+
├── include
32+
│   └── TODO_PACKAGE_NAME
33+
│   └── TODO_NODE_NAME_node.hpp
34+
├── package.xml
35+
├── README.md
36+
├── src
37+
│   ├── TODO_NODE_NAME.cpp
38+
│   └── TODO_NODE_NAME_node.cpp
39+
└── tests
40+
└── unit.cpp
41+
```
42+
43+
TODO_NODE_NAME_node: Source files for the ROS2 node object itself, and only itself
44+
45+
TODO_NODE_NAME.cpp: Source for the main function of the node, and only the main function
46+
47+
tests/unit.cpp: Example file for unit tests. This is linked to the node and ros, so both can be used
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include "rclcpp/rclcpp.hpp"
4+
#include "std_msgs/msg/string.hpp"
5+
6+
class TODO_NODE_NAME : public rclcpp::Node {
7+
private:
8+
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub;
9+
10+
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub;
11+
12+
public:
13+
TODO_NODE_NAME(const rclcpp::NodeOptions& options);
14+
15+
/// subscriber callback
16+
void sub_cb(std_msgs::msg::String::SharedPtr msg);
17+
};

package.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>TODO_PACKAGE_NAME</name>
5+
<version>0.1.0</version>
6+
<description>A node template</description>
7+
<maintainer email="avealov@umich.edu">Andrew Ealovega</maintainer>
8+
<license>MIT</license>
9+
10+
<buildtool_depend>ament_cmake</buildtool_depend>
11+
12+
<depend>rclcpp</depend>
13+
14+
<!--Messages TODO_EXTRA-->
15+
<depend>ackermann_msgs</depend>
16+
<depend>sensor_msgs</depend>
17+
<depend>std_msgs</depend>
18+
19+
<!--OpenCv Things TODO_EXTRA-->
20+
<depend>cv_bridge</depend>
21+
<depend>libopencv-dev</depend>
22+
23+
<test_depend>ament_lint_auto</test_depend>
24+
<test_depend>ament_cmake_flake8</test_depend>
25+
<test_depend>ament_cmake_xmllint</test_depend>
26+
<test_depend>ament_cmake_clang_format</test_depend>
27+
<test_depend>ament_cmake_cppcheck</test_depend>
28+
<test_depend>ament_cmake_pep257</test_depend>
29+
<test_depend>ament_clang_tidy</test_depend>
30+
<test_depend>ament_cmake_gtest</test_depend>
31+
<test_depend>ament_cmake_nose</test_depend>
32+
33+
<export>
34+
<build_type>ament_cmake</build_type>
35+
</export>
36+
</package>

src/TODO_NODE_NAME.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "TODO_PACKAGE_NAME/TODO_NODE_NAME_node.hpp"
2+
3+
int main(int argc, char** argv) {
4+
// Setup runtime
5+
rclcpp::init(argc, argv);
6+
rclcpp::executors::MultiThreadedExecutor exec;
7+
rclcpp::NodeOptions options;
8+
9+
// Add nodes to executor
10+
auto node = std::make_shared<TODO_NODE_NAME>(options);
11+
exec.add_node(node);
12+
13+
// Run
14+
exec.spin();
15+
rclcpp::shutdown();
16+
return 0;
17+
}

src/TODO_NODE_NAME_node.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "TODO_PACKAGE_NAME/TODO_NODE_NAME_node.hpp"
2+
3+
// For _1
4+
using namespace std::placeholders;
5+
6+
TODO_NODE_NAME::TODO_NODE_NAME(const rclcpp::NodeOptions& options) : Node("TODO_NODE_NAME", options) {
7+
// Parameters
8+
float x = this->declare_parameter<float>("foo", -10.0);
9+
10+
// Pub Sub
11+
this->sub =
12+
this->create_subscription<std_msgs::msg::String>("/str", 1, std::bind(&TODO_NODE_NAME::sub_cb, this, _1));
13+
this->pub = this->create_publisher<std_msgs::msg::String>("/run_folder", 1);
14+
15+
// Log a sample log
16+
RCLCPP_INFO(this->get_logger(), "You passed %f", x);
17+
18+
// Send a sample message
19+
std_msgs::msg::String msg{};
20+
msg.data = std::string{"Hello World!"};
21+
pub->publish(msg);
22+
}
23+
24+
void TODO_NODE_NAME::sub_cb(const std_msgs::msg::String::SharedPtr msg) {
25+
// Echo message
26+
this->pub->publish(*msg);
27+
}

tests/unit.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <gtest/gtest.h>
2+
3+
#include <rclcpp/rclcpp.hpp>
4+
5+
#include "TODO_PACKAGE_NAME/TODO_NODE_NAME_node.hpp"
6+
7+
TEST(TODO_NODE_NAME, Test1) {}
8+
9+
int main(int argc, char** argv) {
10+
rclcpp::init(0, nullptr);
11+
12+
::testing::InitGoogleTest(&argc, argv);
13+
auto res = RUN_ALL_TESTS();
14+
15+
rclcpp::shutdown();
16+
return res;
17+
}

0 commit comments

Comments
 (0)