Skip to main content

Python 示例

本文件为 API 中公开的函数与类型提供简短示例,演示如何使用这些接口。

机器人关节名称(G1 2.2)

关节组列表

机器人关节组名称包括:["head", "left_arm", "right_arm", "leg", "left_gripper", "right_gripper", "left_suction_cup", "right_suction_cup"]

各关节组详细信息

关节组名称关节组英文名关节数量关节名称列表
头部head2head_joint1, head_joint2
腿部leg5leg_joint1, leg_joint2, leg_joint3, leg_joint4, leg_joint5
左臂left_arm7left_arm_joint1, left_arm_joint2, left_arm_joint3, left_arm_joint4, left_arm_joint5, left_arm_joint6, left_arm_joint7
右臂right_arm7right_arm_joint1, right_arm_joint2, right_arm_joint3, right_arm_joint4, right_arm_joint5, right_arm_joint6, right_arm_joint7
左夹爪left_gripper1left_gripper_joint1
右夹爪right_gripper1right_gripper_joint1
左吸盘left_suction_cup1left_suction_cup_joint1
右吸盘right_suction_cup1right_suction_cup_joint1

如何正确使用 joint_groups

joint_groups 的设计单位是“关节组(运动链)”,而不是单个关节。这样设计是为了保证:

  • 运动链一致性:头/臂/腿等关节按链路整体校验和控制。
  • 指令顺序确定性:joint_groups 会按传入顺序展开为具体关节。
  • 组级约束校验:执行前会检查关节组的 active/passive 属性及输入合法性。

传参规则:

  1. 需要控制整条链路时,优先使用 joint_groups(head/arm/leg/gripper/suction cup)。
  2. joint_names 非空时,优先使用 joint_names,会覆盖 joint_groups
  3. joint_groupsjoint_names 都为空时,SDK 默认控制所有 active body 关节组。
  4. 建议先调用 get_joint_group_names()get_joint_names(True, groups),避免手写字符串出错。

G1 关节组典型场景

关节组典型场景
head头部朝向/相机对准
left_arm / right_arm机械臂抓取与操作
leg下肢姿态调整
left_gripper / right_gripper夹爪开合宽度控制
left_suction_cup / right_suction_cup吸盘吸放作业

传感器类型与 Frame 说明

获取传感器数据时(get_rgb_dataget_depth_dataget_imu_dataget_lidar_data),通过 SensorType 枚举指定要查询的传感器。可用的 SensorType 枚举值详见:Python API 参考 > 传感器类型

获取传感器外参有两种方式:

  • get_sensor_extrinsic(): SDK 内部已映射 frame ID,直接传入 SensorType 即可
  • get_transform(): 需要显式传入 frame 名称,表格第二列为各传感器对应的 Frame ID
SensorTypeFrame ID
HEAD_LEFT_CAMERAhead_left_camera_color_optical_frame
HEAD_RIGHT_CAMERAhead_right_camera_color_optical_frame
LEFT_ARM_CAMERAleft_arm_camera_color_optical_frame
LEFT_ARM_DEPTH_CAMERAleft_arm_camera_color_optical_frame
RIGHT_ARM_CAMERAright_arm_camera_color_optical_frame
RIGHT_ARM_DEPTH_CAMERAright_arm_camera_color_optical_frame
BASE_LIDARlidar_base_link
TORSO_IMUimu_base_link
BASE_ULTRASONIC—(无 TF frame)
LEFT_FRONT_SURROUND_CAMERAleft_front_surround_color_optical_frame
RIGHT_FRONT_SURROUND_CAMERAright_front_surround_color_optical_frame
LEFT_REAR_SURROUND_CAMERAleft_rear_surround_color_optical_frame
RIGHT_REAR_SURROUND_CAMERAright_rear_surround_color_optical_frame

注意:调用 get_frame_names() 可获取当前所有可用的坐标系名称。

类:GalbotRobot

tips:程序启动后立刻就get,数据可能不会立刻就绪,可适当sleep几秒

获取实例并初始化(get_instance && init)

适用场景:程序启动阶段,获取机器人单例并完成 SDK 初始化。必须在调用其他 API 前执行。

examples/python/galbot_robot/get_instance.py
from galbot_sdk.g1 import GalbotRobot
import time

# Get GalbotRobot
robot = GalbotRobot()

state = robot.init()
if not state:
print("Initialization failed")
else:
print("Initialization succeeded")

while robot.is_running():
# business logic
time.sleep(1)
break

# Send exit signal to exit the program
robot.request_shutdown()
# Wait for exit state
robot.wait_for_shutdown()
# Release SDK-related resources
robot.destroy()

日志函数

适用场景:使用 SDK 内置的日志系统输出日志,统一日志级别和格式。

examples/python/galbot_robot/logger_example.py
import galbot_sdk

cfg = {
# Log storage directory; if empty, defaults to ~/galbot_sdk_log/user_log
"path": "",

# Log file name; if empty, defaults to <process_name>_<current_time>_<pid>_<thread_id>.log
"file_name": "",

# log bytes, log size,
"file_max_size": 10 * 1024 * 1024, # 10MB

# Maximum rotating log files; oldest file is overwritten when limit exceeded
"file_max_num": 5,

# Whether to output logs to console; default is False
"console_output": True,

# Log output level, available values: debug, info, warning, error, critical
"level": "info",
}

galbot_sdk.init_logger(cfg)

# Write log
galbot_sdk.debug("Debug example")
galbot_sdk.info("Info example")
galbot_sdk.warning("Warning example")
galbot_sdk.error("Error example")
galbot_sdk.critical("Critical example")

设置关节角度(set_joint_positions)

适用场景:单次点位移动,低频率的位置控制任务。该接口内部会对目标位置进行速度受限的插值规划,适合一次性移动到目标关节角度的场景。

WARNING: 此接口不适合模型推理输出的高频关节控制场景!该接口每次调用都会产生一次轨迹插值,连续调用会导致运动不连续且有延迟。

如果您在做模型推理场景,请使用 set_joint_commandsset_joint_commands_batch 直接下发关节指令。

examples/python/galbot_robot/set_joint_positions.py
import time
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import ControlStatus

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
print('Initialization succeeded')

# Program started, waiting for data
time.sleep(2)

# Set head joints to 0.2, 0.2, block and wait for motion to complete, max timeout 10s
joint_pos = [0.2, 0.2]
# Set head joint group; if empty, defaults to whole body joints ["leg", "head", "left_arm", "right_arm"]
joint_groups = ["head"]
# Whether to block until joints reach target
is_blocking = True
# Limit joint max speed to 0.1rad/s
max_speed = 0.1
# Maximum blocking wait time
timeout_s = 10

status = robot.set_joint_positions(
joint_pos, joint_groups, [], is_blocking, max_speed, timeout_s
)

if status != ControlStatus.SUCCESS:
print("Joint angle setting failed")
else:
print('Joint angle setting succeeded')

time.sleep(1)

# Use specific joint names for control; this parameter overrides joint_groups
joint_names = ["head_joint1", "head_joint2"]
joint_pos = [0.0, 0.0]

status = robot.set_joint_positions(
joint_pos, [], joint_names, is_blocking, max_speed, timeout_s
)

if status != ControlStatus.SUCCESS:
print("Joint angle setting failed")
else:
print('Joint angle setting succeeded')

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

设置夹爪指令(set_gripper_command)

适用场景:控制夹爪开合。支持位置控制和力矩控制两种模式。

examples/python/galbot_robot/set_gripper_command.py
import time
from galbot_sdk.g1 import GalbotRobot, G1JointGroup, ControlStatus

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
print('Initialization succeeded')
# Program started, waiting for data
time.sleep(2)

# Set left gripper width to 0.02m, speed 0.05m, torque 10N, block until gripper reaches position
status = robot.set_gripper_command(
G1JointGroup.left_gripper, 0.02, 0.05, 10, False
)
if status != ControlStatus.SUCCESS:
print("Set gripper failed")
else:
print('Set gripper success')

# Set left gripper width to 0.1m, speed 0.05m, torque 10N, block until gripper reaches position
status = robot.set_gripper_command(
G1JointGroup.left_gripper, 0.1, 0.05, 10, False
)

if status != ControlStatus.SUCCESS:
print("Set gripper failed")
else:
print('Set gripper success')

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

设置吸盘指令(set_suction_cup_command)

适用场景:控制吸盘吸放物体,获取吸盘当前的开启/关闭状态。

examples/python/galbot_robot/set_suction_cup_command.py
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import G1JointGroup, ControlStatus
import time

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
time.sleep(1)
print('Initialization succeeded')

# Set suction cup joint group (right suction cup)
joint_group = G1JointGroup.right_suction_cup

# Whether to activate suction cup
activate = True # True: activate suction cup, False: deactivate suction cup

# Send suction cup control command
status = robot.set_suction_cup_command(
joint_group,
activate
)

# Check execution results
if status != ControlStatus.SUCCESS:
print("Set suction cup failed")
else:
print("Set suction cup succeeded")

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

停止轨迹执行(stop_trajectory_execution)

适用场景:停止当前正在执行的关节轨迹,中断正在进行的运动。

examples/python/galbot_robot/stop_trajectory_execution.py
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import ControlStatus
import time

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
time.sleep(2)
print("Initialization succeeded")

# Stop trajectory execution
while True:
status = robot.stop_trajectory_execution()

# Check execution results
if status == ControlStatus.SUCCESS:
print('Stop trajectory execution succeeded')
break

print("Trajectory stop failed, retrying...")

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

设置轨迹(execute_joint_trajectory)

适用场景:执行一条预定义的关节空间轨迹,包含多个路点。SDK 会按照时间节点执行整条轨迹。

examples/python/galbot_robot/execute_joint_trajectory.py
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import G1JointGroup, ControlStatus, Trajectory, TrajectoryPoint, JointCommand
import time
import numpy as np
from typing import List

# Generate trajectory point with position and time info
def generate_target_point(q: List[float], target_time: float = 10):
"""Generate target for joints"""
joint_position = TrajectoryPoint()
joint_position.time_from_start_second = target_time
joint_command_vec = []
for joint in q:
joint_cmd = JointCommand()
joint_cmd.position = joint
joint_command_vec.append(joint_cmd)
joint_position.joint_command_vec = joint_command_vec
return joint_position

def generate_target_trajectory(trajectory, joint_groups=[], joint_names=[], dt=0.008):
"""Generate trajectory for joints"""
if trajectory is None or np.ndim(trajectory) != 2 or len(trajectory) == 0:
return None

# Create Trajectory
traj = Trajectory()
traj.joint_groups = joint_groups
traj.joint_names = joint_names

time = 0.0
points = []
for state in trajectory:
time += dt
# Create single trajectory point
traj_point = generate_target_point(state, time)
points.append(traj_point)

traj.points = points
return traj

# Trajectory execution function
def traj_exec():
# Get GalbotRobot singleton and initialize; only needs to be initialized once
robot = GalbotRobot()
robot.init()
time.sleep(1)
print("Initialization succeeded")

head_traj = np.linspace(
[0.0, 0.0],
[0.5, 0.0],
num=200,
)
# Whether to block and wait for trajectory execution to complete
is_block = True
# Specify which joint group trajectory to execute
joint_groups = ["head"]
# Execute specified joint trajectory; if provided, overrides joint_groups parameters
joint_names = []
status = robot.execute_joint_trajectory(generate_target_trajectory(head_traj.tolist(), joint_groups, joint_names), is_block)

# Check execution results
if status != ControlStatus.SUCCESS:
print("Trajectory execution failed")
else:
print("Trajectory execution succeeded")

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

traj_exec()

设置关节指令 (set_joint_commands)

适用场景:高频关节控制,例如模型推理输出(每步推理输出一帧关节指令)、自定义轨迹跟踪。直接下发关节指令给底层控制器,不做额外插值。

examples/python/galbot_robot/set_joint_commands_example.py
import time
import math
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import JointCommand

def head_high_frequency_control():
"""
Head high-frequency control example
"""

control_frequency = 100.0 # Hz
dt = 1.0 / control_frequency
duration = 4.0 # Control for 4 seconds

amplitude = 0.3 # Maximum oscillation amplitude (rad)
frequency = 0.5 # Sine frequency (Hz)
# Joint group name to control
joint_groups = ["head"]
# Fill this field to control specific joints, which will override joint_groups. If empty, controls all joints in joint_groups by default
joint_names = []

print("Start high-frequency head control")

joint_commands = [JointCommand(), JointCommand()]

