Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/plugins/sharpa_avatar/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
#include "cli.hpp"

#include <avatar/avatar_hand_tracking_plugin.hpp>
#include <log_bridge/logger.hpp>

#include <atomic>
#include <chrono>
#include <csignal>
#include <iostream>
#include <stdexcept>
#include <string>
#include <thread>
Expand All @@ -46,6 +46,7 @@ AvatarPluginConfig parse_args(int argc, char** argv)
{
AvatarPluginConfig config;
std::string datasets_arg = "human,raw,robot,haptic";
auto logger = isaaccapture::Logger::get("isaaccapture.plugins.sharpa_avatar");

for (int i = 1; i < argc; ++i)
{
Expand All @@ -64,7 +65,7 @@ AvatarPluginConfig parse_args(int argc, char** argv)
}
else
{
std::cerr << "AvatarHandPlugin: ignoring unknown argument '" << arg << "'" << std::endl;
logger->warn("ignoring unknown argument '{}'", arg);
}
}

Expand Down Expand Up @@ -92,7 +93,7 @@ AvatarPluginConfig parse_args(int argc, char** argv)
}
else
{
std::cerr << "AvatarHandPlugin: ignoring unknown data set '" << ds << "'" << std::endl;
logger->warn("ignoring unknown data set '{}'", ds);
}
}

Expand All @@ -109,7 +110,8 @@ AvatarPluginConfig parse_args(int argc, char** argv)
int main(int argc, char** argv)
try
{
std::cout << "Avatar Hand Plugin starting..." << std::endl;
auto logger = isaaccapture::Logger::get("isaaccapture.plugins.sharpa_avatar");
logger->info("Avatar Hand Plugin starting...");

const AvatarPluginConfig config = parse_args(argc, argv);
AvatarTracker tracker(config);
Expand All @@ -118,7 +120,7 @@ try
std::signal(SIGINT, signal_handler);
std::signal(SIGTERM, signal_handler);

std::cout << "Plugin running. Press Ctrl+C to stop." << std::endl;
logger->info("Plugin running. Press Ctrl+C to stop.");

// Target 90Hz frequency (~11.1ms period).
const auto target_frame_duration = std::chrono::nanoseconds(1000000000 / 90);
Expand All @@ -132,15 +134,18 @@ try
std::this_thread::sleep_until(frame_start + target_frame_duration);
}

logger->info("Avatar Hand Plugin stopped: received SIGINT or SIGTERM.");
return 0;
}
catch (const std::exception& e)
{
std::cerr << argv[0] << ": " << e.what() << std::endl;
auto logger = isaaccapture::Logger::get("isaaccapture.plugins.sharpa_avatar");
logger->error("Avatar Hand Plugin exiting on error: {}", e.what());
return 1;
}
catch (...)
{
std::cerr << argv[0] << ": Unknown error occurred" << std::endl;
auto logger = isaaccapture::Logger::get("isaaccapture.plugins.sharpa_avatar");
logger->error("Avatar Hand Plugin exiting on an unknown error.");
return 1;
}
41 changes: 23 additions & 18 deletions src/plugins/sharpa_avatar/core/avatar_hand_tracking_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "avatar_glove_collection.hpp"

#include <flatbuffers/flatbuffers.h>
#include <log_bridge/logger.hpp>
#include <oxr/oxr_session.hpp>
#include <oxr_utils/math.hpp>
#include <oxr_utils/os_time.hpp>
Expand All @@ -17,7 +18,6 @@
#include <array>
#include <chrono>
#include <cmath>
#include <iostream>
#include <memory>
#include <optional>
#include <stdexcept>
Expand All @@ -37,9 +37,14 @@ namespace
constexpr size_t kJointFlatbufferSize = 4096;
constexpr auto kAvatarDataTimeout = std::chrono::seconds(10);
constexpr auto kGloveRetryInterval = std::chrono::seconds(2);
constexpr auto kGloveWaitLogInterval = std::chrono::seconds(10);
constexpr auto kHapticCommandTimeout = std::chrono::milliseconds(200);

const std::shared_ptr<spdlog::logger>& logger()
{
static const auto instance = isaaccapture::Logger::get("isaaccapture.plugins.sharpa_avatar.AvatarTracker");
return instance;
}

