Skip to main content

Staubli Communication SDK for Python

UnderAutomation Staubli communication SDK

PyPI Python SOAP Platforms

🤖 Effortlessly Communicate with Staubli Robots from Python

The Staubli Communication SDK for Python wraps the native Staubli SOAP stack and exposes a clean, Pythonic API for automation engineers, researchers, and integrators. Use it to supervise industrial robots, orchestrate motion, exchange I/O, and manage VAL3 applications-all without requiring additional Staubli software licenses.

🔗 More Information: underautomation.com
🔗 Available also for 🟣 .NET & 🟨 LabVIEW


🚀 TL;DR

✅ Install the SDK with pip install UnderAutomation.Staubli.
✅ Connect to Staubli controllers via the native SOAP protocol.
✅ Control motion, read/write I/O, monitor robots, and manage applications directly from Python.

Highlights:

  • ⚡ Real-time SOAP communication through the embedded UnderAutomation.Staubli.dll
  • 🐍 Pythonic wrappers for controllers, parameters, and data objects
  • 🔁 Full motion lifecycle & kinematics helpers
  • 📡 Access to physical & logical I/Os
  • 📦 VAL3 project and task management

📦 Installation

pip install UnderAutomation.Staubli

The package bundles the required .NET assemblies and depends on pythonnet to bridge Python and .NET. Make sure the target machine has a compatible .NET runtime installed.

On Linux, you should also install .NET Core and set environment variable PYTHONNET_RUNTIME to coreclr :

sudo apt-get install -y dotnet-runtime-8.0
PYTHONNET_RUNTIME=coreclr

📖 Examples

Ready-to-run scripts are included in the repository. Each example connects to a controller, demonstrates a specific feature, and can be executed directly.

# File Description
1 example_move_robot.py Connect, compute forward & inverse kinematics, display results, then power on and move the robot to the zero joint position.
2 example_controller_info.py Retrieve and display robots, DH parameters, joint ranges, and controller parameters.
3 example_read_ios.py List all physical IOs, then interactively read any IO by name or index in a loop.
4 example_write_ios.py List all physical IOs, then interactively write values to any IO by name or index in a loop.
5 example_applications.py List VAL3 applications, load & start a project, then suspend, resume, and kill the task step by step.

Run any example with:

python example_move_robot.py

Note: Update the IP address in each script to match your controller before running. Also, if you encounter an InvalidLicenseException, obtain a trial license key from underautomation.com/license and register it in the script.


✨ Features

🔌 Connect to Your Controller

from underautomation.staubli.staubli_controller import StaubliController
from underautomation.staubli.connection_parameters import ConnectionParameters

controller = StaubliController()
parameters = ConnectionParameters("192.168.0.1")

# Optional: configure SOAP credentials and port
parameters.soap.enable = True
parameters.soap.user = "default"
parameters.soap.password = "default"

controller.connect(parameters)

You can also disable the pre-connection ping if needed:

parameters.ping_before_connect = False

UnderAutomation Staubli communication SDK


🔍 Explore System Information

  • List robots: controller.soap.get_robots()
  • Inspect controller parameters: controller.soap.get_controller_parameters()
  • Retrieve DH parameters: controller.soap.get_dh_parameters(robot=0)
  • Retrieve joint ranges: controller.soap.get_joint_range(robot=0)
# List robots and display their properties
robots = controller.soap.get_robots()
for i, robot in enumerate(robots):
    print(f"Robot {i}: arm={robot.arm}, kinematic={robot.kinematic}, mount={robot.mount_type}")

# Controller parameters (serial number, firmware, etc.)
for param in controller.soap.get_controller_parameters():
    print(f"{param.key}: {param.value}")

# DH parameters for robot 0
for j, dh in enumerate(controller.soap.get_dh_parameters(0)):
    print(f"Joint {j}: theta={dh.theta}, d={dh.d}, a={dh.a}, alpha={dh.alpha}")

# Joint ranges for robot 0
joint_range = controller.soap.get_joint_range(0)
for j in range(len(joint_range.min)):
    print(f"Joint {j}: min={joint_range.min[j]:.2f}, max={joint_range.max[j]:.2f}")

UnderAutomation Staubli communication SDK


📍 Track Positions & Joints

  • Cartesian pose + joints: controller.soap.get_current_cartesian_joint_position()
  • Joint-only feedback: controller.soap.get_current_joint_position()

The cartesian position is returned as a Frame (a 3×4 homogeneous matrix with columns N, O, A, P).

# Get joint positions
joints = controller.soap.get_current_joint_position(robot=0)
print(f"Joints: {list(joints)}")

# Get full cartesian + joint position
cart = controller.soap.get_current_cartesian_joint_position(robot=0)
print(f"Joints: {list(cart.joints_position)}")
print(f"Position: X={cart.cartesian_position.x}, Y={cart.cartesian_position.y}, Z={cart.cartesian_position.z}")

UnderAutomation Staubli communication SDK


🧠 Kinematics Helpers

  • Forward kinematics: controller.soap.forward_kinematics(robot, joints) → returns a Frame position and Config
  • Inverse kinematics: controller.soap.reverse_kinematics(robot, joints, target, config, joint_range) → returns joint values and a ReversingResult
# Forward kinematics: joints → cartesian
joints = controller.soap.get_current_joint_position(robot=0)
fk = controller.soap.forward_kinematics(0, joints)
pos = fk.position
print(f"FK position: px={pos.px}, py={pos.py}, pz={pos.pz}")
print(f"FK config: {fk.config}")

# Inverse kinematics: cartesian → joints
joint_range = controller.soap.get_joint_range(robot=0)
ik = controller.soap.reverse_kinematics(0, joints, fk.position, fk.config, joint_range)
print(f"IK joints: {list(ik.joint)}")
print(f"IK result: {ik.result}")  # Success, NoConvergence, etc.

