From ae0b7aa2cab7c9b40c1e115ffef2d3afbd94e48e Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nicolas.pope@utu.fi> Date: Thu, 15 Oct 2020 09:21:43 +0300 Subject: [PATCH] Pylon properties from master machine --- applications/vision/src/main.cpp | 1 + components/common/cpp/include/ftl/timer.hpp | 7 +++ .../{net => common}/cpp/include/ftl/uuid.hpp | 0 components/common/cpp/src/timer.cpp | 12 ++++ .../net/cpp/include/ftl/net/universe.hpp | 3 + components/net/cpp/src/universe.cpp | 4 ++ .../src/sources/stereovideo/pylon.cpp | 62 ++++++++++++++++++- 7 files changed, 86 insertions(+), 3 deletions(-) rename components/{net => common}/cpp/include/ftl/uuid.hpp (100%) diff --git a/applications/vision/src/main.cpp b/applications/vision/src/main.cpp index afbddb050..40531fa3a 100644 --- a/applications/vision/src/main.cpp +++ b/applications/vision/src/main.cpp @@ -88,6 +88,7 @@ static void run(ftl::Configurable *root) { if (opt_time_master) { time_peer = *opt_time_master; LOG(INFO) << "Found a time master: " << time_peer.to_string(); + ftl::timer::setTimeMaster(time_peer); } int sync_counter = 0; diff --git a/components/common/cpp/include/ftl/timer.hpp b/components/common/cpp/include/ftl/timer.hpp index 6530aeadd..1dd3ff76f 100644 --- a/components/common/cpp/include/ftl/timer.hpp +++ b/components/common/cpp/include/ftl/timer.hpp @@ -3,9 +3,12 @@ #include <ftl/handle.hpp> #include <functional> +#include <optional> namespace ftl { +class UUID; + /** * A single global timer mechanism to call functions with either high or low * precision timing accuracy. This is used to provide accurate frame timing for @@ -114,6 +117,10 @@ size_t count(timerlevel_t); */ void reset(); +void setTimeMaster(const ftl::UUID &m); + +std::optional<ftl::UUID> getTimeMaster(); + } } diff --git a/components/net/cpp/include/ftl/uuid.hpp b/components/common/cpp/include/ftl/uuid.hpp similarity index 100% rename from components/net/cpp/include/ftl/uuid.hpp rename to components/common/cpp/include/ftl/uuid.hpp diff --git a/components/common/cpp/src/timer.cpp b/components/common/cpp/src/timer.cpp index e49a955cf..e9587355e 100644 --- a/components/common/cpp/src/timer.cpp +++ b/components/common/cpp/src/timer.cpp @@ -1,5 +1,6 @@ #include <ftl/timer.hpp> #include <ftl/threads.hpp> +#include <ftl/uuid.hpp> #include <loguru.hpp> #include <vector> @@ -28,6 +29,8 @@ static MUTEX mtx; static int last_id = 0; static bool clock_slave = true; static std::future<void> timer_future; +static ftl::UUID time_master(0); +static bool has_time_master = false; struct TimerJob { int id=0; @@ -42,6 +45,15 @@ struct TimerJob { static list<TimerJob> jobs[kTimerMAXLEVEL]; +void ftl::timer::setTimeMaster(const ftl::UUID &m) { + has_time_master = true; + time_master = m; +} + +std::optional<ftl::UUID> ftl::timer::getTimeMaster() { + return (has_time_master) ? time_master : std::optional<ftl::UUID>{}; +} + int64_t ftl::timer::get_time() { return time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count()+clock_adjust; } diff --git a/components/net/cpp/include/ftl/net/universe.hpp b/components/net/cpp/include/ftl/net/universe.hpp index 8ee642fe6..58f23053a 100644 --- a/components/net/cpp/include/ftl/net/universe.hpp +++ b/components/net/cpp/include/ftl/net/universe.hpp @@ -214,6 +214,8 @@ class Universe : public ftl::Configurable { size_t getSendBufferSize(ftl::URI::scheme_t s); size_t getRecvBufferSize(ftl::URI::scheme_t s); + + static inline Universe *getInstance() { return instance_; } private: void _run(); @@ -274,6 +276,7 @@ class Universe : public ftl::Configurable { std::list<ErrHandler> on_error_; static callback_t cbid__; + static Universe *instance_; // std::map<std::string, std::vector<ftl::net::Peer*>> subscriptions_; }; diff --git a/components/net/cpp/src/universe.cpp b/components/net/cpp/src/universe.cpp index ce1137ee0..3dbcd5887 100644 --- a/components/net/cpp/src/universe.cpp +++ b/components/net/cpp/src/universe.cpp @@ -47,6 +47,7 @@ struct NetImplDetail { #define WS_RECEIVE_BUFFER_SIZE (62*1024) callback_t ftl::net::Universe::cbid__ = 0; +Universe *Universe::instance_ = nullptr; Universe::Universe() : Configurable(), @@ -94,6 +95,9 @@ Universe::Universe(nlohmann::json &config) : } return true; }); + + if (instance_ != nullptr) LOG(FATAL) << "Multiple net instances"; + instance_ = this; } Universe::~Universe() { diff --git a/components/rgbd-sources/src/sources/stereovideo/pylon.cpp b/components/rgbd-sources/src/sources/stereovideo/pylon.cpp index 6901837f6..6281cdd51 100644 --- a/components/rgbd-sources/src/sources/stereovideo/pylon.cpp +++ b/components/rgbd-sources/src/sources/stereovideo/pylon.cpp @@ -81,6 +81,8 @@ PylonDevice::PylonDevice(nlohmann::json &config) _configureCamera(lcam_); if (rcam_) _configureCamera(rcam_); + value("gain", lcam_->Gain.GetValue()); + lcam_->StartGrabbing( Pylon::GrabStrategy_OneByOne); if (rcam_) rcam_->StartGrabbing( Pylon::GrabStrategy_OneByOne); @@ -106,6 +108,11 @@ PylonDevice::PylonDevice(nlohmann::json &config) //hres_hm_ = cv::cuda::HostMem(fullheight_, fullwidth_, CV_8UC4); //rtmp_.create(fullheight_, fullwidth_, CV_8UC4); + //on("gain", [this]() { + // lcam_->Gain.SetValue(value("gain",1.0)); + // rcam_->Gain.SetValue(value("gain",1.0)); + //}); + on("exposure", [this]() { if (lcam_->GetDeviceInfo().GetModelName() != "Emulation") { lcam_->ExposureTime.SetValue(value("exposure", 24000.0f)); // Exposure time in microseconds @@ -138,6 +145,26 @@ PylonDevice::PylonDevice(nlohmann::json &config) return true; }); + + auto *net = ftl::net::Universe::getInstance(); + if (!net->isBound("pylon_gain")) { + net->bind("pylon_gain", [this]() { + return (lcam_) ? lcam_->Gain.GetValue() : 0.0; + }); + net->bind("pylon_exposure", [this]() { + return (lcam_) ? lcam_->ExposureTime.GetValue() : 0.0; + }); + net->bind("pylon_white", [this]() { + cv::Vec3d wb; + lcam_->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Blue); + wb[0] = lcam_->BalanceRatio.GetValue(); + lcam_->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Green); + wb[1] = lcam_->BalanceRatio.GetValue(); + lcam_->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Red); + wb[2] = lcam_->BalanceRatio.GetValue(); + return wb; + }); + } } PylonDevice::~PylonDevice() { @@ -200,13 +227,42 @@ void PylonDevice::_configureCamera(CBaslerUniversalInstantCamera *cam) { LOG(WARNING) << "Could not change pixel format"; } + auto *net = ftl::net::Universe::getInstance(); + auto tm = ftl::timer::getTimeMaster(); + if (cam->GetDeviceInfo().GetModelName() != "Emulation") { // Emulated device throws exception with these - cam->ExposureTime.SetValue(value("exposure", 24000.0f)); // Exposure time in microseconds + if (tm) { + double expo = net->call<double>(*tm, "pylon_exposure"); + cam->ExposureTime.SetValue(expo); + LOG(INFO) << "Pylon exposure from master = " << expo; + } else { + cam->ExposureTime.SetValue(value("exposure", 24000.0f)); // Exposure time in microseconds + } + cam->AutoTargetBrightness.SetValue(0.3); cam->LightSourcePreset.SetValue(Basler_UniversalCameraParams::LightSourcePreset_Tungsten2800K); // White balance option - cam->BalanceWhiteAuto.SetValue(Basler_UniversalCameraParams::BalanceWhiteAuto_Once); - cam->GainAuto.SetValue(Basler_UniversalCameraParams::GainAuto_Once); + + if (tm) { + cv::Vec3d white = net->call<cv::Vec3d>(*tm, "pylon_white"); + cam->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Blue); + cam->BalanceRatio.SetValue(white[0]); + cam->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Green); + cam->BalanceRatio.SetValue(white[1]); + cam->BalanceRatioSelector.SetValue(Basler_UniversalCameraParams::BalanceRatioSelector_Red); + cam->BalanceRatio.SetValue(white[2]); + LOG(INFO) << "Pylon WB from master = " << white; + } else { + cam->BalanceWhiteAuto.SetValue(Basler_UniversalCameraParams::BalanceWhiteAuto_Once); + } + + if (tm) { + double gain = net->call<double>(*tm, "pylon_gain"); + cam->Gain.SetValue(gain); + LOG(INFO) << "Pylon Gain from master = " << gain; + } else { + cam->GainAuto.SetValue(Basler_UniversalCameraParams::GainAuto_Once); + } cam->DeviceTemperatureSelector.SetValue(Basler_UniversalCameraParams::DeviceTemperatureSelector_Coreboard); } } -- GitLab