Skip to main content

Joint Group Control

set_group_cmd()​

Python
set_group_cmd(
position_cmd: Dict[str, list[float]],
velocity_cmd: Dict[str, list[float]] | None = None,
torque_cmd: Dict[str, list[float]] | None = None
)

Sends position, velocity, and torque commands to one or more joint groups. position_cmd is required; the others are optional. Commands take effect immediately — interpolation is recommended to avoid sudden jumps.

ParameterTypeDescription
position_cmdDict[str, list[float]]group name → target joint position list (rad)
velocity_cmdDict[str, list[float]] | Nonegroup name → target joint velocity list (rad/s)
torque_cmdDict[str, list[float]] | Nonegroup name → target joint torque list (Nm)

Valid group names (depends on robot model; refer to hardware.json):

waist (5 DOF), head (2 DOF), left_manipulator (7 DOF), right_manipulator (7 DOF), left_end_effector, right_end_effector

The two end effectors can be used as raw command targets and expose a one-dimensional state via get_group_state(); however, get_group_motion_state() and get_group_motor_cfg() currently support only waist, head, left_manipulator, and right_manipulator — do not pass left_end_effector or right_end_effector to them.

danger

Waist commands must contain five joint values. Its safe default position is [-1.25, 2.15, -0.918, 0, 0]; never command all waist joints to zero.

Example: upper-body control with interpolation

Targets are generated from "current reading + bounded offset" instead of hardcoded absolute poses (joint zero positions are not fixed; keep single-joint offsets within ±0.03 rad). Joint commands must be streamed continuously in state 4 (upper_body_tele_task):

Python
import os
import time

os.environ.setdefault("FASTDDS_BUILTIN_TRANSPORTS", "UDPv4") # required on the robot

from fourier_aurora_client import AuroraClient

client = AuroraClient.get_instance(domain_id=123, robot_name="grw")
try:
time.sleep(1.0)
if not client.set_fsm_state(4):
raise RuntimeError("state change request not accepted")
deadline = time.monotonic() + 4.0
while client.get_fsm_state() != 4:
if time.monotonic() >= deadline:
raise RuntimeError("did not switch to upper_body_tele_task")
time.sleep(0.05)

init_pose = client.get_group_state("left_manipulator", key="position")
target_pose = list(init_pose)
target_pose[0] += 0.03
steps = 200

for i in range(steps + 1): # move to target
pose = [s + (t - s) * i / steps for s, t in zip(init_pose, target_pose)]
client.set_group_cmd({"left_manipulator": pose})
time.sleep(0.01)
for i in range(steps + 1): # return to start
pose = [t + (s - t) * i / steps for s, t in zip(init_pose, target_pose)]
client.set_group_cmd({"left_manipulator": pose})
time.sleep(0.01)
finally:
if client.get_fsm_state() == 4:
client.set_fsm_state(3) # back to the standing policy state
client.close()

get_group_state()​

Python
get_group_state(group_name: str, key: str = 'position') -> list[float]

Reads the current state of a specified joint group.

ParameterTypeDescription
group_namestrJoint group name
keystrData type to return — see table below
key valueDescription
'position'Joint positions (rad), default
'velocity'Joint velocities (rad/s)
'effort'Joint torques (Nm)

Example

Python
import os
import time

os.environ.setdefault("FASTDDS_BUILTIN_TRANSPORTS", "UDPv4") # required on the robot

from fourier_aurora_client import AuroraClient

client = AuroraClient.get_instance(domain_id=123, robot_name="grw")
try:
time.sleep(1.0) # wait for state data
pos = client.get_group_state("waist", key="position")
vel = client.get_group_state("waist", key="velocity")
print(f"waist position: {pos}")
print(f"waist velocity: {vel}")
finally:
client.close()

get_group_motion_state()​

Python
get_group_motion_state(group_name: str) -> int

Reads the current motion state of a specified joint group.

Return valueDescription
0Idle
1Moving
2Stopping
3Error
GR-W limitation

While interpolation commands are streamed at 100 Hz in state 4, the motion state of left_manipulator stays 0 (idle). The return value does not reflect motion caused by teleoperation commands and must not be used to wait for "motion complete"; rely on the end of the command stream and convergence of get_group_state() positions instead.

Example

Python
import os
import time

os.environ.setdefault("FASTDDS_BUILTIN_TRANSPORTS", "UDPv4") # required on the robot

from fourier_aurora_client import AuroraClient

client = AuroraClient.get_instance(domain_id=123, robot_name="grw")
try:
time.sleep(1.0) # wait for state data
state = client.get_group_motion_state("left_manipulator")
print(f"motion state: {state} (0=idle)")
finally:
client.close()