Skip to content

Commit

Permalink
Put how-to and tutorials into move arm section, fix arm API description
Browse files Browse the repository at this point in the history
  • Loading branch information
JessamyT committed Dec 31, 2024
1 parent 8a2e840 commit b2a7b6b
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 10 deletions.
4 changes: 2 additions & 2 deletions docs/dev/reference/apis/components/arm.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ date: "2022-01-01"
# updated: "" # When the content was last entirely checked
---

The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning.
If you want self-collision prevention and obstacle avoidance, use the [motion API](/dev/reference/apis/services/motion/).
The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning with self-collision prevention.
If you want the arm to avoid obstacles, or you want to plan complex motion in an automated way, use the [motion API](/dev/reference/apis/services/motion/).

The arm component supports the following methods:

Expand Down
28 changes: 28 additions & 0 deletions docs/operate/mobility/move-arm/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
linkTitle: "Move an arm"
title: "Move an arm"
weight: 50
layout: "docs"
type: "docs"
no_list: true
description: "Move an arm with joint positions or automated motion planning."
---

You have two options for moving a robotic arm:

- Use direct joint position commands and simple linear commands with the [arm API](/dev/reference/apis/components/arm/)
- Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/)

{{< cards >}}
{{% card link="/dev/reference/apis/components/arm/" %}}
{{% card link="/dev/reference/apis/services/motion/" %}}
{{< /cards >}}

## Tutorials and example usage

{{< cards >}}
{{% card link="/operate/mobility/move-arm/move-robot-arm/" %}}
{{% card link="/operate/mobility/move-arm/plan-motion-with-arm-gripper/" %}}
{{% card link="/operate/mobility/move-arm/constrain-motion/" %}}
{{% card link="/tutorials/projects/claw-game/" %}}
{{< /cards >}}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Add Constraints and Transforms to a Motion Plan"
linkTitle: "Add Motion Constraints"
title: "Add constraints and transforms to a motion plan"
linkTitle: "Add motion constraints"
type: "docs"
description: "Use constraints and transforms with the motion service."
videos:
Expand All @@ -19,6 +19,8 @@ level: "Intermediate"
date: "2023-07-03"
# updated: ""
cost: 8400
aliases:
- /tutorials/services/constrain-motion/
---

{{<gif webm_src="/tutorials/videos/motion_constraints.webm" mp4_src="/tutorials/videos/motion_constraints.mp4" alt="An arm moving a cup from one side of a tissue box to the other, across a table. The cup stays upright." class="alignright" max-width="250px">}}
Expand Down
220 changes: 220 additions & 0 deletions docs/operate/mobility/move-arm/move-robot-arm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
---
title: "Move a robot arm with the arm API"
linkTitle: "Use the arm API"
weight: 70
type: "docs"
tags: ["arm", "components"]
images: ["/how-tos/move_to_position.gif"]
videos: ["/how-tos/move_to_position.webm", "/how-tos/move_to_position.mp4"]
description: "Connect to a robotic arm and control it with the arm API."
aliases:
- /tutorials/motion/accessing-and-moving-robot-arm
- /tutorials/motion/
- /how-tos/move-robot-arm/
languages: ["Python", "Go"]
viamresources: ["arm"]
platformarea: ["mobility"]
level: "Intermediate"
date: "2024-10-31"
# updated: "" # When the tutorial was last entirely checked
cost: "8400"
---

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.

{{< alert title="In this page" color="tip" >}}

