Skip to content

Commit

Permalink
Merge pull request #109 from zivid/MISC-2024-06-19-ros2-testing
Browse files Browse the repository at this point in the history
ROS2: Add samples and other fixups
  • Loading branch information
micragz committed Jul 19, 2024
2 parents c9829ed + 12835f6 commit a428dec
Show file tree
Hide file tree
Showing 28 changed files with 1,352 additions and 369 deletions.
22 changes: 22 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Style from `ament_clang_format` linter.
# https://github.com/ament/ament_lint/blob/master/ament_clang_format/ament_clang_format/configuration/.clang-format
---
Language: Cpp
BasedOnStyle: Google

AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
BraceWrapping:
AfterClass: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterEnum: true
BreakBeforeBraces: Custom
ColumnLimit: 100
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 2
DerivePointerAlignment: false
PointerAlignment: Middle
ReflowComments: false
...
4 changes: 0 additions & 4 deletions .github/workflows/ROS-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ jobs:
compiler: 'g++-12'
- os: 'ros:humble-ros-base-jammy'
compiler: 'g++-13'
- os: 'ros:humble-ros-base-jammy'
compiler: 'g++-14'
- os: 'ros:humble-ros-base-jammy'
compiler: 'clang++-15'
- os: 'ros:jazzy-ros-core-noble'
compiler: 'g++-14'
- os: 'ros:jazzy-ros-core-noble'
compiler: 'clang++-14'
- os: 'ros:jazzy-ros-core-noble'
Expand Down
103 changes: 96 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,25 +343,111 @@ will cause some additional processing time for calculating the normals.
In the `zivid_samples` package we have added samples that demonstrate how to use
the Zivid ROS driver. These samples can be used as a starting point for your project.

_More samples will soon be provided_.
To launch the Python samples using `ros2 launch`, you need `python` to be available as a command.
For example, the `python-is-python3` package can be installed to achieve this, by running the
following command:

```bash
sudo apt install python-is-python3
```

On Windows, the Python samples cannot be launched using `ros2 launch`. Instead, please launch the
samples using `ros2 run zivid_samples <sample_name>.py` together with
`ros2 run zivid_camera zivid_camera` in another terminal window.

### Sample Capture

