diff --git a/cmvr/__init__.py b/cmvr/__init__.py index 4294e61..6f31244 100644 --- a/cmvr/__init__.py +++ b/cmvr/__init__.py @@ -2,7 +2,7 @@ from .client import CMVRGrpcClient from .enums import CMVRErrorCode, DeviceState, FingerType from .models import ( MicState, SpeakerState, CameraState, - RH56DFTPDexHand, DexHandState, FacialExpressionState, + FreedomState, DexHandState, FacialExpressionState, FingerTactileData, PalmTactileData, HandTactileSensors ) @@ -10,6 +10,6 @@ __all__ = [ 'CMVRGrpcClient', 'CMVRErrorCode', 'DeviceState', 'FingerType', 'MicState', 'SpeakerState', 'CameraState', - 'RH56DFTPDexHand', 'DexHandState', 'FacialExpressionState', + 'FreedomState', 'DexHandState', 'FacialExpressionState', 'FingerTactileData', 'PalmTactileData', 'HandTactileSensors' ] \ No newline at end of file diff --git a/cmvr/camera_client.py b/cmvr/camera_client.py index 66d01fa..26bea1a 100644 --- a/cmvr/camera_client.py +++ b/cmvr/camera_client.py @@ -6,7 +6,7 @@ from typing import Tuple from .enums import CMVRErrorCode from .models import CameraState - +from .models import Rs2Intrinsics class CameraClient: """相机客户端""" @@ -116,6 +116,23 @@ class CameraClient: # 将字节数据转换为numpy数组 img_data = np.frombuffer(response.color_frame.data, dtype=np.uint8) + + # 从 Protobuf 消息中读取 intrinsics 数据 + protobuf_intrinsics = response.intrinsics + + # 构造 Python 数据类对象(字段名称完全对应) + python_intrinsics = Rs2Intrinsics( + cx=protobuf_intrinsics.cx, + cy=protobuf_intrinsics.cy, + fx=protobuf_intrinsics.fx, + fy=protobuf_intrinsics.fy, + coeffs=list(protobuf_intrinsics.coeffs) # Protobuf repeated 字段通常是列表类型,直接转换 + ) + + # 示例:访问读取后的数据 + print(f"主点坐标: ({python_intrinsics.cx}, {python_intrinsics.cy})") + print(f"焦距: ({python_intrinsics.fx}, {python_intrinsics.fy})") + print(f"畸变系数: {python_intrinsics.coeffs}") # 重塑为图像格式 (height, width, channels) channels = 3 # 假设是RGB图像 if size == width * height * channels: diff --git a/cmvr/dexhand_client.py b/cmvr/dexhand_client.py index a0de0b0..d15fb34 100644 --- a/cmvr/dexhand_client.py +++ b/cmvr/dexhand_client.py @@ -4,7 +4,7 @@ from typing import Tuple from typing import Dict from .enums import CMVRErrorCode, FingerType -from .models import DexHandState, RH56DFTPDexHand, HandTactileSensors +from .models import DexHandState, FreedomState, HandTactileSensors class DexHandClient: """灵巧手客户端""" @@ -57,7 +57,7 @@ class DexHandClient: # 填充手指状态 for i, hand_state in enumerate(response.state.hands): if i < len(state.hands): - state.hands[i] = RH56DFTPDexHand( + state.hands[i] = FreedomState( angle=hand_state.angle, speed=hand_state.speed, force=hand_state.force, diff --git a/cmvr/models.py b/cmvr/models.py index c6f9c74..26d8ffb 100644 --- a/cmvr/models.py +++ b/cmvr/models.py @@ -30,9 +30,18 @@ class CameraState: width: int = 0 height: int = 0 fps: int = 0 +@dataclass +class CameraIntrinsics: + """相机内参(与Protobuf Rs2Intrinsics对齐)""" + cx: float = 0.0 # 对应Protobuf tag=1 + cy: float = 0.0 # 对应Protobuf tag=2 + fx: float = 0.0 # 对应Protobuf tag=3 + fy: float = 0.0 # 对应Protobuf tag=4 + # 畸变系数:固定5个元素(k1, k2, p1, p2, k3),与Protobuf tag=5对齐 + coeffs: List[float] = field(default_factory=lambda: [0.0]*5) @dataclass -class RH56DFTPDexHand: +class FreedomState: """灵巧手自由度状态""" dof_id: int = 0 angle: int = 0 @@ -48,7 +57,7 @@ class RH56DFTPDexHand: class DexHandState: """灵巧手整体状态""" is_initialized: bool = False - hands: List[RH56DFTPDexHand] = field(default_factory=lambda: [RH56DFTPDexHand() for _ in range(6)]) + hands: List[FreedomState] = field(default_factory=lambda: [FreedomState() for _ in range(6)]) @dataclass class FacialExpressionState: diff --git a/examples/example_usage.py b/examples/example_usage.py index 733d789..1fd4846 100644 --- a/examples/example_usage.py +++ b/examples/example_usage.py @@ -659,8 +659,8 @@ def test_microphone(): print(f"开始录音失败,错误码: {result}") if __name__ == "__main__": - test_biohead() - # test_camera() + # test_biohead() + test_camera() # test_rgb_image_stream() # test_dexhand() # test_sensor_data_stream() diff --git a/protos/cmvr/api/camera_command.proto b/protos/cmvr/api/camera_command.proto index 36dfe9a..03a8f35 100644 --- a/protos/cmvr/api/camera_command.proto +++ b/protos/cmvr/api/camera_command.proto @@ -21,6 +21,14 @@ message FrameData { bool is_key_frame = 6; } +message CameraIntrinsics { + float cx = 1; // 主点水平坐标(从左边缘的像素偏移) + float cy = 2; // 主点垂直坐标(从上边缘的像素偏移) + float fx = 3; // x方向焦距(像素宽度的倍数) + float fy = 4; // y方向焦距(像素高度的倍数) + repeated float coeffs = 5 [packed = true]; // 畸变系数(固定5个元素) +} + message CameraState { bool is_initialized = 1; bool is_opened = 2; @@ -71,6 +79,7 @@ message GetRGBImageCommand { message Feedback { CommandHeader.Feedback header = 1; FrameData color_frame = 2; + CameraIntrinsics intrinsics = 3; } } @@ -82,6 +91,7 @@ message GetDepthImageCommand { message Feedback { CommandHeader.Feedback header = 1; FrameData depth_frame = 2; + CameraIntrinsics intrinsics = 3; } } @@ -94,6 +104,7 @@ message GetRGBDImagesCommand { CommandHeader.Feedback header = 1; FrameData color_frame = 2; FrameData depth_frame = 3; + CameraIntrinsics intrinsics = 4; } } @@ -126,7 +137,8 @@ message GetRGBImageStreamCommand { message Feedback { CommandHeader.Feedback header = 1; FrameData color_frame = 2; - int32 seq_no = 3; + CameraIntrinsics intrinsics = 3; + int32 seq_no = 4; } } @@ -139,7 +151,8 @@ message GetDepthImageStreamCommand { message Feedback { CommandHeader.Feedback header = 1; FrameData depth_frame = 2; - int32 seq_no = 3; + CameraIntrinsics intrinsics = 3; + int32 seq_no = 4; } } @@ -153,7 +166,8 @@ message GetRGBDImagesStreamCommand { CommandHeader.Feedback header = 1; FrameData color_frame = 2; FrameData depth_frame = 3; - int32 seq_no = 4; + CameraIntrinsics intrinsics = 4; + int32 seq_no = 5; } } diff --git a/protos/cmvr/api/common.proto b/protos/cmvr/api/common.proto index 19c35bd..0bea15c 100644 --- a/protos/cmvr/api/common.proto +++ b/protos/cmvr/api/common.proto @@ -28,3 +28,16 @@ message CommandHeader { google.protobuf.Timestamp timestamp = 3; // 回复时间 } } + +message ConfigParam { + + string param_name = 1; + + oneof param_value { + int32 int_value = 2; // 整数类型 + double double_value = 3; // 浮点数类型 + string string_value = 4; // 字符串类型 + bool bool_value = 5; // 布尔类型 + bytes bytes_value = 6; // 二进制数据类型 + } +} \ No newline at end of file diff --git a/protos/cmvr/api/dexhand_command.proto b/protos/cmvr/api/dexhand_command.proto index 5e89c97..9d65a7f 100644 --- a/protos/cmvr/api/dexhand_command.proto +++ b/protos/cmvr/api/dexhand_command.proto @@ -9,7 +9,7 @@ message FreedomValue { float value = 2; // 值 0-1百分比 } -message RH56DFTPDexHand { +message FreedomState { int32 dof_id = 1; // 自由度ID,唯一标识不同的关节或自由度 int32 angle = 2; // 自由度角度 int32 speed = 3; // 自由度速度 @@ -57,7 +57,7 @@ message SensorData { message DexHandState { bool is_initialized = 1; // 是否初始化 - repeated RH56DFTPDexHand hands = 2; // 包含多个自由度状态 + repeated FreedomState hands = 2; // 包含多个自由度状态 } message GetDexHandStateCommand { diff --git a/protos/cmvr/api/system_command.proto b/protos/cmvr/api/system_command.proto index 7498dd6..668bc9d 100644 --- a/protos/cmvr/api/system_command.proto +++ b/protos/cmvr/api/system_command.proto @@ -48,3 +48,12 @@ message GetSystemStatusCommand { repeated DeviceList device_list = 7; } } + +message UpdateParamsCommand { + message Request {} + + message Feedback { + CommandHeader.Feedback header = 1; + repeated ConfigParam params = 2; + } +} diff --git a/protos/cmvr/api/system_service.proto b/protos/cmvr/api/system_service.proto index 3ae6654..e46a728 100644 --- a/protos/cmvr/api/system_service.proto +++ b/protos/cmvr/api/system_service.proto @@ -8,4 +8,7 @@ package cmvr.api; service SystemService { rpc GetSystemInfo(GetSystemInfoCommand.Request) returns (GetSystemInfoCommand.Feedback) {} rpc GetSystemStatus(GetSystemStatusCommand.Request) returns (GetSystemStatusCommand.Feedback) {} + + rpc UpdateParams(UpdateParamsCommand.Request) returns (UpdateParamsCommand.Feedback) {} + } \ No newline at end of file