Skip to main content

Joint-Space Motion Complete Example

This example shows how to run upper-body joint-space point-to-point motion with MoveTools: connect to GR-Controller, switch the upper body to a remotely controllable state, start MoveTools, and call move_joint() to move both arms through a small offset relative to the current pose and back. Targets are generated from the current joint positions plus a bounded offset β€” no hardcoded absolute poses (joint zero positions are not fixed across robots).

Related states: JointStand, upper_body_tele_task

Related APIs: AuroraClient.get_instance(), set_fsm_state(), MoveToolsSession.start(), move_joint(), wait_until_idle()

Python
import os
import time

import numpy as np

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

from fourier_aurora_client import AuroraClient
from movetools_session import MoveToolsSession

ARMS = ("left_manipulator", "right_manipulator")
JOINT_OFFSET = 0.05 # single-joint offset (rad), keep it small


def wait_fsm(client, expected, timeout_s=8.0):
deadline = time.monotonic() + timeout_s
while client.get_fsm_state() != expected:
if time.monotonic() >= deadline:
raise RuntimeError(f"state {expected} not reached")
time.sleep(0.05)


def check_result(result, name):
if not result.success:
raise RuntimeError(f"{name} failed: {result.code} {result.message}")


client = AuroraClient.get_instance(
domain_id=123, # Must match the DDS domain used by the running AuroraCore
robot_name="grw",
)
movetools = MoveToolsSession(client, robot_name="grw")
started = False

try:
input("Press Enter to switch to JointStand...")
client.set_fsm_state(1)
wait_fsm(client, 1)
time.sleep(2.0)

input("Press Enter to switch to upper_body_tele_task...")
client.set_fsm_state(4)
wait_fsm(client, 4)
time.sleep(1.0)

movetools.start()
started = True

# Read current joint positions as the start pose; the waist only echoes its current value
start = {arm: list(client.get_group_state(arm, key="position")) for arm in ARMS}
waist_q = list(client.get_group_state("waist", key="position"))
print(f"start positions: {start}")

target = {arm: list(q) for arm, q in start.items()}
for arm in ARMS:
target[arm][0] += JOINT_OFFSET

input("Press Enter to run move_joint...")
result = movetools.move_joint(
groups=["waist", "left_manipulator", "right_manipulator"],
target_q={
"waist": np.array(waist_q),
"left_manipulator": np.array(target["left_manipulator"]),
"right_manipulator": np.array(target["right_manipulator"]),
},
expect_vel=150,
)
check_result(result, "move_joint")

movetools.wait_until_idle()
movetools.raise_if_error()
moved = {arm: list(client.get_group_state(arm, key="position")) for arm in ARMS}
print(f"joint0 delta: {[round(moved[a][0] - start[a][0], 4) for a in ARMS]}")

input("Press Enter to return to the start pose...")
result = movetools.move_joint(
groups=["waist", "left_manipulator", "right_manipulator"],
target_q={
"waist": np.array(waist_q),
"left_manipulator": np.array(start["left_manipulator"]),
"right_manipulator": np.array(start["right_manipulator"]),
},
expect_vel=150,
)
check_result(result, "move_joint back")
movetools.wait_until_idle()
movetools.raise_if_error()
print("move_joint complete")

finally:
if started:
movetools.stop()
if client.get_fsm_state() != 3:
client.set_fsm_state(3) # back to the standing policy state; avoids arm droop in state 4
wait_fsm(client, 3)
client.close()