Skip to content

set_joint_wall

Runs at once Any mode Takes control

Change one joint's freedrive wall, live. The robot merges the fields given into the joint's wall settings, checks the result and applies it at once; fields left out keep their value. Numbers are kept to 4 significant digits. Every wall re-arms: a joint that is inside its wall feels nothing until it has been back in its range once. Called with no fields, it sends every joint's live walls again.

The change is not saved: save_joint_walls() writes it into the robot XML. Until then, the robot software starts again with the robot XML's walls.

Syntax

robot.set_joint_wall(joint, **fields)

Arguments

Name Type Default Description
joint int required The joint, from 1 to 6.
**fields Any {} The settings to change. Each takes a value, or "auto" (or None) for its default; freedrive takes no "auto". at: "soft" (the wall at the soft limit) or "hard" (at the hard limit; refused on a joint with an endstop, whose hard limit is the endstop). frequency_hz: the wall's natural frequency, in Hz, above 0 and up to the filter's stable maximum; higher feels stiffer. damping_ratio: above 0 and inside the stable window at that frequency; about 0.7 settles without bouncing, below 0.3 it rings. filter_ms: the speed filter behind the damping, 0 to 8 ms; less filtering allows a stiffer wall. max_torque_nm: the most the wall pushes, in Nm, above 0 and up to <haptic_walls><joint_max_torque> (20 Nm as shipped). breakthrough_deg: how far past the wall the joint counts as pushed through, 2 to 90 deg, never past an endstop. freedrive: "warn" (a live J<n>:JOINT_WALL_WARNING) or "stop" (the error J<n>:JOINT_WALL) when pushed through. scaling: "adaptive" (stiffness and damping follow the joint's inertia at each pose) or "fixed" (the lightest pose's at every pose: softer where the joint carries more).

Default values

From each joint's <freedrive_wall> in the robot XML, read when the robot software starts; save_joint_walls() writes it. Every field auto as shipped: 7.1 Hz, damping ratio 0.67 and a 4 ms filter (from config/system.xml <haptic_walls>), "adaptive", "warn"; the wall at the soft limit, or at the hard limit on a joint without an endstop; a breakthrough of the soft-to-hard margin, 2 to 15 deg (15 deg at a hard limit); a max torque of the spring at the breakthrough at the heaviest pose, at most 5 Nm.

Returns

Any

The walls now in force, as get_joint_walls() returns them.

Examples

robot.set_joint_wall(5, frequency_hz=5.0, damping_ratio=0.7)
robot.set_joint_wall(5, frequency_hz="auto", damping_ratio="auto")

Further details

Warning

A wall pushes with up to its max torque: let go of a joint deep inside its wall and it springs back. Try a new setting gently, with a hand on the arm.

Usage restrictions 6 codes

This command runs at once; it is not queued. The robot accepts it in any mode and state, from the client that holds control or when no client does.

It answers with one of these codes when it does not carry the command out:

  • [6101] Control held by another client — another client holds control; the message names it
  • [6003] Invalid arguments — joint is not from 1 to 6; a field name is unknown; a value is not one of its words, not a number or outside its range; at is "hard" on a joint with an endstop; or breakthrough_deg reaches past the joint's endstop. Nothing changes
  • [6018] Wall setting unstable — the frequency is above the stable maximum for the joint's filter, or the damping ratio is outside the stable window at that frequency and filter. The message gives the stable range; nothing changes
  • [6017] No freedrive wall on this joint — the joint has no wall: joint walls are off in config/system.xml <haptic_walls> (<enabled> or <joint_walls> is 0), or the robot has no inertia for the joint. Nothing changes
  • [6025] RTI not running or not answering — rTI did not answer within 1 s: it is not running or not responding. The command may still have taken effect
  • [6026] Refused by RTI — rTI could not use the wall settings. The message says why; the walls in force stay

In Python, a code above raises CommandRejected; its number is the code. The call raises:

  • CommandRejected: The robot refused it; the code says why (see Errors). Also when another client holds control. Or RTI refused it or did not answer within 1 s (Errors:).
  • RobotTimeout: The robot did not answer within 5 s.
  • RobotConnectionError: The client is not connected.
  • ValueError: joint is not a whole number. Nothing is sent.
  • TypeError: joint is not a number. Nothing is sent.

If the connection drops while the call waits for the robot's answer, it raises CommandRejected with the code CONNECTION_LOST (DISCONNECTED after disconnect()); while it waits for the robot's status, RobotConnectionError.

Like every immediate command, it also answers BAD_ARGS when a raw client sends a value the robot cannot read at all, and INTERNAL when it fails inside the robot.

Protocol

A client that does not use robotclient sends this over the TCP command protocol (port 29000) for the example above:

{"id": "c1", "cmd": "set_joint_wall", "args": [5, {"frequency_hz": 5.0, "damping_ratio": 0.7}]}

See also