23 #include "base_thread.h"
25 #include "acquisition_thread.h"
26 #include "aqt_vision_threads.h"
28 #include <aspect/vision.h>
29 #include <core/exceptions/software.h>
30 #include <core/threading/barrier.h>
31 #include <core/threading/mutex.h>
32 #include <core/threading/mutex_locker.h>
33 #include <core/threading/thread.h>
34 #include <fvcams/cam_exceptions.h>
35 #include <fvcams/control/factory.h>
36 #include <fvcams/factory.h>
37 #include <fvutils/ipc/shm_image.h>
38 #include <fvutils/ipc/shm_lut.h>
39 #include <fvutils/system/camargp.h>
40 #include <logging/logger.h>
46 using namespace firevision;
76 SharedMemoryImageBuffer::cleanup(
false);
77 SharedMemoryLookupTable::cleanup(
false);
84 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
90 owned_controls_.
lock();
92 for (i = owned_controls_.begin(); i != owned_controls_.end(); ++i) {
95 owned_controls_.clear();
106 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
107 ait_->second->set_vt_prepfin_hold(
true);
111 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
112 ait_->second->set_vt_prepfin_hold(
false);
119 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
122 ait_->second->wakeup(aqt_barrier_);
126 aqt_barrier_->
wait();
129 for (ait_ = aqts_.begin(); ait_ != aqts_.end();) {
130 if (ait_->second->vision_threads->empty()
131 && (ait_->second->vision_threads->empty_time() > aqt_timeout_)) {
132 logger->
log_info(
name(),
"Acquisition thread %s timed out, destroying", ait_->second->name());
142 started_threads_.
lock();
144 while (stit != started_threads_.end()) {
146 "Thread %s has been started, %zu",
147 stit->second->name(),
148 started_threads_.size());
151 stit->second->vision_threads->set_thread_running(stit->first);
153 if (stit->second->vision_threads->has_cyclic_thread()) {
155 stit->second->set_enabled(
true);
159 "Switching acquisition thread %s to cyclic mode",
160 stit->second->name());
162 stit->second->prepare_finalize();
163 stit->second->cancel();
164 stit->second->join();
166 stit->second->start();
167 stit->second->cancel_finalize();
169 }
else if (stit->second->vision_threads->has_cont_thread()) {
171 stit->second->set_enabled(
true);
175 "Switching acquisition thread %s to continuous mode",
176 stit->second->name());
177 stit->second->prepare_finalize();
178 stit->second->cancel();
179 stit->second->join();
181 stit->second->start();
182 stit->second->cancel_finalize();
186 "Acquisition thread %s has no threads while we expected some",
187 stit->second->name());
189 stit->second->set_enabled(
false);
194 started_threads_.erase(stittmp);
196 started_threads_.
unlock();
199 unsigned int num_cyclic_threads = 0;
200 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
201 if (ait_->second->vision_threads->has_cyclic_thread()) {
202 ++num_cyclic_threads;
205 cond_recreate_barrier(num_cyclic_threads);
207 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
208 ait_->second->set_vt_prepfin_hold(
false);
232 if (vision_thread == NULL) {
239 if (aqts_.find(
id) != aqts_.end()) {
241 c = aqts_[id]->camera_instance(cspace,
243 == VisionAspect::CONTINUOUS));
245 aqts_[id]->vision_threads->add_waiting_thread(thread);
250 cam = CameraFactory::instance(cap);
254 e.
append(
"Could not open camera");
271 "Acquisition thread '%s' started for thread '%s' and camera '%s'",
281 e.
append(
"FvBaseVisionMaster: could not instantiate camera");
286 e.
append(
"FvBaseVisionMaster: could not open or start camera");
305 if (aqts_.find(
id) != aqts_.end()) {
306 aqts_[id]->raw_subscriber_thread = thread;
317 FvBaseThread::create_camctrl(
const char *camera_string)
319 CameraControl *cc = CameraControlFactory::instance(camera_string);
321 owned_controls_.
lock();
322 owned_controls_.push_back(cc);
323 owned_controls_.sort();
324 owned_controls_.unique();
328 throw Exception(
"Cannot create camera control of desired type");
340 if (aqts_.find(
id) != aqts_.end()) {
341 return CameraControlFactory::instance(aqts_[
id]->get_camera());
343 return create_camctrl(cam_string);
355 if (aqts_.find(
id) != aqts_.end()) {
356 return CameraControlFactory::instance(typeinf, aqts_[
id]->get_camera());
358 return create_camctrl(cam_string);
365 owned_controls_.
lock();
367 if ((f = std::find(owned_controls_.begin(), owned_controls_.end(), cc))
368 != owned_controls_.end()) {
370 owned_controls_.erase(f);
380 FvBaseThread::cond_recreate_barrier(
unsigned int num_cyclic_threads)
382 if ((num_cyclic_threads + 1) != aqt_barrier_->
count()) {
384 aqt_barrier_ =
new Barrier(num_cyclic_threads + 1);
392 unsigned int num_cyclic_threads = 0;
394 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
396 ait_->second->vision_threads->remove_thread(thread);
398 if (ait_->second->raw_subscriber_thread == thread) {
399 ait_->second->raw_subscriber_thread = NULL;
402 if (ait_->second->vision_threads->has_cyclic_thread()) {
403 ++num_cyclic_threads;
407 "Switching acquisition thread %s to continuous mode "
409 ait_->second->name());
411 ait_->second->prepare_finalize();
412 ait_->second->cancel();
413 ait_->second->join();
415 ait_->second->start();
416 ait_->second->cancel_finalize();
419 if (ait_->second->vision_threads->empty()) {
422 "Disabling capturing on thread %s (no more threads)",
423 ait_->second->name());
424 ait_->second->set_enabled(
false);
428 cond_recreate_barrier(num_cyclic_threads);
437 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
438 if (ait_->second->vision_threads->has_waiting_thread(thread)) {
439 started_threads_.lock();
440 started_threads_[thread] = ait_->second;
441 started_threads_.unlock();
453 for (ait_ = aqts_.begin(); ait_ != aqts_.end(); ++ait_) {
454 ait_->second->vision_threads->remove_waiting_thread(thread);
FireVision base application acquisition thread.
FvAqtVisionThreads * vision_threads
Vision threads assigned to this acquisition thread.
@ AqtContinuous
continuous mode, use if there are only continuous threads for this acquisition thread.
@ AqtCyclic
cyclic mode, use if there is at least one cyclic thread for this acquisition thread.
firevision::Camera * camera_instance(firevision::colorspace_t cspace, bool deep_copy)
Get a camera instance.
void add_waiting_thread(fawkes::Thread *thread)
Add a thread in waiting state.
virtual void release_camctrl(firevision::CameraControl *cc)
Release a camera control.
virtual ~FvBaseThread()
Destructor.
virtual firevision::VisionMaster * vision_master()
Get vision master.
virtual firevision::CameraControl * acquire_camctrl(const char *cam_string)
Retrieve a CameraControl for the specified camera string.
virtual bool thread_init_failed(fawkes::Thread *thread)
Thread initialization failed.
virtual void loop()
Thread loop.
FvBaseThread()
Constructor.
virtual void unregister_thread(fawkes::Thread *thread)
Unregister a thread.
virtual void finalize()
Finalize the thread.
virtual bool thread_started(fawkes::Thread *thread)
Thread started successfully.
virtual firevision::Camera * register_for_raw_camera(const char *camera_string, fawkes::Thread *thread)
Register thread for camera.
virtual firevision::Camera * register_for_camera(const char *camera_string, fawkes::Thread *thread, firevision::colorspace_t cspace=firevision::YUV422_PLANAR)
Register thread for camera.
virtual void init()
Initialize the thread.
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
virtual void wait()
Wait for other threads.
unsigned int count()
Get number of threads this barrier will wait for.
Thread aspect to use blocked timing.
Clock * clock
By means of this member access to the clock is given.
Base class for exceptions in Fawkes.
void append(const char *format,...)
Append messages to the message list.
virtual void unlock() const
Unlock list.
virtual void lock() const
Lock list.
void lock() const
Lock list.
RefPtr< Mutex > mutex() const
Get access to the internal mutex.
void unlock() const
Unlock list.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Logger * logger
This is the Logger member used to access the logger.
virtual void add(ThreadList &tl)=0
Add multiple threads.
virtual void remove(ThreadList &tl)=0
Remove multiple threads.
ThreadCollector * thread_collector
Thread collector.
Thread class encapsulation of pthreads.
const char * name() const
Get name of thread.
void add_notification_listener(ThreadNotificationListener *notification_listener)
Add notification listener.
Thread aspect to use in FireVision apps.
VisionThreadMode vision_thread_mode()
Get the vision thread mode of this thread.
std::string cam_id() const
Get camera ID.
std::string cam_type() const
Get camera type.
Camera control interface base class.
Camera interface for image aquiring devices in FireVision.
virtual void open()=0
Open the camera.
Unknown camera type exception.
Fawkes library namespace.