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
- Picked a workcell.
anvil.workcell.WorkcellConfig.OPENYAM_V1_SINGLEis the single-arm yam as Anvil ships it: the arm, its gripper, its tuning and where it stands. - Stood it in the sim.
anvil.sim.Worldstarts a sim and stands the arm in it, on a lift, its drives off;anvil.hw.SimHwtakes the arm over and drives it the way the real drives are driven.enable()switches the drives on. - Started the control loop.
anvil.control.Runtimeruns the loop on a thread of its own at 500 Hz, ticking the active controller each time. Here it holds one, theanvil.control.JointTrajectoryController, which plays timed joint trajectories. - Moved the arm.
anvil.workcell.RobotConfig.home_trajectoryplans the homing run the arm's description states, from where the arm stands, andplayruns it, returning once the arm is home. - Read where it is.
tip_poseturns 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
anvil.control.Runtime: the loop, and switching controllers.anvil.control: the other controllers, which follow streamed joint targets or end-effector poses.