Week 4 — A moving belt and a vacuum grip
GSoC 2026 · Week 4 · Coding period
Week 4: A moving belt and a vacuum grip
Last week the Palletizing scene loaded but nothing in it moved — the conveyor was a static mesh, the boxes sat where I placed them, and the arm shared its gripper with Pick & Place. This week I made all three of those things untrue. Palletizing now has its own branches, its own exercise row, a conveyor that actually carries boxes, and a UR5 that wears a suction cup instead of fingers.
Giving Palletizing a home of its own
Up to now Palletizing had been riding inside Pick & Place’s exercise — sharing its card, its robot, its everything. That was the right call for standing the scene up quickly, but the moment the two exercises start to differ (and a suction gripper is exactly that moment), they need to be separable.
So I cut palletizing-exercise branches on both RoboticsAcademy and RoboticsInfrastructure, wired the exercise into the database as its own entry — exercise 27, universe 71 — and rebuilt the Gazebo world under that identity. The HAL templates I scaffolded from pick_place as a starting point; they’re stubs for now, but they give the exercise a place to grow its own student-facing API.
RoboticsInfrastructure@7d409c4
The conveyor belt
A pallet exercise where boxes don’t arrive isn’t much of an exercise. The Pick & Place conveyor looks like a belt but is a static mesh — so I replaced it with a real moving one using Gazebo Harmonic’s built-in TrackController system, the same machinery Gazebo uses to drive tank treads. The contact surface of the belt link gets a commanded velocity, and anything resting on it gets carried along.
On top of the belt I wrote a box_spawner.py node that owns the full box lifecycle:
- A box spawns at the feed end of the belt.
- It rides the belt to the centre.
- The belt stops.
- The box is placed on the pallet table.
- The cycle restarts.
The belt speed is also controllable from ROS — there’s a bridge exposing it as a topic, so the speed isn’t baked into the world and can be driven from a node (or, eventually, from the exercise logic).
RoboticsInfrastructure@af25aff
The suction gripper
A palletizing robot doesn’t pinch boxes between two fingers — it grabs them by the face with a vacuum cup. So the UR5 needed a new end effector, and that ripples out further than you’d expect:
- A new URDF for the suction-cup variant of the arm.
- A new SRDF — and this one is genuinely different, not a copy. It’s arm-only: no finger group, because there are no fingers to plan for.
- A matching controllers config and a MoveIt launcher for the new robot.
- A
palletizing_harmonic.launch.pyfor RViz.
I registered the suction arm as a new robot in the database and pointed the Palletizing universe at it instead of the Robotiq-gripper UR5.
The last piece was the grab itself. RoboticsInfrastructure uses a gz_link_attacher plugin to fake the grasp — when the gripper closes, it rigidly attaches the target object to the gripper link. That plugin had the robot model name and gripper link hardcoded to the Robotiq finger tips. I patched it to take both as SDF parameters, so Palletizing can point it at the suction cup face instead. Pick & Place keeps its old behaviour by passing the old values; Palletizing passes its own.
RoboticsInfrastructure@1623d8f
Demo
The conveyor carrying boxes, and the suction gripper picking them off:
What’s next
Next up is the HAL — replacing GripperSet with a SuctionSet that just toggles the vacuum on/off. The motion API carries over from Pick & Place; it’s only the end-effector verb that changes, finger pinch → vacuum on.
Until next week 👋
Enjoy Reading This Article?
Here are some more articles you might like to read next: