Multi-Segment Cartesian Motion Complete Example
This example shows how to combine one move_point segment and one move_line segment with move_sequence(): lift the left end effector 3 cm in the base frame, make a small tool-frame displacement, and return to the start. Targets are generated from the current end-effector pose plus bounded offsets; positions are in meters and quaternions use xyzw order.
Related states: JointStand, upper_body_tele_task
Related APIs: create_move_sequence_builder(), seq.add_move_point(), seq.add_move_line(), move_sequence()
Python
import math
import os
import time
os.environ.setdefault("FASTDDS_BUILTIN_TRANSPORTS", "UDPv4") # required on the robot
from fourier_aurora_client import AuroraClient
from movetools_session import MoveToolsSession
Z_OFFSET = 0.03 # base-frame lift (m)
TOOL_DELTA = [0.0, 0.0, 0.02] # tool-frame small displacement (m)
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}")
def normalized_pose(pose):
pose = list(pose)
norm = math.sqrt(sum(q * q for q in pose[3:]))
return pose[:3] + [q / norm for q in pose[3:]]
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
start_pose = normalized_pose(client.get_cartesian_state("left_manipulator", "pose"))
print(f"start pose: {[round(v, 4) for v in start_pose]}")
up_pose = start_pose[:2] + [start_pose[2] + Z_OFFSET] + start_pose[3:]
seq = movetools.create_move_sequence_builder(groups=["left_manipulator"])
# Segment 1: base-frame point-to-point lift of 3 cm
seq.add_move_point(
{"left_end_effector_link": up_pose},
expect_vel=150,
frame="base",
)
# Segment 2: tool-frame straight-line displacement
seq.add_move_line(
{"left_end_effector_link": TOOL_DELTA + [0.0, 0.0, 0.0, 1.0]},
expect_vel=120,
frame="tool",
)
# Segment 3: return to the start pose
seq.add_move_point(
{"left_end_effector_link": start_pose},
expect_vel=150,
frame="base",
)
input("Press Enter to run move_sequence...")
result = movetools.move_sequence(seq)
check_result(result, "move_sequence")
movetools.wait_until_idle()
movetools.raise_if_error()
end_pose = normalized_pose(client.get_cartesian_state("left_manipulator", "pose"))
print(f"restored z delta: {round(end_pose[2] - start_pose[2], 4)}")
print("move_sequence complete")
finally:
if started:
movetools.stop()
if client.get_fsm_state() != 3:
client.set_fsm_state(3) # back to the standing policy state
wait_fsm(client, 3)
client.close()