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.
In this page
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.
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.
Caution: Keep your API key and machine address safe
We strongly recommend that you add your API key and machine address as an environment variable. Anyone with these secrets can access your machine, and the computer running your machine.
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.
Caution
Be careful when instructing robot arms to move. Before running any code, ensure your robotic arm has enough space and that there are no obstacles. Also pay attention to your surroundings, double-check your code for correctness, and make sure anyone nearby is aware and alert before issuing commands to your machine.
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.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!