Add USBCANFD transport and visualize 0x391 door feedback
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include "door_risk.hpp"
|
||||
#include "records.hpp"
|
||||
#include "inference_session.hpp"
|
||||
#include "can_bus.hpp"
|
||||
#include "serialization.hpp"
|
||||
#include "result_conversion.hpp"
|
||||
#include <opencv2/core.hpp>
|
||||
#include <atomic>
|
||||
@@ -60,6 +62,7 @@ struct CameraPipeline::Impl {
|
||||
std::unique_ptr<DoorRisk> risk;
|
||||
std::shared_ptr<const BinaryMask> doorPixels;
|
||||
std::unique_ptr<Camera> camera;
|
||||
std::unique_ptr<CanBus> can;
|
||||
std::thread captureThread,detectorThread,inferenceThread;
|
||||
mutable std::mutex stateMutex;
|
||||
std::exception_ptr failure;
|
||||
@@ -70,6 +73,8 @@ struct CameraPipeline::Impl {
|
||||
|
||||
explicit Impl(PipelineConfig c):config(std::move(c)),captures(config.queue_capacity),detections(config.queue_capacity) {
|
||||
if(!config.replay_session.empty())sessionReader=std::make_unique<SessionReader>(config);
|
||||
auto canConfig=config.can;if(sessionReader)canConfig.enabled=false;
|
||||
can=std::make_unique<CanBus>(canConfig);
|
||||
if(config.queue_capacity>8)throw std::invalid_argument("Queue capacity must be between 1 and 8");
|
||||
if(config.max_people<1||config.max_people>16||!std::isfinite(config.detector_confidence)||config.detector_confidence<=0||config.detector_confidence>=1)
|
||||
throw std::invalid_argument("Invalid detector configuration");
|
||||
@@ -80,9 +85,11 @@ struct CameraPipeline::Impl {
|
||||
if(captureThread.joinable())captureThread.join();
|
||||
if(detectorThread.joinable())detectorThread.join();
|
||||
if(inferenceThread.joinable())inferenceThread.join();
|
||||
can->join();
|
||||
}
|
||||
void stop() noexcept {
|
||||
stopped=true;active=false;
|
||||
can->requestStop();
|
||||
// Camera stays alive until all threads have joined. start()/destruction
|
||||
// are owner-thread operations; requestStop() only interrupts existing work.
|
||||
{std::lock_guard<std::mutex> lock(stateMutex);if(camera)camera->requestStop();}
|
||||
@@ -98,6 +105,7 @@ struct CameraPipeline::Impl {
|
||||
void start() {
|
||||
{std::lock_guard<std::mutex> lock(stateMutex);if(started||stopped)throw std::logic_error("CameraPipeline can only be started once");started=true;}
|
||||
try {
|
||||
can->start();
|
||||
outputWriter=std::make_unique<OutputWriter>(config.output);
|
||||
sessionWriter=std::make_unique<SessionWriter>(config);
|
||||
detector=std::make_unique<Detector>(config.engines/"yolo11s.engine",logger,config.detector_confidence,config.max_people);
|
||||
@@ -160,6 +168,12 @@ struct CameraPipeline::Impl {
|
||||
auto record=makeRecord(index,raw,isolated,fused,!config.record_session.empty(),false);
|
||||
auto riskData=risk->evaluate(index,record);
|
||||
auto result=std::make_shared<FrameResult>(makeFrameResult(record,riskData,detected->frame.metadata));
|
||||
if(detected->frame.replay_record) {
|
||||
auto const& recorded=detected->frame.replay_record->at("result");
|
||||
if(recorded.contains("can"))result->can=deserializeCan(recorded.at("can"));
|
||||
else result->can.status="NOT_RECORDED";
|
||||
result->can.source="replay";
|
||||
}else result->can=can->snapshot();
|
||||
attachPoses(*result,fused);
|
||||
result->image=std::move(detected->frame.image);result->door_mask_pixels=doorPixels;
|
||||
result->door_mask_calibration_verified=config.door_mask_calibration_verified;
|
||||
@@ -178,6 +192,17 @@ CameraPipeline::CameraPipeline(PipelineConfig config):impl_(std::make_unique<Imp
|
||||
CameraPipeline::~CameraPipeline()=default;
|
||||
void CameraPipeline::start(){impl_->start();}
|
||||
FrameResultPtr CameraPipeline::latest()const{return impl_->results.load();}
|
||||
CanSnapshot CameraPipeline::canStatus()const {
|
||||
if(impl_->sessionReader) {
|
||||
auto result=impl_->results.load();if(result)return result->can;
|
||||
CanSnapshot s;s.source="replay";s.status="WAITING";return s;
|
||||
}
|
||||
return impl_->can->snapshot();
|
||||
}
|
||||
bool CameraPipeline::sendCan(CanFrame const& frame) {
|
||||
if(impl_->sessionReader)throw std::logic_error("CAN transmission is disabled during replay");
|
||||
return impl_->can->send(frame);
|
||||
}
|
||||
bool CameraPipeline::running()const noexcept{return impl_->active.load();}
|
||||
void CameraPipeline::requestStop()noexcept{impl_->stop();}
|
||||
void CameraPipeline::join(){impl_->joinWorkers();{std::lock_guard<std::mutex> lock(impl_->stateMutex);impl_->camera.reset();}impl_->rethrowFailure();}
|
||||
|
||||
Reference in New Issue
Block a user