Concepts
The Trossen Arm driver is the library your application uses to control the arm. It communicates with the Arm Controller over the network: UDP carries the real-time commands and state feedback, and TCP carries the handshake, configuration, and logs. Your application creates a driver object, configures it, then issues commands and reads state in a loop.
This page explains the concepts behind the API. For the method-by-method reference, see the Trossen Arm Driver API; for a fully annotated example, see Writing a Script.
Note
The C++ and Python APIs are equivalent.
The Python trossen_arm package is a direct binding of the C++ libtrossen_arm library, with the same classes, methods, enums, and behavior.
Examples below use C++ names; the Python names are identical.
The Driver Lifecycle
Every application follows the same arc:
Construct a
trossen_arm::TrossenArmDriver.Configure it with
configure(), passing the robottrossen_arm::Model, thetrossen_arm::EndEffectorproperties, and the Arm Controller’s IP address. This opens the connection and, ifclear_erroris true, clears any existing error state.Use the arm: set modes, send commands, read state.
Clean up with
cleanup()(or let the destructor do it). Passingtrueto it, or callingreboot_controller(), also reboots the controller.
Joints and Indexing
An arm has several revolute joints plus a gripper.
Joints are 0-indexed, and the gripper is always the last joint (for example Joint 6 on the 6-DOF WidowX AI).
Most getters and setters come in four scopes, so you can act on whatever set of joints you need:
set_all_*/get_all_*: every joint, including the gripper.set_arm_*/get_arm_*: the arm joints only.set_gripper_*/get_gripper_*: the gripper only.set_joint_*/get_joint_*: a single joint by index.
Modes
Each joint is always in one of five modes, set independently:
Behavior |
|
|---|---|
|
The joint is braked and holds position. |
|
The joint tracks a commanded position. |
|
The joint tracks a commanded velocity. |
|
The joint applies the commanded effort on top of gravity- and friction-compensated efforts. |
|
The joint applies the commanded effort directly, without compensation. |
In any mode other than idle the Arm Controller’s LED is solid blue (see LED Status).
Set modes with set_all_modes(), set_arm_modes(), set_gripper_mode(), or set_joint_modes().
The inputs you send must match the mode each joint is configured in, otherwise the Arm Controller rejects them (see Error Codes).
Commanding Motion
Once joints are in a motion mode, command them in joint space or Cartesian space.
Each command takes a goal, a goal_time to reach it, a blocking flag, and optional feed-forward derivatives.
Cartesian commands additionally take an trossen_arm::InterpolationSpace (joint or cartesian) that selects whether the path is interpolated in joint or Cartesian space.
Quantity |
Joint space |
Cartesian space |
|---|---|---|
Position |
||
Velocity |
||
Effort |
The joint-space commands above use the all scope; arm, gripper, and joint variants exist for each (see the Trossen Arm Driver API).
When blocking is true, the call returns once the goal is reached; when false, it returns immediately and the motion continues in the background.
To avoid numerical issues, the interpolation type is chosen automatically from goal_time:
longer than
0.2 s: quintic polynomial for positions, cubic for velocities, and linear for efforts (goal derivatives default to zero if not given)between
0.001 sand0.2 s: linear interpolation0.001 sor shorter: the goal is applied immediately, without interpolation
Frames and Units
Joint quantities use these units:
Quantity |
Arm joints |
Gripper |
|---|---|---|
Position |
rad |
m |
Velocity |
rad/s |
m/s |
Effort |
Nm |
N |
Cartesian quantities are 6-element vectors:
Quantity |
Layout |
Frame |
|---|---|---|
Position |
translation (m), then angle-axis rotation (rad) |
end effector frame, measured in the base frame |
Velocity |
linear (m/s), then angular (rad/s) |
end effector frame, with respect to the base frame, measured in the base frame |
External effort |
force (N), then torque (Nm) |
applied to the end effector frame, measured in the base frame |
Reading State
get_robot_output() returns a trossen_arm::RobotOutput snapshot:
Field |
Contents |
|---|---|
|
Message |
|
Per-joint state as |
|
End effector positions, velocities, and external efforts, in the base frame. |
For convenience, the same values are reachable through getters like get_arm_positions(), get_cartesian_positions(), or get_joint_effort() without handling the full struct.
Gravity and Friction Compensation
In external_effort mode, gravity and joint friction are compensated automatically, so a commanded external effort of zero leaves the arm weightless and back-drivable.
The compensating efforts are reported in the compensation_efforts field of the robot output.
This is the basis for gravity-compensation and teleoperation applications, demonstrated in the Demo Scripts.
Error Handling
When the Arm Controller detects an error it stops, sets all joints to idle, and records the error state. The error is reported in the log with the specific joint and value. The full list of error codes and how to clear them is in Error Codes.
Logging
By default the driver logs to stderr in C++ and to Python’s logging module.
Set the verbosity with set_log_level() using a trossen_arm::LogLevel from trace to critical, or route output to your own handler with set_logger_backend().
The error_recovery_and_logging demo shows both in practice.
Configuration
Beyond motion, the driver exposes the arm’s configuration: joint characteristics, end effector properties, joint limits, motor parameters, IP settings, and more.
Some changes apply immediately, others at the next boot, and some persist across power cycles while others reset.
The complete reference, including which is which, is in Configuration.
Configurations can be saved to and loaded from YAML with save_configs_to_file() and load_configs_from_file().
What’s Next
Walk through a complete script in Writing a Script.
Browse runnable examples in the Demo Scripts catalog.
Look up specific methods in the Trossen Arm Driver API.