Autonomous pick-and-place system using Franka FR3 robotic arm with RGBD vision and MoveIt Task Constructor
- 🎥 Vision Pipeline - RGBD camera-based object detection and 6D pose estimation
- 🎯 Dynamic Tracking - Real-time cube position updates and motion triggering
- 🤖 Motion Planning - MoveIt Task Constructor for complex pick-and-place sequences
- 🌍 Simulation - Full Gazebo environment with custom worlds and models
- 📦 Flexible Configuration - Adjustable grasp parameters, table boundaries, and detection thresholds
- 🐳 Docker Ready - Containerized development environment for easy setup
- RGBD camera detects cubes on the workspace table
- Vision pipeline estimates pose
- MoveIt Task Constructor plans collision-free pick-and-place trajectory
- Franka FR3 robot executes the motion to pick and place cubes in bins
- System continuously monitors for new cubes and repeats
- System Architecture
- Prerequisites
- Installation
- Usage
- Configuration
- Project Structure
- Troubleshooting
- Roadmap
- Contributing
- License
- Acknowledgments
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ RGBD Camera │─────▶│ Vision Pipeline │─────▶│ Detected Poses │
└─────────────┘ │ (OpenCV) │ │ (vision_msgs) │
└──────────────────┘ └────────┬────────┘
│
┌──────────────────┐ │
│ MTC Planner │◀─────────────┘
│ (pick & place) │
└────────┬─────────┘
│
┌────────▼─────────┐
│ Franka FR3 Arm │
│ (Gazebo Sim) │
└──────────────────┘
Vision Pipeline (vision_pipeline_node)
- Subscribes to RGBD camera topics (
/rgbd_camera/image,/rgbd_camera/depth_image) - Performs table segmentation and cube detection using OpenCV
- Publishes detected cube poses to
/vision/detected_cube_pose
Motion Planner (franka_pick_place_node)
- Subscribes to detected cube poses
- Generates MoveIt Task Constructor pipeline with stages:
- Current state → Approach → Grasp → Lift → Place → Retreat
- Executes motion and monitors for position changes
Simulation Environment
- Gazebo Ignition with custom world (
pick_place_with_bins.sdf) - RGBD camera mounted above workspace
- Franka FR3 robot with gripper
- Spawnable cubes and bins
- OS: Ubuntu 22.04 LTS
- ROS 2: Humble Hawksbill
- Docker: 20.10+ (for containerized setup)
- Hardware:
- 8GB+ RAM recommended
- MoveIt 2
- ros2_control
- Gazebo Ignition (Fortress)
- OpenCV
- yaml-cpp
Docker provides an isolated, reproducible environment and is the easiest way to get started.
git clone --recurse-submodules https://github.com/kalaiselvan-t/vision-sorter.git
cd pick-and-placecd src
docker compose builddocker compose up -d franka_ros2
docker exec -it franka_ros2 bashcd /ros2_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bashFor users who prefer a local installation without Docker.
Follow the official ROS 2 Humble installation guide.
Install Desktop version for full GUI tools:
sudo apt update && sudo apt install ros-humble-desktopsudo apt install -y \
ros-humble-moveit \
ros-humble-ros2-control \
ros-humble-ros2-controllers \
ros-humble-ros-gz-sim \
ros-humble-ros-gz-bridge \
python3-colcon-common-extensions \
libyaml-cpp-dev \
libopencv-devmkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone --recurse-submodules https://github.com/kalaiselvan-t/vision-sorter.git .
# Import additional dependencies
vcs import < franka.repos
# Build
cd ~/ros2_ws
source /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install
source install/setup.bashTerminal 1: Launch Gazebo simulation with robot
source install/setup.bash
ros2 launch franka_pick_place gazebo_fr3.launch.pyThis launches:
- Gazebo with custom world (table, bins, camera)
- Franka FR3 robot with controllers
- MoveIt move_group
- RViz for visualization
- MTC pick-and-place node
Terminal 2: Start vision pipeline
source install/setup.bash
ros2 run franka_pick_place vision_pipeline_nodeTerminal 3: Spawn cubes
python3 spawn_multiple_cubes.py 3The robot will automatically detect and pick the cubes!
# Launch with DEBUG logging
ros2 launch franka_pick_place gazebo_fr3.launch.py log_level:=DEBUG# View detected cube poses
ros2 topic echo /vision/detected_cube_pose
# View joint states
ros2 topic echo /joint_statesEdit franka_pick_place/config/params.yaml to customize behavior:
| Parameter | Description | Default | Unit |
|---|---|---|---|
cube_size |
Side length of cube | 0.03 | meters |
approach_distance |
Distance to stop before grasp | 0.15 | meters |
pre_grasp_distance |
Distance to open gripper | 0.06 | meters |
lift_distance |
Height to lift after grasp | 0.08 | meters |
place_approach_distance |
Distance above bin for placement | 0.30 | meters |
cube_position_change_tolerance |
Minimum movement to trigger re-plan | 0.05 | meters |
cube_orientation_change_tolerance |
Minimum rotation to trigger re-plan | 1.0 | degrees |
Edit franka_pick_place/config/planning_scene.yaml to adjust:
- Table dimensions and position
- Collision objects (bins, walls)
- Workspace boundaries
franka_pick_place/
├── config/
│ ├── params.yaml # Pick-place parameters
│ ├── planning_scene.yaml # Collision objects & table
│ └── moveit_controllers.yaml # MoveIt controller config
├── include/
│ ├── franka_pick_and_place.hpp
│ └── vision.hpp
├── launch/
│ └── gazebo_fr3.launch.py # Main launch file
├── models/
│ ├── cube/ # Gazebo cube model
│ ├── bins/ # Target bins
│ └── camera/ # RGBD camera
├── scripts/
│ ├── spawn_cube.py # Spawn single cube
│ └── spawn_multiple_cubes.py # Spawn multiple cubes
├── src/
│ ├── main.cpp # Pick-place node entry
│ ├── vision_main.cpp # Vision node entry
│ ├── mtc/
│ │ ├── franka_pick_and_place.cpp # Main MTC logic
│ │ ├── cube_tracking.cpp # Pose tracking
│ │ ├── mtc.cpp # MTC pipeline
│ │ └── planning_scene_loader.cpp # Scene setup
│ ├── vision/
│ │ └── vision.cpp # Detection & pose estimation
│ └── utilities/
│ └── test_utilities.cpp # Helper functions
└── worlds/
└── pick_place_with_bins.sdf # Gazebo world
Check if MoveIt service is running:
ros2 service list | grep plan_kinematic_pathVerify controllers are active:
ros2 control list_controllersExpected output:
arm_controller[active]
gripper_controller[active]
joint_state_broadcaster[active]
Check camera topics:
ros2 topic list | grep rgbd_camera
ros2 topic hz /rgbd_camera/imageVerify cube is on table:
- Cubes must be within table boundaries (see
planning_scene.yaml) - Check RViz to see camera view
Adjust detection thresholds: Edit vision pipeline source if needed (src/vision/vision.cpp)
Missing dependencies:
rosdep install --from-paths src --ignore-src -r -yClean build:
rm -rf build/ install/ log/
colcon build --symlink-installIncrease shared memory (Docker):
# In docker-compose.yml, add:
shm_size: '2gb'Check GPU drivers (if using):
nvidia-smi- Add unit tests for vision and MTC components
- Support for different object shapes (cylinders, boxes)
- Multi-object sorting by color/size
- Real Franka FR3 hardware integration
- Performance benchmarks and optimization
- VLA (Vision-Language-Action) model integration
- ROS 2 parameters for runtime configuration
- CI/CD pipeline with automated testing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
Copyright 2024-2025 Kalaiselvan Thangaraj
This project builds upon excellent open-source work:
- franka_ros2 - Franka Robotics ROS 2 integration
- MoveIt 2 - Motion planning framework
- MoveIt Task Constructor - Task-level motion planning
- Franka Robotics - For creating amazing research robots
Special thanks to the ROS and robotics open-source community!

