Skip to content

Commit

Permalink
adding examples for searching and curve streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
thecaptury committed Jul 1, 2024
1 parent b7a1c7f commit 33de88c
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 5 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ 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)
add_executable(SearchExample examples/search.cpp)
target_include_directories(SearchExample PRIVATE ".")
target_link_libraries(SearchExample RemoteCapturyStatic Threads::Threads)

add_custom_target(Examples DEPENDS PollingExample CallbackExample CurvesExample SearchExample)
28 changes: 24 additions & 4 deletions examples/curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,37 @@ int main(int argc, char** argv)
// 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);
Captury_startStreamingImagesAndAngles(CAPTURY_STREAM_POSES | CAPTURY_STREAM_ANGLES, /*camera*/-1, 2, angles);

#ifdef WIN32
Sleep(100000);
#else
usleep(100000*1000);
usleep(10000*1000);
#endif

// instead of the callback approach you can also use polling like this:
// int numAngles;
// CapturyAngleData* angles = Captury_getCurrentAngles(actorId, &numAngles);
uint64_t lastTimestamp = 0;
while (true) {
// get list of actors - otherwise we won't know whom to poll
const CapturyActor* actors;
int numActors = Captury_getActors(&actors);

for (int i = 0; i < numActors; ++i) {
int numAngles;
CapturyAngleData* angles = Captury_getCurrentAngles(actors[i].id, &numAngles);
if (angles == NULL)
continue;

for (int n = 0; n < numAngles; ++n)
Captury_log(CAPTURY_LOG_INFO, "actor %x has new angle %d: %g\n", actors[i].id, angles[n].type, angles[n].value);
}

#ifdef WIN32
Sleep(20);
#else
usleep(20*1000);
#endif
}

Captury_stopStreaming();

Expand Down
116 changes: 116 additions & 0 deletions examples/search.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include <stdio.h>
#include "RemoteCaptury.h"
#ifndef WIN32
#include <unistd.h>
#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);

while (true) {
// get list of actors - otherwise we won't know whom to poll
const CapturyActor* actors;
int numActors = Captury_getActors(&actors);

// check whether there is a person being tracked already
bool anyAlive = false;
for (int i = 0; i < numActors; ++i) {
int status = Captury_getActorStatus(actors[i].id);

switch (status) {
case ACTOR_SCALING:
case ACTOR_TRACKING:
anyAlive = true;
break;
case ACTOR_STOPPED:
// keep the list of actors clean
Captury_deleteActor(actors[i].id);
break;
case ACTOR_DELETED:
case ACTOR_UNKNOWN:
break;
}
if (anyAlive)
break;
}

// if there is no person being tracked, try to find a new one
if (!anyAlive) {
// try to find a new actor at the location (1m, 1m) with any orientation (500 > 360deg)
Captury_snapActor(-1000.0f, 0.0f, 500.0f);
}

// sleep 1 second
#ifdef WIN32
Sleep(1000);
#else
usleep(1000*1000);
#endif
}

Captury_stopStreaming();

Captury_disconnect();

return 0;
}

0 comments on commit 33de88c

Please sign in to comment.