pub struct VisionClient { /* private fields */ }Expand description
ctx.vision — the vision engine facade.
Cloning shares the one underlying IPC client. The ring resolver caches each
camera’s mapped /dev/shm region keyed by shm_name so a steady frame
stream maps each ring once, not once per frame.
Implementations§
Source§impl VisionClient
impl VisionClient
Sourcepub fn with_shm_dir(self, dir: impl Into<PathBuf>) -> Self
pub fn with_shm_dir(self, dir: impl Into<PathBuf>) -> Self
Resolve frame rings under dir instead of /dev/shm, with an empty
ring cache. Mirrors the Python client’s shm_dir; the engine’s
counterpart is ADOS_SHM_DIR. Call before subscribing: an existing
subscription keeps the cache it was registered with.
Sourcepub async fn subscribe_frames(
&self,
camera_id: Option<&str>,
callback: FrameCallback,
) -> Result<(), ClientError>
pub async fn subscribe_frames( &self, camera_id: Option<&str>, callback: FrameCallback, ) -> Result<(), ClientError>
Subscribe to frames, optionally filtered to one camera_id. The host
delivers matching frame descriptors as vision.deliver events; this
client resolves each to pixels and invokes callback with the Frame.
Registers a frame callback on the client’s vision.deliver path (keyed
on camera_id), then sends the methods::SUBSCRIBE_FRAMES RPC (gated
on vision.frame.read) so the engine starts or widens the stream. A
camera_id of None receives every camera’s frames; a Some(id) filter
is applied at the engine and, as a backstop, in the resolver. The
vision.deliver push carries the descriptor in a descriptor binary arg
(no topic), so it does not use the event.subscribe topic path.
Sourcepub async fn register_model(
&self,
model: &ModelMetadata,
) -> Result<Value, ClientError>
pub async fn register_model( &self, model: &ModelMetadata, ) -> Result<Value, ClientError>
Register an inference model with the engine. Sends
methods::REGISTER_MODEL (gated on vision.model.register) in the
vision_rpc shape the engine decodes. The engine files it as
<plugin_id>/<id> (the reply’s model_id), so it never replaces the
node’s own models or another plugin’s; a plugin holds at most eight. An
engine-run model’s model_path must be a model delivered to this plugin
(see Self::resolved_model).
Sourcepub async fn resolved_model(&self) -> Result<Vec<ModelResolution>, ClientError>
pub async fn resolved_model(&self) -> Result<Vec<ModelResolution>, ClientError>
Read this plugin’s resolved model-delivery status: one
ModelResolution per declared model, keyed by model_id. This is the
model-delivery last mile — a plugin loads its detector from the resolved
path. Sends methods::READ_MODEL (gated on vision.model.read); an
unresolved plugin returns an empty list rather than erroring, so a caller
can poll until its model resolves.
Sourcepub async fn infer(
&self,
model_id: &str,
frame: &Frame,
) -> Result<Vec<Detection>, ClientError>
pub async fn infer( &self, model_id: &str, frame: &Frame, ) -> Result<Vec<Detection>, ClientError>
Run a registered model against one frame on the shared backend and
return its detections. Sends methods::INFER (gated on
vision.model.register); the engine arbitrates access to the
accelerator. model_id names this plugin’s own model or one of the
node’s configured models. The frame is passed by descriptor (the engine
reads its own ring), so no pixels cross the RPC envelope. A frame whose
slot the ring has since recycled is an error; infer on a fresher frame.
Sourcepub async fn publish_detection(
&self,
batch: &DetectionBatch,
) -> Result<Value, ClientError>
pub async fn publish_detection( &self, batch: &DetectionBatch, ) -> Result<Value, ClientError>
Publish a detection batch on vision.detection. Sends
methods::PUBLISH_DETECTION (gated on vision.detection.publish) in
the vision_rpc shape the engine decodes. Subscribers see its
model_id as
<plugin_id>/<model_id>, and lock_state / track_id are cleared
unless this plugin also holds vision.track.designate.
Sourcepub async fn publish_one(
&self,
model_id: &str,
frame: &Frame,
detection: Detection,
) -> Result<Value, ClientError>
pub async fn publish_one( &self, model_id: &str, frame: &Frame, detection: Detection, ) -> Result<Value, ClientError>
Publish a single detection against one frame, building the
DetectionBatch from the frame’s source camera and id. A convenience
over publish_detection for the common
one-box-per-frame case.
Sourcepub async fn advertise_offload(
&self,
advert: &OffloadAdvertisement,
) -> Result<Value, ClientError>
pub async fn advertise_offload( &self, advert: &OffloadAdvertisement, ) -> Result<Value, ClientError>
Report the perception-offload link this plugin holds, so the node’s
perception tier reads offload while it is live. Re-advertise at least
every ~10 s (the link goes stale after 20 s) and send paired: false
when the link drops. Gated on vision.offload.advertise. See
PluginIpcClient::offload_advertise.
Sourcepub async fn register_vio_component(&self) -> Result<Value, ClientError>
pub async fn register_vio_component(&self) -> Result<Value, ClientError>
Register this plugin as the visual-odometry MAVLink component so the FC
attributes injected pose to a vision source. Call once before
inject_pose / inject_odometry.
Sourcepub async fn inject_pose(&self, pose: &Pose) -> Result<Value, ClientError>
pub async fn inject_pose(&self, pose: &Pose) -> Result<Value, ClientError>
Build a VISION_POSITION_ESTIMATE from pose and send it to the FC over
the host’s MAVLink path under the visual-odometry component id. Replaces
hand-built MAVLink frames in VIO plugins.
Sourcepub async fn inject_odometry(
&self,
odometry: &Odometry,
) -> Result<Value, ClientError>
pub async fn inject_odometry( &self, odometry: &Odometry, ) -> Result<Value, ClientError>
Build an ODOMETRY message from odometry (pose plus body-frame twist)
and send it to the FC under the visual-odometry component id.
Sourcepub async fn subscribe_detections(
&self,
camera_id: Option<&str>,
callback: DetectionCallback,
) -> Result<(), ClientError>
pub async fn subscribe_detections( &self, camera_id: Option<&str>, callback: DetectionCallback, ) -> Result<(), ClientError>
Receive the engine’s detection batches.
camera_id of None receives every camera. The engine fans all cameras
onto one stream, so a Some(id) filter is applied here rather than
narrowed at the engine — matching the frame subscription and the Python
client.
A batch that will not decode is dropped rather than surfaced: the wire carries a version and an older producer round-trips, so an undecodable batch means a genuinely broken frame, not a version skew the caller could act on.
Sourcepub async fn designate_track(
&self,
camera_id: &str,
detection: &Detection,
) -> Result<Value, ClientError>
pub async fn designate_track( &self, camera_id: &str, detection: &Detection, ) -> Result<Value, ClientError>
Lock the tracker onto a specific detection, overriding its auto-lock.
This is the operator-designation path: the engine presents a lock state only for a track a caller designated, so this is what makes a lock mean “the target that was chosen” rather than “whatever scored highest”. The detection’s box, label and confidence cross; it must carry a box.