├── .github └── workflows │ └── ci.yml ├── Dockerfile ├── LICENSE ├── README.md ├── docs ├── rm_vision.svg └── rm_vision_inside.svg └── rm_vision_bringup ├── CMakeLists.txt ├── config ├── camera_info.yaml ├── launch_params.yaml └── node_params.yaml ├── launch ├── common.py ├── no_hardware.launch.py └── vision_bringup.launch.py └── package.xml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: rm_vision CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | docker-build-and-push: 9 | if: github.event_name == 'push' 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: read 13 | 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v3 17 | 18 | - name: Login to Docker Hub 19 | uses: docker/login-action@v2 20 | with: 21 | username: chenjunnn 22 | password: ${{ secrets.DOCKERHUB_TOKEN }} 23 | 24 | - name: Set up Docker Buildx 25 | uses: docker/setup-buildx-action@v2 26 | 27 | - name: Build and push 28 | uses: docker/build-push-action@v4 29 | with: 30 | context: . 31 | file: ./Dockerfile 32 | push: true 33 | tags: chenjunnn/rm_vision:lastest 34 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:humble-ros-base 2 | 3 | # create workspace 4 | RUN mkdir -p /ros_ws/src 5 | WORKDIR /ros_ws/ 6 | 7 | # clone projects 8 | RUN cd src && git clone https://github.com/chenjunnn/rm_auto_aim --depth=1 && \ 9 | git clone https://github.com/chenjunnn/ros2_mindvision_camera --depth=1 && \ 10 | git clone https://github.com/chenjunnn/ros2_hik_camera --depth=1 && \ 11 | git clone https://github.com/chenjunnn/rm_gimbal_description --depth=1 && \ 12 | git clone https://github.com/chenjunnn/rm_serial_driver --depth=1 && \ 13 | git clone https://github.com/chenjunnn/rm_vision --depth=1 14 | 15 | # install dependencies and some tools 16 | RUN apt-get update && rosdep install --from-paths src --ignore-src -r -y && \ 17 | apt-get install ros-humble-foxglove-bridge wget htop vim -y && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # setup zsh 21 | RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.1.2/zsh-in-docker.sh)" -- \ 22 | -t jispwoso -p git \ 23 | -p https://github.com/zsh-users/zsh-autosuggestions \ 24 | -p https://github.com/zsh-users/zsh-syntax-highlighting && \ 25 | chsh -s /bin/zsh && \ 26 | rm -rf /var/lib/apt/lists/* 27 | 28 | # build 29 | RUN . /opt/ros/humble/setup.sh && colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release 30 | 31 | # setup .zshrc 32 | RUN echo 'export TERM=xterm-256color\n\ 33 | source /ros_ws/install/setup.zsh\n\ 34 | eval "$(register-python-argcomplete3 ros2)"\n\ 35 | eval "$(register-python-argcomplete3 colcon)"\n'\ 36 | >> /root/.zshrc 37 | 38 | # source entrypoint setup 39 | RUN sed --in-place --expression \ 40 | '$isource "/ros_ws/install/setup.bash"' \ 41 | /ros_entrypoint.sh 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ChenJun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rm_vision 2 | 3 | rm_vision 4 | 5 | ## Overview 6 | 7 | rm_vision 项目旨在为 RoboMaster 队伍提供一个规范、易用、鲁棒、高性能的视觉框架方案,为 RM 开源生态的建设添砖加瓦 8 | 9 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 10 | 11 | [![Build Status](https://github.com/chenjunnn/rm_vision/actions/workflows/ci.yml/badge.svg)](https://github.com/chenjunnn/rm_vision/actions/workflows/ci.yml) 12 | 13 | ## 包含项目 14 | 15 | 装甲板自动瞄准算法模块 https://github.com/chenjunnn/rm_auto_aim 16 | 17 | MindVision 相机模块 https://github.com/chenjunnn/ros2_mindvision_camera 18 | 19 | HikVision 相机模块 https://github.com/chenjunnn/ros2_hik_camera 20 | 21 | 机器人云台描述文件 https://github.com/chenjunnn/rm_gimbal_description 22 | 23 | 串口通讯模块 https://github.com/chenjunnn/rm_serial_driver 24 | 25 | 视觉算法仿真器 https://github.com/chenjunnn/rm_vision_simulator 26 | 27 | ## 通过 Docker 部署 28 | 29 | 拉取镜像 30 | 31 | ``` 32 | docker pull chenjunnn/rm_vision:lastest 33 | ``` 34 | 35 | 构建开发容器 36 | 37 | ``` 38 | docker run -it --name rv_devel \ 39 | --privileged --network host \ 40 | -v /dev:/dev -v $HOME/.ros:/root/.ros -v ws:/ros_ws \ 41 | chenjunnn/rm_vision:lastest \ 42 | ros2 launch foxglove_bridge foxglove_bridge_launch.xml 43 | ``` 44 | 45 | 构建运行容器 46 | 47 | ``` 48 | docker run -it --name rv_runtime \ 49 | --privileged --network host --restart always \ 50 | -v /dev:/dev -v $HOME/.ros:/root/.ros -v ws:/ros_ws \ 51 | chenjunnn/rm_vision:lastest \ 52 | ros2 launch rm_vision_bringup vision_bringup.launch.py 53 | ``` 54 | 55 | TBD 56 | 57 | ## 源码编译 58 | 59 | TBD 60 | -------------------------------------------------------------------------------- /docs/rm_vision.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/rm_vision_inside.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rm_vision_bringup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(rm_vision_bringup) 3 | 4 | find_package(ament_cmake_auto REQUIRED) 5 | 6 | if(BUILD_TESTING) 7 | find_package(ament_lint_auto REQUIRED) 8 | set(ament_cmake_copyright_FOUND TRUE) 9 | ament_lint_auto_find_test_dependencies() 10 | endif() 11 | 12 | ament_auto_package( 13 | INSTALL_TO_SHARE 14 | launch 15 | config 16 | ) 17 | -------------------------------------------------------------------------------- /rm_vision_bringup/config/camera_info.yaml: -------------------------------------------------------------------------------- 1 | image_width: 1440 2 | image_height: 1080 3 | camera_name: narrow_stereo 4 | camera_matrix: 5 | rows: 3 6 | cols: 3 7 | data: [1807.12121, 0. , 711.11997, 8 | 0. , 1806.46896, 562.49495, 9 | 0. , 0. , 1. ] 10 | distortion_model: plumb_bob 11 | distortion_coefficients: 12 | rows: 1 13 | cols: 5 14 | data: [-0.078049, 0.158627, 0.000304, -0.000566, 0.000000] 15 | rectification_matrix: 16 | rows: 3 17 | cols: 3 18 | data: [1., 0., 0., 19 | 0., 1., 0., 20 | 0., 0., 1.] 21 | projection_matrix: 22 | rows: 3 23 | cols: 4 24 | data: [1790.52356, 0. , 710.04861, 0. , 25 | 0. , 1794.3208 , 562.32704, 0. , 26 | 0. , 0. , 1. , 0. ] 27 | -------------------------------------------------------------------------------- /rm_vision_bringup/config/launch_params.yaml: -------------------------------------------------------------------------------- 1 | camera: hik 2 | 3 | odom2camera: 4 | xyz: "\"0.10 0.0 0.05\"" 5 | rpy: "\"0.0 0.0 0.0\"" 6 | 7 | detector_log_level: INFO 8 | tracker_log_level: INFO 9 | serial_log_level: INFO 10 | -------------------------------------------------------------------------------- /rm_vision_bringup/config/node_params.yaml: -------------------------------------------------------------------------------- 1 | /camera_node: 2 | ros__parameters: 3 | camera_info_url: package://rm_vision_bringup/config/camera_info.yaml 4 | exposure_time: 2500 5 | gain: 8.0 6 | 7 | /serial_driver: 8 | ros__parameters: 9 | timestamp_offset: 0.006 10 | device_name: /dev/ttyACM0 11 | baud_rate: 115200 12 | flow_control: none 13 | parity: none 14 | stop_bits: "1" 15 | 16 | /armor_detector: 17 | ros__parameters: 18 | debug: true 19 | 20 | detect_color: 0 21 | binary_thres: 80 22 | 23 | light.min_ratio: 0.1 24 | armor.min_light_ratio: 0.8 25 | 26 | classifier_threshold: 0.8 27 | ignore_classes: ["negative"] 28 | 29 | /armor_tracker: 30 | ros__parameters: 31 | target_frame: odom 32 | max_armor_distance: 10.0 33 | 34 | ekf: 35 | sigma2_q_xyz: 0.05 36 | sigma2_q_yaw: 5.0 37 | sigma2_q_r: 80.0 38 | 39 | r_xyz_factor: 4e-4 40 | r_yaw: 5e-3 41 | 42 | tracker: 43 | max_match_distance: 0.5 44 | max_match_yaw_diff: 1.0 45 | 46 | tracking_thres: 5 47 | lost_time_thres: 1.0 48 | -------------------------------------------------------------------------------- /rm_vision_bringup/launch/common.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | 4 | from ament_index_python.packages import get_package_share_directory 5 | from launch.substitutions import Command 6 | from launch_ros.actions import Node 7 | 8 | launch_params = yaml.safe_load(open(os.path.join( 9 | get_package_share_directory('rm_vision_bringup'), 'config', 'launch_params.yaml'))) 10 | 11 | robot_description = Command(['xacro ', os.path.join( 12 | get_package_share_directory('rm_gimbal_description'), 'urdf', 'rm_gimbal.urdf.xacro'), 13 | ' xyz:=', launch_params['odom2camera']['xyz'], ' rpy:=', launch_params['odom2camera']['rpy']]) 14 | 15 | robot_state_publisher = Node( 16 | package='robot_state_publisher', 17 | executable='robot_state_publisher', 18 | parameters=[{'robot_description': robot_description, 19 | 'publish_frequency': 1000.0}] 20 | ) 21 | 22 | node_params = os.path.join( 23 | get_package_share_directory('rm_vision_bringup'), 'config', 'node_params.yaml') 24 | 25 | tracker_node = Node( 26 | package='armor_tracker', 27 | executable='armor_tracker_node', 28 | output='both', 29 | emulate_tty=True, 30 | parameters=[node_params], 31 | ros_arguments=['--log-level', 'armor_tracker:='+launch_params['tracker_log_level']], 32 | ) 33 | -------------------------------------------------------------------------------- /rm_vision_bringup/launch/no_hardware.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from ament_index_python.packages import get_package_share_directory 4 | sys.path.append(os.path.join(get_package_share_directory('rm_vision_bringup'), 'launch')) 5 | 6 | 7 | def generate_launch_description(): 8 | 9 | from common import launch_params, robot_state_publisher, node_params, tracker_node 10 | from launch_ros.actions import Node 11 | from launch import LaunchDescription 12 | 13 | detector_node = Node( 14 | package='armor_detector', 15 | executable='armor_detector_node', 16 | emulate_tty=True, 17 | output='both', 18 | parameters=[node_params], 19 | arguments=['--ros-args', '--log-level', 20 | 'armor_detector:='+launch_params['detector_log_level']], 21 | ) 22 | 23 | return LaunchDescription([ 24 | robot_state_publisher, 25 | detector_node, 26 | tracker_node, 27 | ]) 28 | -------------------------------------------------------------------------------- /rm_vision_bringup/launch/vision_bringup.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from ament_index_python.packages import get_package_share_directory 4 | sys.path.append(os.path.join(get_package_share_directory('rm_vision_bringup'), 'launch')) 5 | 6 | 7 | def generate_launch_description(): 8 | 9 | from common import node_params, launch_params, robot_state_publisher, tracker_node 10 | from launch_ros.descriptions import ComposableNode 11 | from launch_ros.actions import ComposableNodeContainer, Node 12 | from launch.actions import TimerAction, Shutdown 13 | from launch import LaunchDescription 14 | 15 | def get_camera_node(package, plugin): 16 | return ComposableNode( 17 | package=package, 18 | plugin=plugin, 19 | name='camera_node', 20 | parameters=[node_params], 21 | extra_arguments=[{'use_intra_process_comms': True}] 22 | ) 23 | 24 | def get_camera_detector_container(camera_node): 25 | return ComposableNodeContainer( 26 | name='camera_detector_container', 27 | namespace='', 28 | package='rclcpp_components', 29 | executable='component_container', 30 | composable_node_descriptions=[ 31 | camera_node, 32 | ComposableNode( 33 | package='armor_detector', 34 | plugin='rm_auto_aim::ArmorDetectorNode', 35 | name='armor_detector', 36 | parameters=[node_params], 37 | extra_arguments=[{'use_intra_process_comms': True}] 38 | ) 39 | ], 40 | output='both', 41 | emulate_tty=True, 42 | ros_arguments=['--ros-args', '--log-level', 43 | 'armor_detector:='+launch_params['detector_log_level']], 44 | on_exit=Shutdown(), 45 | ) 46 | 47 | hik_camera_node = get_camera_node('hik_camera', 'hik_camera::HikCameraNode') 48 | mv_camera_node = get_camera_node('mindvision_camera', 'mindvision_camera::MVCameraNode') 49 | 50 | if (launch_params['camera'] == 'hik'): 51 | cam_detector = get_camera_detector_container(hik_camera_node) 52 | elif (launch_params['camera'] == 'mv'): 53 | cam_detector = get_camera_detector_container(mv_camera_node) 54 | 55 | serial_driver_node = Node( 56 | package='rm_serial_driver', 57 | executable='rm_serial_driver_node', 58 | name='serial_driver', 59 | output='both', 60 | emulate_tty=True, 61 | parameters=[node_params], 62 | on_exit=Shutdown(), 63 | ros_arguments=['--ros-args', '--log-level', 64 | 'serial_driver:='+launch_params['serial_log_level']], 65 | ) 66 | 67 | delay_serial_node = TimerAction( 68 | period=1.5, 69 | actions=[serial_driver_node], 70 | ) 71 | 72 | delay_tracker_node = TimerAction( 73 | period=2.0, 74 | actions=[tracker_node], 75 | ) 76 | 77 | return LaunchDescription([ 78 | robot_state_publisher, 79 | cam_detector, 80 | delay_serial_node, 81 | delay_tracker_node, 82 | ]) 83 | -------------------------------------------------------------------------------- /rm_vision_bringup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rm_vision_bringup 5 | 0.0.0 6 | TODO: Package description 7 | chenjun 8 | TODO: License declaration 9 | 10 | ament_cmake 11 | 12 | rm_auto_aim 13 | rm_serial_driver 14 | 15 | 16 | ament_cmake 17 | 18 | 19 | --------------------------------------------------------------------------------