This sample performs single-acquisition 3D captures in a loop. This sample shows how to [configure](#configuration)
the capture settings, how to subscribe to the [points/xyzrgba](#points/xyzrgba) topic, and how to invoke the
the capture settings, how to subscribe to the [points/xyzrgba](#pointsxyzrgba) topic, and how to invoke the
[capture](#capture) service.

Source code: [C++](./zivid_samples/src/sample_capture.cpp)
Source code: [C++](./zivid_samples/src/sample_capture.cpp) [Python](./zivid_samples/scripts/sample_capture.py)

```bash
ros2 launch zivid_samples sample.launch sample:=sample_capture_cpp
ros2 launch zivid_samples sample.launch sample:=sample_capture.py
```
Using ros2 run (when `zivid_camera` node is already running):
```bash
ros2 run zivid_samples sample_capture_cpp
ros2 run zivid_samples sample_capture.py
```

_More samples will soon be provided_.
### Sample Capture 2D

This sample performs single-acquisition 2D captures in a loop. This sample shows how to [configure](#configuration) the
capture 2d settings with a YAML string, how to subscribe to the [color/image_color](#colorimage_color) topic, and how to
invoke the [capture_2d](#capture_2d) service.

Source code: [C++](./zivid_samples/src/sample_capture_2d.cpp) [Python](./zivid_samples/scripts/sample_capture_2d.py)

```bash
ros2 launch zivid_samples sample.launch sample:=sample_capture_2d_cpp
ros2 launch zivid_samples sample.launch sample:=sample_capture_2d.py
```
Using ros2 run (when `zivid_camera` node is already running):
```bash
ros2 run zivid_samples sample_capture_2d_cpp
ros2 run zivid_samples sample_capture_2d.py
```

### Sample Capture and Save

This sample performs a capture, and stores the resulting frame to file. This sample shows how to
[configure](#configuration) the capture settings with a YAML string, how to invoke the
[capture_and_save](#capture_and_save) service, and how to read the response from the service call.

Source code: [C++](./zivid_samples/src/sample_capture_and_save.cpp) [Python](./zivid_samples/scripts/sample_capture_and_save.py)

```bash
ros2 launch zivid_samples sample.launch sample:=sample_capture_and_save_cpp
ros2 launch zivid_samples sample.launch sample:=sample_capture_and_save.py
```

Using ros2 run (when `zivid_camera` node is already running):

```bash
ros2 run zivid_samples sample_capture_and_save_cpp
ros2 run zivid_samples sample_capture_and_save.py
```

### Sample Capture Assistant

This sample shows how to invoke the [capture_assistant/suggest_settings](#capture_assistantsuggest_settings) service to
suggest and set capture settings. Then, it shows how to subscribe to the [points/xyzrgba](#pointsxyzrgba) and
[color/image_color](#colorimage_color) topics, and finally invoke the [capture](#capture) service.

Source code: [C++](./zivid_samples/src/sample_capture_assistant.cpp) [Python](./zivid_samples/scripts/sample_capture_assistant.py)

```bash
ros2 launch zivid_samples sample.launch sample:=sample_capture_assistant_cpp
ros2 launch zivid_samples sample.launch sample:=sample_capture_assistant.py
```
Using ros2 run (when `zivid_camera` node is already running):
```bash
ros2 run zivid_samples sample_capture_assistant_cpp
ros2 run zivid_samples sample_capture_assistant.py
```

### Sample Capture with Settings from File

This sample performs single-acquisition 3D captures in a loop. This sample shows how to [configure](#configuration) the
capture settings from a yaml file, how to subscribe to the [points/xyzrgba](#pointsxyzrgba) topic, and how to invoke the
[capture](#capture) service.

Source code: [C++](./zivid_samples/src/sample_capture_with_settings_from_file.cpp) [Python](./zivid_samples/scripts/sample_capture_with_settings_from_file.py)

```bash
ros2 launch zivid_samples sample.launch sample:=sample_capture_with_settings_from_file_cpp
ros2 launch zivid_samples sample.launch sample:=sample_capture_with_settings_from_file.py
```

Using ros2 run (when `zivid_camera` node is already running):

```bash
ros2 run zivid_samples sample_capture_with_settings_from_file_cpp
ros2 run zivid_samples sample_capture_with_settings_from_file.py
```

## Frequently Asked Questions

Expand Down Expand Up @@ -462,13 +548,16 @@ colcon build --cmake-args -DCOMPILER_WARNINGS=ON

### How to format the source code

The CI test for this package enforces the linting defined by `ament_lint_auto`.
The CI test for this package enforces the linting defined by `clang-format`. From the code analysis
docker image, run:

```bash
cd ~/ros2_ws/src/zivid-ros
ament_uncrustify --reformat ./
find /host -name '*.cpp' -or -name '*.hpp' | xargs clang-format -i
```

The style follows the one from
[`ament_clang_format`](https://github.com/ament/ament_lint/blob/master/ament_clang_format/doc/index.rst).

## License

This project is licensed under BSD 3-clause license, see the [LICENSE](LICENSE) file for details.
Expand Down
2 changes: 2 additions & 0 deletions continuous-integration/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Bash does not play well with Windows line endings.
**.sh text eol=lf
2 changes: 1 addition & 1 deletion continuous-integration/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ rosdep install -i --from-path src -y || exit $?

echo "Building with compiler=$CI_TEST_COMPILER"

colcon build --symlink --cmake-args "-DCOMPILER_WARNINGS=ON -DCMAKE_CXX_COMPILER=/usr/bin/$CI_TEST_COMPILER" || exit $?
colcon build --symlink --event-handlers console_direct+ --cmake-args -DCOMPILER_WARNINGS=ON -DCMAKE_CXX_COMPILER=/usr/bin/$CI_TEST_COMPILER -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || exit $?

echo "Check that the expected packages are found"
source ~/ros2_ws/install/setup.bash
Expand Down
16 changes: 16 additions & 0 deletions continuous-integration/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ROOT_DIR=$(realpath "$SCRIPT_DIR/..")

pythonFiles=$(find "$ROOT_DIR" -name '*.py')
bashFiles=$(find "$ROOT_DIR" -name '*.sh')
cppFiles=$(find "$ROOT_DIR" -name '*.cpp' -or -name '*.hpp')

echo Running black on:
echo "$pythonFiles"
Expand All @@ -16,4 +17,19 @@ echo Running shellcheck on:
echo "$bashFiles"
shellcheck -x -e SC1090,SC2086,SC2046 $bashFiles || exit $?

echo Running clang-format on:
echo "$cppFiles"
clangFormatIssues=0
for file in $cppFiles; do
diff_output=$(diff -u "$file" <(clang-format "$file"))
if [ -n "$diff_output" ]; then
echo "$diff_output"
clangFormatIssues=1
fi
done

if [ $clangFormatIssues -ne 0 ]; then
exit $clangFormatIssues
fi

echo Success! ["$(basename $0)"]
1 change: 1 addition & 0 deletions continuous-integration/run_build_and_test_in_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ docker run \
--workdir /host/continuous-integration \
--env CI_TEST_ZIVID_VERSION="$CI_TEST_ZIVID_VERSION" \
--env CI_TEST_COMPILER="$CI_TEST_COMPILER" \
--env CI_TEST_OS="$CI_TEST_OS" \
--env CI_TEST_DOWNLOAD_TELICAM="$CI_TEST_DOWNLOAD_TELICAM" \
$CI_TEST_OS \
bash -c "./build_and_test.sh" || exit $?
3 changes: 1 addition & 2 deletions continuous-integration/setup/setup_build_and_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ echo "Installing compiler $CI_TEST_COMPILER"

if [[ "$CI_TEST_COMPILER" == "g++" ||
"$CI_TEST_COMPILER" == "g++-12" ||
"$CI_TEST_COMPILER" == "g++-13" ||
"$CI_TEST_COMPILER" == "g++-14"
"$CI_TEST_COMPILER" == "g++-13"
]]; then

apt-yes install software-properties-common || exit $?
Expand Down
16 changes: 15 additions & 1 deletion continuous-integration/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,22 @@ unzip ./FileCameraZivid2M70.zip -d /usr/share/Zivid/data/ || exit $?
rm ./FileCameraZivid2M70.zip || exit $?

echo "Running tests"

# We exclude `clang_format` here since it has variations between versions, instead we check it during code analysis.
excludeTests="clang_format"

if [ "$CI_TEST_OS" == "ros:humble-ros-base-jammy" ] || [ "$CI_TEST_OS" == "ros:iron-ros-core-jammy" ]; then
# The listed OSes have issues invoking clang-tidy correctly:
# - Humble seems to not invoke it with the correct C++ language version, resulting in it not finding
# std::optional and std::variant.
# - Iron does not find the compile commands.
# On the other hand, Jazzy seems to work well, so we get the checks when testing on this OS.
echo "Skipping clang-tidy tests since OS is '$CI_TEST_OS'"
excludeTests+="|clang_tidy"
fi

export GTEST_BREAK_ON_FAILURE=1;
colcon test --event-handlers console_direct+ --ctest-args tests --output-on-failure --ros-args --log-level debug || exit $?
colcon test --event-handlers console_direct+ --ctest-args tests --exclude-regex $excludeTests --output-on-failure --ros-args --log-level debug || exit $?

echo "Check for test errors"
colcon test-result --all || exit $?
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tool.black]
skip-string-normalization = true # Black prefers double quotes, however, this is incompatible with the `ament_flake8` configuration.
4 changes: 1 addition & 3 deletions zivid_camera/cmake/CompilerWarnings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,8 @@ function(set_target_warning_compile_options TARGET)
weak-vtables # The vtable must be duplicated in multiple translation units. Small
# problem, maybe even linker will resolve this. Must add boilerplate to
# fix, not worth it
covered-switch-default # We don't want this warning, because we want the default labels for safety.
)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
list(APPEND WARNINGS_THAT_SHOULD_BE_IGNORED return-std-move-in-c++11) # Applies to old compilers, we aim for newer C++17 compilers
endif()

foreach(WARNING ${WARNINGS_THAT_SHOULD_BE_IGNORED})
list(APPEND TARGET_FLAGS -Wno-${WARNING})
Expand Down
31 changes: 17 additions & 14 deletions zivid_camera/include/zivid_camera/zivid_camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,28 @@

#pragma once

#include <image_transport/image_transport.hpp>
#include <memory>
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <sensor_msgs/msg/point_cloud2.hpp>
#include <std_srvs/srv/trigger.hpp>
#include <string>

#include <zivid_camera/visibility.hpp>

#include <image_transport/image_transport.hpp>
#include <rclcpp/rclcpp.hpp>
#include <zivid_interfaces/srv/camera_info_model_name.hpp>
#include <zivid_interfaces/srv/camera_info_serial_number.hpp>
#include <zivid_interfaces/srv/capture_and_save.hpp>
#include <zivid_interfaces/srv/capture_assistant_suggest_settings.hpp>
#include <zivid_interfaces/srv/is_connected.hpp>

#include <sensor_msgs/msg/image.hpp>
#include <sensor_msgs/msg/point_cloud2.hpp>
#include <std_srvs/srv/trigger.hpp>

namespace Zivid
{
class Application;
class Camera;
class CameraIntrinsics;
struct ColorRGBA;
class Frame;
template<typename T>
template <typename T>
class Image;
class PointCloud;
class Settings2D;
Expand All @@ -61,22 +58,28 @@ class Settings;

namespace zivid_camera
{
enum class CameraStatus { Idle, Connected, Disconnected };
template<typename SettingsType>
enum class CameraStatus
{
Idle,
Connected,
Disconnected
};
template <typename SettingsType>
class CaptureSettingsController;

class ZividCamera : public rclcpp::Node
{
public:
ZIVID_CAMERA_ROS_PUBLIC ZividCamera(const rclcpp::NodeOptions & options);
~ZividCamera();
~ZividCamera() override;
ZIVID_CAMERA_ROS_PUBLIC Zivid::Application & zividApplication();

private:
void onCameraConnectionKeepAliveTimeout();
void reconnectToCameraIfNecessary();
void setCameraStatus(CameraStatus camera_status);

rcl_interfaces::msg::SetParametersResult setParametersCallback(
const std::vector<rclcpp::Parameter> & parameters);
void cameraInfoModelNameServiceHandler(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<zivid_interfaces::srv::CameraInfoModelName::Request> request,
Expand Down Expand Up @@ -140,9 +143,9 @@ class ZividCamera : public rclcpp::Node
sensor_msgs::msg::CameraInfo::ConstSharedPtr makeCameraInfo(
const std_msgs::msg::Header & header, std::size_t width, std::size_t height,
const Zivid::CameraIntrinsics & intrinsics);

[[noreturn]] void logErrorAndThrowRuntimeException(const std::string & message);

OnSetParametersCallbackHandle::SharedPtr set_parameters_callback_handle_;
rclcpp::TimerBase::SharedPtr camera_connection_keepalive_timer_;
bool use_latched_publisher_for_points_xyz_{false};
bool use_latched_publisher_for_points_xyzrgba_{false};
Expand Down
11 changes: 10 additions & 1 deletion zivid_camera/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@
<depend>rosidl_default_generators</depend>
<depend>zivid_interfaces</depend>
<exec_depend>ros2launch</exec_depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>ament_cmake_clang_format</test_depend>
<test_depend>ament_cmake_clang_tidy</test_depend>
<test_depend>ament_cmake_copyright</test_depend>
<test_depend>ament_cmake_cppcheck</test_depend>
<test_depend>ament_cmake_flake8</test_depend>
<test_depend>ament_cmake_lint_cmake</test_depend>
<test_depend>ament_cmake_pep257</test_depend>
<test_depend>ament_cmake_xmllint</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
Expand Down
Loading

0 comments on commit a428dec

Please sign in to comment.