Previous
Encoder
Add a gantry to your machine’s configuration so you can control linear positioning along one or more axes from the Viam app and from code.
A gantry component controls linear motion along one or more axes. The API provides:
Viam includes two built-in gantry models:
| Model | What it does |
|---|---|
single-axis | Controls one linear rail driven by a motor. |
multi-axis | Composes multiple single-axis gantries into a coordinated system. |
The fake built-in model is useful for testing without hardware. Browse all available gantry models in the Viam registry.
single-axis model: a motor
is configured and tested.my-gantry) and click Create.Single-axis gantry:
{
"motor": "my-motor",
"length_mm": 500,
"mm_per_rev": 8
}
| Attribute | Type | Required | Description |
|---|---|---|---|
motor | string | Yes | Name of the motor that drives this axis. |
length_mm | int | Yes | Total travel length of the axis in mm. |
mm_per_rev | int | Yes | Distance traveled per motor revolution in mm (for example, lead screw pitch). |
board | string | No | Board with limit switches, if using them. |
limit_pins | object | No | Pin names for limit switches at each end of travel. |
gantry_mm_per_sec | int | No | Default speed in mm/s. Defaults to 100. |
Multi-axis gantry:
First configure each axis as a separate single-axis gantry, then compose
them:
{
"subaxes_list": ["x-axis", "y-axis", "z-axis"],
"move_simultaneously": true
}
| Attribute | Type | Required | Description |
|---|---|---|---|
subaxes_list | list of strings | Yes | Names of the single-axis gantry components. |
move_simultaneously | bool | No | Whether to move all axes at the same time. Defaults to false. |
Click Save, then expand the TEST section.
Read the gantry’s position and move it along the axis.
To get the credentials for the code below, go to your machine’s page in the Viam app, click the CONNECT tab, and select SDK code sample. Toggle Include API key on. Copy the machine address, API key, and API key ID from the code sample. If you’re using real hardware, you’ll see the gantry move along its axis when you run the code below. With a fake gantry, position values update without physical motion.
pip install viam-sdk
Save this as gantry_test.py:
import asyncio
from viam.robot.client import RobotClient
from viam.components.gantry import Gantry
async def main():
opts = RobotClient.Options.with_api_key(
api_key="YOUR-API-KEY",
api_key_id="YOUR-API-KEY-ID"
)
robot = await RobotClient.at_address("YOUR-MACHINE-ADDRESS", opts)
gantry = Gantry.from_robot(robot, "my-gantry")
# Get axis lengths
lengths = await gantry.get_lengths()
print(f"Axis lengths (mm): {lengths}")
# Get current position
position = await gantry.get_position()
print(f"Current position (mm): {position}")
# Move to 100mm at 50mm/s
print("Moving to 100mm...")
await gantry.move_to_position(
positions=[100.0],
speeds=[50.0]
)
# Verify new position
position = await gantry.get_position()
print(f"New position (mm): {position}")
await robot.close()
if __name__ == "__main__":
asyncio.run(main())
Run it:
python gantry_test.py
mkdir gantry-test && cd gantry-test
go mod init gantry-test
go get go.viam.com/rdk
Save this as main.go:
package main
import (
"context"
"fmt"
"go.viam.com/rdk/components/gantry"
"go.viam.com/rdk/logging"
"go.viam.com/rdk/robot/client"
"go.viam.com/rdk/utils"
)
func main() {
ctx := context.Background()
logger := logging.NewLogger("gantry-test")
robot, err := client.New(ctx, "YOUR-MACHINE-ADDRESS", logger,
client.WithCredentials(utils.Credentials{
Type: utils.CredentialsTypeAPIKey,
Payload: "YOUR-API-KEY",
}),
client.WithAPIKeyID("YOUR-API-KEY-ID"),
)
if err != nil {
logger.Fatal(err)
}
defer robot.Close(ctx)
g, err := gantry.FromProvider(robot, "my-gantry")
if err != nil {
logger.Fatal(err)
}
// Get axis lengths
lengths, err := g.Lengths(ctx, nil)
if err != nil {
logger.Fatal(err)
}
fmt.Printf("Axis lengths (mm): %v\n", lengths)
// Get current position
position, err := g.Position(ctx, nil)
if err != nil {
logger.Fatal(err)
}
fmt.Printf("Current position (mm): %v\n", position)
// Move to 100mm at 50mm/s
fmt.Println("Moving to 100mm...")
if err := g.MoveToPosition(ctx, []float64{100.0}, []float64{50.0}, nil); err != nil {
logger.Fatal(err)
}
// Verify new position
position, err = g.Position(ctx, nil)
if err != nil {
logger.Fatal(err)
}
fmt.Printf("New position (mm): %v\n", position)
}
Run it:
go run main.go
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!