From 083ce0f02ff94454a4d591b5fd4f35a08e545ee8 Mon Sep 17 00:00:00 2001 From: Florian Vahl Date: Sun, 5 Jan 2025 18:38:23 +0100 Subject: [PATCH] Remove technical challenge vision. All other code related to the challenge is tagged / on a branch, but this component is on the main. This might be confusing, a maintenance and build time overhead we can reduce. --- .../.gitignore | 2 - .../__init__.py | 0 .../bitbots_technical_challenge_vision.py | 183 ------------------ .../config/range.yaml | 118 ----------- .../launch/vision.launch | 8 - .../package.xml | 27 --- .../bitbots_technical_challenge_vision | 0 .../setup.cfg | 4 - .../setup.py | 34 ---- sync_includes_wolfgang_nuc.yaml | 1 - 10 files changed, 377 deletions(-) delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/.gitignore delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/__init__.py delete mode 100755 bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision.py delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/config/range.yaml delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/launch/vision.launch delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/package.xml delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/resource/bitbots_technical_challenge_vision delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/setup.cfg delete mode 100644 bitbots_misc/bitbots_technical_challenge_vision/setup.py diff --git a/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/.gitignore b/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/.gitignore deleted file mode 100644 index ab08e78d3..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Ignore generate parameter library build artifacts -bitbots_technical_challenge_vision_params.py diff --git a/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/__init__.py b/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision.py b/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision.py deleted file mode 100755 index 7c7957aad..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision/bitbots_technical_challenge_vision.py +++ /dev/null @@ -1,183 +0,0 @@ -from typing import Optional, Tuple - -import cv2 -import numpy as np -import rclpy -import rclpy.logging -from ament_index_python.packages import get_package_share_directory -from cv_bridge import CvBridge -from rclpy.node import Node -from sensor_msgs.msg import Image -from soccer_vision_2d_msgs.msg import Robot, RobotArray - -from bitbots_technical_challenge_vision.bitbots_technical_challenge_vision_params import ( - bitbots_technical_challenge_vision, -) - - -class TechnicalChallengeVision(Node): - def __init__(self): - super().__init__("bitbots_technical_challenge_vision") - - self._package_path = get_package_share_directory("bitbots_technical_challenge_vision") - self._cv_bridge = CvBridge() - self._annotations_pub = self.create_publisher(RobotArray, "/robots_in_image", 10) - self._debug_img_pub = self.create_publisher(Image, "/bitbots_technical_challenge_vision_debug_img", 10) - self._debug_clrmp_pub_blue = self.create_publisher( - Image, "/bitbots_technical_challenge_vision_debug_clrmp_blue", 10 - ) - self._debug_clrmp_pub_red = self.create_publisher( - Image, "/bitbots_technical_challenge_vision_debug_clrmp_red", 10 - ) - self._img_sub = self.create_subscription(Image, "/camera/image_proc", self.image_callback, 10) - self._param_listener = bitbots_technical_challenge_vision.ParamListener(self) - self._params = self._param_listener.get_params() - - def create_robot_msg(self, x: int, y: int, w: int, h: int, t: int) -> Robot: - """ - Creates a Robot message from a robots bounding box data and its color. - - :param x: bb top left x - :param y: bb top left y - :param w: bb width - :param h: bb height - :param t: robot team - :return: robot message for that robot - """ - robot = Robot() - - robot.bb.center.position.x = float(x + (w / 2)) - robot.bb.center.position.y = float(y + (h / 2)) - robot.bb.size_x = float(w) - robot.bb.size_y = float(h) - robot.attributes.team = t - - return robot - - def process_image( - self, img: np.ndarray, debug_img: np.ndarray, arg - ) -> Tuple[list[Robot], list[Robot], np.ndarray, np.ndarray]: - """ - gets annotations from the camera image - - :param img: ndarray containing the camera image - :param debug_img: copy of img debug annotations should be drawn here - :param arg: __RosParameters object containing the dynamic parameters - :return: [[blue_robots], [red_robots], clrmp_blue, clrmp_red] - """ - # convert img to hsv to isolate colors better - img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) - - # get color maps - blue_map = cv2.inRange( - img, - (arg.blue_lower_h, arg.blue_lower_s, arg.blue_lower_v), - (arg.blue_upper_h, arg.blue_upper_s, arg.blue_upper_v), - ) - - red_map = cv2.inRange( - img, - (arg.red_lower_h, arg.red_lower_s, arg.red_lower_v), - (arg.red_upper_h, arg.red_upper_s, arg.red_upper_v), - ) - - # get contours in color maps - blue_contours, _ = cv2.findContours(blue_map, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) - red_contours, _ = cv2.findContours(red_map, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) - - # get lists of bounding boxes - blue_robots = [] - red_robots = [] - - def annotate(x, y, w, h, c) -> Optional[np.ndarray]: - if not arg.debug_mode: - return None - return cv2.rectangle( - debug_img, - (x, y), - (x + w, y + h), - c, - 2, - ) - - for cnt in blue_contours: - x, y, w, h = cv2.boundingRect(cnt) - if min(w, h) >= arg.min_size and max(h, w) <= arg.max_size: - # draw bb on debug img - annotate(x, y, w, h, (255, 0, 0)) - - # TODO I think 1 is for the blue team? - blue_robots.append(self.create_robot_msg(x, y, w, h, 1)) - - for cnt in red_contours: - x, y, w, h = cv2.boundingRect(cnt) - if min(w, h) >= arg.min_size and max(h, w) <= arg.max_size: - # draw bb on debug img - annotate(x, y, w, h, (0, 0, 255)) - - red_robots.append(self.create_robot_msg(x, y, w, h, 2)) - - return blue_robots, red_robots, blue_map, red_map, debug_img - - def image_callback(self, msg: Image): - # get dynamic parameters - if self._param_listener.is_old(self._params): - self._param_listener.refresh_dynamic_parameters() - self._params = self._param_listener.get_params() - - arg = self._params - - # set variables - img = self._cv_bridge.imgmsg_to_cv2(img_msg=msg, desired_encoding="bgr8") - header = msg.header - - if arg.debug_mode: - debug_img = np.copy(img) - else: - debug_img = None - - # get annotations - blue_robots, red_robots, blue_map, red_map, debug_img = self.process_image(img, debug_img, arg) - robots = [] - robots.extend(blue_robots) - robots.extend(red_robots) - - # make output message - robot_array_message = RobotArray() - robot_array_message.header = header - robot_array_message.robots = robots - - # publish output message - self._annotations_pub.publish(robot_array_message) - - if arg.debug_mode: - # make debug image message - debug_img_msg = self._cv_bridge.cv2_to_imgmsg(cvim=debug_img, encoding="bgr8", header=header) - - # publish debug image - self._debug_img_pub.publish(debug_img_msg) - - # make color map messages - clrmp_blue_img = cv2.cvtColor(blue_map, cv2.COLOR_GRAY2BGR) - clrmp_blue_msg = self._cv_bridge.cv2_to_imgmsg(cvim=clrmp_blue_img, encoding="bgr8", header=header) - - clrmp_red_img = cv2.cvtColor(red_map, cv2.COLOR_GRAY2BGR) - clrmp_red_msg = self._cv_bridge.cv2_to_imgmsg(clrmp_red_img, encoding="bgr8", header=header) - - # publish color map messages - self._debug_clrmp_pub_blue.publish(clrmp_blue_msg) - self._debug_clrmp_pub_red.publish(clrmp_red_msg) - - -def main(args=None): - rclpy.init(args=args) - node = TechnicalChallengeVision() - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - node.destroy_node() - - -if __name__ == "__main__": - main() diff --git a/bitbots_misc/bitbots_technical_challenge_vision/config/range.yaml b/bitbots_misc/bitbots_technical_challenge_vision/config/range.yaml deleted file mode 100644 index 6716d55af..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/config/range.yaml +++ /dev/null @@ -1,118 +0,0 @@ -bitbots_technical_challenge_vision: - blue_lower_h: { - type: int, - default_value: 92, - description: "hue value of the lower boundary for blue obstacles", - validation: { - bounds<>: [0, 179] - } - } - blue_upper_h: { - type: int, - default_value: 110, - description: "hue value of the upper boundary for blue obstacles", - validation: { - bounds<>: [0, 179] - } - } - blue_lower_s: { - type: int, - default_value: 90, - description: "separation value of the lower boundary for blue obstacles", - validation: { - bounds<>: [0, 255] - } - } - blue_upper_s: { - type: int, - default_value: 236, - description: "separation value of the upper boundary for blue obstacles", - validation: { - bounds<>: [0, 255] - } - } - blue_lower_v: { - type: int, - default_value: 0, - description: "value value of the lower boundary for blue obstacles", - validation: { - bounds<>: [0, 255] - } - } - blue_upper_v: { - type: int, - default_value: 255, - description: "value value of the upper boundary for blue obstacles", - validation: { - bounds<>: [0, 255] - } - } - red_lower_h: { - type: int, - default_value: 138, - description: "hue value of the lower boundary for red obstacles", - validation: { - bounds<>: [0, 179] - } - } - red_upper_h: { - type: int, - default_value: 179, - description: "hue value of the upper boundary for red obstacles", - validation: { - bounds<>: [0, 179] - } - } - red_lower_s: { - type: int, - default_value: 78, - description: "separation value of the lower boundary for red obstacles", - validation: { - bounds<>: [0, 255] - } - } - red_upper_s: { - type: int, - default_value: 255, - description: "separation value of the upper boundary for red obstacles", - validation: { - bounds<>: [0, 255] - } - } - red_lower_v: { - type: int, - default_value: 0, - description: "value value of the lower boundary for red obstacles", - validation: { - bounds<>: [0, 255] - } - } - red_upper_v: { - type: int, - default_value: 255, - description: "value value of the upper boundary for red obstacles", - validation: { - bounds<>: [0, 255] - } - } - min_size: { - type: int, - default_value: 20, - description: "minimum size of an obstacle to be considered", - validation: { - gt_eq<>: 0 - } - } - max_size: { - type: int, - default_value: 400, - description: "maximum size of an obstacle to be considered", - validation: { - gt_eq<>: 0 - } - } - debug_mode: { - type: bool, - default_value: false, - description: "set true if debug images should be drawn and published", - } diff --git a/bitbots_misc/bitbots_technical_challenge_vision/launch/vision.launch b/bitbots_misc/bitbots_technical_challenge_vision/launch/vision.launch deleted file mode 100644 index 1d36dc25f..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/launch/vision.launch +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/bitbots_misc/bitbots_technical_challenge_vision/package.xml b/bitbots_misc/bitbots_technical_challenge_vision/package.xml deleted file mode 100644 index 9c0a53d6e..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/package.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - bitbots_technical_challenge_vision - 0.0.0 - TODO: Package description - par - TODO: License declaration - - rclpy - python3-opencv - python3-numpy - cv_bridge - sensor_msgs - soccer_vision_2d_msgs - - generate_parameter_library - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/bitbots_misc/bitbots_technical_challenge_vision/resource/bitbots_technical_challenge_vision b/bitbots_misc/bitbots_technical_challenge_vision/resource/bitbots_technical_challenge_vision deleted file mode 100644 index e69de29bb..000000000 diff --git a/bitbots_misc/bitbots_technical_challenge_vision/setup.cfg b/bitbots_misc/bitbots_technical_challenge_vision/setup.cfg deleted file mode 100644 index 34ccaf1e9..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/lib/bitbots_technical_challenge_vision -[install] -install_scripts=$base/lib/bitbots_technical_challenge_vision diff --git a/bitbots_misc/bitbots_technical_challenge_vision/setup.py b/bitbots_misc/bitbots_technical_challenge_vision/setup.py deleted file mode 100644 index 4603d372c..000000000 --- a/bitbots_misc/bitbots_technical_challenge_vision/setup.py +++ /dev/null @@ -1,34 +0,0 @@ -import glob - -from generate_parameter_library_py.setup_helper import generate_parameter_module -from setuptools import find_packages, setup - -package_name = "bitbots_technical_challenge_vision" - -setup( - name=package_name, - version="0.0.0", - packages=find_packages(exclude=["test"]), - data_files=[ - ("share/ament_index/resource_index/packages", ["resource/" + package_name]), - ("share/" + package_name, ["package.xml"]), - ("share/" + package_name + "/config", glob.glob("config/*.yaml")), - ("share/" + package_name + "/launch", glob.glob("launch/*.launch")), - ], - install_requires=["setuptools"], - zip_safe=True, - maintainer="par", - maintainer_email="paer-wiegmann@gmx.de", - description="This Package provides a simple vision to detect the obstacles for the obstacle avoidance challenge.", - license="MIT", - entry_points={ - "console_scripts": [ - "bitbots_technical_challenge_vision = bitbots_technical_challenge_vision.bitbots_technical_challenge_vision:main", - ], - }, -) - -generate_parameter_module( - "bitbots_technical_challenge_vision_params", - "config/range.yaml", -) diff --git a/sync_includes_wolfgang_nuc.yaml b/sync_includes_wolfgang_nuc.yaml index d3b11f678..7c2e24c43 100644 --- a/sync_includes_wolfgang_nuc.yaml +++ b/sync_includes_wolfgang_nuc.yaml @@ -14,7 +14,6 @@ include: - bitbots_ipm - bitbots_parameter_blackboard - bitbots_robot_description - - bitbots_technical_challenge_vision - bitbots_teleop - bitbots_tf_buffer - bitbots_tts