MoveIt 2 tutorial: planning and execution in ROS 2

Get MoveIt 2 working: Setup Assistant, SRDF planning groups, planner choices, collision geometry and the errors behind most failed first attempts.

Reference
RE-1074
Published
Read
6 min

About the author · Sources, testing and AI policy

Engineer reviewing a robot arm motion plan on screen in a robotics lab

MoveIt 2 does not plan because your robot description is wrong, not because the planner is bad. A missing collision geometry, a mismatched planning group or a controller name that does not exist will stop it before OMPL ever runs.

This guide covers what MoveIt 2 actually does, how to generate a configuration with the Setup Assistant, how planning and execution are separated, and the errors that account for most failed first attempts.

What MoveIt 2 is responsible for

MoveIt 2 is a motion planning framework, not a robot driver. It takes a robot description, builds a planning scene, finds a collision-free path and sends joint trajectories to a controller. Each of those steps can fail on its own.

  • Robot model: URDF for geometry, SRDF for planning groups and collision rules.
  • Planning scene: the robot plus the world, including attached objects.
  • Kinematics: inverse kinematics solvers per planning group.
  • Planner: OMPL by default, with Pilz and CHOMP as alternatives.
  • Execution: a controller from ros2_control that accepts a joint trajectory.
  • Visualisation: RViz with the Motion Planning display.

If any one of the six is misconfigured, the symptom appears at a different place. That is why “MoveIt does not work” is almost never a useful bug report.

Generate a configuration first

The Setup Assistant reads your URDF and writes a moveit_config package containing the SRDF, kinematics, joint limits, controllers and launch files. Do not hand-write this on a first project; generate it, then edit.

ros2 launch moveit_setup_assistant setup_assistant.launch.py
  • Load the URDF or xacro output, not the xacro source.
  • Generate a self-collision matrix; it takes a minute and prevents false collisions.
  • Define one planning group per arm, and a separate group for the gripper.
  • Pick a kinematic solver and give it a timeout.
  • Set the controller names to match your ros2_control configuration exactly.
  • Save the package into your workspace and build it.

The generated launch file starts move_group, RViz and, depending on the template, a fake controller or your real one. Start with the fake controller until planning works, then switch to hardware. Debugging planning and hardware at the same time doubles the work.

The SRDF decides more than people expect

The SRDF is where you tell MoveIt which joints form a group, which pairs can never collide, and which named poses exist. A planning group with the wrong joints produces strange IK results or refuses to move a joint you expected.

SRDF elementWhat it controlsTypical mistake
Planning groupWhich joints move togetherGripper joints left inside the arm group
Virtual jointHow the robot attaches to the worldMissing fixed base, so the robot floats
Disabled collisionsPairs that are allowed to overlapAdjacent links flagged, blocking every plan
Group stateNamed poses such as homePose outside joint limits
End effectorTool used for graspingTool not attached, so grasp poses are wrong

Planning is not execution

move_group produces a trajectory. A controller executes it. In RViz you can plan and preview without any hardware, which is useful, but it also hides execution problems until later. When the ghost robot moves and the real one does not, the plan was fine and the controller side is broken.

ros2 control list_controllers
ros2 control list_hardware_interfaces
ros2 topic echo /joint_states --once

Those three commands answer most execution questions. No active controller, no command interface, or no joint states means MoveIt has nothing to talk to. The controller name in the moveit_config must match the name in the ros2_control YAML, character for character.

Choosing a planner

OMPL’s default RRTConnect is a good general planner for free-space motion. It is fast and reliable but produces paths that look inelegant and do not follow straight lines. For process motion, use the Pilz industrial motion planner, which offers PTP, LIN and CIRC moves that behave like industrial robot instructions.

  • RRTConnect: default for reaching a pose in a cluttered cell.
  • RRTstar: slower, shorter paths, useful when path length matters.
  • PRM: good for repeated queries in a static environment.
  • Pilz PTP/LIN/CIRC: deterministic process motion.
  • CHOMP and STOMP: optimisation-based, useful for smooth trajectories.

Planning time is a parameter, not a fixed cost. A two-second allowance on a simple pick is wasteful; a 100 ms allowance on a tight cell produces failures that look random. Set it per request.

Collision checking that tells the truth

MoveIt checks the collision geometry in the URDF, not the visual meshes. If your collision meshes are simplified boxes, the plan is only as accurate as those boxes. If they are full visual meshes, planning becomes slow and may report collisions inside the gripper.

  • Use simple primitives or convex hulls for collision geometry.
  • Disable collisions between adjacent links that always touch.
  • Add the fixture and the machine to the planning scene, not just the robot.
  • Attach grasped objects so the planner accounts for them.
  • Allow collision with the object you are about to grasp, then attach it.

Errors you will meet in the first week

SymptomLikely cause
No kinematic solver loadedPlugin missing or wrong group name in kinematics.yaml
Every plan fails instantlyStart state in collision, often the home pose
Plan succeeds, robot does not moveController inactive or name mismatch
Robot moves in RViz onlyFake controller still selected
Planning takes many secondsMesh collision geometry or a large scene
IK fails near a reachable poseJoint limits or a solver timeout that is too short
Robot drifts after executionJoint state source not the real hardware

A debugging order that works

  • Confirm the URDF loads and the TF tree is complete.
  • Open RViz, check the robot model matches the real robot.
  • Move joints with the sliders before planning anything.
  • Plan to a nearby pose with no obstacles.
  • Add the fixture and plan again.
  • Switch from the fake controller to hardware and execute a short trajectory.
  • Only then tune planners and velocities.

This order separates model, kinematics, planning, scene and execution. Each step gives a clear yes or no, which is far faster than changing five parameters and hoping.

Related: URDF for ROS 2, ros2_control tutorial, TF2 tutorial, robot arm kinematics, Gazebo simulation.

What is MoveIt 2 used for?

Motion planning, collision checking, inverse kinematics and trajectory execution for robot arms in ROS 2. It plans a path and hands it to a ros2_control controller.

Do I need MoveIt 2 for a mobile robot?

No. MoveIt 2 is for manipulators. Mobile robots use Nav2 for path planning; a mobile manipulator uses both.

Why does MoveIt 2 fail to plan?

Usually a start state in collision, missing collision geometry, a wrong planning group, or joint limits that make the goal unreachable. Check the start state first.

What is the difference between URDF and SRDF?

The URDF describes links and joints. The SRDF adds planning groups, disabled collision pairs, named poses and end effectors that MoveIt needs.

Can MoveIt 2 run without hardware?

Yes, with a fake controller and simulated joint states. Plan in RViz first, then switch to the real controller.

Execution reaches the motors through ros2_control, covered in the hardware interface tutorial.

A working URDF starts with sane geometry, and the robot arm design guide covers joint limits and cable routing.

It helps to solve a two-link arm by hand first; the worked example shows what the solver is doing.

MoveIt 2 expects a working desktop install, and the Windows WSL2 route is the shortest path for students without a spare Ubuntu machine.

Sources and further reading

Pass it onWhatsAppLinkedIn

Keep reading

Continue learning

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.