UnderAutomation Staubli communication SDK


⚙️ Motion Control Lifecycle

  • Power management: controller.soap.set_power(True/False)
  • Motion primitives: move_l, move_jc, move_jj, move_c
  • Lifecycle control: stop_motion, reset_motion, restart_motion

The MotionDesc object controls velocity, acceleration, tool frame, and world frame:

from underautomation.staubli.soap.data.motion_desc import MotionDesc
from underautomation.staubli.soap.data.frame import Frame

mdesc = MotionDesc()
mdesc.velocity = 100              # Joint velocity (%)
mdesc.acceleration = 100          # Acceleration (%)
mdesc.deceleration = 100          # Deceleration (%)
mdesc.translation_velocity = 250  # Translation velocity (mm/s)
mdesc.rotation_velocity = 100     # Rotation velocity (deg/s)
mdesc.frequency = 100             # Interpolation frequency (%)
mdesc.tool = Frame()              # Tool frame (identity)
mdesc.frame = Frame()             # World frame (identity)

# Power on, move, power off
controller.soap.set_power(True)

# Joint move (MoveJJ)
result = controller.soap.move_jj(0, [0, 0, 0, 0, 0, 0], mdesc)
print(f"Move result: {result.return_code}")

# Linear move (MoveL)
target = Frame()
target.px, target.py, target.pz = 300, 0, 450
result = controller.soap.move_l(0, target, mdesc)

controller.soap.set_power(False)

UnderAutomation Staubli communication SDK


📡 Physical & Logical I/O Management

  • Discover I/Os: controller.soap.get_all_physical_ios()
  • Read states: controller.soap.read_ios(["io_name"])
  • Write outputs: controller.soap.write_ios(["io_name"], [value])
# List all IOs
for io in controller.soap.get_all_physical_ios():
    print(f"{io.name} ({io.type_str}) - {io.description}")

# Read an IO
states = controller.soap.read_ios(["BasicDO_1"])
for s in states:
    print(f"Value={s.value}, State={s.state}, Locked={s.locked}, Simulated={s.simulated}")

# Write an IO
responses = controller.soap.write_ios(["BasicDO_1"], [1.0])
for r in responses:
    print(f"Found={r.found}, Success={r.success}")

UnderAutomation Staubli communication SDK


📦 Application & Project Control

  • Load projects: controller.soap.load_project("Disk://project/project.pjx")
  • Start applications: controller.soap.start_application("project_name")
  • Inspect VAL3 apps: controller.soap.get_val_applications()
  • Stop and unload: stop_application(), stop_and_unload_all()
# List available applications
for app in controller.soap.get_val_applications():
    print(f"{app.name} - loaded={app.loaded}, running={app.is_running}")

# Load and start a project
controller.soap.load_project("Disk://project/project.pjx")
controller.soap.start_application("MyProject")

# Stop everything
controller.soap.stop_and_unload_all()

UnderAutomation Staubli communication SDK


🔁 Task Supervision

  • List VAL3 tasks: controller.soap.get_tasks()
  • Control execution: task_suspend, task_resume, task_kill
# List all running tasks
for task in controller.soap.get_tasks():
    print(f"{task.name}: state={task.state!r}, priority={task.priority}, created_by={task.created_by}")

# Suspend, resume, and kill a task
controller.soap.task_suspend("project~", "default")
controller.soap.task_resume("project~", "default")
controller.soap.task_kill("project~", "default")

🔌 Disconnect

controller.disconnect()

✅ Compatibility

  • Controllers: CS8, CS9
  • Operating Systems: Windows, Linux, macOS
  • Python: 3.7+
  • Dependency: pythonnet 3.0+

📜 License

⚠️ Commercial license required
🔗 View EULA

When you purchase a license, you receive a license key that can be registered at runtime. This allows you to use the SDK without any limitations or trial restrictions.

After cloning the repository, or installing the package, you have an automatic 30-days trial period. After the trial expires, you can obtain a license key from underautomation.com/license and register it in your code to continue using the SDK:

from underautomation.staubli.staubli_controller import StaubliController

license_info = StaubliController.register_license("Your Company", "XXXX-XXXX")
print(license_info.is_licensed)
print(license_info.state)

🤝 Contributing

You're welcome to:

  • Submit issues & pull requests
  • Share feature suggestions
  • Help improve documentation & samples

👉 Contribute on GitHub


📬 Need Help?


⭐ Star the repo if useful
👁️ Watch for updates

Release files for UnderAutomation.Staubli 0.4.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for UnderAutomation.Staubli 0.4.0.0
File Size Uploaded
underautomation_staubli-0.4.0.0.tar.gz 65.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for UnderAutomation.Staubli 0.4.0.0
File Interpreter ABI Platform
underautomation_staubli-0.4.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 185.8 kB

Release files / underautomation_staubli-0.4.0.0.tar.gz

Download URL underautomation_staubli-0.4.0.0.tar.gz
Size 65.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3b87f47d7745085df80a67ebc6d53b0b1b45b1102037bb7232a7eadaf6c6e45d
BLAKE2b-256 checksum
How to use checksums
cb30958fadec5b3b4c431c1cdd391e99e46d3fe71eb096093cd4efbed1942253
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / underautomation_staubli-0.4.0.0-py3-none-any.whl

Download URL underautomation_staubli-0.4.0.0-py3-none-any.whl
Size 120.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c2434024ce60eb64bd6e64696b3b33d3926b49ac294eb213749d91900eb4d94
BLAKE2b-256 checksum
How to use checksums
36080336724c08f2f16170a39b579f162aed2b27be25cfbd4514b9357bbd883f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

0.4.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page