├── .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 |
4 |
5 | ## Overview
6 |
7 | rm_vision 项目旨在为 RoboMaster 队伍提供一个规范、易用、鲁棒、高性能的视觉框架方案,为 RM 开源生态的建设添砖加瓦
8 |
9 | [](https://opensource.org/licenses/MIT)
10 |
11 | [](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 |
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 |
--------------------------------------------------------------------------------