2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2016-12-21 21:58:42 -08:00
|
|
|
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "wpi/vision/VisionRunner.hpp"
|
2016-12-21 21:58:42 -08:00
|
|
|
|
2024-09-20 17:43:39 -07:00
|
|
|
#include <memory>
|
2018-04-29 13:29:07 -07:00
|
|
|
#include <thread>
|
|
|
|
|
|
2017-08-27 00:11:52 -07:00
|
|
|
#include <opencv2/core/mat.hpp>
|
|
|
|
|
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "wpi/cameraserver/CameraServerShared.hpp"
|
2016-12-21 21:58:42 -08:00
|
|
|
|
2025-11-07 20:00:05 -05:00
|
|
|
using namespace wpi::vision;
|
2016-12-21 21:58:42 -08:00
|
|
|
|
|
|
|
|
VisionRunnerBase::VisionRunnerBase(cs::VideoSource videoSource)
|
2017-12-10 20:58:14 -08:00
|
|
|
: m_image(std::make_unique<cv::Mat>()),
|
|
|
|
|
m_cvSink("VisionRunner CvSink"),
|
|
|
|
|
m_enabled(true) {
|
2016-12-21 21:58:42 -08:00
|
|
|
m_cvSink.SetSource(videoSource);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Located here and not in header due to cv::Mat forward declaration.
|
2020-12-28 00:37:33 -08:00
|
|
|
VisionRunnerBase::~VisionRunnerBase() = default;
|
2016-12-21 21:58:42 -08:00
|
|
|
|
|
|
|
|
void VisionRunnerBase::RunOnce() {
|
2025-11-07 20:00:05 -05:00
|
|
|
auto csShared = wpi::vision::GetCameraServerShared();
|
2018-04-29 13:29:07 -07:00
|
|
|
auto res = csShared->GetRobotMainThreadId();
|
|
|
|
|
if (res.second && (std::this_thread::get_id() == res.first)) {
|
|
|
|
|
csShared->SetVisionRunnerError(
|
2016-12-21 21:58:42 -08:00
|
|
|
"VisionRunner::RunOnce() cannot be called from the main robot thread");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto frameTime = m_cvSink.GrabFrame(*m_image);
|
|
|
|
|
if (frameTime == 0) {
|
|
|
|
|
auto error = m_cvSink.GetError();
|
2021-05-24 23:36:26 -07:00
|
|
|
csShared->ReportDriverStationError(error.c_str());
|
2016-12-21 21:58:42 -08:00
|
|
|
} else {
|
|
|
|
|
DoProcess(*m_image);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VisionRunnerBase::RunForever() {
|
2025-11-07 20:00:05 -05:00
|
|
|
auto csShared = wpi::vision::GetCameraServerShared();
|
2018-04-29 13:29:07 -07:00
|
|
|
auto res = csShared->GetRobotMainThreadId();
|
|
|
|
|
if (res.second && (std::this_thread::get_id() == res.first)) {
|
|
|
|
|
csShared->SetVisionRunnerError(
|
2016-12-21 21:58:42 -08:00
|
|
|
"VisionRunner::RunForever() cannot be called from the main robot "
|
|
|
|
|
"thread");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-10 20:58:14 -08:00
|
|
|
while (m_enabled) {
|
2016-12-21 21:58:42 -08:00
|
|
|
RunOnce();
|
|
|
|
|
}
|
2017-08-19 22:14:34 -07:00
|
|
|
}
|
2017-12-10 20:58:14 -08:00
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
void VisionRunnerBase::Stop() {
|
|
|
|
|
m_enabled = false;
|
|
|
|
|
}
|