start_time = time.time()

while True:
current_time = time.time() - start_time
if current_time > duration:
break

# Generate sine trajectory
target_position = amplitude * math.sin(
2 * math.pi * frequency * current_time
)

# Set head joint angles
joint_commands[0].position = target_position
joint_commands[1].position = target_position
print(f"current: {current_time:.2f}s, target: {target_position:.3f} rad")

# Expected arrival time
time_from_start_sec = 0.0

execution_status = GalbotRobot().set_joint_commands(
joint_commands,
joint_groups,
joint_names,
time_from_start_sec
)

# Sleep at a fixed interval
time.sleep(dt)

print("end")

def main():
# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()

if robot.init():
print("System initialized successfully!")
else:
print("System initialization failed!")
return

# Program started, waiting for data
time.sleep(2)

head_high_frequency_control()

# Exit system and release SDK resources
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()
print("Program exited")


if __name__ == "__main__":
main()

批量设置关节指令(set_joint_commands_batch)

适用场景:批量下发未来多帧关节指令,用于运动预测模型一次性输出多步结果的场景,可以提高控制频率和连续性。

examples/python/galbot_robot/set_joint_commands_batch.py
from galbot_sdk.g1 import GalbotRobot, G1JointGroup, ControlStatus, Trajectory, TrajectoryPoint, JointCommand
import time
import numpy as np
from typing import List

# Generate trajectory point with position and time info
def generate_target_point(q: List[float], target_time: float = 10):
"""Generate target for joints"""
joint_position = TrajectoryPoint()
joint_position.time_from_start_second = target_time
joint_command_vec = []
for joint in q:
joint_cmd = JointCommand()
joint_cmd.position = joint
joint_cmd.velocity = 0.0
joint_cmd.acceleration = 0.0
joint_cmd.effort = 0.0
# joint_cmd.Kp = 0.0
# joint_cmd.Kd = 0.0
joint_command_vec.append(joint_cmd)
joint_position.joint_command_vec = joint_command_vec
return joint_position

def generate_batch_trajectory(trajectory, joint_groups=[], joint_names=[], dt=0.008):
"""Generate batch trajectory for joints"""
if trajectory is None or np.ndim(trajectory) != 2 or len(trajectory) == 0:
return None

# Create Trajectory
traj = Trajectory()
traj.joint_groups = joint_groups
traj.joint_names = joint_names

time = 0.0
points = []
for state in trajectory:
time += dt
# Create single trajectory point
traj_point = generate_target_point(state, time)
points.append(traj_point)

traj.points = points
return traj

# Batch set-joint-command function
def batch_commands_exec():
# Get GalbotRobot singleton and initialize; only needs to be initialized once
robot = GalbotRobot()
robot.init()
time.sleep(1)
print("Initialization succeeded")

# Generate batched trajectory data (joint commands at multiple time points)
head_traj = np.linspace(
[0.0, 0.0],
[0.5, 0.0],
num=10, # Number of batch trajectory points
)
# Specify which joint group trajectory to execute
joint_groups = ["head"]
# Execute specified joint trajectory; if provided, overrides joint_groups parameters
joint_names = []

# Batch set joint commands (non-blocking, returns immediately)
status = robot.set_joint_commands_batch(generate_batch_trajectory(head_traj.tolist(), joint_groups, joint_names))

# Check execution results
if status != ControlStatus.SUCCESS:
print("Batch command submission failed")
else:
print("Batch commands submitted, executing in background (non-blocking)")

# Wait for a while to let the command execute
time.sleep(1)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

batch_commands_exec()

直接发布原始目标(publish_target)

适用场景:高级用户直接构造 SingoriXTarget 并通过 publish 通道下发到底层 WBCS,适合高频原始 target 发送与 joint/task mixed target 一次性 dispatch。

examples/python/galbot_robot/publish_target_example.py
"""
G1 PublishTarget menu example for SDK mirror SingoriXTarget.

This example shows how to construct `SingoriXTarget` directly at the Python SDK
layer and send it to the low-level WBCS through `publish_target()`.

1. Joint-space commands are written into `target_group_trajectory_map`
2. Chassis pose / twist style task-space commands are written into `target_task_trajectory_map`
3. One `SingoriXTarget` can contain both joint trajectory and task trajectory
4. The current SDK does not automatically switch the chassis controller, so
pose / twist / mixed scenes explicitly call `switch_controller(...)`
5. The base twist scene automatically sends a zero-twist target after the
configured duration to stop the chassis
"""

import math
import time

from galbot_sdk.g1 import (
ControlStatus,
G1ControllerName,
G1JointGroup,
GalbotRobot,
GroupCommand,
JointCommand,
Pose,
SingoriXTarget,
TargetConfig,
TargetGroupTrajectory,
TargetSampling,
TargetTaskTrajectory,
TaskCommand,
Twist,
Vector3,
FrameTriad,
TARGET_DATA_DEFAULT,
TARGET_DATA_FRAME_POSE,
TARGET_DATA_FRAME_TWIST,
TARGET_TYPE_DEFAULT,
TARGET_TYPE_OVERRIDE,
TARGET_TYPE_PROVERRIDE,
)


CHASSIS_TASK_NAME = "chassis"
CHASSIS_SUBTASK_POSE = "chassis_pose"
CHASSIS_SUBTASK_TWIST = "chassis_twist"


def now_ns():
return time.time_ns()


def status_to_string(status):
return getattr(status, "name", str(status))


def yaw_to_quaternion(yaw):
return [0.0, 0.0, math.sin(yaw * 0.5), math.cos(yaw * 0.5)]


def make_empty_target():
target = SingoriXTarget()
target.header.timestamp_ns = now_ns()
target.header.frame_id = "base_link"
return target


def make_group_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_DEFAULT
config.target_type = TARGET_TYPE_PROVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_DEFAULT
config.target_priority = 1
return config


def make_pose_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_FRAME_POSE
config.target_type = TARGET_TYPE_PROVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_LINEAR_INTERPOLATE
config.target_priority = 1
return config


def make_twist_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_FRAME_TWIST
config.target_type = TARGET_TYPE_OVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_DIRECT_PASS
config.target_priority = 1
return config


def make_joint_command(position):
command = JointCommand()
command.position = position
command.velocity = 0.0
command.acceleration = 0.0
command.effort = 0.0
return command


def make_vector3(x, y, z):
vec = Vector3()
vec.x = x
vec.y = y
vec.z = z
return vec


def build_joint_target(group_name, joint_names, positions, time_from_start_s):
target = make_empty_target()

group_traj = TargetGroupTrajectory()
group_traj.target_config = make_group_target_config()
group_traj.joint_names = list(joint_names)

command = GroupCommand()
command.time_from_start_s = time_from_start_s
command.joint_commands = [make_joint_command(position) for position in positions]
group_traj.group_commands = [command]

target.target_group_trajectory_map = {group_name: group_traj}
return target


def build_chassis_pose_target(x, y, yaw, time_from_start_s, frame_id="odom", reference_frame_id="odom"):
target = make_empty_target()

task_traj = TargetTaskTrajectory()
task_traj.target_config = make_pose_target_config()
task_traj.group_names = [G1JointGroup.chassis]
task_traj.subtask_names = [CHASSIS_SUBTASK_POSE]

triad = FrameTriad()
triad.header.timestamp_ns = now_ns()
triad.header.frame_id = frame_id
triad.body_frame_id = "base_link"
triad.reference_frame_id = reference_frame_id
triad.pose = Pose([x, y, 0.0], yaw_to_quaternion(yaw))

command = TaskCommand()
command.time_from_start_s = time_from_start_s
command.subtask_commands = [triad]
task_traj.task_commands = [command]

target.target_task_trajectory_map = {CHASSIS_TASK_NAME: task_traj}
return target


def build_chassis_twist_target(vx, vy, wz, time_from_start_s):
target = make_empty_target()

task_traj = TargetTaskTrajectory()
task_traj.target_config = make_twist_target_config()
task_traj.group_names = [G1JointGroup.chassis]
task_traj.subtask_names = [CHASSIS_SUBTASK_TWIST]

twist = Twist()
twist.linear = make_vector3(vx, vy, 0.0)
twist.angular = make_vector3(0.0, 0.0, wz)

triad = FrameTriad()
triad.header.timestamp_ns = now_ns()
triad.header.frame_id = "base_link"
triad.body_frame_id = "base_link"
triad.reference_frame_id = "base_link"
triad.twist = twist

command = TaskCommand()
command.time_from_start_s = time_from_start_s
command.subtask_commands = [triad]
task_traj.task_commands = [command]

target.target_task_trajectory_map = {CHASSIS_TASK_NAME: task_traj}
return target


def build_stop_twist_target():
return build_chassis_twist_target(0.0, 0.0, 0.0, 0.1)


def merge_targets(targets):
merged = make_empty_target()
group_map = {}
task_map = {}
for target in targets:
group_map.update(target.target_group_trajectory_map)
task_map.update(target.target_task_trajectory_map)
merged.target_group_trajectory_map = group_map
merged.target_task_trajectory_map = task_map
return merged


def ensure_controller(robot, controller_name):
status = robot.switch_controller(controller_name)
print(f"switch_controller({controller_name}): {status_to_string(status)}")
return status


def run_twist_scene(robot, scene_name, target, twist_duration_s):
print(f"{scene_name}: start moving for {twist_duration_s} seconds")
motion_status = robot.publish_target(target)
print(f"{scene_name} publish_target status: {status_to_string(motion_status)}")
if motion_status != ControlStatus.SUCCESS:
return motion_status

time.sleep(twist_duration_s)
print(f"{scene_name}: send stop twist target")
stop_status = robot.publish_target(build_stop_twist_target())
print(f"{scene_name} stop status: {status_to_string(stop_status)}")
return stop_status


def print_menu():
print(
"\nAvailable commands:\n"
" joint - publish a joint-only head target\n"
" base_pose - publish a chassis pose target\n"
" base_twist - publish a chassis twist target with auto stop\n"
" mixed_pose - publish head + left_arm + chassis pose in one target\n"
" mixed_twist - publish head + left_arm + chassis twist in one target\n"
" quit - exit example\n"
)


def main():
robot = GalbotRobot()
if not robot.init():
print("robot init failed")
return

time.sleep(2)

head_joint_names = robot.get_joint_names(True, [G1JointGroup.head])
left_arm_joint_names = robot.get_joint_names(True, [G1JointGroup.left_arm])
if not head_joint_names or not left_arm_joint_names:
print("failed to fetch active head/left_arm joints")
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()
return

head_single_joint = [head_joint_names[0]]
arm_single_joint = [left_arm_joint_names[0]]
joint_time_s = 3.0
pose_time_s = 4.0
twist_command_time_s = 0.2
twist_duration_s = 2.0

print_menu()

while True:
command = input("Enter command: ").strip()
if command == "quit":
break

if command == "joint":
target = build_joint_target(G1JointGroup.head, head_single_joint, [0.2], joint_time_s)
status = robot.publish_target(target)
print(f"joint publish_target status: {status_to_string(status)}")
continue

if command == "base_pose":
if ensure_controller(robot, G1ControllerName.CHASSIS_POSE_CTRL) != ControlStatus.SUCCESS:
continue
target = build_chassis_pose_target(0.2, 0.0, 0.0, pose_time_s)
status = robot.publish_target(target)
print(f"base_pose publish_target status: {status_to_string(status)}")
continue

if command == "base_twist":
if ensure_controller(robot, G1ControllerName.CHASSIS_TWIST_CTRL) != ControlStatus.SUCCESS:
continue
target = build_chassis_twist_target(0.05, 0.0, 0.0, twist_command_time_s)
run_twist_scene(robot, "base_twist", target, twist_duration_s)
continue

if command == "mixed_pose":
if ensure_controller(robot, G1ControllerName.CHASSIS_POSE_CTRL) != ControlStatus.SUCCESS:
continue
target = merge_targets(
[
build_joint_target(G1JointGroup.head, head_single_joint, [0.2], joint_time_s),
build_joint_target(G1JointGroup.left_arm, arm_single_joint, [0.1], joint_time_s),
build_chassis_pose_target(0.1, 0.0, 0.0, pose_time_s),
]
)
status = robot.publish_target(target)
print(f"mixed_pose publish_target status: {status_to_string(status)}")
continue

