Skip to main content

PiperDiagnostics

Struct PiperDiagnostics 

Source
pub struct PiperDiagnostics { /* private fields */ }
Expand description

高级诊断接口(逃生舱)

§持有 Arc 引用计数指针

PiperDiagnostics 持有 Arc<piper_driver::Piper>

  • 轻量级克隆(仅增加引用计数)
  • 独立生命周期,不受原始 Piper 实例约束
  • 可以安全地跨线程传递

§参考设计

这与 Rust 社区成熟库的逃生舱设计一致:

  • reqwest::Client:持有 Arc<ClientInner>,可跨线程
  • tokio::runtime::Handle:持有 Arc<Runtime>,独立生命周期

Implementations§

Source§

impl PiperDiagnostics

Source

pub fn register_callback(&self, callback: Arc<dyn FrameCallback>) -> Result<()>

注册自定义 FrameCallback

§性能要求

回调会在 Driver 层的 RX 线程中执行,必须保证:

  • 执行时间 <1μs
  • 不阻塞
  • 线程安全(Send + Sync)
§示例
let robot = PiperBuilder::new()
    .interface("can0")
    .build()?;

let active = robot.enable_position_mode(Default::default())?;
let diag = active.diagnostics();

let (hook, _rx) = AsyncRecordingHook::new();
diag.register_callback(Arc::new(hook))?;
Source

pub fn send_frame(&self, frame: &PiperFrame) -> Result<()>

发送原始 CAN 帧

§⚠️ 安全警告

严禁在 Active 状态下发送控制指令帧(0x1A1-0x1FF)。 这会导致与驱动层的周期性发送任务产生双控制流冲突。

§允许的使用场景
  • ✅ Standby 状态:发送配置帧(0x5A1-0x5FF)
  • ✅ ReplayMode:回放预先录制的帧
  • ✅ 调试:发送测试帧
§禁止的使用场景
  • Active<MIT>:发送 0x1A1-0x1A6(位置/速度/力矩指令)
  • Active<Position>: 发送 0x1A1-0x1A6
§示例
let robot = PiperBuilder::new()
    .interface("can0")
    .build()?;

let active = robot.enable_position_mode(Default::default())?;
let diag = active.diagnostics();

// 发送配置帧(安全)
let frame = PiperFrame {
    id: 0x5A1,
    data: [0, 1, 2, 3, 4, 5, 6, 7],
    len: 8,
    is_extended: false,
    timestamp_us: 0,
};
diag.send_frame(&frame)?;
Source

pub fn driver(&self) -> Arc<Piper>

获取 driver 实例的 Arc 克隆(完全访问)

§⚠️ 高级逃生舱

此方法提供对底层 piper_driver::Piper 的完全访问。 仅用于极端特殊场景,99% 的情况下应该使用上面的 register_callbacksend_frame

§使用前提

你必须完全理解以下文档:

  • piper_driver 模块文档
  • 类型状态机设计
  • Driver 层 IO 线程模型
§安全保证

返回的是 Arc 引用计数指针,而非不可变引用:

  • ✅ 可以跨线程传递
  • ✅ 可以长期持有
  • ❌ 无法直接调用 enable/disable(这些方法需要 &mut self
§示例
let robot = PiperBuilder::new()
    .interface("can0")
    .build()?;

let active = robot.enable_position_mode(Default::default())?;
let diag = active.diagnostics();

// 获取完全访问权限(仅在极端特殊场景使用)
let driver = diag.driver();

// 访问底层 hooks
let hooks = driver.hooks();

Trait Implementations§

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more