-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9899051
commit 042b668
Showing
13 changed files
with
3,088 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Basic Build Workflow | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build-noetic: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
container: | ||
image: rostooling/setup-ros-docker:ubuntu-focal-ros-noetic-desktop-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: ros-tooling/[email protected] | ||
with: | ||
required-ros-distributions: noetic | ||
- uses: ros-tooling/[email protected] | ||
with: | ||
package-name: continuous_tracking | ||
target-ros1-distro: noetic | ||
vcs-repo-file-url: "${{ github.workspace }}/.github/workflows/dependencies.repos" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
repositories: | ||
librosqt: | ||
type: git | ||
url: https://github.com/1r0b1n0/librosqt.git | ||
version: master | ||
ethernet_bridge: | ||
type: git | ||
url: https://github.com/UniBwTAS/ethernet_bridge.git | ||
version: master | ||
ouster-ros: | ||
type: git | ||
url: https://github.com/ouster-lidar/ouster-ros.git | ||
version: master | ||
ogre_helpers: | ||
type: git | ||
url: https://github.com/UniBwTAS/ogre_helpers.git | ||
version: master | ||
rviz_range_image: | ||
type: git | ||
url: https://github.com/UniBwTAS/rviz_range_image.git | ||
version: master | ||
rviz_continuous_point_cloud: | ||
type: git | ||
url: https://github.com/UniBwTAS/rviz_continuous_point_cloud.git | ||
version: master | ||
rviz_colorize_point_cloud_by_label: | ||
type: git | ||
url: https://github.com/UniBwTAS/rviz_colorize_point_cloud_by_label.git | ||
version: master | ||
rosbag_panel: | ||
type: git | ||
url: https://github.com/UniBwTAS/rosbag_panel.git | ||
version: master | ||
ros_comm: | ||
type: git | ||
url: https://github.com/UniBwTAS/ros_comm.git | ||
version: dev-ctrl-by-srv-minimal | ||
object_instance_msgs: | ||
type: git | ||
url: https://github.com/UniBwTAS/object_instance_msgs.git | ||
version: master | ||
ogre_primitives: | ||
type: git | ||
url: https://github.com/UniBwTAS/ogre_primitives.git | ||
version: master | ||
rviz_object_instance: | ||
type: git | ||
url: https://github.com/UniBwTAS/rviz_object_instance.git | ||
version: master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: Publish Docker image | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- 'master' | ||
tags: | ||
- 'v*' | ||
|
||
jobs: | ||
push_to_registry: | ||
name: Push Docker image to Docker Hub | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check out the repo | ||
uses: actions/checkout@v4 | ||
|
||
- name: Log in to Docker Hub | ||
uses: docker/login-action@v3 | ||
with: | ||
username: ${{ secrets.DOCKER_USERNAME }} | ||
password: ${{ secrets.DOCKER_PASSWORD }} | ||
|
||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: andreasr30/continuous_tracking_demo | ||
|
||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
file: ./vnc.Dockerfile | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
cmake_minimum_required(VERSION 3.0.2) | ||
project(continuous_tracking) | ||
|
||
find_package(catkin REQUIRED COMPONENTS roscpp tf2_eigen tf2_ros object_instance_msgs visualization_msgs dynamic_reconfigure message_filters image_geometry) | ||
|
||
generate_dynamic_reconfigure_options( | ||
cfg/ContinuousTracker.cfg | ||
) | ||
|
||
catkin_package( | ||
# INCLUDE_DIRS include | ||
# LIBRARIES continuous_tracking | ||
CATKIN_DEPENDS roscpp tf2_eigen tf2_ros object_instance_msgs visualization_msgs dynamic_reconfigure message_filters image_geometry | ||
# DEPENDS system_lib | ||
) | ||
|
||
include_directories( | ||
include | ||
${catkin_INCLUDE_DIRS} | ||
) | ||
|
||
add_executable(continuous_tracker_node src/continuous_tracker_node.cpp) | ||
target_link_libraries(continuous_tracker_node ${catkin_LIBRARIES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,138 @@ | ||
[![Basic Build Workflow](https://github.com/UniBwTAS/continuous_tracking/actions/workflows/basic-build-ci.yaml/badge.svg?branch=master)](https://github.com/UniBwTAS/continuous_tracking/actions/workflows/basic-build-ci.yaml) | ||
[![Publish Docker image](https://github.com/UniBwTAS/continuous_tracking/actions/workflows/publish-docker-image.yaml/badge.svg)](https://github.com/UniBwTAS/continuous_tracking/actions/workflows/publish-docker-image.yaml) | ||
|
||
# Low Latency Tracking on Continuous Clustering for Rotating LiDARs | ||
|
||
Code will be uploaded soon. Stay tuned. | ||
![Continuous Tracking Demo](https://github.com/UniBwTAS/continuous_tracking/blob/master/assets/demo.gif) | ||
|
||
## Abstract: | ||
|
||
In an intelligent vehicle, it is essential to minimize the latencies in order to be able to react fast. Especially in the | ||
early stages of the perception pipeline, on which many subsequent steps depend, the processing time should be minimized. | ||
One of these fundamental processing steps often includes the instance segmentation of LiDAR point clouds. In a previous | ||
work, we presented an algorithm that significantly reduces the overall latency by processing the incoming point measurements | ||
immediately instead of first accumulating the points for a full revolution. More precisely, the points of a newly incoming | ||
column of the LiDAR range image are immediately clustered to the existing points. Once the LiDAR sensor has rotated | ||
far enough that geometrically no points can be close enough to an existing cluster, this instance segment is published. In | ||
addition to the low latency, this approach has the advantage that there are no problematic discontinuities between the end | ||
of the previous point cloud and the start of the new one. In this work, we present a simple but effective multi-object | ||
tracking algorithm that consistently continues this philosophy and achieves an average latency of only 8 ms and enough | ||
throughput to run in real time. We particularly investigate the association problem since the resulting clusters are no longer | ||
accumulated for a full revolution but arrive in a continuous and out-of-sequence manner. Despite these challenges, we are | ||
capable of keeping pace with other state-of-the-art approaches while significantly reducing latency. Another advantage is that | ||
our method is able to track every object in the environment, regardless of the object class. We are publishing the source | ||
code at https://github.com/UniBwTAS/continuous_tracking. | ||
|
||
## Acknowledgement | ||
|
||
The authors gratefully acknowledge funding by the Federal Office of Bundeswehr Equipment, Information Technology and | ||
In-Service Support (BAAINBw). | ||
|
||
## Overview | ||
|
||
- [Examples](#examples) | ||
- [Get Started](#run-it-yourself) | ||
- [1. Download Sensor Data](#1-download-sensor-data) | ||
- [2. Setup Environment](#2-setup-environment) | ||
- [2.1. Option: Docker + GUI (VNC)](#21-option-docker--gui-vnc) | ||
- [2.2. Option: Locally on Ubuntu 20.04 (Focal) and ROS Noetic](#22-option-locally-on-ubuntu-2004-focal-and-ros-noetic) | ||
- [3. Run Continuous Tracking](#3-run-continuous-clustering) | ||
- [TODOs](#todos) | ||
|
||
# Run it yourself: | ||
|
||
## 1. Download Sensor Data | ||
|
||
Download the example rosbag: | ||
|
||
```bash | ||
cd /folder/with/enough/space | ||
pip3 install gdown && gdown 1zM4xPRahgxdJXJGHNXYUpM_g4-9UrcwC | ||
export ROSBAG_PATH=$(pwd) | ||
``` | ||
|
||
Alternatively download it manually from | ||
our [Google Drive](https://drive.google.com/file/d/1zM4xPRahgxdJXJGHNXYUpM_g4-9UrcwC/view?usp=sharing) and set the | ||
environment variable `ROSBAG_PATH` accordingly: `export ROSBAG_PATH=/parent/folder/of/rosbag` | ||
|
||
Available bags: | ||
|
||
- `gdown 1zM4xPRahgxdJXJGHNXYUpM_g4-9UrcwC` ( | ||
3.9GB, [Manual Download](https://drive.google.com/file/d/1zM4xPRahgxdJXJGHNXYUpM_g4-9UrcwC/view?usp=sharing)) | ||
- Long recording in urban scenario (no camera to reduce file size, no Ouster sensors) | ||
- `gdown 1qjCG6-nWBZ_2wJwoP80jj0gGopBT2c23` ( | ||
2.4GB, [Manual Download](https://drive.google.com/file/d/1qjCG6-nWBZ_2wJwoP80jj0gGopBT2c23/view?usp=sharing)) | ||
- Recording including Ouster 32 sensor data (blurred camera for privacy reasons) | ||
- `gdown 146IaBdEmkfBWdIgGV5HzrEYDTol84a1H` ( | ||
0.7GB, [Manual Download](https://drive.google.com/file/d/146IaBdEmkfBWdIgGV5HzrEYDTol84a1H/view?usp=sharing)) | ||
- Short recording of German Highway (blurred camera for privacy reasons) | ||
|
||
## 2. Setup Environment | ||
|
||
### 2.1. Option: Docker + GUI (VNC) | ||
|
||
This option is the fastest to set up. However, due to missing hardware acceleration in the VNC Docker container for RVIZ | ||
the rosbag is played at 1/10 speed. | ||
|
||
1. Install [Docker Engine](https://docs.docker.com/engine/install/ubuntu/) | ||
2. Ensure shell variable `ROSBAG_PATH` is (still) set correctly (see above) | ||
3. Pull and run docker container: | ||
|
||
```bash | ||
docker run -d -p 6080:80 -v /dev/shm:/dev/shm -v ${ROSBAG_PATH}:/mnt/rosbags -e ROSBAG_PATH=/mnt/rosbags --name continuous_tracking_demo andreasr30/continuous_tracking_demo:master | ||
``` | ||
|
||
4. Open your browser on host and enter: http://localhost:6080 (wait a few seconds and retry if it does not load) | ||
5. Open terminal in browser window (click 'Start' -> 'System Tools' -> 'LXTerminal') | ||
6. Continue with step "Run Continuous Tracking" (see below) in the terminal opened in step 2. (There you can use the | ||
clipboard feature of noVNC; tiny arrow on the left of the screen) | ||
|
||
### 2.2. Option: Locally on Ubuntu 20.04 (Focal) and ROS Noetic | ||
|
||
```bash | ||
# install ROS (if not already installed) | ||
wget -P /tmp https://raw.githubusercontent.com/UniBwTAS/continuous_clustering/master/scripts/install_ros.sh | ||
bash /tmp/install_ros.sh | ||
|
||
# setup ROS workspace (if not already existing) | ||
wget -P /tmp https://raw.githubusercontent.com/UniBwTAS/continuous_clustering/master/scripts/setup_workspace.sh | ||
bash /tmp/setup_workspace.sh # created at ~/catkin_ws | ||
|
||
# switch to your ROS workspace, in our case: | ||
cd ~/catkin_ws/src | ||
|
||
# install dependencies and clone repos to current working directory | ||
wget -P /tmp https://raw.githubusercontent.com/UniBwTAS/continuous_tracking/master/scripts/clone_repositories_and_install_dependencies.sh | ||
bash /tmp/clone_repositories_and_install_dependencies.sh | ||
catkin build | ||
``` | ||
|
||
## 3. Run Continuous Tracking | ||
|
||
```bash | ||
# run on VW Touareg rosbag (set the playback speed lower in Rviz (RosbagPanel) if you run in docker due to missing | ||
# hardware acceleration for graphical output) | ||
roslaunch continuous_tracking demo_touareg.launch bag_file:=${ROSBAG_PATH}/vw_touareg_example1.bag | ||
``` | ||
|
||
> [!Tip] | ||
> For the launch file, you can use `--wait_for_tf:=false` (default: `true`) argument. It controls whether to wait | ||
> for the transform from velodyne to fixed frame (e.g. odometry frame) with a timestamp larger than the one of the | ||
> firing or whether to use the latest available (probably incorrect) transform. The former is the accurate approach | ||
> (that's why it is the default) but the columns are published in larger batches/slices because they are accumulated | ||
> between two transforms. The size of a slice depends on the update rate of the transform (i.e. transforms with 50Hz | ||
> lead to batches/slices of 1/5 rotation for a LiDAR rotating with 10Hz). So for a nice visualization where the columns | ||
> are published one by one like it the GIF at the top of the page you should disable this flag. | ||
## Teaser GIF: | ||
# TODOs | ||
|
||
![Continuous Tracking Demo](https://github.com/UniBwTAS/continuous_tracking/blob/master/assets/demo.gif) | ||
- Port it to ROS2: planned soon | ||
- Add features: | ||
- Ground point segmentation: | ||
- In our paper we do ground point segmentation by using an accumulated terrain grid | ||
- However, the source code for our terrain estimation is not published yet | ||
- We do segmentation only based on current range image column (without temporal information) | ||
- This is slightly worse | ||
- TODO: publish source for terrain estimation | ||
- Publish [kitti2bag](https://github.com/tomas789/kitti2bag) fork, which splits the 360° PointCloud2 into individual | ||
firings in order to run it on KITTI rosbags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#!/usr/bin/env python | ||
PACKAGE = "continuous_tracking" | ||
|
||
from dynamic_reconfigure.parameter_generator_catkin import * | ||
|
||
gen = ParameterGenerator() | ||
|
||
g = gen.add_group("A Association") | ||
g.add("max_centroid_distance", double_t, 0, "todo", 2., 0, 50) | ||
|
||
ls = gen.add_group("B Line Search Algorithm") | ||
ls.add("min_line_length", double_t, 0, "only extract lines with at least this length from start to end point", 1., 0, | ||
10.) | ||
ls.add("min_number_of_inliers", int_t, 0, | ||
"only extract lines with at least this number of inlier points (excluding start and end point)", 12, 0, 200) | ||
ls.add("max_distance_from_line", double_t, 0, "maximum distance of a point to be considered as inlier", 0.08, 0., 1.) | ||
ls.add("max_distance_between_points", double_t, 0, "maximum distance between adjacent points in a line", 1.0, 0., 10) | ||
ls.add("max_windows_with_no_inliers", int_t, 0, "todo", 1, 0, 20) | ||
ls.add("max_line_length", double_t, 0, | ||
"stop line extraction at this length (should be not too big for efficiency reasons)", 4., 0., 100.) | ||
ls.add("row_window_size", int_t, 0, "todo", 3, 1, 10) | ||
ls.add("row_window_stride", int_t, 0, "todo", 1, 1, 10) | ||
find_line_direction_enum = gen.enum([ | ||
gen.const("Against_Sensor_Rotation", int_t, -1, ""), | ||
gen.const("With_Sensor_Rotation", int_t, 1, "") | ||
], "find_line_direction_enum") | ||
ls.add("find_line_direction", int_t, 0, "todo", 1, -1, 1, edit_method=find_line_direction_enum) | ||
ls.add("line_end_min_columns_jump_ahead", int_t, 0, "todo", 4, 1, 100) | ||
|
||
ht = gen.add_group("C Hide Tracks") | ||
ht.add("hide_long_track_min_length", double_t, 0, "todo", 20., 0, 200) | ||
ht.add("hide_large_base_track_min_edge_length", double_t, 0, "todo", 5., 0, 200) | ||
ht.add("hide_long_and_high_track_min_length", double_t, 0, "todo", 4., 0, 200) | ||
ht.add("hide_long_and_high_track_min_height", double_t, 0, "todo", 4., 0, 200) | ||
ht.add("hide_flat_track_max_height", double_t, 0, "todo", 0.3, -0.1, 5) | ||
ht.add("hide_long_and_flat_track_min_length", double_t, 0, "todo", 4, 0, 30) | ||
ht.add("hide_long_and_flat_track_max_height", double_t, 0, "todo", 0.5, -0.1, 5) | ||
|
||
dy = gen.add_group("D Track Init and Dynamics") | ||
dy.add("max_survival_duration_without_update", double_t, 0, "todo", 0.15, 0, 5) | ||
dy.add("max_history_age", double_t, 0, "todo", 2., 0, 30) | ||
dy.add("minimum_absolute_centroid_motion_for_init", double_t, 0, "todo", 1.5, 0.01, 30.) | ||
dy.add("minimum_relative_centroid_motion_for_init", double_t, 0, "todo", 1.5, 1., 10.) | ||
dy.add("minimum_centroid_motion_for_update", double_t, 0, "todo", 0.3, 0.01, 30.) | ||
|
||
bb = gen.add_group("E Bounding Box") | ||
bounding_box_by_enum = gen.enum([ | ||
gen.const("Track", int_t, 0, ""), | ||
gen.const("Cluster", int_t, 1, "") | ||
], "bounding_box_by_enum") | ||
bb.add("bounding_box_by", int_t, 0, "todo", 0, 0, 1, edit_method=bounding_box_by_enum) | ||
bounding_box_enable_if_enum = gen.enum([ | ||
gen.const("Yaw_Initialized", int_t, 0, ""), | ||
gen.const("Has_Line", int_t, 1, ""), | ||
gen.const("Had_Previous_Motion", int_t, 2, ""), | ||
gen.const("Always", int_t, 3, "") | ||
], "bounding_box_enable_if_enum") | ||
bb.add("bounding_box_enable_if", int_t, 0, "todo", 0, 0, 3, edit_method=bounding_box_enable_if_enum) | ||
bounding_box_yaw_by_enum = gen.enum([ | ||
gen.const("Track_Yaw", int_t, 0, ""), | ||
gen.const("Longest_Line", int_t, 1, ""), | ||
gen.const("Principal_Component", int_t, 2, ""), | ||
gen.const("Previous_Motion", int_t, 3, "") | ||
], "bounding_box_yaw_by_enum") | ||
bb.add("bounding_box_yaw_by", int_t, 0, "todo", 0, 0, 3, edit_method=bounding_box_yaw_by_enum) | ||
|
||
exit(gen.generate(PACKAGE, "continuous_tracker", "ContinuousTracker")) |
Oops, something went wrong.