if command == "mixed_twist":
if ensure_controller(robot, G1ControllerName.CHASSIS_TWIST_CTRL) != ControlStatus.SUCCESS:
continue
target = merge_targets(
[
build_joint_target(G1JointGroup.head, head_single_joint, [-0.2], joint_time_s),
build_joint_target(G1JointGroup.left_arm, arm_single_joint, [-0.1], joint_time_s),
build_chassis_twist_target(0.05, 0.0, 0.0, twist_command_time_s),
]
)
run_twist_scene(robot, "mixed_twist", target, twist_duration_s)
continue

print(f"Unknown command: {command}")
print_menu()

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()


if __name__ == "__main__":
main()

直接请求原始目标(request_target)

适用场景:高级用户直接构造 SingoriXTarget 并通过 request 通道下发到底层 WBCS,适合需要获取服务端错误返回的 raw target 场景。

examples/python/galbot_robot/request_target_example.py
"""
G1 RequestTarget menu example for SDK mirror SingoriXTarget.

This example shows how to construct `SingoriXTarget` directly at the Python SDK
layer and send it to the low-level WBCS through `request_target()`.

1. Joint-space commands are written into `target_group_trajectory_map`
2. Chassis pose / twist style task-space commands are written into `target_task_trajectory_map`
3. One `SingoriXTarget` can contain both joint trajectory and task trajectory
4. The current SDK does not automatically switch the chassis controller, so
pose / twist / mixed scenes explicitly call `switch_controller(...)`
5. The base twist scene automatically sends a zero-twist target after the
configured duration to stop the chassis
"""

import math
import time

from galbot_sdk.g1 import (
ControlStatus,
ErrorInfo,
G1ControllerName,
G1JointGroup,
GalbotRobot,
GroupCommand,
JointCommand,
Pose,
SingoriXTarget,
TargetConfig,
TargetGroupTrajectory,
TargetSampling,
TargetTaskTrajectory,
TaskCommand,
Twist,
Vector3,
FrameTriad,
TARGET_DATA_DEFAULT,
TARGET_DATA_FRAME_POSE,
TARGET_DATA_FRAME_TWIST,
TARGET_TYPE_DEFAULT,
TARGET_TYPE_OVERRIDE,
TARGET_TYPE_PROVERRIDE,
)


CHASSIS_TASK_NAME = "chassis"
CHASSIS_SUBTASK_POSE = "chassis_pose"
CHASSIS_SUBTASK_TWIST = "chassis_twist"


def now_ns():
return time.time_ns()


def yaw_to_quaternion(yaw):
return [0.0, 0.0, math.sin(yaw * 0.5), math.cos(yaw * 0.5)]


def make_empty_target():
target = SingoriXTarget()
target.header.timestamp_ns = now_ns()
target.header.frame_id = "base_link"
return target


def make_group_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_DEFAULT
config.target_type = TARGET_TYPE_PROVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_DEFAULT
config.target_priority = 1
return config


def make_pose_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_FRAME_POSE
config.target_type = TARGET_TYPE_PROVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_LINEAR_INTERPOLATE
config.target_priority = 1
return config


def make_twist_target_config():
config = TargetConfig()
config.target_data = TARGET_DATA_FRAME_TWIST
config.target_type = TARGET_TYPE_OVERRIDE
config.target_sampling = TargetSampling.TARGET_SAMPLING_DIRECT_PASS
config.target_priority = 1
return config


def make_joint_command(position):
command = JointCommand()
command.position = position
command.velocity = 0.0
command.acceleration = 0.0
command.effort = 0.0
return command


def make_vector3(x, y, z):
vec = Vector3()
vec.x = x
vec.y = y
vec.z = z
return vec


def build_joint_target(group_name, joint_names, positions, time_from_start_s):
target = make_empty_target()

group_traj = TargetGroupTrajectory()
group_traj.target_config = make_group_target_config()
group_traj.joint_names = list(joint_names)

command = GroupCommand()
command.time_from_start_s = time_from_start_s
command.joint_commands = [make_joint_command(position) for position in positions]
group_traj.group_commands = [command]

target.target_group_trajectory_map = {group_name: group_traj}
return target


def build_chassis_pose_target(x, y, yaw, time_from_start_s, frame_id="odom", reference_frame_id="odom"):
target = make_empty_target()

task_traj = TargetTaskTrajectory()
task_traj.target_config = make_pose_target_config()
task_traj.group_names = [G1JointGroup.chassis]
task_traj.subtask_names = [CHASSIS_SUBTASK_POSE]

triad = FrameTriad()
triad.header.timestamp_ns = now_ns()
triad.header.frame_id = frame_id
triad.body_frame_id = "base_link"
triad.reference_frame_id = reference_frame_id
triad.pose = Pose([x, y, 0.0], yaw_to_quaternion(yaw))

command = TaskCommand()
command.time_from_start_s = time_from_start_s
command.subtask_commands = [triad]
task_traj.task_commands = [command]

target.target_task_trajectory_map = {CHASSIS_TASK_NAME: task_traj}
return target


def build_chassis_twist_target(vx, vy, wz, time_from_start_s):
target = make_empty_target()

task_traj = TargetTaskTrajectory()
task_traj.target_config = make_twist_target_config()
task_traj.group_names = [G1JointGroup.chassis]
task_traj.subtask_names = [CHASSIS_SUBTASK_TWIST]

twist = Twist()
twist.linear = make_vector3(vx, vy, 0.0)
twist.angular = make_vector3(0.0, 0.0, wz)

triad = FrameTriad()
triad.header.timestamp_ns = now_ns()
triad.header.frame_id = "base_link"
triad.body_frame_id = "base_link"
triad.reference_frame_id = "base_link"
triad.twist = twist

command = TaskCommand()
command.time_from_start_s = time_from_start_s
command.subtask_commands = [triad]
task_traj.task_commands = [command]

target.target_task_trajectory_map = {CHASSIS_TASK_NAME: task_traj}
return target


def build_stop_twist_target():
return build_chassis_twist_target(0.0, 0.0, 0.0, 0.1)


def merge_targets(targets):
merged = make_empty_target()
group_map = {}
task_map = {}
for target in targets:
group_map.update(target.target_group_trajectory_map)
task_map.update(target.target_task_trajectory_map)
merged.target_group_trajectory_map = group_map
merged.target_task_trajectory_map = task_map
return merged


def print_error_info(scene_name, error_info):
if error_info is None:
print(f"{scene_name}: request_target returned None")
return
if not isinstance(error_info, ErrorInfo):
print(f"{scene_name}: unexpected response type {type(error_info)}")
return
if not error_info.error_vec:
print(f"{scene_name}: request_target success, service returned no errors")
return

print(f"{scene_name}: request_target returned {len(error_info.error_vec)} error entries:")
for error in error_info.error_vec:
print(
f" component={error.commpent}, code={error.error_code}, description={error.description}"
)


def ensure_controller(robot, controller_name):
status = robot.switch_controller(controller_name)
print(f"switch_controller({controller_name}): {getattr(status, 'name', status)}")
return status


def run_twist_scene(robot, scene_name, target, twist_duration_s):
print(f"{scene_name}: start moving for {twist_duration_s} seconds")
print_error_info(scene_name, robot.request_target(target))
time.sleep(twist_duration_s)
print(f"{scene_name}: send stop twist target")
print_error_info(f"{scene_name}_stop", robot.request_target(build_stop_twist_target()))


def print_menu():
print(
"\nAvailable commands:\n"
" joint - request a joint-only head target\n"
" base_pose - request a chassis pose target\n"
" base_twist - request a chassis twist target with auto stop\n"
" mixed_pose - request head + left_arm + chassis pose in one target\n"
" mixed_twist - request head + left_arm + chassis twist in one target\n"
" quit - exit example\n"
)


def main():
robot = GalbotRobot()
if not robot.init():
print("robot init failed")
return

time.sleep(2)

head_joint_names = robot.get_joint_names(True, [G1JointGroup.head])
if not head_joint_names:
print("failed to fetch active head joints")
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()
return

head_single_joint = [head_joint_names[0]]
joint_time_s = 3.0
pose_time_s = 4.0
twist_command_time_s = 0.2
twist_duration_s = 2.0

print_menu()

while True:
command = input("Enter command: ").strip()
if command == "quit":
break

if command == "joint":
target = build_joint_target(G1JointGroup.head, head_single_joint, [0.2], joint_time_s)
print_error_info("joint", robot.request_target(target))
continue

if command == "base_pose":
if ensure_controller(robot, G1ControllerName.CHASSIS_POSE_CTRL) != ControlStatus.SUCCESS:
continue
target = build_chassis_pose_target(0.2, 0.0, 0.0, pose_time_s)
print_error_info("base_pose", robot.request_target(target))
continue

if command == "base_twist":
if ensure_controller(robot, G1ControllerName.CHASSIS_TWIST_CTRL) != ControlStatus.SUCCESS:
continue
target = build_chassis_twist_target(0.05, 0.0, 0.0, twist_command_time_s)
run_twist_scene(robot, "base_twist", target, twist_duration_s)
continue

if command == "mixed_pose":
if ensure_controller(robot, G1ControllerName.CHASSIS_POSE_CTRL) != ControlStatus.SUCCESS:
continue
target = merge_targets(
[
build_joint_target(G1JointGroup.head, head_single_joint, [0.2], joint_time_s),
build_chassis_pose_target(0.1, 0.0, 0.0, pose_time_s),
]
)
print_error_info("mixed_pose", robot.request_target(target))
continue

if command == "mixed_twist":
if ensure_controller(robot, G1ControllerName.CHASSIS_TWIST_CTRL) != ControlStatus.SUCCESS:
continue
target = merge_targets(
[
build_joint_target(G1JointGroup.head, head_single_joint, [-0.2], joint_time_s),
build_chassis_twist_target(0.05, 0.0, 0.0, twist_command_time_s),
]
)
run_twist_scene(robot, "mixed_twist", target, twist_duration_s)
continue

print(f"Unknown command: {command}")
print_menu()

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()


if __name__ == "__main__":
main()

设置底盘速度(set_base_velocity)

适用场景:控制移动底盘的线速度和角速度,用于导航或远程遥控。

examples/python/galbot_robot/set_base_velocity.py
from galbot_sdk.g1 import GalbotRobot, ControlStatus
import time

# Get GalbotRobot
robot = GalbotRobot()
robot.init()
time.sleep(1)
print("Initialization succeeded")

# Set chassis speed
linear_velocity = [0.05, 0.0, 0.0] # 0.5 m/s
angular_velocity = [0.0, 0.0, 0.1] # 0.1 rad/s

duration_s = 2.0 # Automatically stop after 2 seconds
status = robot.set_base_velocity(linear_velocity, angular_velocity, duration_s)

if status == ControlStatus.SUCCESS:
print(f"Chassis speed set successfully; will auto-stop after {duration_s} seconds.")
else:
print("Set chassis speed failed.")

time.sleep(duration_s + 0.5)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取关节状态(get_joint_states)

适用场景:获取所有关节的完整状态信息,包括位置、速度、电流等。适用于需要完整关节信息的算法(如动力学计算、状态估计)。

examples/python/galbot_robot/get_joint_states.py
import time
from galbot_sdk.g1 import GalbotRobot

def print_joint_states(joint_states):
"""
joint_state_vec: List of JointState; each object has position, velocity, acceleration, effort, current
"""
for js in joint_states:
print(f" : position = {js.position} , velocity = {js.velocity} "
f", acceleration = {js.acceleration} , effort = {js.effort} , current = {js.current}")

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")
# Get joint states by joint group names; returns all joints if empty
joint_group_names = ["left_arm"]
ret = robot.get_joint_states(joint_group_names, [])
print_joint_states(ret)

# Get specified joint states; if provided, overrides joint group input
joint_names = ["left_arm_joint1", "left_arm_joint2"]
state_ret = robot.get_joint_states([], joint_names)
print_joint_states(state_ret)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取关节位置(get_joint_positions)

适用场景:仅获取当前关节位置。当你只需要关节位置信息时使用此接口,比 get_joint_states 更轻量。

examples/python/galbot_robot/get_joint_positions.py
import time
from galbot_sdk.g1 import GalbotRobot

def print_joint_positions(joint_positions):
print(f"pos count is {len(joint_positions)}")
for pos in joint_positions:
print(pos)

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

# Get joint positions by joint group names; returns all joints if empty
joint_group_names = ["left_arm"]
ret = robot.get_joint_positions(joint_group_names, [])
print("Left arm joint positions:")
print_joint_positions(ret)
# Get specified joint positions; if provided, overrides joint group input
joint_names = ["left_arm_joint1", "left_arm_joint2"]
state_ret = robot.get_joint_positions([], joint_names)
print("Left arm joints 1 and 2 positions:")
print_joint_positions(state_ret)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取关节名称(get_joint_names)

