Skip to content
Open
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
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

38 changes: 38 additions & 0 deletions ERRORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[place_recognition_node.py-1] 2025-03-31 14:33:42.986 | WARNING | opr.models.place_recognition.pointmamba:<module>:16 - The 'pointmamba' package is not installed. Please install it manually if neccessary.
[place_recognition_node.py-1] [INFO] [1743431623.286569389] [multimodal_multicamera_lidar_place_recognition]: Initialized PlaceRecognitionNode node.
[place_recognition_node.py-1] [INFO] [1743431696.078611049] [multimodal_multicamera_lidar_place_recognition]: Received synchronized messages.
[place_recognition_node.py-1] Traceback (most recent call last):
[place_recognition_node.py-1] File "/home/docker_opr_ros2/ros2_ws/install/open_place_recognition/lib/open_place_recognition/place_recognition_node.py", line 377, in <module>
[place_recognition_node.py-1] main()
[place_recognition_node.py-1] File "/home/docker_opr_ros2/ros2_ws/install/open_place_recognition/lib/open_place_recognition/place_recognition_node.py", line 371, in main
[place_recognition_node.py-1] rclpy.spin(pr_node)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/__init__.py", line 226, in spin
[place_recognition_node.py-1] executor.spin_once()
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 739, in spin_once
[place_recognition_node.py-1] self._spin_once_impl(timeout_sec)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 736, in _spin_once_impl
[place_recognition_node.py-1] raise handler.exception()
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/task.py", line 239, in __call__
[place_recognition_node.py-1] self._handler.send(None)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 437, in handler
[place_recognition_node.py-1] await call_coroutine(entity, arg)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 362, in _execute_subscription
[place_recognition_node.py-1] await await_or_execute(sub.callback, msg)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 107, in await_or_execute
[place_recognition_node.py-1] return callback(*args)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/message_filters/__init__.py", line 83, in callback
[place_recognition_node.py-1] self.signalMessage(msg)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/message_filters/__init__.py", line 64, in signalMessage
[place_recognition_node.py-1] cb(*(msg + args))
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/message_filters/__init__.py", line 313, in add
[place_recognition_node.py-1] self.signalMessage(*msgs)
[place_recognition_node.py-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/message_filters/__init__.py", line 64, in signalMessage
[place_recognition_node.py-1] cb(*(msg + args))
[place_recognition_node.py-1] File "/home/docker_opr_ros2/ros2_ws/install/open_place_recognition/lib/open_place_recognition/place_recognition_node.py", line 354, in listener_callback
[place_recognition_node.py-1] output = self.pipeline.infer(input_data)
[place_recognition_node.py-1] File "/home/docker_opr_ros2/OpenPlaceRecognition/src/opr/pipelines/place_recognition/base.py", line 124, in infer
[place_recognition_node.py-1] _, pred_i = self.database_index.search(descriptor, 1)
[place_recognition_node.py-1] File "/usr/local/lib/python3.10/dist-packages/faiss-1.7.4-py3.10.egg/faiss/class_wrappers.py", line 329, in replacement_search
[place_recognition_node.py-1] assert d == self.d
[place_recognition_node.py-1] AssertionError
[ERROR] [place_recognition_node.py-1]: process has died [pid 2597, exit code 1, cmd '/home/docker_opr_ros2/ros2_ws/install/open_place_recognition/lib/open_place_recognition/place_recognition_node.py --ros-args -r __node:=multimodal_multicamera_lidar_place_recognition --params-file /tmp/launch_params_wdk5sjdl'].
141 changes: 93 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
# OpenPlaceRecognition-ROS2

The ROS2 wrapper is intended for:
The OpenPlaceRecognition ROS2 wrapper is intended for:

- 🔌 **Easy integration** of multimodal localization into robots and autonomous systems based on ROS2.
- 🚘 **Application in existing robotic platforms and autopilots** running ROS2.
- ⚙️ **Rapid deployment** of neural network-based global localization methods into real-world ROS2 projects.

> Check out out [OpenPlaceRecognition library](https://github.com/OPR-Project/OpenPlaceRecognition).
> It is a library for place recognition and localization, which includes a collection of datasets, including ITLP-Campus.
> The library provides a unified API for loading datasets, training and evaluating models, and performing place recognition tasks.
> The library is designed to be easy to use and extensible, allowing researchers and developers to quickly experiment with different models and datasets.

## Installation

### Requirements
# Requirements

#### Hardware

Expand All @@ -34,75 +27,127 @@ The ROS2 wrapper is intended for:
- CUDA Toolkit >= 11.1
- cuDNN >= 7.5
- [OpenPlaceRecognition](https://github.com/OPR-Project/OpenPlaceRecognition)
- ROS2 Humble
- [ROS2 Humble](https://docs.ros.org/en/humble/Installation.html)
- Docker

# Installation

Firstly retreave all dependencies for this project

```bash
# Step 1: Clone the main repository with submodules
cd ~
git clone --recursive https://github.com/OPR-Project/OpenPlaceRecognition

If you want to install all dependencies manually, please refer to the
[Advanced Installation section of the OpenPlaceRecognition documentation](https://openplacerecognition.readthedocs.io/en/latest/#installation)
for detailed instructions.
# Step 2: Clone the ITLP-Campus-Outdoor dataset
git clone https://huggingface.co/datasets/OPR-Project/ITLP-Campus-Outdoor ~/Datasets/ITLP-Campus-Outdoor

The only additional dependency is ROS2. Please refer to the
[ROS2 Humble installation guide](https://docs.ros.org/en/humble/Installation.html)
for instructions on how to install it.
# Step 3: Create required directories for pretrained weights
mkdir -p ~/OpenPlaceRecognition/weights/place_recognition
mkdir -p ~/OpenPlaceRecognition/weights/registration

### Quick start
# Step 4: Download pretrained weights
wget https://huggingface.co/OPR-Project/PlaceRecognition-NCLT/resolve/main/minkloc3d_nclt.pth \
-O ~/OpenPlaceRecognition/weights/place_recognition/minkloc3d_nclt.pth

It is highly recommended to use the provided Dockerfile to build the environment.
The scripts to build, run and enter the container are provided in the [docker/](./docker) directory.
You can use the following commands:
wget https://huggingface.co/OPR-Project/Registration-KITTI/resolve/main/geotransformer_kitti.pth \
-O ~/OpenPlaceRecognition/weights/registration/geotransformer_kitti.pth

# Step 5: Export environment variables
export OPR_PATH=$HOME/OpenPlaceRecognition
export DATASETS_DIR=$HOME/Datasets
export DISPLAY=:0
```

### Quick Start with Docker

It is highly recommended to use the provided Dockerfile to build the complete environment. The Docker scripts are located in the `docker/` directory. For now, we only support x86_64 architecture. The aarch64 version will be released soon.

```bash
# 0. clone the repository and init submodules
# 0. Clone the repository
git clone https://github.com/OPR-Project/OpenPlaceRecognition-ROS2.git
cd OpenPlaceRecognition-ROS2
git submodule update --init --recursive

# 1. build the image
bash docker/build.sh
# 1. Build the Docker image
bash docker/build_x86_64.sh

# 2. start the container and mount the data directory
bash docker/start.sh [DATA_DIR]
# 2. Start the container with the data directory mounted
bash docker/start_x86_64.sh

# 3. enter the container
# 3. Enter the container
bash docker/into.sh
```

To use [OpenPlaceRecognition](https://github.com/OPR-Project/OpenPlaceRecognition) library in the container, you need to install it first.
Run the following command inside the container:
Inside the container, install the additional Python dependencies:

```bash
pip install -e ~/ros2_ws/dependencies/OpenPlaceRecognition
pip install -e ~/OpenPlaceRecognition
pip install -e ~/OpenPlaceRecognition/third_party/GeoTransformer
pip install -e ~/OpenPlaceRecognition/third_party/HRegNet
pip install -e ~/OpenPlaceRecognition/third_party/PointMamba
```

## Running nodes

### Build the workspace

Inside `ros2_ws/` directory, run the following command:
### Build the ROS2 Workspace

```bash
colcon build --packages-select open_place_recognition opr_interfaces
cd ~/ros2_ws/
colcon build --symlink-install
source ~/ros2_ws/install/setup.bash
```

### Run the nodes

Open the new terminal and run:
## Launch Files and Usage

```bash
source ros2_ws/install/setup.bash
```
The project provides a variety of launch files to support testing, visualization, and deployment. Each launch file is configurable via command-line arguments to adapt to different sensor setups and dataset paths.

Run the place recognition node using launch file:
- **Dataset Conversion from Bag Files:**
Convert ROS2 bag files into a standardized OPR dataset format for further processing.
```bash
ros2 launch open_place_recognition dataset_from_bag.launch.py
```

```bash
ros2 launch open_place_recognition place_recognition_launch.py
```
- **Dataset Conversion from RTAB-Map:**
Convert RTAB-Map datasets to the compatible format required by the OPR pipeline.
```bash
ros2 launch open_place_recognition dataset_from_rtabmap.launch.py
```

- **Dataset Publisher:**
Publish sensor streams (cameras, LiDAR, etc.) for dataset creation or real-time monitoring.
```bash
ros2 launch open_place_recognition dataset_publisher.launch.py
```

- **Dataset Indexing:**
Index your dataset features to prepare for efficient retrieval and subsequent training.
```bash
ros2 launch open_place_recognition dataset_indexing.launch.py
```

Run the visualizer node using launch file:
- **Place Recognition:**
This node performs a simple database search using the current sensor inputs (e.g. images, LiDAR) to identify the closest matching location in the pre-built database.
```bash
ros2 launch open_place_recognition place_recognition.launch.py
```

- **Localization:**
This pipeline extends place recognition by adding position matching algorithms, improving accuracy and robustness for real-world deployment.
```bash
ros2 launch open_place_recognition localization.launch.py
```


## Additional Tools

For further analysis and visualization, you can run Jupyter Lab from within the container:

```bash
ros2 launch open_place_recognition visualizer_launch.py
export PATH=$PATH:$HOME/.local/bin
cd ~/OpenPlaceRecognition/notebooks
jupyter lab --ip=0.0.0.0 --port=8888 --allow-root
```


## License

[Apache 2.0 license](./LICENSE)
This project is licensed under the [Apache 2.0 License](./LICENSE).
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Fix place_recognition node
- Fix localization node
- Add gps/barometer for better global localization
- Test rtabmap and rosbag convertions
- Add docker supports for aarch64(Jetson based PC)
1 change: 0 additions & 1 deletion dependencies/OpenPlaceRecognition
Submodule OpenPlaceRecognition deleted from 68eb76
111 changes: 111 additions & 0 deletions docker/Dockerfile.jetson
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
FROM open-place-recognition-jetson:r35.4.1-cu114-cp310
ARG MAX_JOBS=4

ENV DEBIAN_FRONTEND noninteractive

RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test && \
apt-get update && apt-get upgrade -y && apt-get install -y \
openssh-server \
g++-11 \
unzip \
zip \
default-jdk \
&& rm -rf /var/lib/apt/lists/*

RUN ln -s /usr/local/bin/python3 /usr/local/bin/python

# upgrade pip
ARG PIP_VERSION=23.3.2
ARG SETUPTOOLS_VERSION=69.0.3
RUN pip install pip==${PIP_VERSION} setuptools==${SETUPTOOLS_VERSION}

# install tensorrt bindings for python3.10
# COPY docker/TensorRT /TensorRT
RUN git clone --branch=release/8.5 https://github.com/NVIDIA/TensorRT.git && \
git submodule update --init --recursive
ENV TRT_OSSPATH=/TensorRT
ENV EXT_PATH=/external
RUN mkdir -p ${EXT_PATH} && cd ${EXT_PATH} && \
git clone https://github.com/pybind/pybind11.git
RUN wget https://www.python.org/ftp/python/3.10.14/Python-3.10.14.tar.xz && \
tar -xf Python-3.10.14.tar.xz && \
mkdir ${EXT_PATH}/python3.10 && \
cp -r Python-3.10.14/Include ${EXT_PATH}/python3.10/include && \
cp /usr/include/aarch64-linux-gnu/python3.10/pyconfig.h ${EXT_PATH}/python3.10/include/. && \
rm -rf Python-3.10.14.tar.xz Python-3.10.14
RUN cd ${TRT_OSSPATH}/python && \
PYTHON_MAJOR_VERSION=3 PYTHON_MINOR_VERSION=10 TARGET_ARCHITECTURE=aarch64 bash build.sh
RUN cd ${TRT_OSSPATH}/python/build/dist && \
pip install tensorrt-*.whl


### install MinkowskiEngine
ARG NINJA_VERSION=1.11.1.1
RUN pip install ninja==${NINJA_VERSION}
RUN git clone --recursive "https://github.com/alexmelekhin/MinkowskiEngine.git" && \
cd MinkowskiEngine && \
git checkout 4b628a7 && \
python3 setup.py install --force_cuda --blas=openblas && \
cd .. && \
rm -rf MinkowskiEngine

RUN pip install \
numpy'<2.0.0' \
opencv-python==4.10.0.84

### Install Torch-TensorRT. See: https://pytorch.org/TensorRT/getting_started/installation.html#compiling-from-source.

WORKDIR /
RUN rm -rf /TensorRT
RUN git clone -b v2.2.0 https://github.com/pytorch/TensorRT.git

# Install Bazel.
WORKDIR /TensorRT
RUN export BAZEL_VERSION=$(cat .bazelversion); \
mkdir bazel; \
cd bazel; \
curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-dist.zip; \
unzip bazel-${BAZEL_VERSION}-dist.zip
WORKDIR /TensorRT/bazel
RUN bash ./compile.sh
RUN cp output/bazel /usr/local/bin/

# Install the torch_tensorrt package.
RUN pip install pyyaml
WORKDIR /TensorRT
# See: https://github.com/pytorch/TensorRT/issues/2623.
COPY docker/torch_tensorrt_workspace/WORKSPACE.jp51 /TensorRT/WORKSPACE
RUN python3 setup.py install --use-cxx11-abi

# install onnx-runtime
RUN wget https://nvidia.box.com/shared/static/ndh4omnbyx9icnbwsizmivngnjo5kp1b.whl -O onnxruntime_gpu-1.18.0-cp310-cp310-linux_aarch64.whl && \
pip install onnxruntime_gpu-1.18.0-cp310-cp310-linux_aarch64.whl && \
rm onnxruntime_gpu-1.18.0-cp310-cp310-linux_aarch64.whl

# COPY docker/Open3D /Open3D
RUN git clone https://github.com/isl-org/Open3D.git && cd Open3D && git checkout c8856fc
WORKDIR /Open3D
RUN bash util/install_deps_ubuntu.sh assume-yes && \
rm -rf /var/lib/apt/lists/*
RUN mkdir build && cd build && \
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DGLIBCXX_USE_CXX11_ABI=ON \
-DBUILD_CUDA_MODULE=ON \
-DBUILD_PYTORCH_OPS=ON \
-DBUILD_TENSORFLOW_OPS=OFF \
-DPYTHON_EXECUTABLE=$(which python) \
-DCMAKE_INSTALL_PREFIX=/usr/local \
.. && \
make -j1 && \
make install -j1
RUN pip install yapf==0.43.0
ENV LD_PRELOAD=${LD_PRELOAD}:/usr/local/lib/libOpen3D.so
RUN cd build && make install-pip-package -j1

# install polygraphy
RUN pip install colored polygraphy --extra-index-url https://pypi.ngc.nvidia.com

# install pytorch3d
RUN FORCE_CUDA=1 pip install "git+https://github.com/facebookresearch/pytorch3d.git@stable"
Loading