From db1ba9c369f2d37107d08bc21bdf719d55b09278 Mon Sep 17 00:00:00 2001 From: Nils Hasler Date: Mon, 1 Jul 2024 08:32:54 +0200 Subject: [PATCH] more examples --- CMakeLists.txt | 10 ++++++ README.md | 8 +++++ examples/callback.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++ examples/curves.cpp | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 examples/callback.cpp create mode 100644 examples/curves.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ab3901..a1a4216 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,3 +69,13 @@ find_package(Threads REQUIRED) add_executable(PollingExample examples/polling.cpp) target_include_directories(PollingExample PRIVATE ".") target_link_libraries(PollingExample RemoteCapturyStatic Threads::Threads) + +add_executable(CallbackExample examples/callback.cpp) +target_include_directories(CallbackExample PRIVATE ".") +target_link_libraries(CallbackExample RemoteCapturyStatic Threads::Threads) + +add_executable(CurvesExample examples/curves.cpp) +target_include_directories(CurvesExample PRIVATE ".") +target_link_libraries(CurvesExample RemoteCapturyStatic Threads::Threads) + +add_custom_target(Examples DEPENDS PollingExample CallbackExample CurvesExample) diff --git a/README.md b/README.md index eaded4f..9a70377 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ We use CMake for configuring the build process. There are two main targets `Remo If Python3 is available the additional target `RemoteCapturyPython` can be built. If the Android NDK can be found `RemoteCapturyAndroid` can also be built. This last target actually builds four versions of the RemoteCaptury library for the following platforms: `arm64-v8a`, `armeabi-v7a`, `x86`, and `x86_64`. +Here are the quickstart commands: + ``` git clone https://github.com/thecaptury/RemoteCaptury.git mkdir RemoteCaptury/build && cd RemoteCaptury/build @@ -19,6 +21,12 @@ cmake .. cmake --build . -- RemoteCaptury ``` +You can build all examples like this: + +``` +cmake --build . -- Examples +``` + ## Using There are primarily two ways of using the library: diff --git a/examples/callback.cpp b/examples/callback.cpp new file mode 100644 index 0000000..6a5ff17 --- /dev/null +++ b/examples/callback.cpp @@ -0,0 +1,81 @@ +#include +#include "RemoteCaptury.h" +#ifndef WIN32 +#include +#endif + +// This example uses the callback interface to get the current pose of all actors from CapturyLive + + + +// This callback is called every time a new pose becomes available. +// Make sure this callback is quick. Otherwise frames may get dropped. +void newPoseCallback(CapturyActor* actor, CapturyPose* pose, int trackingQuality) +{ + Captury_log(CAPTURY_LOG_INFO, "actor %x has a new pose now\n", actor->id); +} + +// this is called whenever an actor changes state (starts or stops tracking or finishes scaling or is deleted). +// Make sure this callback is quick. Otherwise frames may get dropped. +void actorChangedCallback(int actorId, int mode) +{ + Captury_log(CAPTURY_LOG_INFO, "actor %x has state %s now\n", actorId, CapturyActorStatusString[mode]); + + switch (mode) { + case ACTOR_SCALING: + break; + case ACTOR_TRACKING: + break; + case ACTOR_STOPPED: + break; + case ACTOR_DELETED: + break; + case ACTOR_UNKNOWN: + break; + } + + const CapturyActor* actor = Captury_getActor(actorId); + // do something with it +} + +int main(int argc, char** argv) +{ + // This is cheating a little as we're not connecting to a remote machine + // but you can change the IP. There is also a more advanced version of Captury_connect() that gives you more options + // to control ports or to enable asynchronous connect mode. + int ret = Captury_connect("127.0.0.1", 2101); + if (ret == 0) + return -1; + + // This is optional but sometimes it's quite useful to know the exact time on the CapturyLive machine. + // The accuracy of the synchronization depends primarily on your OS and the network topology between + // the CapturyLive machine and this machine. On a LAN running Windows on the target machine you can + // expect about 100us accuracy. + Captury_startTimeSynchronizationLoop(); + + // register callback that is called in a different thread whenever a new pose becomes available + ret = Captury_registerNewPoseCallback(newPoseCallback); + if (ret == 0) + return -1; + + ret = Captury_registerActorChangedCallback(actorChangedCallback); + if (ret == 0) + return -1; + + // start streaming + // The recommended features are CAPTURY_STREAM_POSES and CAPTURY_STREAM_COMPRESSED. + // Additional flags should be added as required. + Captury_startStreaming(CAPTURY_STREAM_POSES | CAPTURY_STREAM_COMPRESSED); + + #ifdef WIN32 + Sleep(100000); + #else + usleep(100000*1000); + #endif + + Captury_stopStreaming(); + + Captury_disconnect(); + + return 0; +} diff --git a/examples/curves.cpp b/examples/curves.cpp new file mode 100644 index 0000000..da56d9f --- /dev/null +++ b/examples/curves.cpp @@ -0,0 +1,61 @@ +#include +#include "RemoteCaptury.h" +#ifndef WIN32 +#include +#endif + +// This example demonstrates how to stream biomechanical angle data rather than poses from CapturyLive + + + +// This callback is called every time a new pose becomes available. +// Make sure this callback is quick. Otherwise frames may get dropped. +void newAnglesCallback(const CapturyActor* actor, int numAngles, struct CapturyAngleData* values) +{ + for (int i = 0; i < numAngles; ++i) + Captury_log(CAPTURY_LOG_INFO, "actor %x received new angle %d: %g\n", actor->id, values[i].type, values[i].value); +} + +int main(int argc, char** argv) +{ + // This is cheating a little as we're not connecting to a remote machine + // but you can change the IP. There is also a more advanced version of Captury_connect() that gives you more options + // to control ports or to enable asynchronous connect mode. + int ret = Captury_connect("127.0.0.1", 2101); + if (ret == 0) + return -1; + + // This is optional but sometimes it's quite useful to know the exact time on the CapturyLive machine. + // The accuracy of the synchronization depends primarily on your OS and the network topology between + // the CapturyLive machine and this machine. On a LAN running Windows on the target machine you can + // expect about 100us accuracy. + Captury_startTimeSynchronizationLoop(); + + // register callback that is called in a different thread whenever a new pose becomes available + ret = Captury_registerNewAnglesCallback(newAnglesCallback); + if (ret == 0) + return -1; + + // start streaming + // The recommended features are CAPTURY_STREAM_POSES and CAPTURY_STREAM_COMPRESSED. + // Here we stream angle data rather than pose data. This can be easier to process, e.g. in biofeedback applications. + // Additional flags should be added as required. + uint16_t angles[] = {CAPTURY_LEFT_KNEE_FLEXION_EXTENSION, CAPTURY_RIGHT_KNEE_FLEXION_EXTENSION}; + Captury_startStreamingImagesAndAngles(CAPTURY_STREAM_ANGLES, /*camera*/-1, 2, angles); + + #ifdef WIN32 + Sleep(100000); + #else + usleep(100000*1000); + #endif + + // instead of the callback approach you can also use polling like this: + // int numAngles; + // CapturyAngleData* angles = Captury_getCurrentAngles(actorId, &numAngles); + + Captury_stopStreaming(); + + Captury_disconnect(); + + return 0; +}