Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Github Actions and update README with Github Markdown features #2

Merged
merged 10 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/happypose_ros_build_and_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: "Humble: Build and Test"

on: [ push, pull_request ]

jobs:
test_happypose_ros:
runs-on: ubuntu-22.04

env:
HAPPYPOSE_DATA_DIR: /tmp/local_data

steps:
- name: Install EGL mesa - required for Panda3D renderer
run: |
sudo apt-get update
sudo apt-get install -qqy libegl1-mesa libegl1-mesa-dev

- name: Install Python C headers and remove Blinker version conflicting with HappyPose
run: |
sudo apt-get update
sudo apt-get install -qqy python3-dev
sudo apt purge -qqy python3-blinker

- name: Caching of the HappyPose installation and data
uses: actions/cache@v4
with:
path: /tmp/local_data
key: data

- name: Update pip
run: pip install -U pip

- name: Download HappyPose source
working-directory: /tmp
run: |
git clone --branch dev --recurse-submodules https://github.com/agimus-project/happypose.git

- name: Build and install HappyPose
working-directory: /tmp/happypose
run: pip install ".[cpu,pypi,evaluation,multiview]" --extra-index-url https://download.pytorch.org/whl/cpu

- name: Download pre-trained models required for tests
run: |
mkdir -p /tmp/local_data
python -m happypose.toolbox.utils.download \
--bop_dataset ycbv \
--cosypose_models \
detector-bop-ycbv-pbr--970850 \
coarse-bop-ycbv-pbr--724183 \
refiner-bop-ycbv-pbr--604090

- name: Unzip HappyPose YCBV models
working-directory: /tmp/local_data/bop_datasets/ycbv
run: |
unzip -n -qq ycbv_base.zip
unzip -n -qq ycbv_models.zip

- name: Remove incompatible PyTest version
run: pip uninstall -y pytest

- name: Install ROS 2 Humble
uses: ros-tooling/[email protected]
with:
required-ros-distributions: humble

- name: Build and test happypose_ros
uses: ros-tooling/[email protected]
with:
package-name: happypose_ros
target-ros2-distro: humble
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@

# happypose_ros