size_t side_index(::avatar::DeviceSide side)
{
switch (side)
Expand Down Expand Up @@ -260,10 +265,9 @@ void GloveState::reset() noexcept

AvatarTracker::AvatarTracker(AvatarPluginConfig config) : m_config(std::move(config)), m_sdk(m_config.sdk_config_path)
{
std::cout << "[Avatar] Avatar SDK initialized." << std::endl;
std::cout << "[Avatar] datasets: human=" << (m_config.human ? "on" : "off")
<< " raw=" << (m_config.raw ? "on" : "off") << " robot=" << (m_config.robot ? "on" : "off")
<< " haptic=" << (m_config.haptic ? "on" : "off") << std::endl;
logger()->info("Avatar SDK initialized.");
logger()->info("datasets: human={} raw={} robot={} haptic={}", m_config.human ? "on" : "off",
m_config.raw ? "on" : "off", m_config.robot ? "on" : "off", m_config.haptic ? "on" : "off");
try_connect_missing_gloves();
initialize_openxr();
}
Expand Down Expand Up @@ -366,8 +370,8 @@ void AvatarTracker::start_glove_if_present(GloveState& glove, ::avatar::DeviceSi
const auto init_error = glove.device->init("{}");
if (init_error != ::avatar::ErrorCode::SUCCESS)
{
std::cerr << "[Avatar] " << to_string(side) << " glove initialization failed: " << error_name(init_error)
<< " (" << static_cast<int>(init_error) << ")" << std::endl;
logger()->warn("{} glove initialization failed: {} ({})", to_string(side), error_name(init_error),
static_cast<int>(init_error));
glove.reset();
return;
}
Expand All @@ -376,13 +380,13 @@ void AvatarTracker::start_glove_if_present(GloveState& glove, ::avatar::DeviceSi
const auto start_error = glove.device->start();
if (start_error != ::avatar::ErrorCode::SUCCESS)
{
std::cerr << "[Avatar] " << to_string(side) << " glove start failed: " << error_name(start_error) << " ("
<< static_cast<int>(start_error) << ")" << std::endl;
logger()->warn(
"{} glove start failed: {} ({})", to_string(side), error_name(start_error), static_cast<int>(start_error));
glove.reset();
return;
}
glove.last_successful_fetch = std::chrono::steady_clock::now();
std::cout << "[Avatar] " << to_string(side) << " glove connected and streaming." << std::endl;
logger()->info("{} glove connected and streaming.", to_string(side));
}

void AvatarTracker::try_connect_missing_gloves()
Expand All @@ -404,12 +408,13 @@ void AvatarTracker::try_connect_missing_gloves()
{
start_glove_if_present(glove(side), side);
}
if (std::none_of(m_gloves.begin(), m_gloves.end(), has_device) &&
(!m_last_glove_wait_log || now - *m_last_glove_wait_log >= kGloveWaitLogInterval))
// Log once per stretch with no glove; a glove connecting re-arms the message.
const bool waiting = std::none_of(m_gloves.begin(), m_gloves.end(), has_device);
if (waiting && !m_glove_wait_logged)
{
m_last_glove_wait_log = now;
std::cout << "[Avatar] Waiting for an online glove..." << std::endl;
logger()->info("Waiting for an online glove...");
}
m_glove_wait_logged = waiting;
}

void AvatarTracker::refresh_data()
Expand Down Expand Up @@ -472,6 +477,7 @@ void AvatarTracker::refresh_data()
}
else if (!state.last_successful_fetch || now - *state.last_successful_fetch >= kAvatarDataTimeout)
{
logger()->warn("{} glove disconnected: no data for {} s.", to_string(side), kAvatarDataTimeout.count());
state.reset();
}
}
Expand Down Expand Up @@ -631,9 +637,8 @@ void AvatarTracker::apply_haptic_command(::avatar::DeviceSide side, const std::a
if (!m_haptic_error_logged[index])
{
m_haptic_error_logged[index] = true;
std::cerr << "[Avatar] set_vibration failed for " << to_string(side) << " glove: " << error_name(error)
<< " (" << static_cast<int>(error) << "); further errors for this side will be silenced."
<< std::endl;
logger()->warn("set_vibration failed for {} glove: {} ({}); further errors for this side will be silenced.",
to_string(side), error_name(error), static_cast<int>(error));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class __attribute__((visibility("default"))) AvatarTracker
std::array<bool, 2> m_haptic_stopped{ { true, true } };
std::array<bool, 2> m_haptic_error_logged{ { false, false } };
std::optional<std::chrono::steady_clock::time_point> m_last_glove_retry;
std::optional<std::chrono::steady_clock::time_point> m_last_glove_wait_log;
bool m_glove_wait_logged = false;
};

} // namespace avatar
Expand Down
Loading