适用场景:获取机器人所有关节的名称列表,用于迭代遍历关节或配置文件生成。

examples/python/galbot_robot/get_joint_names.py
import time
from galbot_sdk.g1 import GalbotRobot

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()
# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

# Get joint positions by joint group names; returns all joints if empty
joint_group_names = ["left_arm"]
# get joint
only_active_joint = True
ret = robot.get_joint_names(only_active_joint, joint_group_names)
print("Left joint names:")
for i, name in enumerate(ret):
print(f"{i + 1}: {name}")

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取夹爪状态(get_gripper_state)

适用场景:获取夹爪当前位置和状态,判断夹爪当前是打开还是闭合。

examples/python/galbot_robot/get_gripper_state.py
import time
from galbot_sdk.g1 import GalbotRobot, G1JointGroup

def print_gripper_state(joint_group, gripper_state):
"""
joint_group: G1JointGroup enum value
gripper_state: object including timestamp_ns, width, velocity, effort, is_moving
"""
print(f"Timestamp (ns): {gripper_state.timestamp_ns}")
print(
f"width {gripper_state.width} "
f"velocity {gripper_state.velocity} "
f"effort {gripper_state.effort} "
f"is moving {gripper_state.is_moving}"
)

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()

# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

# Set gripper joint group (left gripper)
joint_group = G1JointGroup.left_gripper

# Get gripper state
gripper_state = robot.get_gripper_state(joint_group)

if gripper_state is None:
print("get gripper state error")
else:
print("Left gripper state is as follows:")
print_gripper_state(joint_group, gripper_state)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取吸盘状态(get_suction_cup_state)

适用场景:获取吸盘当前是否处于吸合状态,以及是否成功检测到物体。

examples/python/galbot_robot/get_suction_cup_state.py
import time
from galbot_sdk.g1 import GalbotRobot, G1JointGroup

def print_suction_cup_state(suction_cup_state):
"""
suction_cup_state: object including timestamp_ns, pressure, activation, action_state
"""
group_name = joint_group.name
print(f"Timestamp (ns): {suction_cup_state.timestamp_ns}")
print(
f"pressure {suction_cup_state.pressure} "
f"activation {suction_cup_state.activation} "
f"action state {int(suction_cup_state.action_state)}"
)

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()

# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

# Set suction cup joint group (right suction cup)
joint_group = G1JointGroup.right_suction_cup

# Get suction cup state
suction_cup_state = robot.get_suction_cup_state(joint_group)

if suction_cup_state is None:
print("get suction cup error")
else:
print("Right suction cup status:")
print_suction_cup_state(suction_cup_state)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取坐标变换(get_transform)

适用场景:获取两个坐标系之间的变换关系(位姿),用于机械臂抓取、视觉定位等场景。

examples/python/galbot_robot/get_transform.py
import time
from galbot_sdk.g1 import GalbotRobot

def print_pose(pose_vec):
"""
pose_vec: list of floats
"""
print("pose_vec = [" + ", ".join(str(p) for p in pose_vec) + "]")

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()

# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

# Set target frame and source frame
target_frame = "base_link"
source_frame = "left_arm_link1"
timestamp_ns = 0 # 0 means fetch the latest TF transform value

# Get coordinate transform
ret_val = robot.get_transform(target_frame, source_frame)

if not ret_val[0]:
print("get_transform error")
else:
print("tf_timestamp_ns:", ret_val[1])
print_pose(ret_val[0])

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取 IMU 数据(get_imu_data)

适用场景:获取机器人基座 IMU 的加速度、角速度和姿态信息,用于状态估计、运动分析。

examples/python/galbot_robot/get_imu_data.py
import time
from galbot_sdk.g1 import GalbotRobot, SensorType
from typing import Dict

def print_imu_data(imu_data: dict):
"""
imu_data: dict, includes:
- 'timestamp_ns'
- 'accel' : {'x', 'y', 'z'}
- 'gyro' : {'x', 'y', 'z'}
- 'magnet' : {'x', 'y', 'z'}
"""
if not imu_data:
print("IMU data is empty")
return

print(f"Timestamp (ns): {imu_data.get('timestamp_ns')}")

accel = imu_data.get("accel", {})
gyro = imu_data.get("gyro", {})
magnet = imu_data.get("magnet", {})

print(
f"Accelerometer: x={accel.get('x')}, "
f"y={accel.get('y')}, "
f"z={accel.get('z')}"
)
print(
f"Gyroscope: x={gyro.get('x')}, "
f"y={gyro.get('y')}, "
f"z={gyro.get('z')}"
)
print(
f"Magnetometer: x={magnet.get('x')}, "
f"y={magnet.get('y')}, "
f"z={magnet.get('z')}"
)

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init({SensorType.TORSO_IMU})

# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

imu_data = robot.get_imu_data(SensorType.TORSO_IMU)
if not imu_data:
print("No imu data!")
else:
print("IMU data:")
print_imu_data(imu_data)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取设备信息(get_device_information)

适用场景:获取机器人硬件版本、固件版本等设备信息,用于调试和兼容性检查。

examples/python/galbot_robot/get_device_information.py
import time
from galbot_sdk.g1 import GalbotRobot
from typing import Dict

def print_device_info(device_info: dict):
"""
device_info: dict, including the following fields:
- 'model': Device model (str)
- 'serial_number': Serial number (str)
- 'firmware_version': Firmware version (str)
- 'hardware_version': Hardware version (str)
- 'manufacturer': Manufacturer (str)
"""
if not device_info:
print("Device information is empty")
return

print("Device information:")
print(f" Model: {device_info.get('model', 'N/A')}")
print(f" Serial number: {device_info.get('serial_number', 'N/A')}")
print(f" Firmware version: {device_info.get('firmware_version', 'N/A')}")
print(f" Hardware version: {device_info.get('hardware_version', 'N/A')}")
print(f" : {device_info.get('manufacturer', 'N/A')}")

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()

# Program started, waiting for data
time.sleep(1)
print("Initialization succeeded")

device_info = robot.get_device_information()
if not device_info:
print("Failed to get device information!")
else:
print("Device information retrieved successfully!")
print_device_info(device_info)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

获取电池信息(get_bms_information)

适用场景:获取电池电压、电量等信息,用于低电量检测和状态监控。

examples/python/galbot_robot/get_bms_information.py
import time
from galbot_sdk.g1 import GalbotRobot


def print_bms_information(bms_info: dict):
"""
bms_info: dict, includes:
- 'voltage' : float (V)
- 'current' : float (A)
- 'battery_level' : float (0-100)
- 'temperature' : float (°C)
- 'charging_status' : str or int
- 'health_status' : str or int
- 'capacity' : float (Ah)
"""
if not bms_info:
print("BMS information is empty")
return

print(f"Voltage (V): {bms_info.get('voltage')}")
print(f"Current (A): {bms_info.get('current')}")
print(f"Battery level (%): {bms_info.get('battery_level')}")
print(f"Temperature (C): {bms_info.get('temperature')}")
print(f"Charging status: {bms_info.get('charging_status')}")
print(f"Health status: {bms_info.get('health_status')}")
print(f"Capacity (Ah): {bms_info.get('capacity')}")


# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
robot.init()

# Program started, waiting for data
time.sleep(3)
print("Initialization succeeded")

bms_info = robot.get_bms_information()
print_bms_information(bms_info)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print("Resources released successfully")

获取相机图像数据(get_rgb_data && get_depth_data)

适用场景:获取 RGB 图像和深度图像数据,用于视觉感知、目标检测、SLAM 等任务。

examples/python/galbot_robot/get_camera_data.py
try:
from galbot_sdk.g1 import GalbotRobot, SensorType
except ImportError:
print("import galbot_sdk failed, please install it first or check if it is in the PYTHONPATH")
exit(1)

import os

try:
import cv2
except ImportError:
os.system("pip install opencv-python")
import cv2

try:
import numpy as np
except ImportError:
os.system("pip install numpy")
import numpy as np

import time
from typing import Dict

def decode_compressed_image(compressed_image):
"""
decode CompressedImage image

Parameters:
compressed_image (dict): image dict, keys:[header, format, data, "depth_scale"]

Returns:
numpy.ndarray: decoded image
"""
image_data = compressed_image["data"]
if compressed_image["format"] == "rgb8":
return decode_rgb_image(image_data)
elif compressed_image["format"] == "16UC1":
return decode_depth_image(compressed_image)
else:
raise ValueError(f"Unsupport data format: {compressed_image['format']}")