[![License](https://img.shields.io/badge/License-BSD_2--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause)
[![Test happypose_ros](https://github.com/agimus-project/happypose_ros/actions/workflows/happypose_ros_build_and_test.yaml/badge.svg)](https://github.com/agimus-project/happypose_ros/actions/workflows/happypose_ros_build_and_test.yaml
)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/agimus-project/happypose_ros/main.svg)](https://results.pre-commit.ci/latest/github/agimus-project/happypose_ros/main)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

ROS 2 wrapper for a 6D pose estimation library, [Happypose](https://github.com/agimus-project/happypose).

## Build instructions


:warning: Conda installation is not supported
> [!WARNING]
> Conda installation is not supported

Currently, there is no automated build for happypose library itself built into the ROS node. Please follow the installation guide found in the [happypose README.md](https://github.com/agimus-project/happypose?tab=readme-ov-file#example-with-venv).

Expand All @@ -17,11 +26,14 @@ colcon build --symlink-install

## Launch

:warning: Intrinsic parameters of the camera are approximate in the demos and may cause inaccurate results! You can change them by modifying the `k_matrix` param in [cosypose_params.yaml](./happypose_examples/config/cosypose_params.yaml) file.
> [!NOTE]
> Intrinsic parameters of the camera are approximate in the demos and may cause inaccurate results! You can change them by modifying the `k_matrix` param in [cosypose_params.yaml](./happypose_examples/config/cosypose_params.yaml) file.

:warning: When running the demos, make sure to change `device` parameter according to your hardware configuration!
> [!TIP]
> When running the demos, make sure to change `device` parameter according to your hardware configuration!

Before running the demos download the dataset model and pretrained detectors for object type you plan to use. The default dataset used in the examples is ycbv. For more information refer to [*Downloading and preparing the data* page](https://agimus-project.github.io/happypose/cosypose/download_data.html) in the HappyPose documentation.
> [!IMPORTANT]
> Before running the demos download the dataset model and pretrained detectors for object type you plan to use. The default dataset used in the examples is ycbv. For more information refer to [*Downloading and preparing the data* page](https://agimus-project.github.io/happypose/cosypose/download_data.html) in the HappyPose documentation.

To launch the demo run:
```bash
Expand Down
6 changes: 3 additions & 3 deletions happypose_ros/test/single_view_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ def test_03_trigger_pipeline(self, proc_output: ActiveIoHandler) -> None:
assert ready, "Failed to trigger the pipeline!"

def test_04_receive_messages(self) -> None:
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/markers", timeout=2.0)
self.node.assert_message_received("happypose/vision_info", timeout=2.0)
self.node.assert_message_received("happypose/detections", timeout=180.0)
self.node.assert_message_received("happypose/markers", timeout=6.0)
self.node.assert_message_received("happypose/vision_info", timeout=6.0)

def test_05_check_vision_info(self) -> None:
vision_info = self.node.get_received_message("happypose/vision_info")
Expand Down
14 changes: 7 additions & 7 deletions happypose_ros/test/test_multi_view_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ def test_05_trigger_pipeline(self, proc_output: ActiveIoHandler) -> None:
self.fail("Failed to trigger the pipeline!")

def test_06_receive_messages(self) -> None:
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/vision_info", timeout=2.0)
self.node.assert_message_received("happypose/detections", timeout=180.0)
self.node.assert_message_received("happypose/vision_info", timeout=8.0)

def test_07_check_vision_info(self) -> None:
vision_info = self.node.get_received_message("happypose/vision_info")
Expand Down Expand Up @@ -244,11 +244,11 @@ def test_12_dynamic_params_camera_no_timeout(self) -> None:
# Disable timeout. Single image should trigger now
self.set_timeout(0.0)
self.node.publish_image("cam_1", self.cam_1_image, self.K)
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/detections", timeout=180.0)

def expect_no_detection(self) -> None:
with self.assertRaises(AssertionError) as excinfo:
self.node.assert_message_received("happypose/detections", timeout=5.0)
self.node.assert_message_received("happypose/detections", timeout=60.0)
self.assertTrue(
"No messages received" in str(excinfo.exception),
msg="One image after timeout triggered the pipeline!",
Expand Down Expand Up @@ -284,7 +284,7 @@ def test_15_dynamic_params_camera_timeout_three_cameras_ok(self) -> None:
self.node.publish_image("cam_1", self.cam_1_image, self.K)
self.node.publish_image("cam_2", self.cam_2_image, self.K)
self.node.publish_image("cam_3", self.cam_3_image, self.K)
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/detections", timeout=60.0)

def test_16_dynamic_params_camera_timeout_three_cameras_short(self) -> None:
# Set timeout to a small value
Expand Down Expand Up @@ -315,7 +315,7 @@ def test_17_dynamic_params_camera_timeout_three_cameras_short_ok(self) -> None:
self.node.publish_image("cam_1", self.cam_1_image, self.K)
self.node.publish_image("cam_2", self.cam_2_image, self.K)
self.node.publish_image("cam_3", self.cam_3_image, self.K)
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/detections", timeout=60.0)

def setup_timestamp_test(
self, offsets: List[float], expected: float, strategy: str
Expand Down Expand Up @@ -350,7 +350,7 @@ def setup_timestamp_test(
self.set_timeout(0.0)
self.node.publish_image("cam_3", self.cam_3_image, self.K, cam_3_stamp)
# Await the results
self.node.assert_message_received("happypose/detections", timeout=20.0)
self.node.assert_message_received("happypose/detections", timeout=60.0)

detections = self.node.get_received_message("happypose/detections")
stamp_sec = (Time.from_msg(detections.header.stamp) - now).nanoseconds / S_TO_NS
Expand Down