Skip to content

Quickstart

Bring an arm up in the sim, move it home, and read back where its gripper is. Nothing here needs a robot: the sim stands in for the drives, so the same script runs against a real arm by swapping one line.

Install

The SDK is the anvil package, which PyPI holds as anvil-robotics; its sim extra brings the sim:

pip install 'anvil-robotics[sim]'

The script below then runs as it is.

The script

"""Brings an arm up in the sim, homes it, and says where its gripper ended up."""

import anvil.control
import anvil.hw
import anvil.sim
import anvil.workcell

# The single-arm yam, as Anvil ships it.
workcell = anvil.workcell.WorkcellConfig.OPENYAM_V1_SINGLE
robot = workcell.robot

# The sim stands in for the bench: a world with the arm bolted onto a lift, its drives enabled as real ones would be.
with anvil.sim.World(robot=robot, scene="lift") as world:
    hw = anvil.hw.SimHw(world=world)
    hw.enable()

    # The control loop, holding the one controller this script needs, ticking at 500 Hz on a thread of its own.
    trajectory_controller = anvil.control.JointTrajectoryController(robot=robot)
    with anvil.control.Runtime(hw=hw, controllers=[trajectory_controller], rate_hz=500) as runtime:
        runtime.start()
        handle = runtime.controller(kind=anvil.control.JointTrajectoryController)
        runtime.activate(controller=handle)

        # Home the arm from wherever it stands, and wait for the move to finish.
        home = robot.home_trajectory(from_q=runtime.latest().q)
        handle.play(trajectory=home, timeout_s=30.0)

        arm = anvil.control.control_arms(robot=robot, kind=anvil.control.JointTrajectoryController)[0]
        tip = arm.tip_pose(q=runtime.latest().q)
        print(f"homed: the gripper is at {[round(x, 3) for x in tip.position]} m")

Run it with python quickstart.py. It prints where the gripper ended up, in meters, in the world frame:

homed: the gripper is at [0.28, 0.0, 0.299] m

What it did

  1. Picked a workcell. anvil.workcell.WorkcellConfig.OPENYAM_V1_SINGLE is the single-arm yam as Anvil ships it: the arm, its gripper, its tuning and where it stands.
  2. Stood it in the sim. anvil.sim.World starts a sim and stands the arm in it, on a lift, its drives off; anvil.hw.SimHw takes the arm over and drives it the way the real drives are driven. enable() switches the drives on.
  3. Started the control loop. anvil.control.Runtime runs the loop on a thread of its own at 500 Hz, ticking the active controller each time. Here it holds one, the anvil.control.JointTrajectoryController, which plays timed joint trajectories.
  4. Moved the arm. anvil.workcell.RobotConfig.home_trajectory plans the homing run the arm's description states, from where the arm stands, and play runs it, returning once the arm is home.
  5. Read where it is. tip_pose turns the measured joint positions into the gripper's pose.

Leaving the with blocks stops the loop and closes the sim.

On a real arm

The same script drives real drives with anvil.hw.DamiaoHw in place of the sim, once the bench passes its readiness check. Run on real arms takes it there, and says how to take the drives down without dropping an arm: leaving the with blocks disables them.

Next