Week 5 — Swapping in the UR10 and cleaning up the framework

GSoC 2026 · Week 5 · Coding period

Week 5: Swapping in the UR10 and cleaning up the framework

My mentors suggested upgrading the palletizing arm from a UR5 to a UR10 — the UR10 has a 1.3 m reach (vs 0.85 m) and a 10 kg payload, which is a much better match for a real palletizing scenario. That sounded like a one-word change (ur_type: ur10), but the rabbit hole went a bit deeper than expected.


The hardcoded group name problem

The three shared C++ action servers that drive arm motion — move, robmove, robpose — all had this:

std::string group_name = "ur5_manipulator";   // hardcoded in 5 places
move_group_interface_ROB = MoveGroupInterface(node, group_name);

MoveIt uses this string to look up the planning group in the SRDF. If it doesn’t match exactly, every motion call fails silently with “unknown group.” So a UR10 that declares its group ur10_arm in the SRDF would never plan anything — not because the geometry is wrong, but because a single string literal points somewhere else.

The fix I went with (matching an approach mentor Jesus used on a parallel branch) was to add a MOVE_GROUP ROS parameter with a default of "ur5_manipulator". The existing Pick & Place launcher passes nothing → gets the default → unchanged behaviour. The new UR10 launcher explicitly sets {"MOVE_GROUP": "ur10_arm"} on all three nodes. Five hardcoded literals replaced, one rebuild, zero regressions.


The arm swap itself

With the framework unblocked, the swap was mostly renaming and config edits:

  • ur_type, ROB_PARAMur10 everywhere
  • SRDF group ur5_manipulatorur10_arm
  • Joint limits and Pilz Cartesian limits swapped to the ur10/config/ paths
  • The Gazebo spawn entity name and the world’s <robot_model_name> both updated to ur10_suction — these two must change together because gz_link_attacher looks up the robot by that name to know where to attach the suction grip

Naming things properly

At one point during the work I noticed we had a file called ur5_suction.urdf.xacro that was already describing a UR10 arm. That’s exactly the kind of confusion that causes real bugs — a future me would open that file assuming UR5 geometry and get UR10 instead.

So I renamed the whole family: ur5_suction.*ur10_suction.*, and moved the URDF from models/ur5/ into a proper models/ur10/ folder. The shared generic xacro includes (ur.urdf.xacro, ur.ros2_control.xacro) stayed in models/ur5/ — those are arm-agnostic and Pick & Place relies on them — but the suction-specific file now lives where it should.


The ghost package bug

While validating the xacro I ran into a crash: Package 'ur5_gripper_description' not found. It turned out config/ur10/visual_parameters.yaml was imported from IFRA (the upstream framework) with all 14 mesh references pointing at that package — which isn’t installed in the RA image. The UR10 meshes actually live inside ros2srrc_robots/ur10/meshes/, mirroring the convention the UR5 yaml already uses correctly.

One bulk replace later, the xacro parsed cleanly to 575 lines. The arm would have loaded without meshes otherwise — a silent rendering failure that would have been genuinely annoying to track down.


Demo

Here’s the current state — the UR10 loaded in Gazebo Harmonic alongside the palletizing scene, with the arm skeleton showing in RViz:

UR10 in the Palletizing Harmonic World — Gazebo (top) and RViz skeleton (bottom).

Also this week: rectangular boxes

One detail I also got in: the palletizing boxes are now proper rectangular cuboids instead of cubes. Real-world palletizing almost never involves perfect cubes, and the rectangular shape makes placement orientation meaningful — which matters once the motion planning is written.


What’s next

The arm is in, named correctly, and plans against the right group. Next is getting the HAL’s SuctionSet wired up — replacing the GripperSet stub copied from Pick & Place with a proper vacuum on/off toggle — and then writing the actual pick-and-place motion logic for the palletizing cycle.

Until next week.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Week 12 — One workcell, many palletizing patterns
  • Week 11 — A slower week and more SKU planning
  • Week 10 — Starting SKU-based palletizing
  • Week 9 — Syncing the palletizing exercise with upstream
  • Week 8 — Polishing on mentors' feedback