How to Set Up and Control a Robotic Arm Using MoveIt and ROS

In this tutorial, I will show you how to set up and control a robotic arm using MoveIt and ROS. MoveIt is a motion planning software for robotic arms. Here is the output:

Real-World Applications

This project has a number of real-world applications: 

  • Indoor and Outdoor Delivery Robots
  • Room Service Robots
  • Robot Vacuums
  • Order Fulfillment
  • Manufacturing
  • Factories

Our robot will exist in a world that contains a post office and three houses. The use case for this simulated robot would be picking up packages at a post office and delivering them to houses in a neighborhood. 

Let’s get started!


  • You have completed this tutorial where you learned how to create a simulated mobile manipulator.
  • You have completed this tutorial where you set up and configured the ROS Navigation Stack for your robot.

All the code you need is located at this link.

Install MoveIt

Let’s install MoveIt

Open a new terminal window, and type the following commands:

sudo apt install ros-noetic-moveit
sudo apt-get install ros-noetic-moveit-setup-assistant
sudo apt-get install ros-noetic-moveit-simple-controller-manager
sudo apt-get install ros-noetic-moveit-fake-controller-manager

Configure the Robotic Arm

Let’s use the MoveIt Setup Assistant to configure our robotic arm.

Open a new terminal window, and type the following command.

roslaunch moveit_setup_assistant setup_assistant.launch

Click Create New MoveIt Configuration Package.

Load the mobile_manipulator.urdf file. Click Load Files.


If the URDF file loads properly, you will see a success message.


Click the Self-Collisions tab on the left-hand side.

Click Generate Collision Matrix.


If you wish, you can manually enable pairs of links for which you want MoveIt to check for collisions during the motion planning process. I will leave the defaults as-is.

Let’s skip the Virtual Joints tab. We won’t have any virtual joints for our mobile manipulator.

Click the Planning Groups tab.


Click Add Group.

Let’s call the group arm.

In the Kinematic Solver dropdown box, select the kdl_kinematics_plugin/KDLKinematicsPlugin.

Keep the resolution and timeout as the default values.

Choose RRTstar as the Group Default Planner.

Add the five joints of the robotic arm.

Click the Robot Poses tab.


Click Add Pose.

Let’s add a pose for the home position.

Pose Name: home_position

  • arm_base_joint: 0.0
  • shoulder_joint: 0.0
  • bottom_wrist_joint: 0.0
  • elbow_joint: 0.0
  • top_wrist_joint: 0.0

Click Save.

Click Add Pose.

Pose Name: goal_position

  • arm_base_joint: 1.5794
  • shoulder_joint: -0.9893
  • bottom_wrist_joint: -0.9893
  • elbow_joint: 0.0
  • top_wrist_joint: -0.6769

Click Save.


We don’t have a gripper or suction cup on the end of our robotic arm, so we can skip the End Effectors tab.

Click the Passive Joints tab. Here is what my setup assistant looks like. I have added all the wheel joints to the passive joints list.


Click the ROS Control tab.

Click the Auto Add FollowJointsTrajectory Controllers For Each Planning Group button.

Click the Author Information tab.

Add your name and email address.


Click the Configuration Files tab.


Select the destination where you want to save the configuration files. I will choose my ~catkin_ws/src/ folder. The name of the folder will be mobile_manipulator_moveit_config.

Click Generate Package.


Click Exit Setup Assistant.

Control the Robotic Arm Manually

Let’s install a couple more packages before we get started. Open a terminal window, and type the following commands.

sudo apt-get update
sudo apt install ros-noetic-moveit-resources-prbt-moveit-config
sudo apt install ros-noetic-pilz-industrial-motion-planner

Open your mobile_manipulator_moveit_controller_manager.launch.xml file.

cd ~/catkin_ws/src/mobile_manipulator_moveit_config/launch
gedit mobile_manipulator_moveit_controller_manager.launch.xml

Add this line in the line below the opening <launch> tag:

