A fixed-pose baseline and a camera-guided approach that segments a live depth point cloud, classifies what it sees, and sorts it into a box — both running identically against Gazebo or the real UR3.
The UR3 arm running at the socialab lab.
Two independent choices — approach (how the target pose is decided) and environment (what's actually moving the arm) — combine into four launch commands. Environment only changes the bringup; the pick-place logic is identical either way.
| Simulation | Real robot | |
|---|---|---|
| Static | roslaunch ur3_pick_place static/sim.launch |
roslaunch ur3_pick_place static/real.launch |
| Dynamic | roslaunch ur3_pick_place dynamic/sim.launch † |
roslaunch ur3_pick_place dynamic/real.launch † |
† run dynamic/calibrate.launch once per camera mount first.
scripts/static/static_pick_place.py
No perception — the object's location is fixed and known ahead of time. Home → approach → grasp → lift → move to drop pose → release → retreat, driven entirely through MoveIt. The baseline that validates the driver, controller, and planning pipeline before perception is layered on.
scripts/dynamic/*.py
Environment picks the bringup; approach picks the pipeline. Both land on the same MoveIt call.
Environment — pick one:
Dynamic approach:
Static approach is the same tail end, minus the perception stages —
static_pick_place.py talks straight to move_group
with poses read from config/static/poses.yaml. Neither approach
talks to the bringup directly, only to MoveIt and fixed topic names — that's
what makes the environment swap invisible to the pick-place logic.
What each bringup actually starts.
| Aspect | Simulation | Real robot |
|---|---|---|
| Bringup | bringup_sim.launch | bringup_real.launch |
| Arm | Gazebo + ur_gazebo | Universal_Robots_ROS_Driver |
| Camera | Gazebo depth plugin | RealSense, relayed to matching topics |
| Env vars | env/sim.env.sh | env/real.env.sh |
catkin_ws/src/ur3_pick_place/
├── msg/DetectedObject.msg # class, pose, size, confidence
├── urdf/depth_camera.urdf.xacro # overhead depth camera for Gazebo
├── src/ur3_pick_place/
│ └── gripper_interface.py # shared GripperCommand wrapper
├── env/
│ ├── sim.env.sh
│ └── real.env.sh
├── config/
│ ├── static/poses.yaml
│ └── dynamic/
│ ├── sorting_box.yaml
│ ├── object_classes.yaml
│ ├── aruco_markers.yaml
│ └── camera_extrinsics.yaml
├── launch/
│ ├── common/ # bringup_sim, bringup_real, moveit_planning
│ ├── static/{sim,real}.launch
│ └── dynamic/{calibrate,sim,real}.launch
└── scripts/
├── static/static_pick_place.py
└── dynamic/{camera_calibration,pointcloud_object_detector,dynamic_pick_place}.py
Ubuntu 18.04 + ROS Melodic. Full setup steps are in the repo README.
Simulation + Static
source env/sim.env.sh
roslaunch ur3_pick_place static/sim.launch
Simulation + Dynamic
source env/sim.env.sh
roslaunch ur3_pick_place dynamic/calibrate.launch # once per camera mount
roslaunch ur3_pick_place dynamic/sim.launch
Real robot + Static
roslaunch ur_calibration calibration_correction.launch \
robot_ip:=$UR3_ROBOT_IP target_filename:="$UR3_KINEMATICS_CONFIG" # once per unit
source env/real.env.sh
roslaunch ur3_pick_place static/real.launch
Real robot + Dynamic
roslaunch ur_calibration calibration_correction.launch \
robot_ip:=$UR3_ROBOT_IP target_filename:="$UR3_KINEMATICS_CONFIG" # once per unit
source env/real.env.sh
roslaunch ur3_pick_place dynamic/calibrate.launch # once per camera mount
roslaunch ur3_pick_place dynamic/real.launch
UR3 work at the socialab lab, 2020.