MAClient/src/cameras.cpp
uvos 48a04fdf79 change stiching method
add camera temperature readout
2021-07-05 11:27:38 +02:00

312 lines
6.5 KiB
C++

#include "cameras.h"
#include <QRandomGenerator>
#include <string>
#include <functional>
#include <QDebug>
#include <unistd.h>
#include <QTimer>
Cameras::Cameras(uvosled* led): led_(led)
{
ledTimer.setSingleShot(true);
cameraFailureTimer.setSingleShot(true);
connect(&ledTimer, &QTimer::timeout, this, &Cameras::lightOff);
connect(&cameraFailureTimer, &QTimer::timeout, this, &Cameras::reloadCameras);
}
Cameras::~Cameras()
{
lightOff();
}
bool Cameras::setCameras(const std::vector<cam::Camera::Description>& descriptions)
{
clear();
bool ret = true;
for(auto& camera : descriptions)
{
if(!addCamera(camera))
ret = false;
}
return ret;
}
void Cameras::reloadCameras()
{
setCameras(getCameras());
}
void Cameras::clear()
{
free_ = false;
for(auto& camera : cameras_)
cameraRemoved(camera);
cameras_.clear();
if(led_)
uvosled_set_current(led_, 0xFF, 0);
}
std::vector<cam::Camera::Description> Cameras::getCameras()
{
std::vector<cam::Camera::Description> desc;
desc.reserve(cameras_.size());
for(std::shared_ptr<Camera> camera : cameras_)
desc.push_back(camera->cam()->getDescription());
return desc;
}
std::shared_ptr<Camera> Cameras::getCamera(size_t id)
{
std::vector<cam::Camera::Description> desc = getCameras();
for(size_t i = 0; i < desc.size(); ++i)
{
if(desc[i].getId() == id)
return cameras_[i];
}
return std::shared_ptr<Camera>(nullptr);
}
bool Cameras::addCamera(const cam::Camera::Description& desc)
{
cameras_.push_back(std::shared_ptr<Camera>(new Camera(desc)));
if(!cameras_.back()->cam()->isOpen())
{
cameras_.pop_back();
return false;
}
enableCapture(false);
blockCaptureId_ = cameras_.back()->id();
cameras_.back()->cam()->setExposureTime(exposrueTime_);
if(desc.getVendor().find("Photonfocus") != std::string::npos)
{
qDebug()<<"Mitiagting broken PhotonFocus single shot mode";
std::shared_ptr<Camera> camera = cameras_.back();
camera->cam()->setTriggerMode(cam::Camera::TRIGGER_FREE);
camera->cam()->setAcquisitionMode(cam::Camera::MODE_FREE);
camera->cam()->setFrameRate(10);
camera->cam()->startAcquisition();
std::this_thread::sleep_for (std::chrono::milliseconds(200));
camera->cam()->stopAcquisition();
cameras_.pop_back();
camera = nullptr;
std::this_thread::sleep_for (std::chrono::milliseconds(200));
cameras_.push_back(std::shared_ptr<Camera>(new Camera(desc)));
if(!cameras_.back()->cam()->isOpen())
{
cameras_.pop_back();
return false;
}
camera = cameras_.back();
cameraAdded(camera);
camera->cam()->setTriggerMode(cam::Camera::TRIGGER_FREE);
camera->cam()->setAcquisitionMode(cam::Camera::MODE_FREE);
camera->cam()->setFrameRate(10);
camera->cam()->startAcquisition();
QTimer::singleShot(5000, [camera, this](){finishAddCamera(camera);});
}
else
{
finishAddCamera(cameras_.back());
}
return true;
}
void Cameras::finishAddCamera(std::shared_ptr<Camera> camera)
{
camera->cam()->setTriggerMode(cam::Camera::TRIGGER_SOFTWARE);
setFree(free_);
connect(camera.get(), &Camera::newImage, this, &Cameras::imageRecived);
if(blockCaptureId_ == camera->id())
enableCapture(true);
qDebug()<<"Using camera"<<camera->id();
}
bool Cameras::lightFor(const LightingSetup& lighting, double time)
{
int ret = 0;
if(led_)
{
ret = uvosled_set_current(led_, lighting.mask, lighting.brightness);
ledTimer.start(time*1000);
}
return ret == 0;
}
void Cameras::lightOff()
{
if(led_)
uvosled_set_current(led_, 0xff, 0);
ledTimer.stop();
}
void Cameras::trigger()
{
lightFor(lighting_, exposrueTime_*1.5);
for(auto& camera : cameras_)
camera->cam()->trigger();
}
bool Cameras::start()
{
bool ret = true;
for(auto& camera : cameras_)
{
if(!camera->cam()->startAcquisition())
ret = false;
}
if(free_)
uvosled_set_current(led_, lighting_.mask, lighting_.brightness);
return ret;
}
bool Cameras::stop()
{
bool ret = true;
for(auto& camera : cameras_)
{
if(!camera->cam()->stopAcquisition())
ret = false;
}
lightOff();
return ret;
}
void Cameras::disable(bool disable)
{
disable_ = disable;
}
bool Cameras::setFree(bool free)
{
stop();
free_ = free;
bool ret = true;
for(auto& camera : cameras_)
{
if(!camera->cam()->setAcquisitionMode(free ? cam::Camera::MODE_FREE : cam::Camera::MODE_SINGLE))
{
qDebug()<<"failed to set acquisition mode on camera"<<camera->id();
ret = false;
}
if(ret)
camera->cam()->setTriggerMode(free ? cam::Camera::TRIGGER_FREE : cam::Camera::TRIGGER_SOFTWARE);
}
return ret;
}
bool Cameras::setExposureTime(double exposureTime)
{
stop();
exposrueTime_ = exposureTime;
bool ret = true;
for(auto& camera : cameras_)
{
if(!camera->cam()->setExposureTime(exposrueTime_*1000000))
{
qDebug()<<"failed to set exposure on camera"<<camera->id();
ret = false;
}
}
return ret;
}
void Cameras::imageRecived(Camera::Image img)
{
if(!disable_)
{
qDebug()<<"free"<<free_;
bool allreadyUpdated = false;
for(auto& image : images_)
{
if(image.cameraId == img.cameraId)
{
allreadyUpdated = true;
break;
}
}
if(!allreadyUpdated)
images_.push_back(img);
qDebug()<<"Recived"<<images_.size()<<"of"<<cameras_.size()<<"images";
if(images_.size() == 1)
cameraFailureTimer.start(exposrueTime_*1000+1000);
if(images_.size() == cameras_.size())
{
cameraFailureTimer.stop();
newImages(images_);
images_.clear();
}
}
}
double Cameras::getMeanTemp()
{
double mean = 0;
bool failure = false;
for(auto& camera : cameras_)
{
double temp;
if(camera->cam()->getTemperature(temp))
mean+=temp;
else
failure = true;
}
if(!failure)
return mean/cameras_.size();
else
return NAN;
}
void Cameras::setSetup(const std::vector<CameraSetup>& setups)
{
for(auto& camera : cameras_)
for(auto& setup : setups)
if(camera->id() == setup.id)
camera->cam()->setBayerMode(setup.bayerMode);
}
void Cameras::store(QSettings &settings)
{
std::vector<cam::Camera::Description> available = cam::Camera::getAvailableCameras();
settings.beginWriteArray(GROUP, cameras_.size());
for(size_t i = 0; i < cameras_.size(); ++i)
{
settings.setArrayIndex(i);
settings.setValue("id", static_cast<unsigned long long>(cameras_[i]->id()));
}
settings.endArray();
}
void Cameras::load(QSettings &settings)
{
std::vector<cam::Camera::Description> available = cam::Camera::getAvailableCameras();
int size = settings.beginReadArray(GROUP);
for(int i = 0; i < size; ++i)
{
settings.setArrayIndex(i);
size_t hash = settings.value("id", 0).toULongLong();
for(auto& camera : available)
{
if(camera.getId() == hash)
addCamera(camera);
}
}
settings.endArray();
}