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);
231 VisionAspect *vision_thread = dynamic_cast<VisionAspect *>(thread);
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);
void add_notification_listener(ThreadNotificationListener *notification_listener)
Add notification listener.
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.
unsigned int count()
Get number of threads this barrier will wait for.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Camera interface for image aquiring devices in FireVision.
void lock() const
Lock list.
virtual void lock() const
Lock list.
virtual void remove(ThreadList &tl)=0
Remove multiple threads.
Fawkes library namespace.
virtual void wait()
Wait for other threads.
virtual firevision::Camera * register_for_camera(const char *camera_string, fawkes::Thread *thread, firevision::colorspace_t cspace=firevision::YUV422_PLANAR)
Register thread for camera.
Unknown camera type exception.
FvAqtVisionThreads * vision_threads
Vision threads assigned to this acquisition thread.
virtual void finalize()
Finalize the thread.
Thread class encapsulation of pthreads.
FireVision base application acquisition thread.
Logger * logger
This is the Logger member used to access the logger.
std::string cam_id() const
Get camera ID.
virtual firevision::VisionMaster * vision_master()
Get vision master.
ThreadCollector * thread_collector
Thread collector.
Clock * clock
By means of this member access to the clock is given.
Thread aspect to use blocked timing.
virtual void release_camctrl(firevision::CameraControl *cc)
Release a camera control.
virtual firevision::CameraControl * acquire_camctrl(const char *cam_string)
Retrieve a CameraControl for the specified camera string.
Camera control interface base class.
Base class for exceptions in Fawkes.
FvBaseThread()
Constructor.
Thread aspect to use in FireVision apps.
VisionThreadMode vision_thread_mode()
Get the vision thread mode of this thread.
virtual void unregister_thread(fawkes::Thread *thread)
Unregister a thread.
virtual void unlock() const
Unlock list.
void unlock() const
Unlock list.
const char * name() const
Get name of thread.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
firevision::Camera * camera_instance(firevision::colorspace_t cspace, bool deep_copy)
Get a camera instance.
virtual void add(ThreadList &tl)=0
Add multiple threads.
virtual ~FvBaseThread()
Destructor.
virtual void open()=0
Open the camera.
void add_waiting_thread(fawkes::Thread *thread)
Add a thread in waiting state.
cyclic mode, use if there is at least one cyclic thread for this acquisition thread.
std::string cam_type() const
Get camera type.
virtual void loop()
Thread loop.
virtual bool thread_init_failed(fawkes::Thread *thread)
Thread initialization failed.
virtual void init()
Initialize the thread.
RefPtr< Mutex > mutex() const
Get access to the internal mutex.
continuous mode, use if there are only continuous threads for this acquisition thread.
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
void append(const char *format,...)
Append messages to the message list.