1. [Access the arm](#access-the-arm)
1. [Move the arm](#move-the-arm)

{{< /alert >}}

## 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](/components/arm/).

## Access the arm

{{< table >}}
{{% tablestep link="/configure/" %}}
**1. Configure a machine with an arm**

{{% snippet "setup.md" %}}

Add an arm component.
Select a model that supports your arm. Refer to the [documentation for the model](/components/arm/#configuration) for information about your arm's configuration attributes.

{{<imgproc src="/how-tos/access-arm/config.png" resize="500x" class="fill aligncenter" style="width: 400px" declaredimensions=true alt="Configuration builder UI with a blank arm component">}}
Save your config.

{{% /tablestep %}}
{{% tablestep link="/appendix/apis/components/arm/#getendposition" %}}
**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.

{{% snippet "show-secret.md" %}}

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`](/internals/orientation-vector/).
For more information, see [`GetEndPosition`](/appendix/apis/components/arm/#getendposition).

{{% /tablestep %}}
{{% tablestep %}}
**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:

{{< tabs >}}
{{% tab name="Python" %}}

```python
# 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}")
```

{{% /tab %}}
{{% tab name="Go" %}}

```go
// 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)
```

{{% /tab %}}
{{< /tabs >}}

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.

{{% /tablestep %}}
{{< /table >}}

## 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.

{{< alert title="Caution" color="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.
{{< /alert >}}

{{< table >}}
{{% tablestep %}}
**1. Initiate motion with a joint position command**

{{< tabs >}}
{{% tab name="Python" %}}
Add the following line to your import list to be able to assign values to a `JointPositions` data structure:

```python
from viam.proto.component.arm import JointPositions
```

Add the following code to your script:

```python
# 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)
```

{{% /tab %}}
{{% tab name="Go" link="/appendix/apis/components/arm/#movetojointpositions" %}}
Add `armapi "go.viam.com/api/component/arm/v1"` to your import list.
Add the following code to your script:

```go
// 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
}
```

{{% /tab %}}
{{< /tabs >}}

{{<gif webm_src="/how-tos/joint_positions.webm" mp4_src="/how-tos/joint_positions.mp4" alt="The robot arm moving through joint position commands" max-width="200px" class="alignleft">}}

Run the code.
The third joint of your arm should move 30 degrees.
For more information, see [`MoveToJointPositions`](/appendix/apis/components/arm/#movetojointpositions).

{{% /tablestep %}}
{{% tablestep link="/appendix/apis/components/arm/#movetoposition" %}}
**2. Command to move to position**

{{< tabs >}}
{{% tab name="Python" %}}

Add the following code to your script:

```python
# 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)
```

{{% /tab %}}
{{% tab name="Go" %}}
Add `"go.viam.com/rdk/spatialmath"` to your import list.

Add the following code to your script:

```go
// 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
}
```

{{% /tab %}}
{{< /tabs >}}

{{<gif webm_src="/how-tos/move_to_position.webm" mp4_src="/how-tos/move_to_position.mp4" alt="A robot arm moving to a commanded position" max-width="200px" class="alignright">}}

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`](/internals/orientation-vector/) when commanding arm motion.
Run the code to see your arm move 100 mm upwards.
For more information, see [`MoveToPosition`](/appendix/apis/components/arm/#movetoposition).

{{% /tablestep %}}
{{< /table >}}

## Next steps

{{< cards >}}
{{% card link="/tutorials/services/plan-motion-with-arm-gripper" %}}
{{% card link="/tutorials/projects/claw-game/" %}}
{{< /cards >}}

For more resources on robot kinematics, read through the Wikipedia pages for [Forward kinematics](https://en.wikipedia.org/wiki/Forward_kinematics) and [Inverse kinematics](https://en.wikipedia.org/wiki/Inverse_kinematics).
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "Plan Motion with an Arm and a Gripper"
linkTitle: "Plan Motion with an Arm"
title: "Plan motion with an arm and gripper"
linkTitle: "Use the motion service"
type: "docs"
description: "Use the motion service to move robot arms and other components."
description: "Use the motion service to move a robot arm and gripper."
videos:
[
"/tutorials/videos/motion_armmoving.webm",
Expand All @@ -19,6 +19,8 @@ date: "2023-03-07"
# updated: ""
cost: 8400
no_list: true
aliases:
- /tutorials/services/plan-motion-with-arm-gripper/
---

With Viam you can move individual components, like [arms](/components/arm/), by issuing commands like `MoveToPosition` or `MoveToJointPosition`.
Expand Down Expand Up @@ -55,8 +57,8 @@ This also helps simplify and shorten the code examples presented below.

## Configure a robot

The [robot configuration from the prior tutorial](/how-tos/move-robot-arm/) should be used for this tutorial.
We will revisit that robot configuration and add new components during specific sections below.
Use the robot configuration from the [prerequisite guide](/how-tos/move-robot-arm/) for this tutorial as well.
We will revisit that robot configuration and add new components.

The motion service is one of the "built-in" services, which means that no initial configuration is required to start planning and executing complex motion.
All you need is a robot with a component that can move, such as a robotic arm.
Expand Down
2 changes: 1 addition & 1 deletion docs/operate/reference/components/arm/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ date: "2024-10-21"
# SME: Peter L
---

The arm component provides an API for linear motion planning, including self-collision prevention and obstacle avoidance.
The arm component provides an API for linear motion, including self-collision prevention.

If you have a physical robotic arm, consisting of a serial chain of joints and links, with a fixed end and an end effector end, use an arm component.

Expand Down

0 comments on commit b2a7b6b

Please sign in to comment.