def decode_rgb_image(image_data):
"""decode rgb image"""
nparr = np.frombuffer(image_data, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
raise ValueError("Fail to Decode RGB Image")
return img

def decode_depth_image(image_data):
"""decode depth image"""
depth_img = np.frombuffer(image_data["data"], dtype=np.uint16).copy()

# Check whether height and width exist
if "height" not in image_data or "width" not in image_data:
raise ValueError("Missing 'height' or 'width' in depth image metadata.")
if image_data["height"] == 0 or image_data["width"] == 0:
raise ValueError(f"Invalid 'height' ({image_data['height']}) or 'width' ({image_data['width']}) in depth image metadata.")

# Parse depth image
depth_img = depth_img.reshape((image_data["height"], image_data["width"]))
depth_img = depth_img.astype(np.float32) / image_data["depth_scale"]

return depth_img

def main():
SHOW_IMAGE = False
robot = GalbotRobot()

# Get left arm RGB and depth images, right arm depth image, chassis lidar data, torso IMU data
enable_sensor_set = {SensorType.LEFT_ARM_CAMERA, # Left arm depth camera
SensorType.LEFT_ARM_DEPTH_CAMERA,} # Left arm RGB camera
robot.init(enable_sensor_set)
print("Initialization succeeded")
# Program started, waiting for data
time.sleep(5)
# Get left arm RGB image
rgb_image_data = robot.get_rgb_data(SensorType.LEFT_ARM_CAMERA)
if not rgb_image_data:
print("No rgb image data!")
else:
print("get rgb image suceess")
print(rgb_image_data['header'])
img = decode_compressed_image(rgb_image_data)

# Save RGB image
cv2.imwrite("rgb_image_data.jpg", img)
# 可视化RGB图像
if SHOW_IMAGE:
cv2.namedWindow("rgb image", cv2.WINDOW_NORMAL)
cv2.imshow("rgb image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# Get left arm depth image
depth_data = robot.get_depth_data(SensorType.LEFT_ARM_DEPTH_CAMERA)
if not depth_data or "data" not in depth_data:
print("Depth camera not ready")
else:
print("get depth data suceess")
print(depth_data['header'])
depth_img_raw = decode_compressed_image(depth_data)
depth_img = cv2.normalize(depth_img_raw, None, 0, 255, cv2.NORM_MINMAX) # Normalize depth values to 0-1 range
depth_img = depth_img.astype(np.uint8)

# Save depth image
cv2.imwrite("depth_data.jpg", depth_img)
# 可视化深度图
if SHOW_IMAGE:
cv2.namedWindow("depth image", cv2.WINDOW_NORMAL)
cv2.imshow("depth image", depth_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

if __name__=="__main__":
main()

获取传感器内外参(get_camera_intrinsic && get_sensor_extrinsic)

适用场景:获取相机内参和传感器相对于机器人基座的外参,用于计算机视觉计算和 3D 重建。

examples/python/galbot_robot/get_camera_params.py
try:
from galbot_sdk.g1 import GalbotRobot, SensorType
except ImportError:
print("import galbot_sdk failed, please install it first or check if it is in the PYTHONPATH")
exit(1)

import os

try:
import cv2
except ImportError:
os.system("pip install opencv-python")
import cv2

try:
import numpy as np
except ImportError:
os.system("pip install numpy")
import numpy as np

import time
from typing import Dict

def decode_compressed_image(compressed_image):
"""
decode CompressedImage image

Parameters:
compressed_image (dict): image dict, keys:[header, format, data, "depth_scale"]

Returns:
numpy.ndarray: decoded image
"""
image_data = compressed_image["data"]
if compressed_image["format"] == "rgb8":
return decode_rgb_image(image_data)
elif compressed_image["format"] == "16UC1":
return decode_depth_image(compressed_image)
else:
raise ValueError(f"Unsupport data format: {compressed_image['format']}")

def decode_rgb_image(image_data):
"""decode rgb image"""
nparr = np.frombuffer(image_data, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
raise ValueError("Fail to Decode RGB Image")
return img

def decode_depth_image(image_data):
"""decode depth image"""
depth_img = np.frombuffer(image_data["data"], dtype=np.uint16).copy()

# Check whether height and width exist
if "height" not in image_data or "width" not in image_data:
raise ValueError("Missing 'height' or 'width' in depth image metadata.")
if image_data["height"] == 0 or image_data["width"] == 0:
raise ValueError(f"Invalid 'height' ({image_data['height']}) or 'width' ({image_data['width']}) in depth image metadata.")

# Parse depth image
depth_img = depth_img.reshape((image_data["height"], image_data["width"]))
depth_img = depth_img.astype(np.float32) / image_data["depth_scale"]

return depth_img

def main():
robot = GalbotRobot()

# Get left arm RGB and depth images, right arm depth image, chassis lidar data, torso IMU data
enable_sensor_set = {SensorType.LEFT_ARM_CAMERA, # Left arm depth camera
SensorType.LEFT_ARM_DEPTH_CAMERA,} # Left arm RGB camera
robot.init(enable_sensor_set)
print("Initialization succeeded")

# Program started, waiting for data
time.sleep(5)

# Get left arm RGB image
rgb_image_data = robot.get_rgb_data(SensorType.LEFT_ARM_CAMERA)
if not rgb_image_data:
print("No rgb image data!")
else:
print("get rgb image suceess")
print(rgb_image_data['header'])
img = decode_compressed_image(rgb_image_data)

# Save RGB image
cv2.imwrite("rgb_image_data.jpg", img)

# Get left arm camera intrinsics
camera_intrinsics = robot.get_camera_intrinsic(SensorType.LEFT_ARM_CAMERA)
if not camera_intrinsics:
print("No camera intrinsics data!")
else:
print("get camera intrinsics suceess")
print(camera_intrinsics)

# Get left arm depth image
depth_data = robot.get_depth_data(SensorType.LEFT_ARM_DEPTH_CAMERA)
if not depth_data or "data" not in depth_data:
print("Depth camera not ready")
else:
print("get depth data suceess")
print(depth_data['header'])
depth_img_raw = decode_compressed_image(depth_data)
depth_img = cv2.normalize(depth_img_raw, None, 0, 255, cv2.NORM_MINMAX) # Normalize depth values to 0-1 range
depth_img = depth_img.astype(np.uint8)

# Save depth image
cv2.imwrite("depth_data.jpg", depth_img)

# Get left-arm depth camera intrinsics
camera_intrinsics = robot.get_camera_intrinsic(SensorType.LEFT_ARM_DEPTH_CAMERA)
if not camera_intrinsics:
print("No camera intrinsics data!")
else:
print("get camera intrinsics suceess")
print(camera_intrinsics)

# Extrinsics
time.sleep(2)
camera_extrinsics, timestamp_ns = robot.get_sensor_extrinsic(SensorType.LEFT_ARM_DEPTH_CAMERA)
if not camera_extrinsics:
print("No camera extrinsics data!")
else:
print("get camera extrinsics suceess")
print(camera_extrinsics)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

if __name__=="__main__":
main()

获取雷达数据(get_lidar_data)

适用场景:获取激光雷达点云数据,用于导航、避障、环境建模。

examples/python/galbot_robot/get_lidar_data.py
from galbot_sdk.g1 import GalbotRobot, SensorType
from typing import Dict
import time
import numpy as np

def convert_pointcloud(cloud):
"""
Convert cloud dict to NumPy array dictionary

Args:
pointcloud_msg: PointCloud2 protobuf message object

Returns:
Dictionary: {field_name: NumPy array}
- Single-element fields: shape (N,)
- Multi-element fields: shape (N, count) or (N,)
- N = width * height (total number of points)
"""

if not cloud:
return {}

num_points = cloud["height"] * cloud["width"]
if num_points == 0:
return {}

DTYPE_MAP = {
1: np.int8,
2: np.uint8,
3: np.int16,
4: np.uint16,
5: np.int32,
6: np.uint32,
7: np.float32,
8: np.float64
}
dtype_list = []
for field in cloud["fields"]:
# Get base data type
np_dtype_class = DTYPE_MAP.get(field["datatype"])
if np_dtype_class is None:
raise ValueError(f"Unsupported data type: {field['datatype']}")

dtype_inst = np.dtype(np_dtype_class)

# Handle byte order (endianness)
if dtype_inst.itemsize > 1:
byteorder = '>' if cloud["is_bigendian"] else '<'
dtype_inst = dtype_inst.newbyteorder(byteorder)

# Add to dtype list
if field["count"] == 1:
dtype_list.append((field["name"], dtype_inst))
else:
# Multi-element fields (e.g., rgb)
dtype_list.append((field["name"], dtype_inst, field["count"]))

# Create structured dtype
dtype = np.dtype(dtype_list)

# Data integrity check
expected_size = num_points * cloud["point_step"]
if len(cloud["data"]) < expected_size:
raise ValueError(
f"Insufficient data length: expected {expected_size} bytes, "
f"actual {len(cloud['data'])} bytes"
)

# Create NumPy structured array from binary data
# count parameter ensures only expected number of points are read
arr = np.frombuffer(cloud["data"], dtype=dtype, count=num_points)

# Convert to regular dictionary (copy data to avoid modifying original)
result = {}
for field in cloud["fields"]:
field_data = arr[field["name"]]

# Handle shape of multi-element fields
if field["count"] == 1:
result[field["name"]] = field_data.copy()
else:
# Keep original shape or flatten, choose according to needs
result[field["name"]] = field_data.copy()

return result


def get_xyz_array(pointcloud_dict: Dict[str, np.ndarray],
remove_nan: bool = False) -> np.ndarray:
"""
Extract XYZ coordinate array from converted point cloud dictionary

Args:
pointcloud_dict: Dictionary returned by pointcloud2_to_numpy()
remove_nan: Whether to remove points containing NaN (for FLOAT32/FLOAT64 types)

Returns:
Nx3 point coordinate array
"""
required = ['x', 'y', 'z']
if not all(k in pointcloud_dict for k in required):
raise ValueError("Point cloud data missing required xyz fields")

points = np.stack([pointcloud_dict['x'],
pointcloud_dict['y'],
pointcloud_dict['z']], axis=1)

if remove_nan:
mask = ~np.isnan(points).any(axis=1)
points = points[mask]

return points

def save_xyz_to_pcd(xyz_array: np.ndarray, filename: str, binary: bool = False) -> None:
"""
Save XYZ coordinates to PCD file format (simplest option for coordinate-only data)

Args:
xyz_array: Nx3 array of XYZ coordinates
filename: Output PCD file path
binary: If True, saves in binary format; otherwise ASCII
"""
if xyz_array.ndim != 2 or xyz_array.shape[1] != 3:
raise ValueError(f"xyz_array must have shape (N, 3), got {xyz_array.shape}")

num_points = xyz_array.shape[0]
header = [
"# .PCD v0.7 - Point Cloud Data file format",
"VERSION 0.7",
"FIELDS x y z",
"SIZE 4 4 4",
"TYPE F F F", # F = float32
"COUNT 1 1 1",
f"WIDTH {num_points}",
"HEIGHT 1",
"VIEWPOINT 0 0 0 1 0 0 0",
f"POINTS {num_points}",
f"DATA {'binary' if binary else 'ascii'}"
]

if binary:
with open(filename, 'wb') as f:
f.write(('\n'.join(header) + '\n').encode('ascii'))
f.write(xyz_array.astype(np.float32).tobytes())
else:
with open(filename, 'w') as f:
f.write('\n'.join(header) + '\n')
np.savetxt(f, xyz_array, fmt='%f')

# Get and initialize the GalbotRobot singleton
robot = GalbotRobot()
enable_sensor_set = {SensorType.BASE_LIDAR}
# To save resource overhead, only cameras and LiDAR sensors passed during initialization can retrieve data
robot.init(enable_sensor_set)
print("Initialization succeeded")
# Program started, waiting for data
time.sleep(4)

cloud = robot.get_lidar_data(SensorType.BASE_LIDAR)
if not cloud:
print("No lidar data!")
else:
pointcloud_dict = convert_pointcloud(cloud)
xyz_points = get_xyz_array(pointcloud_dict)
save_xyz_to_pcd(xyz_points, "output_xyz.pcd")
print(pointcloud_dict)
print("get lidar data success")

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

一键回零-odom坐标系(whole_body_reset_zero_odom)

适用场景:快速将全身上下所有关节运动到零位(初始姿态),基于 odom 坐标系。通常用于程序启动后的初始化。

examples/python/galbot_robot/whole_body_reset_zero_odom_example.py
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import GalbotMotion
import time


def main():
robot = GalbotRobot()
motion = GalbotMotion()

if not robot.init():
print("GalbotRobot init failed.")
return
if not motion.init():
print("GalbotMotion init failed.")
return

time.sleep(2)

# Whole-body joints: leg(5) + head(2) + left_arm(7) + right_arm(7)
whole_body_joint_1 = [
0.25, 1.1, 0.85, 0.0, 0.0, # leg
0.5, 0.5, # head
2.0, -1.55, -0.55, -1.7, -0.0, -0.8, 0.2, # left_arm
-2.0, 1.55, 0.55, 1.7, 0.0, 0.8, 0.2 # right_arm
]

# Base pose command odom(x, y, yaw)
base_x_1 = 0.2
base_y_1 = 0.0
base_yaw_1 = 0.0

# Optional frames (frame_id: base_link/odom/map, reference_frame_id: odom/map)
frame_id = "base_link"
reference_frame_id = "odom"

# Chassis pose interpolation time (seconds), used to generate a smooth chassis trajectory
base_time_s = 15.0

time.sleep(1)

# reset to zero
result = robot.zero_whole_body_and_base(
frame_id,
reference_frame_id,
True,
0.2,
15.0,
)
print("Zero joint status:", result[0])
print("Zero base status:", result[1])

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()


if __name__ == "__main__":
main()

一键回零-map坐标系(whole_body_reset_zero_map)

适用场景:快速将全身上下所有关节运动到零位(初始姿态),基于 map 坐标系。

examples/python/galbot_robot/whole_body_reset_zero_map_example.py
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import GalbotMotion
import time


def main():
robot = GalbotRobot()
motion = GalbotMotion()

if not robot.init():
print("GalbotRobot init failed.")
return
if not motion.init():
print("GalbotMotion init failed.")
return

time.sleep(2)

# Whole-body joints: leg(5) + head(2) + left_arm(7) + right_arm(7)
whole_body_joint_1 = [
0.25, 1.1, 0.85, 0.0, 0.0, # leg
0.5, 0.5, # head
2.0, -1.55, -0.55, -1.7, -0.0, -0.8, 0.2, # left_arm
-2.0, 1.55, 0.55, 1.7, 0.0, 0.8, 0.2 # right_arm
]

# Base pose command map(x, y, yaw) Note: adjust based on the robot's actual localization in the map frame
base_x_1 = -0.4
base_y_1 = 0.226593
base_yaw_1 = 0.0

# Optional frames (frame_id: base_link/odom/map, reference_frame_id: odom/map)
frame_id = "base_link"
reference_frame_id = "map"

# Chassis pose interpolation time (seconds), used to generate a smooth chassis trajectory
base_time_s = 15.0

time.sleep(1)

# reset to zero
result = robot.zero_whole_body_and_base(
frame_id,
reference_frame_id,
True,
0.2,
15.0,
)
print("Zero joint status:", result[0])
print("Zero base status:", result[1])

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()


if __name__ == "__main__":
main()

类:GalbotMotion

获取实例并初始化

适用场景:获取运动规划模块单例并初始化。必须在使用运动规划功能前调用。

examples/python/galbot_motion/get_instance.py
from galbot_sdk.g1 import GalbotMotion
from galbot_sdk.g1 import GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")

if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# You can still manage the robot lifecycle through GalbotRobot
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

正运动学(使用当前状态或指定 RobotStates)

适用场景:根据给定的关节角度计算末端执行器的位姿。用于机械臂任务验证和状态分析。

examples/python/galbot_motion/fk.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(1)

chain_joints = {
"leg": [0.4992,1.4991,1.0005,0.0000,-0.0004],
"head": [0.0000,0.0],
"left_arm": [1.9999,-1.6000,-0.5999,-1.6999,0.0000,-0.7999,0.0000],
"right_arm": [-2.0000,1.6001,0.6001,1.7000,0.0000,0.8000,0.0000]
}
chain_pose_baselink = {
"leg": [0.0596,-0.0000,1.0327,0.5000,0.5003,0.4997,0.5000],
"head": [0.0599,0.0002,1.4098,-0.7072,0.0037,0.0037,0.7069],
"left_arm": [0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
"right_arm": [0.1267,-0.2345,0.7358,-0.0225,0.0126,-0.0343,0.9991]
}
whole_body_joint = [
num for key in ["leg", "head", "left_arm", "right_arm"]
for num in chain_joints[key]
]
base_state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
custom_param = gm.Parameter()
reference_frame = "base_link"
target_frame = "EndEffector"
target_chain = "left_arm"
one_chain = [target_chain]
chain_with_torso = [target_chain, "torso"]
error_chains = [target_chain, "torso", "head"]
# Scenario 1: Single-chain inverse kinematics
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ Basic version forward kinematics successful: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ Basic version forward kinematics exception: {e}")

# Scenario 2: Arm chain + torso inverse kinematics
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=chain_with_torso,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ Custom initial joint forward kinematics successful: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ Custom initial joint forward kinematics exception: {e}")

# Scenario 3: invalid chain combination
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=error_chains,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.INVALID_INPUT, "Inverse kinematics calculation failed"
print(f"✅ Invalid chain-combination input check passed")
time.sleep(0.8)
except Exception as e:
print(f"❌ Custom initial joint forward kinematics exception: {e}")

# Scenario 4: Use reference joints
try:
# initial_joint_positions can specify chain joints as IK reference, unspecified chain joints use whole-body joints
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
initial_joint_positions=chain_joints,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ Custom initial joint forward kinematics successful: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ Custom initial joint forward kinematics exception: {e}")

# Scenario 5: Use RobotStates
try:
ref_robot_state = gm.RobotStates()
ref_robot_state.chain_name = target_chain
ref_robot_state.whole_body_joint = whole_body_joint
ref_robot_state.base_state = base_state
target_frame = "EndEffector"
reference_frame = "base_link"
status, joint_map = motion.inverse_kinematics_by_state(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
reference_robot_states=ref_robot_state
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ Based on RobotStates forward kinematics successful: joint angles={joint_map}")
except Exception as e:
print(f"❌ Based on RobotStatesforward kinematics exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

逆运动学(基础与基于 RobotStates)

适用场景:根据期望的末端位姿求解所需的关节角度。是机械臂抓取等操作的核心步骤。

examples/python/galbot_motion/ik.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(1)

chain_joints = {
"leg": [0.4992,1.4991,1.0005,0.0000,-0.0004],
"head": [0.0000,0.0],
"left_arm": [1.9999,-1.6000,-0.5999,-1.6999,0.0000,-0.7999,0.0000],
"right_arm": [-2.0000,1.6001,0.6001,1.7000,0.0000,0.8000,0.0000]
}
chain_pose_baselink = {
"leg": [0.0596,-0.0000,1.0327,0.5000,0.5003,0.4997,0.5000],
"head": [0.0599,0.0002,1.4098,-0.7072,0.0037,0.0037,0.7069],
"left_arm": [0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
"right_arm": [0.1267,-0.2345,0.7358,-0.0225,0.0126,-0.0343,0.9991]
}
whole_body_joint = [
num for key in ["leg", "head", "left_arm", "right_arm"]
for num in chain_joints[key]
]
base_state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
custom_param = gm.Parameter()
reference_frame = "base_link"
target_frame = "EndEffector"
target_chain = "left_arm"
one_chain = [target_chain]
chain_with_torso = [target_chain, "torso"]
error_chains = [target_chain, "torso", "head"]
# Scenario 1: Single-chain inverse kinematics
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ Basic IK succeeded: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ Basic IK exception: {e}")

# Scenario 2: Arm chain + torso inverse kinematics
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=chain_with_torso,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ IK with custom initial joints succeeded: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ IK with custom initial joints exception: {e}")

# Scenario 3: invalid chain combination
try:
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=error_chains,
target_frame=target_frame,
reference_frame=reference_frame,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.INVALID_INPUT, "Inverse kinematics calculation failed"
print(f"✅ Invalid chain-combination input check passed")
time.sleep(0.8)
except Exception as e:
print(f"❌ IK with custom initial joints exception: {e}")

# Scenario 4: Use reference joints
try:
# initial_joint_positions can specify chain joints as IK reference; unspecified chain joints are filled from whole-body joints
status, joint_map = motion.inverse_kinematics(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
initial_joint_positions=chain_joints,
enable_collision_check=False # Disable collision checking for accelerated testing
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ IK with custom initial joints succeeded: joint angles={joint_map}")
time.sleep(0.8)
except Exception as e:
print(f"❌ IK with custom initial joints exception: {e}")

# Scenario 5: Use RobotStates
try:
ref_robot_state = gm.RobotStates()
ref_robot_state.chain_name = target_chain
ref_robot_state.whole_body_joint = whole_body_joint
ref_robot_state.base_state = base_state
target_frame = "EndEffector"
reference_frame = "base_link"
status, joint_map = motion.inverse_kinematics_by_state(
target_pose=chain_pose_baselink[target_chain],
chain_names=one_chain,
target_frame=target_frame,
reference_frame=reference_frame,
reference_robot_states=ref_robot_state
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Inverse kinematics calculation failed"
print(f"✅ RobotStates-based IK succeeded: joint angles={joint_map}")
except Exception as e:
print(f"❌ RobotStates-based IK exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

获取与设置末端位姿

适用场景:直接获取当前末端位姿,或将末端移动到指定位姿。集成了逆运动学计算和执行。

examples/python/galbot_motion/get_set_end_effector_pose.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(1)

chain_pose_baselink = {
"leg": [0.0596,-0.0000,1.0327,0.5000,0.5003,0.4997,0.5000],
"head": [0.0599,0.0002,1.4098,-0.7072,0.0037,0.0037,0.7069],
"left_arm": [0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
"right_arm": [0.1267,-0.2345,0.7358,-0.0225,0.0126,-0.0343,0.9991]
}
custom_param = gm.Parameter()
target_frame = "EndEffector"
reference_frame = "base_link"
target_chain = "left_arm"
# Scenario 1: Basic version
try:
end_ee_link = "left_arm_end_effector_mount_link"
status, pose = motion.get_end_effector_pose(
end_effector_frame=end_ee_link,
reference_frame=reference_frame
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Failed to get end-effector pose"
print(f"✅ Basic end-effector pose retrieval succeeded: {pose}")
time.sleep(0.8)
except Exception as e:
print(f"❌ Basic end-effector pose retrieval exception: {e}")

# Scenario 2: Specify chain name + custom frame
try:
status, pose = motion.get_end_effector_pose_on_chain(
chain_name=target_chain,
frame_id=target_frame,
reference_frame=reference_frame
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Failed to get end-effector pose"
print(f"✅ End-effector pose retrieval by specified chain succeeded: {pose}")
time.sleep(0.8)
except Exception as e:
print(f"❌ End-effector pose retrieval by specified chain exception: {e}")

end_effector_frame="left_arm"
reference_frame = "base_link"
try:
status = motion.set_end_effector_pose(
target_pose=chain_pose_baselink[end_effector_frame],
end_effector_frame=end_effector_frame,
reference_frame=reference_frame,
enable_collision_check=False,
is_blocking=False,
timeout=5.0,
params=custom_param
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Set end-effector pose failed"
print(f"✅ End-effector pose set succeeded: status={status}")
except Exception as e:
print(f"❌ End-effector pose setting exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

单点运动规划(关节空间与笛卡尔空间)

适用场景:规划从当前位姿到单个目标位姿的无碰撞运动轨迹。适用于单点目标到达任务。

examples/python/galbot_motion/motion_plan.py
import time

import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# NOTE:
# - GalbotMotion currently does NOT provide real-time obstacle perception / automatic environment updates.
# - Motion collision checking uses self-collision + a collision world built from objects you load manually via
# add_obstacle()/attach_target_object() (including point clouds if you load them explicitly).

motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Result: SUCCESS")
elif(status == gm.MotionStatus.TIMEOUT):
print("Result: TIMEOUT")
elif(status == gm.MotionStatus.FAULT):
print("Result: FAULT")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Result: INVALID_INPUT")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Result: INIT_FAILED")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Result: IN_PROGRESS")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Result: STOPPED_UNREACHED")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Result: DATA_FETCH_FAILED")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Result: PUBLISH_FAIL")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Result: COMM_DISCONNECTED")

if motion.init():
print("GalbotMotion init OK")
else:
print("GalbotMotion init FAILED")
if robot.init():
print("GalbotRobot init OK")
else:
print("GalbotRobot init FAILED")

# Wait for data to be ready.
time.sleep(1)

chain_joints = {
"leg": [0.4992,1.4991,1.0005,0.0000,-0.0004],
"head": [0.0000,0.0],
"left_arm": [1.9999,-1.6000,-0.5999,-1.6999,0.0000,-0.7999,0.0000],
"right_arm": [-2.0000,1.6001,0.6001,1.7000,0.0000,0.8000,0.0000]
}
chain_pose_baselink = {
"leg": [0.0596,-0.0000,1.0327,0.5000,0.5003,0.4997,0.5000],
"head": [0.0599,0.0002,1.4098,-0.7072,0.0037,0.0037,0.7069],
"left_arm": [0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
"right_arm": [0.1267,-0.2345,0.7358,-0.0225,0.0126,-0.0343,0.9991]
}
whole_body_joint = [
num for key in ["leg", "head", "left_arm", "right_arm"]
for num in chain_joints[key]
]
base_state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
custom_param = gm.Parameter()

# Scenario 1: joint-space planning, target type = joint state
try:
# Construct target joint state

target_joint = gm.JointStates()
target_joint.chain_name = "left_arm"
target_joint.joint_positions = chain_joints[target_joint.chain_name]

status, traj = motion.motion_plan(
target=target_joint,
# When enable_collision_check=True, collision is checked against Motion-side explicitly loaded obstacles
# (add_obstacle/attach_target_object) and self-collision.
enable_collision_check=False,
params=custom_param
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Planning failed"
if traj != {}:
print(f"✅ Joint-space planning + joint-target single-chain single-point planning succeeded: trajectory points={len(traj[target_joint.chain_name])}")
time.sleep(0.8)
else:
print(f"⚠️ Return status is SUCCESS, but trajectory is empty; possibly already reached, check whether the target matches current state or is within tolerance")

except Exception as e:
print(f"ERROR: joint-space single-point planning exception: {e}")

# Scenario 2: joint-space planning, target type = end-effector pose (Cartesian)
try:
# Construct target pose state
target_pose_state = gm.PoseState()
target_pose_state.chain_name = "left_arm"
target_pose_state.frame_id = "EndEffector"
target_pose_state.reference_frame = "base_link"
target_pose_state.pose = gm.Pose(chain_pose_baselink[target_pose_state.chain_name])
# target_pose_state.pose.position.x += 0.2

status, traj = motion.motion_plan(
target=target_pose_state,
enable_collision_check=False
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Planning failed"
if traj != {}:
print(f"✅ Joint-space planning + end-effector-pose-target single-chain single-point planning succeeded: trajectory length={len(traj[target_pose_state.chain_name])}")
time.sleep(0.8)
else:
print(f"⚠️ Return status is SUCCESS, but trajectory is empty; possibly already reached, check whether the target matches current state or is within tolerance")

except Exception as e:
print(f"ERROR: Cartesian single-point planning exception: {e}")

# Scenario 3: joint-space planning with an explicit start state
try:
# Construct target joint state

target_joint = gm.JointStates()
target_joint.chain_name = "left_arm"
target_joint.joint_positions = chain_joints[target_joint.chain_name]

start_joint = gm.JointStates()
start_joint.chain_name = "left_arm"
start_joint.joint_positions = [0] * 7

status, traj = motion.motion_plan(
target=target_joint,
start=start_joint,
enable_collision_check=False,
params=custom_param
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Planning failed"
if traj != {}:
print(f"✅ Joint-space planning + joint-target single-chain single-point planning succeeded: trajectory points={len(traj[target_joint.chain_name])}")
else:
print(f"⚠️ Return status is SUCCESS, but trajectory is empty; possibly already reached, check whether the target matches current state or is within tolerance")

except Exception as e:
print(f"ERROR: joint-space single-point planning exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

多点轨迹规划

适用场景:规划经过多个路径点的连续运动轨迹,适用于需要经过多个中间点的复杂运动。

examples/python/galbot_motion/motion_plan_multi_waypoints.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(2)

chain_joints = {
"leg": [0.4992,1.4991,1.0005,0.0000,-0.0004],
"head": [0.0000,0.0],
"left_arm": [1.9999,-1.6000,-0.5999,-1.6999,0.0000,-0.7999,0.0000],
"right_arm": [-2.0000,1.6001,0.6001,1.7000,0.0000,0.8000,0.0000]
}
chain_pose_baselink = {
"leg": [0.0596,-0.0000,1.0327,0.5000,0.5003,0.4997,0.5000],
"head": [0.0599,0.0002,1.4098,-0.7072,0.0037,0.0037,0.7069],
"left_arm": [0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
"right_arm": [0.1267,-0.2345,0.7358,-0.0225,0.0126,-0.0343,0.9991]
}
whole_body_joint = [
num for key in ["leg", "head", "left_arm", "right_arm"]
for num in chain_joints[key]
]
base_state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
custom_param = gm.Parameter()

# Scenario 1: Multi-waypoint planning in Cartesian space (PoseState target)
try:
# Construct target pose
target_pose_state = gm.PoseState()
target_pose_state.chain_name = "left_arm"

# Construct waypoints (3 intermediate poses)
waypoint_poses = [
[0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.2267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.3267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.4267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
]

status, traj = motion.motion_plan_multi_waypoints(
target=target_pose_state,
waypoint_poses=waypoint_poses,
enable_collision_check=False,
params=custom_param
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Cartesian multi-waypoint single-chain planning failed"
if traj != {}:
print(f"✅ Cartesian waypoint single-chain planning succeeded: trajectory points={len(traj[target_pose_state.chain_name])}")
time.sleep(0.8)
else:
print(f"⚠️ Return status is SUCCESS, but trajectory is empty; possibly already reached, check whether the target matches current state or is within tolerance")
except Exception as e:
print(f"❌ Cartesian multi-point motion planning exception: {e}")

# Scenario 2: Multi-waypoint planning in joint space (JointStates target)
try:
# Construct target pose
target_joint = gm.JointStates()
target_joint.chain_name = "left_arm"

# Construct waypoints (3 intermediate poses)
waypoints = [
[0.1267,0.2342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.2267,0.4342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.3267,0.6342,0.7356,0.0220,0.0127,0.0343,0.9991],
[0.4267,0.8342,0.7356,0.0220,0.0127,0.0343,0.9991]
]

status, traj = motion.motion_plan_multi_waypoints(
target=target_joint,
waypoint_poses=waypoints,
enable_collision_check=False,
params=custom_param
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Cartesian multi-waypoint single-chain planning failed"
if traj != {}:
print(f"✅ Joint-waypoint single-chain planning succeeded: trajectory points={len(traj[target_pose_state.chain_name])}")
else:
print(f"⚠️ Return status is SUCCESS, but trajectory is empty; possibly already reached, check whether the target matches current state or is within tolerance")
except Exception as e:
print(f"❌ Joint-space multi-point motion planning exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

碰撞检测

适用场景:检查给定关节状态是否会发生自碰撞或与环境障碍物碰撞。用于运动规划前的可行性检查。

examples/python/galbot_motion/check_collision.py
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot, GalbotNavigation
import time

# NOTE:
# - GalbotMotion currently does NOT provide real-time obstacle perception / automatic environment updates.
# - Collision checking uses self-collision + the collision world built from objects you load manually via
# add_obstacle()/attach_target_object() (including point clouds if you load them explicitly).

motion = GalbotMotion()
robot = GalbotRobot()
nav = GalbotNavigation()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Result: SUCCESS")
elif(status == gm.MotionStatus.TIMEOUT):
print("Result: TIMEOUT")
elif(status == gm.MotionStatus.FAULT):
print("Result: FAULT")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Result: INVALID_INPUT")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Result: INIT_FAILED")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Result: IN_PROGRESS")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Result: STOPPED_UNREACHED")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Result: DATA_FETCH_FAILED")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Result: PUBLISH_FAIL")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Result: COMM_DISCONNECTED")

if motion.init():
print("GalbotMotion init OK")
else:
print("GalbotMotion init FAILED")
if robot.init():
print("GalbotRobot init OK")
else:
print("GalbotRobot init FAILED")
if nav.init():
print("GalbotNavigation init OK")
else:
print("GalbotNavigation init FAILED")

# Wait for data to be ready.
time.sleep(3)

chain_joints = {
"leg": [0.4992,1.4991,1.0005,0.0000,-0.0004],
"head": [0.0000,0.0],
"left_arm": [1.9999,-1.6000,-0.5999,-1.6999,0.0000,-0.7999,0.0000],
"right_arm": [-2.0000,1.6001,0.6001,1.7000,0.0000,0.8000,0.0000]
}

whole_body_joint = [
num for key in ["leg", "head", "left_arm", "right_arm"]
for num in chain_joints[key]
]
base_state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
custom_param = gm.Parameter()

try:
# Build RobotStates list to check.
check_states = [gm.RobotStates() for _ in range(2)]
check_states[0].whole_body_joint = whole_body_joint
check_states[0].base_state = base_state

bad_left_arm_joint = [1.99995,-1.60004,0.599905,-1.69994,0,-0.799924,0]

check_left_arm = gm.JointStates()
check_left_arm.chain_name = "left_arm"
check_left_arm.joint_positions = bad_left_arm_joint
check_states[1] = check_left_arm

status, collision_res = motion.check_collision(
start=check_states,
enable_collision_check=True
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "Collision check failed"
assert len(collision_res) == len(check_states), "Result size mismatch"
print(f"OK: collision check finished: {collision_res} (False=no collision)")
except Exception as e:
print(f"ERROR: collision check exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

附加工具

适用场景:在机器人末端添加工具(如夹具、吸盘等),更新运动规划模型,以便考虑工具质量和碰撞体积。

examples/python/galbot_motion/attach_tool.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(2)

try:
chain_name = "left_arm"
tool_name = "suction_cup"
status = motion.attach_tool(
chain=chain_name,
tool=tool_name
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "load failed"
print(f"✅ Tool attached successfully")
except Exception as e:
print(f"❌ Tool attachment exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

卸载工具

适用场景:从机器人末端移除已附加的工具,恢复原始机器人模型。

examples/python/galbot_motion/detach_tool.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Execution result: SUCCESS, execution successful")
elif(status == gm.MotionStatus.TIMEOUT):
print("Execution result: TIMEOUT, execution timed out")
elif(status == gm.MotionStatus.FAULT):
print("Execution result: FAULT, a fault occurred and execution cannot continue")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Execution result: INVALID_INPUT, input parameters do not meet requirements")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Execution result: INIT_FAILED, failed to create internal communication components")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Execution result: IN_PROGRESS, in motion but not yet in position")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Execution result: STOPPED_UNREACHED, stopped but target not reached")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Execution result: DATA_FETCH_FAILED, failed to fetch data")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Execution result: PUBLISH_FAIL, data transmission failed")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Execution result: COMM_DISCONNECTED, connection failed")

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(2)

# 1. Detach tool
try:
chain_name = "left_arm"
status = motion.detach_tool(
chain=chain_name
)
printStatus(status)
assert status == gm.MotionStatus.SUCCESS, "detach failed"
print(f"✅ Tool detached successfully")
except Exception as e:
print(f"❌ Tool detachment exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

获取连杆名称列表

适用场景:获取机器人模型中所有连杆的名称列表,用于碰撞检测和运动规划调试。

examples/python/galbot_motion/get_link_names.py
import time
import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# Get and initialize the GalbotMotion singleton
motion = GalbotMotion()
robot = GalbotRobot()

if motion.init():
print("GalbotMotion initialized successfully")
else:
print("GalbotMotion initialization failed")
if robot.init():
print("GalbotRobot initialized successfully")
else:
print("GalbotRobot initialization failed")

# Program started, waiting for data
time.sleep(2)

try:
# Get all link names
all_link_names = motion.get_link_names(only_end_effector=False)
print(f"\nAll link names (total {len(all_link_names)}):")
for i, link_name in enumerate(all_link_names, 1):
print(f" {i}. {link_name}")

# getend effectorexecute link
ee_link_names = motion.get_link_names(only_end_effector=True)
print(f"\nEnd-effector link names (total {len(ee_link_names)}):")
for i, link_name in enumerate(ee_link_names, 1):
print(f" {i}. {link_name}")

# example: link kinematics
if ee_link_names:
print(f"\nRun forward kinematics using end-effector link '{ee_link_names[0]}'...")
success, fk_result = motion.forward_kinematics(ee_link_names[0])
if success == gm.MotionStatus.SUCCESS:
print(f"Forward-kinematics result: {fk_result}")
else:
print(f"Forward-kinematics computation failed: {success}")
except Exception as e:
print(f"❌ Link-name retrieval exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

加载/移除环境碰撞体

适用场景:向运动规划环境中添加障碍物或移除已添加的障碍物,使运动规划考虑环境障碍。

examples/python/galbot_motion/add_obstacle.py
import time

import galbot_sdk.g1 as gm
from galbot_sdk.g1 import GalbotMotion, GalbotRobot

# NOTE:
# - GalbotMotion currently does NOT provide real-time obstacle perception / automatic environment updates.
# - If you want Motion collision checking to consider obstacles (including point clouds), you must load them
# manually via add_obstacle()/attach_target_object().

motion = GalbotMotion()
robot = GalbotRobot()

def printStatus(status):
if(status == gm.MotionStatus.SUCCESS):
print("Result: SUCCESS")
elif(status == gm.MotionStatus.TIMEOUT):
print("Result: TIMEOUT")
elif(status == gm.MotionStatus.FAULT):
print("Result: FAULT")
elif(status == gm.MotionStatus.INVALID_INPUT):
print("Result: INVALID_INPUT")
elif(status == gm.MotionStatus.INIT_FAILED):
print("Result: INIT_FAILED")
elif(status == gm.MotionStatus.IN_PROGRESS):
print("Result: IN_PROGRESS")
elif(status == gm.MotionStatus.STOPPED_UNREACHED):
print("Result: STOPPED_UNREACHED")
elif(status == gm.MotionStatus.DATA_FETCH_FAILED):
print("Result: DATA_FETCH_FAILED")
elif(status == gm.MotionStatus.PUBLISH_FAIL):
print("Result: PUBLISH_FAIL")
elif(status == gm.MotionStatus.COMM_DISCONNECTED):
print("Result: COMM_DISCONNECTED")

if motion.init():
print("GalbotMotion init OK")
else:
print("GalbotMotion init FAILED")
if robot.init():
print("GalbotRobot init OK")
else:
print("GalbotRobot init FAILED")

# Wait for data to be ready.
time.sleep(2)

# 1) Add a box collision object into Motion environment.
# This affects Motion-side collision checking (e.g., motion_plan/check_collision).
try:
obstacle_id = "box_test_1"
obj_type = "box"
obj_pose = [1.0, 0.0, 1.0, 0,0,0,1]
obj_size = [1.0, 1.0, 1.0]
target_frame = "world"
status = motion.add_obstacle(
obstacle_id=obstacle_id,
obstacle_type=obj_type,
pose=obj_pose,
scale=obj_size,
target_frame=target_frame
)
printStatus(status)
motion.clear_obstacle()
assert status == gm.MotionStatus.SUCCESS, "Failed to add obstacle"
print(f"OK: added obstacle: {obstacle_id}")
except Exception as e:
print(f"ERROR: add obstacle exception: {e}")

# 2) Add a duplicate ID (expected to fail).
try:
obstacle_id = "box_test_1"
obj_type = "box"
obj_pose = [1.0, 0.0, 1.0, 0,0,0,1]
obj_size = [1.0, 1.0, 1.0]
target_frame = "world"
status = motion.add_obstacle(
obstacle_id=obstacle_id,
obstacle_type=obj_type,
pose=obj_pose,
scale=obj_size,
target_frame=target_frame
)
status = motion.add_obstacle(
obstacle_id=obstacle_id,
obstacle_type=obj_type,
pose=obj_pose,
scale=obj_size,
target_frame=target_frame
)
printStatus(status)
motion.clear_obstacle()
assert status == gm.MotionStatus.FAULT, "Expected duplicate obstacle ID to fail"
print("OK: duplicate obstacle ID is rejected")
except Exception as e:
print(f"ERROR: duplicate obstacle exception: {e}")

robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

类:GalbotNavigation

获取实例 / 初始化

适用场景:获取导航模块单例并初始化。必须在使用导航功能前调用。

examples/python/galbot_navigation/get_instance.py
from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
import numpy as np

# Initialize system and navigation module
robot = GalbotRobot()
robot.init()

nav = GalbotNavigation()
nav.init()

print("GalbotNavigation has been initialized:", nav is not None)

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

重定位 / 是否已定位 / 获取当前位姿

适用场景:触发重定位,检查机器人是否已经成功定位,并获取机器人在地图中的当前位姿。

examples/python/galbot_navigation/relocalized.py
from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
import numpy as np
import time

nav = GalbotNavigation()
nav.init()
robot = GalbotRobot()
robot.init()

init_pose = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0])

# success
while not nav.is_localized():
nav.relocalize(init_pose)
time.sleep(0.5)

print("Current pose:", nav.get_current_pose())

nav.stop_navigation()
# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print('Resources released successfully')

检查路径可达性并阻塞导航到目标

适用场景:检查目标点是否可达,如果可达则阻塞等待导航完成到达目标。简单场景使用方便。

examples/python/galbot_navigation/check_path_reachability.py
from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import ControlStatus, G1ControllerName
import numpy as np
import sys

nav = GalbotNavigation()
nav.init()
robot = GalbotRobot()
robot.init()

start = nav.get_current_pose()
goal = np.array([1.0, 1.0, 0.0, 0, 0, 0.4794255, 0.8775826])

res = robot.switch_controller(G1ControllerName.CHASSIS_POSE_CTRL)
if res != ControlStatus.SUCCESS:
print("Failed to switch controller!")
sys.exit(1)
else:
print("Controller switched successfully!")

if nav.check_path_reachability(goal, start):
status = nav.navigate_to_goal(
goal, enable_collision_check=True, is_blocking=True, timeout=30
)
print("navigate_to_goal returned status:", status)
print("Reached or not:", nav.check_goal_arrival())
else:
print("Path unreachable or unsafe")

nav.stop_navigation()
# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print("Resources released successfully")

非阻塞导航 + 轮询判断到达

适用场景:启动导航但不阻塞当前线程,可以在导航过程中做其他处理,需要轮询判断是否到达目标。适合需要异步处理的场景。

examples/python/galbot_navigation/navigate_to_goal.py
from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import ControlStatus, G1ControllerName
import numpy as np
import time
import sys

nav = GalbotNavigation()
nav.init()
robot = GalbotRobot()
robot.init()

goal = np.array([0.5, 0.0, 0.0, 0, 0, 0.0, 1.0])

res = robot.switch_controller(G1ControllerName.CHASSIS_POSE_CTRL)
if res != ControlStatus.SUCCESS:
print("Failed to switch controller!")
sys.exit(1)
else:
print("Controller switched successfully!")

nav.navigate_to_goal(goal, enable_collision_check=True, is_blocking=False, timeout=20)

start_time = time.time()
reached = False

while True:
if nav.check_goal_arrival():
reached = True
break
if time.time() - start_time > 20:
print("Navigation timed out; target not reached within 20s")
break
print("Navigating...")
time.sleep(0.5)

if reached:
print("Target reached")

nav.stop_navigation()
# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print("Resources released successfully")

直线移动到目标 / 停止导航

适用场景:让机器人沿直线移动到目标点,或停止当前正在进行的导航任务。

examples/python/galbot_navigation/move_straight_to.py
from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import ControlStatus, G1ControllerName
import numpy as np
import time
import sys

nav = GalbotNavigation()
nav.init()
robot = GalbotRobot()
robot.init()

target = np.array([0.2, 0.0, 0.0, 0, 0, 0.0, 1.0])

res = robot.switch_controller(G1ControllerName.CHASSIS_POSE_CTRL)
if res != ControlStatus.SUCCESS:
print("Failed to switch controller!")
sys.exit(1)
else:
print("Controller switched successfully!")

nav.move_straight_to(target, is_blocking=False, timeout=10)
time.sleep(1.0)
nav.stop_navigation()

# send SIGINT shutdown signal
robot.request_shutdown()
# Wait until entering shutdown state
robot.wait_for_shutdown()
# Perform SDK resource release
robot.destroy()
print("Resources released successfully")

获取导航状态 + 轮询 SUCCESS/FAILED 或超时

适用场景:获取当前导航任务的执行状态,用于非阻塞导航时轮询。

examples/python/galbot_navigation/get_navigation_status.py
"""
example: navigation get_navigation_status, SUCCESS/FAILED timeout exit,
Avoid deadlock and execute error logic.
"""

from galbot_sdk.g1 import GalbotNavigation
from galbot_sdk.g1 import GalbotRobot
from galbot_sdk.g1 import NavigationTaskStatus, ControlStatus, G1ControllerName
import numpy as np
import time
import sys

nav = GalbotNavigation()
nav.init()
robot = GalbotRobot()
robot.init()

goal = np.array([0.5, 0.0, 0.0, 0, 0, 0.0, 1.0])
timeout_s = 20.0
poll_interval_s = 0.5

res = robot.switch_controller(G1ControllerName.CHASSIS_POSE_CTRL)
if res != ControlStatus.SUCCESS:
print("Failed to switch controller!")
sys.exit(1)
else:
print("Controller switched successfully!")
# Non-blocking navigation
nav.navigate_to_goal(
goal, enable_collision_check=True, is_blocking=False, timeout=timeout_s
)
start = time.time()

while True:
status = nav.get_navigation_status()
elapsed = time.time() - start

if status == NavigationTaskStatus.SUCCESS:
print("Target reached")
break
if status == NavigationTaskStatus.FAILED:
print("Navigation failed; exit error-handling logic promptly")
break
if elapsed >= timeout_s:
print("navigationtimeout, exit")
break

if status == NavigationTaskStatus.RUNNING:
print(f"Navigating... Status: {status.name}, elapsed: {elapsed:.1f}s")
else:
print(f"Status: {status.name}, elapsed: {elapsed:.1f}s")

time.sleep(poll_interval_s)

nav.stop_navigation()
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()
print("Resources released successfully")

完整运行示例(简单流程)

适用场景:展示导航功能的完整使用流程,包括初始化、重定位、导航到目标等步骤,供参考。

examples/python/galbot_navigation/complete_example.py
from galbot_sdk.g1 import GalbotRobot, GalbotNavigation
from galbot_sdk.g1 import ControlStatus, G1ControllerName
import numpy as np
import time
import sys

robot = GalbotRobot()
robot.init()
nav = GalbotNavigation()
nav.init()

init_pose = np.array([0.0, 0.0, 0.0, 0, 0, 0.0, 1.0])
goal_pose = np.array([1.0, 0.0, 0.0, 0, 0, 0.0, 1.0])

res = robot.switch_controller(G1ControllerName.CHASSIS_POSE_CTRL)
if res != ControlStatus.SUCCESS:
print("Failed to switch controller!")
sys.exit(1)
else:
print("Controller switched successfully!")

while not nav.is_localized():
nav.relocalize(init_pose)
time.sleep(0.5)

if nav.check_path_reachability(goal_pose, nav.get_current_pose()):
nav.navigate_to_goal(
goal_pose, enable_collision_check=True, is_blocking=True, timeout=30
)
print("Whether reached:", nav.check_goal_arrival())

nav.stop_navigation()
# Shutdown system
robot.request_shutdown()
robot.wait_for_shutdown()
robot.destroy()

类:GalbotPerception

高精度双目深度估计,单次推理并保存伪彩色深度图

适用场景:触发一次双目深度估计推理,并获取推理结果

examples/python/galbot_perception/foundation_stereo_example.py
"""Foundation stereo depth example (G1): single run_once, save a pseudo-color depth image."""

import time

import cv2
import numpy as np

try:
from galbot_sdk import (
GalbotPerception,
GalbotRobot,
MachineType,
PerceptionModule,
)
except ImportError:
print("Failed to import galbot_sdk, please install it first or check if it is in PYTHONPATH")
raise

OUTPUT_IMAGE_PATH = "foundation_stereo_depth.png"


def main():
robot = GalbotRobot.get_instance(MachineType.G1)
if not robot.init():
print("Robot init failed")
return
print("Robot init OK")

perception = GalbotPerception.get_instance(MachineType.G1)
if not perception.init({PerceptionModule.FOUNDATION_STEREO, PerceptionModule.LIGHT_STEREO}):
print("Perception init failed")
return
print("Perception init OK")

time.sleep(12) # Wait for perception models to load
print("Triggering single inference...")

if not perception.run_once(PerceptionModule.FOUNDATION_STEREO):
print("run_once failed to send command")
return

print("Waiting for inference result...")
if not perception.wait_for_new_result(
PerceptionModule.FOUNDATION_STEREO, timeout_s=6.0
):
print("Timed out waiting for inference result")
return

ok, result = perception.get_latest_result(PerceptionModule.FOUNDATION_STEREO)
if not ok:
print("get_latest_result failed")
return

print(result.get_result_info())

depth_map = result.instance_mask
if depth_map is None:
print("No depth map (instance_mask is empty)")
return

print(f"Depth map shape: {depth_map.shape}, dtype: {depth_map.dtype}")
print(f"Depth value range: [{np.nanmin(depth_map)}, {np.nanmax(depth_map)}]")

depth_f = depth_map.astype(np.float32)
valid = depth_f[depth_f > 0]
if valid.size > 0:
vmin, vmax = np.percentile(valid, [1, 99])
normalized = np.clip((depth_f - vmin) / (vmax - vmin + 1e-6), 0, 1)
else:
normalized = np.zeros_like(depth_f)
colored = cv2.applyColorMap(
(normalized * 255).astype(np.uint8), cv2.COLORMAP_TURBO
)

if cv2.imwrite(OUTPUT_IMAGE_PATH, colored):
print(f"Saved: {OUTPUT_IMAGE_PATH}")
else:
print(f"Failed to save: {OUTPUT_IMAGE_PATH}")


if __name__ == "__main__":
main()
GalbotRobot.get_instance(MachineType.G1).request_shutdown()
GalbotRobot.get_instance(MachineType.G1).wait_for_shutdown()
GalbotRobot.get_instance(MachineType.G1).destroy()

类:Parameter

适用场景:创建运动规划参数对象,用于配置运动规划的各种参数如速度限制、加速度限制、规划时间等。

examples/python/galbot_motion/create_parameter.py
from galbot_sdk.g1 import Parameter, create_parameter, G1JointGroup

# Create Parameter via constructor and set options
p = Parameter()
p.set_blocking(True)
p.set_check_collision(False)
p.set_timeout(5.0)
p.set_actuate('with_chain_only')
p.set_tool_pose(False)
p.set_reference_frame('base_link')

p.joint_state = {
G1JointGroup.left_arm: [0.0] * 7,
# Can add others if needed:
# G1JointGroup.right_arm: [0.0] * 7,
# G1JointGroup.LEG: [0.0] * 4,
}

print('blocking:', p.get_blocking())
print('collision check:', p.get_check_collision())
print('timeout:', p.get_timeout())

# Or use factory function to quickly create Parameter
p2 = create_parameter(direct_execute=False, blocking=True, timeout=3.0, actuate='with_chain_only', tool_pose=False, check_collision=True)
print('Factory-created timeout:', p2.get_timeout())

辅助函数

check_motion_status

适用场景:检查运动规划执行结果状态,判断规划是否成功,打印错误信息。

examples/python/galbot_motion/check_motion_status.py
from galbot_sdk.g1 import MotionStatus, check_motion_status

status_str = check_motion_status(MotionStatus.SUCCESS)
print('MotionStatus string:', status_str)

create_joint_state / create_pose_state

适用场景:快速创建关节状态和位姿状态对象,方便运动规划接口调用。

examples/python/galbot_motion/create_pose_state.py
from galbot_sdk.g1 import create_joint_state, create_pose_state, JointStates, PoseState, Pose

# Create helper objects using the factory function
js = create_joint_state()
ps = create_pose_state()

# Fill example fields
js.chain_name = 'left_arm'
js.joint_positions = [0.0] * 7

ps.chain_name = 'left_arm'
# 7D vector: x, y, z, qx, qy, qz, qw
ps.pose = Pose([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0])

print(type(js), js.chain_name)
print(type(ps), ps.chain_name)