Move a robot arm

In this guide you’ll use Viam’s Python or Go SDK to get the current position of your robot arm and issue movement commands.

Requirements

You need the following hardware to complete this tutorial:

  • A single-board computer or other computer to run viam-server.
  • A Linux, macOS or Windows computer that can run SDK code.
  • A robotic arm.

Access the arm

1. Configure a machine with an arm

Add a new machine in the Viam app. On the machine’s page, follow the setup instructions to install viam-server on the computer you’re using for your project. Wait until your machine has successfully connected to the Viam app.

Add an arm component. Select a model that supports your arm. Refer to the documentation for the model for information about your arm’s configuration attributes.

Configuration builder UI with a blank arm component

Save your config.

2. Get the position of the end effector

One way to describe the state of a robot arm is with the position of the end effector, or the “tool” or “hand” of the arm. The code to get this information is a part of the autogenerated code sample the Viam app provides for your machine. Go to the Code sample page of the CONNECT tab and select either Python or Go.

To show your machine’s API key in the sample code, toggle Include API key.

Then, copy and paste the sample code into a file and run the resulting script to see the resources available on your screen and the position of the end effector output as a Pose. For more information, see GetEndPosition.

3. Get the joint positions

The state of a robot arm can also be described as the list of positions of each joint attached to the arm. To get that information, add the following code right after the code that gets the end effector pose from the prior code sample:

# Joint Positions of arm1
my_arm_joint_positions = await arm_1.get_joint_positions()
print(f"myArm get_joint_positions return value: {my_arm_joint_positions}")
// Joint Positions of arm1
myArmJointPositions, err := arm1.JointPositions(context.Background(), nil)
if err != nil {
  logger.Error(err)
  return
}
logger.Infof("myArm JointPositions return value:", myArmJointPositions)

Run your code again. Each individual value corresponds to the current position of a particular joint on your robot. You can also see these values reflected on the CONTROL tab in the Viam app for your robot arm.

Move the arm

The two main options for controlling arm movement are through joint position commands and through pose commands. Joint position commands allow for more detailed control and flexibility instead of commanding movement with the end effector position in a pose command.

1. Initiate motion with a joint position command

Add the following line to your import list to be able to assign values to a JointPositions data structure:

from viam.proto.component.arm import JointPositions

Add the following code to your script:

# Command a joint position move: move the forearm of the arm slightly up
cmd_joint_positions = JointPositions(values=[0, 0, -30.0, 0, 0, 0])
await arm_1.move_to_joint_positions(positions=cmd_joint_positions)

Add armapi "go.viam.com/api/component/arm/v1" to your import list. Add the following code to your script:

// Command a joint position move: move the forearm of the arm slightly up
cmdJointPositions := &armapi.JointPositions{Values: []float64{0.0, 0.0, -30.0, 0.0, 0.0, 0.0}}
err = arm1.MoveToJointPositions(context.Background(), cmdJointPositions, nil)
if err != nil {
    logger.Error(err)
    return
}

Run the code. The third joint of your arm should move 30 degrees. For more information, see MoveToJointPositions.

2. Command to move to position

Add the following code to your script:

# Generate a simple pose move +100mm in the +Z direction of the arm
cmd_arm_pose = await arm_1.get_end_position()
cmd_arm_pose.z += 100.0
await arm_1.move_to_position(pose=cmd_arm_pose)

Add "go.viam.com/rdk/spatialmath" to your import list.

Add the following code to your script:

// Generate a simple pose move +100mm in the +Z direction of the arm
currentArmPose, err := arm1.EndPosition(context.Background(), nil)
if err != nil {
  logger.Error(err)
  return
}
adjustedArmPoint := currentArmPose.Point()
adjustedArmPoint.Z += 100.0
cmdArmPose := spatialmath.NewPose(adjustedArmPoint, currentArmPose.Orientation())

err = arm1.MoveToPosition(context.Background(), cmdArmPose, nil)
if err != nil {
  logger.Error(err)
  return
}

This code gets the arm’s end position, makes a 100 millimeter adjustment in the +Z direction, and then uses that adjustment as a goal Pose when commanding arm motion. Run the code to see your arm move 100 mm upwards. For more information, see MoveToPosition.

Next steps

For more resources on robot kinematics, read through the Wikipedia pages for Forward kinematics and Inverse kinematics.

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.