syntax = "proto3"; package cmvr.api.armteleop.v1; // Versioned, session-oriented protocol for wired arm teleoperation. Existing // unary ArmService RPCs intentionally remain unchanged. service ArmTeleopService { rpc Teleoperate(stream ClientFrame) returns (stream ServerFrame); } enum SessionPhase { SESSION_PHASE_UNSPECIFIED = 0; SESSION_PHASE_OPENED = 1; SESSION_PHASE_READY = 2; SESSION_PHASE_ACTIVE = 3; SESSION_PHASE_HOLDING = 4; SESSION_PHASE_STOPPED = 5; SESSION_PHASE_WATCHDOG_EXPIRED = 6; SESSION_PHASE_LEASE_LOST = 7; SESSION_PHASE_REJECTED = 8; SESSION_PHASE_FAILED = 9; } enum StopReason { STOP_REASON_UNSPECIFIED = 0; STOP_REASON_OPERATOR_REQUEST = 1; STOP_REASON_CLIENT_SHUTDOWN = 2; STOP_REASON_WATCHDOG = 3; STOP_REASON_LEASE_REVOKED = 4; STOP_REASON_ROBOT_FAULT = 5; STOP_REASON_EMERGENCY_STOP = 6; STOP_REASON_PROTOCOL_ERROR = 7; } enum EffortSource { EFFORT_SOURCE_UNSPECIFIED = 0; EFFORT_SOURCE_MOTOR_ESTIMATE = 1; EFFORT_SOURCE_JOINT_SENSOR = 2; EFFORT_SOURCE_FORCE_TORQUE_SENSOR = 3; EFFORT_SOURCE_OBSERVER = 4; } message RobotManifest { string robot_id = 1; string model_sha256 = 2; string calibration_sha256 = 3; repeated string joint_names = 4; string position_unit = 5; string velocity_unit = 6; string effort_unit = 7; string base_frame = 8; string tool_frame = 9; } message OpenSession { uint32 protocol_major = 1; uint32 protocol_minor = 2; string client_instance_id = 3; RobotManifest expected_robot = 4; uint32 requested_command_rate_hz = 5; uint32 requested_state_rate_hz = 6; uint32 watchdog_timeout_ms = 7; uint32 requested_lease_ms = 8; bool request_force_feedback = 9; } message JointSetpoint { // Strictly increasing and non-zero within a session. uint64 sequence = 1; repeated double position_rad = 2; repeated double velocity_rad_s = 3; // The receiver computes its deadline from local arrival time plus this // duration. Zero is invalid for an active setpoint. uint32 valid_for_us = 4; } message ClientHeartbeat { uint64 sequence = 1; } message StopSession { StopReason reason = 1; string detail = 2; } message ClientFrame { oneof payload { OpenSession open = 1; JointSetpoint setpoint = 2; ClientHeartbeat heartbeat = 3; StopSession stop = 4; } } message JointState { uint64 sample_sequence = 1; repeated double position_rad = 2; repeated double velocity_rad_s = 3; repeated double effort_nm = 4; bool position_valid = 5; bool velocity_valid = 6; bool effort_valid = 7; EffortSource effort_source = 8; uint64 sample_age_us = 9; } message SessionStatus { string session_id = 1; SessionPhase phase = 2; uint64 received_sequence = 3; uint64 applied_sequence = 4; uint64 dropped_setpoints = 5; uint64 rejected_setpoints = 6; uint32 negotiated_watchdog_ms = 7; uint32 lease_remaining_ms = 8; StopReason stop_reason = 9; string detail = 10; } message RobotSafetyState { bool connected = 1; bool powered_on = 2; bool protective_stopped = 3; bool emergency_stopped = 4; bool fault = 5; string fault_detail = 6; } message ServerFrame { SessionStatus status = 1; JointState joint_state = 2; RobotSafetyState safety = 3; }