<arg name="execution_type" default="unused" />

Save the file, and close it.

Now, launch the robotic arm in Gazebo by opening a new terminal window, and typing:

roslaunch mobile_manipulator mobile_manipulator_gazebo.launch

Open a new terminal window, and launch MoveIt.

Launch the move_group.launch file by opening a terminal window, and typing:

roslaunch mobile_manipulator_moveit_config move_group.launch

Open another terminal window, and launch RViz. This command below is a single command.

roslaunch mobile_manipulator mobile_manipulator_move_base.launch

Click Add in the bottom left, and add the Motion Planning plugin under moveit_ros_visualization. If you don’t have the Add button, be sure to go to Panels -> Display on the upper menu to make sure it appears.


Click the Planning tab.


For Goal State, choose goal_position.


Click Plan & Execute.


The robotic arm will move to the goal position.


Next Steps

Now you know how to move the robotic arm manually using MoveIt’s RViz interface. If you want to control the robotic arm using code, you can follow this tutorial for C++ or this tutorial for Python.

That’s it! Keep building!

How to Move a Simulated Robot Arm to a Goal Using ROS

In this tutorial, we will learn how to use the ROS actionlib to send goals to a simulated robot arm. By the end of this tutorial, you will be able to build the following:


Real-World Applications

This project has a number of real-world applications: 

  • Order Fulfillment
  • Factories
  • Warehouses
  • Manufacturing
  • Kitchens
  • and more!

Let’s get started!


  • You have completed this tutorial where you learned how to create a simulated robot arm.

Create a ROS Package

Let’s begin by creating a ROS package.

In a new terminal window, move to the src (source) folder of your workspace.

cd ~/catkin_ws/src

Now create the package.

catkin_create_pkg arm_to_goal actionlib roscpp rospy std_msgs
cd ~/catkin_ws/
catkin_make --only-pkg-with-deps arm_to_goal

Write the Code

Open a new terminal window.

Move to your package.

roscd arm_to_goal

Create a folder for the Python script we will write.

mkdir scripts

Move inside that folder.

cd scripts

Create a program.


Add the following code:

#!/usr/bin/env python3

# Author: Automatic Addison
# Description: Uses the ROS action lib to move a robotic arm to a goal location

# Import the necessary libraries
from __future__ import print_function # Printing
import rospy # Python client library
import actionlib # ROS action library
from control_msgs.msg import FollowJointTrajectoryAction, FollowJointTrajectoryGoal # Controller messages
from std_msgs.msg import Float64 # 64-bit floating point numbers
from trajectory_msgs.msg import JointTrajectoryPoint # Robot trajectories

def move_robot_arm(joint_values):
  Function to move the robot arm to desired joint angles.
  :param: joint_values A list of desired angles for the joints of a robot arm 
  # Create the SimpleActionClient, passing the type of the action to the constructor
  arm_client = actionlib.SimpleActionClient('arm_controller/follow_joint_trajectory', FollowJointTrajectoryAction)

  # Wait for the server to start up and start listening for goals.
  # Create a new goal to send to the Action Server
  arm_goal = FollowJointTrajectoryGoal()

  # Store the names of each joint of the robot arm
  arm_goal.trajectory.joint_names = ['arm_base_joint', 'shoulder_joint','bottom_wrist_joint' ,'elbow_joint', 'top_wrist_joint']
  # Create a trajectory point  	
  point = JointTrajectoryPoint()

  # Store the desired joint values
  point.positions = joint_values

  # Set the time it should in seconds take to move the arm to the desired joint angles
  point.time_from_start = rospy.Duration(3)

  # Add the desired joint values to the goal

  # Define timeout values
  exec_timeout = rospy.Duration(10)
  prmpt_timeout = rospy.Duration(5)

  # Send a goal to the ActionServer and wait for the server to finish performing the action
  arm_client.send_goal_and_wait(arm_goal, exec_timeout, prmpt_timeout)

