Visual Positioning System for ROS 2
Over VPS is a ROS 2 package that provides visual positioning and localization for mobile robots using a single camera image. It integrates seamlessly with navigation stacks like Nav2 and AMCL.
Key Features:
- 6-DOF pose estimation from a single image
- TF transform publishing (map → odom)
- 3D point cloud visualization
- Nav2/AMCL integration support
Our Visual Positioning System (VPS) empowers the next generation of robotic navigation, enabling robots, and any device with a camera to understand their precise location and orientation in the physical world. This is made possible through our comprehensive 3D digital twins of real-world environments, live on 150k+ locations worldwide.
🌐 Learn more at overthereality.ai
- ROS 2 Humble
- Python 3.8+
- Over The Reality API key from vps.ovr.ai
- Get OVRMaps .ply from builder.ovr.ai
- Get OVRMaps uuid from builder.ovr.ai
# Clone the repository
cd ~/ros2_ws/src
git clone https://github.com/OVR-Platform/over_vps.git
cd ~/ros2_ws
# Install dependencies with rosdep
rosdep install --from-paths src --ignore-src -r -y
# Build the packages
colcon build --packages-select over_vps over_vps_interfaces over_vps_nav2_demo
source install/setup.bashIf rosdep fails, install Python dependencies manually:
# Option 1: Using pip (recommended)
pip3 install -r src/over_vps/requirements.txt
# Option 2: Using apt (Ubuntu/Debian) + pip for open3d
sudo apt install -y python3-requests python3-numpy python3-scipy \
python3-opencv python3-pil
pip3 install open3d>=0.13.0
# Then build
colcon build --packages-select over_vps over_vps_interfaces over_vps_nav2_demoFor advanced rosdep configuration, see ROSDEP_SETUP.md.
Use VPS with your own robot for visual localization.
1. Configure:
Edit over_vps/config/vps_params.yaml:
vps_action_server:
ros__parameters:
api_key: "your-api-key-here"
map_cloud_file: "/path/to/pointcloud.ply"
map_uuid_for_cloud: "your-map-uuid"
camera_offset: [0.0, 0.0, 0.0]
odom_topic: "odom"
use_sim_time: false (true for gazebo test)Launch your robot with rviz
2. Launch VPS server:
ros2 launch over_vps vps_full.launch.py3. Trigger localization:
# Using image file path
ros2 action send_goal /vps_path \
over_vps_interfaces/action/OverVPSImagePathMapID \
"{image_path: '/path/to/image.jpg', map_id: 'your-map-uuid'}"
# Or using ROS Image topic
ros2 run over_vps over_vps_camera_client --ros-args \
-p input_image_topic:=/camera/image_raw \
-p map_id:='your-map-uuid'Published topics:
/vps/result- VPS result with pose/vps/map_cloud- 3D point cloud visualization/tf- Transform: map → odom
4. Visualize in RViz:
To see the 3D point cloud in RViz:
- Set Fixed Frame to
map - Click Add → By topic →
/vps/map_cloud→ PointCloud2 - Adjust the Size property (e.g., 0.05) for better visibility
- Optionally change Color Transformer to
RGB8orIntensity
Complete example with Gazebo, Nav2, and AMCL integration.
1. Configure:
Edit over_vps/config/vps_params.yaml (API key):
api_key: "your-api-key-here"Edit over_vps_nav2_demo/config/demo_vps_params.yaml (map settings):
map_file: "/path/to/map.yaml"
map_cloud_file: "/path/to/pointcloud.ply"
world_file: "/path/to/gazebo.world"
map_uuid_for_cloud: "your-map-uuid"2. Launch demo:
# Headless mode (no Gazebo GUI)
ros2 launch over_vps_nav2_demo vps_tb3_sim.launch.py
# With Gazebo GUI
ros2 launch over_vps_nav2_demo vps_tb3_sim.launch.py headless:=False3. Trigger VPS localization:
ros2 action send_goal /vps_path \
over_vps_interfaces/action/OverVPSImagePathMapID \
"{image_path: '/path/to/image.jpg', map_id: 'your-map-uuid'}"The demo automatically:
- Launches Gazebo with TurtleBot3
- Starts Nav2 with your map
- Initializes AMCL with VPS pose
- Enables autonomous navigation
4. Visualize in RViz:
RViz is launched automatically with the demo. To view the point cloud:
- In RViz, verify Fixed Frame is set to
map - Click Add → By topic →
/vps/map_cloud→ PointCloud2 - Adjust visualization:
- Size: 0.05 (or adjust for your point cloud density)
- Color Transformer:
RGB8for colored clouds, orIntensity - Decay Time: 0 (to keep the cloud visible permanently)
| Topic | Type | Description |
|---|---|---|
/vps/result |
over_vps_interfaces/VPSResult |
VPS result with robot pose |
/vps/map_cloud |
sensor_msgs/PointCloud2 |
3D point cloud visualization |
/tf |
tf2_msgs/TFMessage |
Transform: map → odom |
/initialpose |
geometry_msgs/PoseWithCovarianceStamped |
Initial pose for AMCL (demo mode) |
| Action | Type | Description |
|---|---|---|
/vps_img |
OverVPSImageMapID |
Localize using ROS Image message + map UUID |
/vps_path |
OverVPSImagePathMapID |
Localize using image file path + map UUID |
map ← Published by VPS
└─ odom ← From robot odometry
└─ base_link ← Robot base frame
Edit over_vps/config/vps_params.yaml:
vps_action_server:
ros__parameters:
api_key: "your-api-key-here" # Over The Reality API key
map_cloud_file: "/path/to/cloud.ply" # Point cloud file
map_uuid_for_cloud: "map-uuid" # Map UUID from Over platform
camera_offset: [0.0, 0.0, 0.3] # Camera offset from base_link [x, y, z]
publish_tf: true # Publish map → odom transform
force_z_zero: true # Force Z=0 for 2D navigation
odom_topic: "odom" # Odometry topic name
use_sim_time: false # Use simulation time (true for Gazebo)Apache License 2.0 - see LICENSE file.
For questions or issues, visit overthereality.ai