感知模块
量子 1 号 SDK 的头部与腕部相机、激光雷达、IMU、ToF、超声波和底盘深度点云接口。
感知模块提供机器人相机与环境传感器的单次读取和流式读取接口。处理流数据时,应主动控制资源释放、显示频率和写盘速度。
能力概览
-
头部相机系统接口:支持获取头部 RGB 图像、深度图像以及左右眼相机的 H.265 编码图像,提供单帧图像和实时图像流两种数据获取方式。
-
左右臂相机系统接口:支持获取左右臂相机的 RGB 图像及相关臂部相机的 H.265 编码图像,提供单帧图像和实时图像流两种数据获取方式。
-
激光雷达接口:支持获取激光扫描数据及实时激光扫描数据流,可用于环境感知、建图和定位等场景。
-
IMU 接口:支持获取底盘惯性测量数据、实时 IMU 数据流及 传感器运行状态。
-
距离传感器接口:支持获取底盘单点红外测距和超声波测距数据,并提供单次读取和实时数据流两种获取方式。
-
底盘前置深度相机接口:支持获取底盘前置深度相机生成的点云数据及实时点云数据流。
头部相机系统接口
get_rgb_image 接口介绍
获取头部 RGB 单帧图像,返回 CompressedImage。
说明: 本接口适用于提供头部 RGB 相机的构型。若当前设备使用双目相机构型且未配置头部 RGB 相机,接口会返回 UNAVAILABLE,请根据实际构型使用左眼或右眼相机接口。
| 字段 | 内容 |
|---|---|
| 函数名 | get_rgb_image() |
| 函数原型 | def get_rgb_image(timeout) -> sensor_msgs_.CompressedImage |
| 功能概述 | 获取单张 RGB 图像 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
将以下代码保存为 head_rgb_image.py:
from typing import Annotated
import cv2
import numpy as np
import typer
from x2robot import connect
def main(
server: Annotated[
str,
typer.Option(
help="SDK Server 地址,例如:192.168.10.1:50051"
),
] = "localhost:50051",
):
robot = connect(f"x2://{server}")
image = robot.head_camera.get_rgb_image()
if not image or not image.data:
raise RuntimeError("未获取到头部 RGB 图像数据")
image_array = np.frombuffer(
bytes(image.data),
dtype=np.uint8,
)
frame = cv2.imdecode(
image_array,
cv2.IMREAD_COLOR,
)
if frame is None:
raise RuntimeError(
f"无法解码头部 RGB 图像,"
f"format={image.format!r}"
)
window_name = "Head RGB"
try:
cv2.imshow(window_name, frame)
print("按任意键关闭图像窗口。")
cv2.waitKey(0)
finally:
cv2.destroyAllWindows()
if __name__ == "__main__":
typer.run(main)运行程序:
python3 head_rgb_image.py \
--server 192.168.10.1:50051get_depth_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_depth_image() |
| 函数原型 | def get_depth_image(timeout) -> sensor_msgs_.CompressedImage |
| 功能概述 | 获取单张深度图像 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
image = robot.head_camera.get_depth_image()get_rgb_video_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_rgb_video_stream() |
| 函数原型 | def get_rgb_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage] |
| 功能概述 | 获取 RGB 图像流 |
| 参数 | 无 |
| 返回值 | Iterator[CompressedImage] |
| 备注 | 无 |
示例:
images = robot.head_camera.get_rgb_video_stream()
for image in images:
# 处理响应
passget_depth_video_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_depth_video_stream() |
| 函数原型 | def get_depth_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage] |
| 功能概述 | 获取深度图像流 |
| 参数 | 无 |
| 返回值 | Iterator[CompressedImage] |
| 备注 | 无 |
示例:
images = robot.head_camera.get_depth_video_stream()
for image in images:
# 处理响应
passget_left_eye_image / get_right_eye_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_left_eye_image()get_right_eye_image() |
| 函数原型 | def get_left_eye_image(timeout) -> sensor_msgs_.CompressedImagedef get_right_eye_image(timeout) -> sensor_msgs_.CompressedImage |
| 功能概述 | 获取左眼或右眼相机的 H.265 编码图像,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
image = robot.head_camera.get_left_eye_image()get_left_eye_video_stream / get_right_eye_video_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_left_eye_video_stream()get_right_eye_video_stream() |
| 函数原型 | def get_left_eye_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage]def get_right_eye_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage] |
| 功能概述 | 获取左眼或右眼相机的 H.265 编码图像流,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | Iterator[CompressedImage] |
| 备注 | 无 |
示例:
images = robot.head_camera.get_left_eye_video_stream()
for image in images:
# 处理响应
pass左臂相机系统
get_raw_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_raw_image() |
| 函数原型 | 无 |
| 功能概述 | 单目相机构型机型:获取手腕相机单张 RGB 图像;双目相机构型机型:获取手腕相机 H.265 编码图像 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 |
示例:
image = robot.left_arm_camera.get_raw_image()get_video_stream 接口介绍
获取左臂腕部相机的实时视频流,返回 CompressedImage 迭代器。
| 字段 | 内容 |
|---|---|
| 函数名 | get_video_stream() |
| 函数原型 | 无 |
| 功能概述 | 单目相机构型机型:获取 手腕相机RGB 图像流 ;双目相机构型机型:获取 H.265 编码图像流 |
| 参数 | 无 |
| 返回值 | Iterator[CompressedImage] |
| 备注 |
示例:
images = robot.left_arm_camera.get_video_stream()
for image in images:
print(
f"format={image.format}, "
f"bytes={len(image.data)}"
)视频流会持续返回数据,可使用 Ctrl+C 停止。
get_elbow_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_elbow_image() |
| 函数原型 | def get_elbow_image(timeout) -> sensor_msgs_.CompressedImage |
| 功能概述 | 获取手腕相机的 H.265 编码图像,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
image = robot.left_arm_camera.get_elbow_image()get_elbow_video_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_elbow_video_stream() |
| 函数原型 | def get_elbow_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage] |
| 功能概述 | 获取手腕相机的 H.265 编码图像,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 |
示例:
images = robot.left_arm_camera.get_elbow_video_stream()
for image in images:
# 处理响应
pass右臂相机系统
get_raw_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_raw_image() |
| 函数原型 | 无 |
| 功能概述 | 单目相机构型机型:获取手腕相机单张 RGB 图像;双目相机构型机型:获取手腕相机 H.265 编码图像 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 |
示例:
image = robot.right_arm_camera.get_raw_image()get_video_stream 接口介绍
获取右臂腕部相机的实时视频流,返回 CompressedImage 迭代器。
| 字段 | 内容 |
|---|---|
| 函数名 | get_video_stream() |
| 函数原型 | 无 |
| 功能概述 | 单目相机构型机型:获取手腕相机 RGB 图像流;双目相机构型机型:获取 手腕相机H.265 编码图像流 |
| 参数 | 无 |
| 返回值 | Iterator[CompressedImage] |
| 备注 |
示例:
images = robot.right_arm_camera.get_video_stream()
for image in images:
print(
f"format={image.format}, "
f"bytes={len(image.data)}"
)视频流会持续返回数据,可使用 Ctrl+C 停止。
get_elbow_image 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_elbow_image() |
| 函数原型 | def get_elbow_image(timeout) -> sensor_msgs_.CompressedImage |
| 功能概述 | 获取手腕相机的 H.265 编码图像,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
image = robot.right_arm_camera.get_elbow_image()get_elbow_video_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_elbow_video_stream() |
| 函数原型 | def get_elbow_video_stream(timeout) -> Iterator[sensor_msgs_.CompressedImage] |
| 功能概述 | 获取手腕相机的 H.265 编码图像流,只支持双目相机构型的机型 |
| 参数 | 无 |
| 返回值 | CompressedImage |
| 备注 | 无 |
示例:
images = robot.right_arm_camera.get_elbow_video_stream()
for image in images:
# 处理响应
pass激光雷达传感器
get_laser_scan 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_laser_scan() |
| 函数原型 | def get_laser_scan(timeout) -> sensor_msgs_.LaserScan |
| 功能概述 | 获取激光雷达扫描数据 |
| 参数 | 无 |
| 返回值 | LaserScan |
| 备注 | 无 |
示例:
scan_data = robot.radar.get_laser_scan()
print(
f"Angle Range: "
f"[{scan_data.angle_min:.3f}, "
f"{scan_data.angle_max:.3f}] rad"
)
print(
f"Angle Increment: "
f"{scan_data.angle_increment:.6f} rad"
)
print(
f"Time Increment: "
f"{scan_data.time_increment:.9f} s"
)get_laser_scan_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_laser_scan_stream() |
| 函数原型 | def get_laser_scan_stream(timeout) -> Iterator[sensor_msgs_.LaserScan] |
| 功能概述 | 获取激光雷达扫描流数据 |
| 参数 | 无 |
| 返回值 | Iterator[LaserScan] |
| 备注 | 无 |
示例:
for scan_data in robot.radar.get_laser_scan_stream():
print(
f"Angle Range: "
f"[{scan_data.angle_min:.3f}, "
f"{scan_data.angle_max:.3f}] rad"
)
print(
f"Angle Increment: "
f"{scan_data.angle_increment:.6f} rad"
)
print(
f"Time Increment: "
f"{scan_data.time_increment:.9f} s"
)IMU 传感器
get_chassis_imu 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_imu() |
| 函数原型 | def get_chassis_imu(timeout) -> sensor_msgs_.Imu |
| 功能概述 | 获取底盘 IMU 数据 |
| 参数 | 无 |
| 返回值 | Imu |
| 备注 |
示例 :
imu_data = robot.imu.get_chassis_imu()
print(f"Orientation Quaternion: {imu_data.orientation}")
print(f"Angular Velocity: {imu_data.angular_velocity}")
print(f"Linear Acceleration: {imu_data.linear_acceleration}")get_chassis_imu_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_imu_stream() |
| 函数原型 | def get_chassis_imu_stream(timeout) -> Iterator[sensor_msgs_.Imu] |
| 功能概述 | 获取底盘 IMU 数据流 |
| 参数 | 无 |
| 返回值 | Iterator[Imu] |
| 备注 |
示例 :
for imu_data in robot.imu.get_chassis_imu_stream():
print(f"Orientation Quaternion: {imu_data.orientation}")
print(f"Angular Velocity: {imu_data.angular_velocity}")
print(f"Linear Acceleration: {imu_data.linear_acceleration}")ToF 单点红外传感器
get_chassis_tof1 / get_chassis_tof2 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_tof1()get_chassis_tof2() |
| 函数原型 | def get_chassis_tof_1(timeout=None) -> sensor_msgs_.Range |
| 功能概述 | 获取单点红外传感器数据 |
| 参数 | 无 |
| 返回值 | Range |
| 备注 |
示例 :
range_data = robot.tof.get_chassis_tof_1()
print(f"Distance: {range_data.range:.3f} m")
print(f"Radiation Type: {range_data.radiation_type}")
print(
f"Field of View: {range_data.field_of_view:.3f} rad "
f"({math.degrees(range_data.field_of_view):.1f}°)"
)
print(f"Min Range: {range_data.min_range:.2f} m")
print(f"Max Range: {range_data.max_range:.2f} m")get_chassis_tof1_stream / get_chassis_tof2_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_tof1_stream()get_chassis_tof2_stream() |
| 函数原型 | def get_chassis_tof_1_stream(timeout=None) -> Iterator[sensor_msgs_.Range] |
| 功能概述 | 获取单点红外传感器流数据 |
| 参数 | 无 |
| 返回值 | Iterator[Range] |
| 备注 |
示例 :
for range_data in robot.tof.get_chassis_tof_1_stream():
print(f"Distance: {range_data.range:.3f} m")
print(f"Radiation Type: {range_data.radiation_type}")
print(
f"Field of View: {range_data.field_of_view:.3f} rad "
f"({math.degrees(range_data.field_of_view):.1f}°)"
)
print(f"Min Range: {range_data.min_range:.2f} m")
print(f"Max Range: {range_data.max_range:.2f} m")超声波传感器
超声波传感器接口由 robot.ultrasonic 提供;robot.tof 只提供 ToF 单点红外传感器接口。
get_chassis_ultrasonic_1 ~ get_chassis_ultrasonic_4 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_ultrasonic_1()、get_chassis_ultrasonic_2()、get_chassis_ultrasonic_3()、get_chassis_ultrasonic_4() |
| 函数原型 | def get_chassis_ultrasonic_1(timeout=None) -> Range |
| 功能概述 | 获取底盘超声波传感器单次测距数据。 |
| 参数 | 无 |
| 返回值 | Range |
| 备注 | 共 4 路超声波传感器,通过方法名末尾的 1~4 选择对应传感器。 |
示例:
import math
range_data = (
robot.ultrasonic
.get_chassis_ultrasonic_1()
)
print(f"Distance: {range_data.range:.3f} m")
print(f"Radiation Type: {range_data.radiation_type}")
print(
f"Field of View: {range_data.field_of_view:.3f} rad "
f"({math.degrees(range_data.field_of_view):.1f}°)"
)
print(f"Min Range: {range_data.min_range:.2f} m")
print(f"Max Range: {range_data.max_range:.2f} m")读取其他超声波传感器时,将方法名中的数字替换为 2、3 或 4。
get_chassis_ultrasonic_1_stream ~ get_chassis_ultrasonic_4_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_ultrasonic_1_stream()、get_chassis_ultrasonic_2_stream()、get_chassis_ultrasonic_3_stream()、get_chassis_ultrasonic_4_stream() |
| 函数原型 | def get_chassis_ultrasonic_1_stream(timeout=None) -> Iterator[Range] |
| 功能概述 | 获取底盘超声波传感器实时测距数据流。 |
| 参数 | 无 |
| 返回值 | Iterator[Range] |
| 备注 | 流式接口会持续返回数据,可使用 Ctrl+C 停止。 |
示例:
import math
for range_data in (
robot.ultrasonic
.get_chassis_ultrasonic_1_stream()
):
print(f"Distance: {range_data.range:.3f} m")
print(f"Radiation Type: {range_data.radiation_type}")
print(
f"Field of View: {range_data.field_of_view:.3f} rad "
f"({math.degrees(range_data.field_of_view):.1f}°)"
)
print(f"Min Range: {range_data.min_range:.2f} m")
print(f"Max Range: {range_data.max_range:.2f} m")底盘前置深度相机系统
底盘前置深度相机点云接口由 robot.depth_points 提供。
get_chassis_depth_points 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_depth_points() |
| 函数原型 | def get_chassis_depth_points(timeout=None) -> PointCloud2 |
| 功能概述 | 获取底盘前置深度相机的单帧点云数据。 |
| 参数 | timeout:可选,RPC 超时时间,单位为秒;None 表示本次调用不显式设置超时。 |
| 返回值 | PointCloud2 |
| 备注 | SDK v1.1.2 返回数据中的 header 可能为空,不应直接假设 msg.header.frame_id 一定存在。 |
示例:
from x2robot import connect
robot = connect("x2://192.168.10.1:50051")
msg = robot.depth_points.get_chassis_depth_points(
timeout=5
)
print(f"width={msg.width}, height={msg.height}")
print(
f"point_step={msg.point_step}, "
f"row_step={msg.row_step}"
)
print(
"fields="
f"{[field.name for field in msg.fields]}"
)
print(f"data_bytes={len(msg.data)}")
print(f"is_dense={msg.is_dense}")
print(f"is_bigendian={msg.is_bigendian}")如果需要显示 frame_id,应先判断 header 是否存在:
frame_id = (
msg.header.frame_id
if msg.header is not None
else "<not provided>"
)
print(f"frame_id={frame_id}")get_chassis_depth_points_stream 接口介绍
| 字段 | 内容 |
|---|---|
| 函数名 | get_chassis_depth_points_stream() |
| 函数原型 | def get_chassis_depth_points_stream(timeout=None) -> Iterator[PointCloud2] |
| 功能概述 | 获取底盘前置深度相机的点云数据流。 |
| 参数 | timeout:可选,整个流式 RPC 的超时时间,单位为秒;None 表示不显式设置超时。 |
| 返回值 | Iterator[PointCloud2] |
| 备注 | 接口会持续返回点云数据,可使用 Ctrl+C 停止。返回数据中的 header 可能为空。 |
示例:
from x2robot import connect
robot = connect("x2://192.168.10.1:50051")
try:
for msg in (
robot.depth_points
.get_chassis_depth_points_stream(
timeout=None
)
):
print(
f"width={msg.width}, "
f"height={msg.height}, "
f"data_bytes={len(msg.data)}"
)
except KeyboardInterrupt:
print("Depth point stream stopped.")如需解析 PointCloud2 中每个点的 x、y、z 坐标,请使用 SDK 中的完整示例,不要只复制解析循环中的局部代码。
运行完整点云示例:
# 单次读取和解析
python3 examples/depth_points.py --action single --server 192.168.10.1:50051
# 流式读取和解析
python3 examples/depth_points.py --action stream --server 192.168.10.1:50051