Skip to main content

ISkeletonClient

interface thread-safe
namespace AR51.Net;

public interface ISkeletonClient

Live skeletons of the people the AR 51 system tracks. Use it through IAR51Client.Skeletons, or on its own as a SkeletonClient with the skeleton service's address.

Two ways to receive skeletons: call StartAsync and handle SkeletonReceived, or read StreamAsync with await foreach. All members are safe to use from any thread.

Units

Positions are in meters, in the AR 51 world: left-handed, X right, Y up, Z forward (the same axes as Unity). See Data conventions.

How-to

This page is reference (facts only). For a walkthrough with a complete sample, see the Skeletons guide.

Properties​

PropertyTypeAccessDescription
IsAvailableboolgettrue when the skeleton service's address is known (always, for a standalone SkeletonClient).

Method summary​

→ Full descriptions in Method details below.

Events​

Standard .NET events (EventHandler<T>): subscribe with +=, unsubscribe with -=. They are raised on a background thread.

EventArgsRaised when
SkeletonReceivedSkeletonEventArgsRaised for every skeleton received while started, on a background thread. Keep handlers short: they run on the receiving thread. An exception thrown by a handler is logged and does not stop the others or the stream.
Example
ar51.Skeletons.SkeletonReceived += (_, e) =>
{
// Background thread: copy what you need and return quickly.
Vector3 nose = e.Skeleton.GetPosition(Joint.Nose);
Console.WriteLine($"{e.Skeleton.Id}: nose at {nose} m");
};

Method details​

StartAsync​

method
Task StartAsync(CancellationToken cancellationToken = default);

Starts receiving skeletons into SkeletonReceived. Returns at once; calling it again does nothing.

Parameters
cancellationTokenCancellationTokenIgnored. Optional.
ReturnsTaskA completed task.
Throws
ObjectDisposedExceptionThe client was disposed.
note

Receiving begins as soon as the skeleton service is reachable, and resumes by itself after the service restarts or the network drops, until StopAsync or dispose.

StopAsync​

method
Task StopAsync(CancellationToken cancellationToken = default);

Stops receiving skeletons: stops SkeletonReceived, ends every StreamAsync loop running now, and waits until the event stream is closed. Calling it again does nothing.

Parameters
cancellationTokenCancellationTokenStops waiting for the stream to close; the stream still closes. Optional.
ReturnsTaskA task that completes when the event stream is closed.
note

StreamAsync loops end normally, without an exception, after the skeleton they are handling. Loops started after this call are not affected.

StreamAsync​

method
IAsyncEnumerable<Skeleton> StreamAsync(CancellationToken cancellationToken = default);

Streams skeletons until StopAsync is called (the loop ends normally), cancellationToken is cancelled, or the connection drops. Works without StartAsync.

Parameters
cancellationTokenCancellationTokenStops the stream. Optional.
ReturnsIAsyncEnumerable<Skeleton>Skeletons in the order they arrive.
Throws
AR51ExceptionThe skeleton service is not available, or the stream failed.
OperationCanceledExceptioncancellationToken was cancelled.
ObjectDisposedExceptionThe client was disposed.
note

Each call opens its own stream, which closes when the loop ends. Unlike SkeletonReceived, it does not reconnect: start a new loop after an AR51Exception.

Example
using var stop = new CancellationTokenSource(TimeSpan.FromSeconds(10));
try
{
await foreach (Skeleton skeleton in ar51.Skeletons.StreamAsync(stop.Token))
Console.WriteLine($"{skeleton.Id} at {skeleton.GetPosition(Joint.MidHip)} m");
}
catch (OperationCanceledException)
{
// ten seconds are up
}

Small types used by this interface, documented here.

SkeletonEventArgs​

class · sealed
public sealed class SkeletonEventArgs : EventArgs

Data for ISkeletonClient.SkeletonReceived.

PropertyTypeAccessDescription
SkeletonSkeletongetThe received skeleton.
Constructor
public SkeletonEventArgs(Skeleton skeleton);

Creates the event data.

See also​

Was this page helpful?