if __name__ == '__main__':
  Main method.
    # Initialize a rospy node so that the SimpleActionClient can
    # publish and subscribe over ROS.

    # Move the joints of the robot arm to the desired angles in radians
    move_robot_arm([-0.1, 0.5, 0.02, 0, 0])

    print("Robotic arm has successfully reached the goal!")
  except rospy.ROSInterruptException:
    print("Program interrupted before completion.", file=sys.stderr)

Change the permissions.

chmod +x

Compile the package.

cd ~/catkin_ws/
catkin_make --only-pkg-with-deps arm_to_goal

Run the Code

Open a new terminal window, and type:

cd ~/catkin_ws/
roslaunch mobile_manipulator_body mobile_manipulator_gazebo.launch

Open a new terminal window, and type the following command to move the robot to the goal location:

rosrun arm_to_goal

That’s it! Keep building!

How to Build a Simulated Mobile Manipulator Using ROS

In this tutorial, we will create a mobile manipulator using a wheeled robot base and a robotic arm. All we need to do is to connect the arm_base link of the robot arm to the base_link of the robot.


This tutorial would not have been possible without Ramkumar Gandhinathan and Lentin Joseph’s awesome book ROS Robotics Projects Second Edition (Disclosure: As an Amazon Associate I earn from qualifying purchases). I highly recommend it if you want to learn ROS 1. Many of the files (URDF, configuration, and STL files), come from their book’s public GitHub page.

Real-World Applications

This project has a number of real-world applications: 

  • Indoor Delivery Robots
  • Order Fulfillment
  • Factories
  • Warehouses
  • Space Exploration
  • Power Plants

Let’s get started!


  • You have completed this tutorial where you learned how to create a mobile robot base.
  • You have completed this tutorial where you learned how to create a robotic arm.

Build the Mobile Manipulator

Open a new terminal window.

Move to the urdf folder of your package.

roscd mobile_manipulator_body/urdf/

Now create a file named mobile_manipulator.urdf.

gedit mobile_manipulator.urdf

Add the mobile_manipulator.urdf code inside there.

Save and close the file.

Test the Mobile Manipulator

Now, let’s launch RViz to see what our robot looks like so far.

roscd mobile_manipulator_body/urdf/
roslaunch urdf_tutorial display.launch model:=mobile_manipulator.urdf

A GUI will appear that will enable you to move the joints.


Launch the Mobile Manipulator

Now let’s launch the mobile manipulator.

Open a new terminal window, and go to the package.

roscd mobile_manipulator_body/launch/

Create a new launch file.

gedit mobile_manipulator_gazebo.launch

Add the mobile_manipulator_gazebo.launch code inside there.

Save and close the file.

Now let’s launch the robot in Gazebo.

Move to your catkin workspace.

cd ~/catkin_ws/
roslaunch mobile_manipulator_body mobile_manipulator_gazebo.launch

Here is how the robot looks.


Here are the active ROS topics.

rostopic list

Open a new terminal, and type this command to move the robot arm a little bit:

rostopic pub /arm_controller/command trajectory_msgs/JointTrajectory '{joint_names: ["arm_base_joint","shoulder_joint", "bottom_wrist_joint", "elbow_joint","top_wrist_joint"], points: [{positions: [-0.1, 0.5, 0.02, 0, 0], time_from_start: [1,0]}]}' -1

Type this command to bring the robot back to the home position.

rostopic pub /arm_controller/command trajectory_msgs/JointTrajectory '{joint_names: ["arm_base_joint","shoulder_joint", "bottom_wrist_joint", "elbow_joint","top_wrist_joint"], points: [{positions: [0, 0, 0, 0, 0], time_from_start: [1,0]}]}' -1

You can steer the robot by opening a new window and typing:

rosrun rqt_robot_steering rqt_robot_steering

You will need to change the topic inside the GUI to:


To see the velocity messages, open a new window and type:

rostopic echo /robot_base_velocity_controller/cmd_vel


ROS Robotics Projects Second Edition