Fawkes API  Fawkes Development Version
webview-ptzcam-thread.cpp
1 
2 /***************************************************************************
3  * webview-ptzcam-thread.cpp - Pan/tilt/zoom camera control for webview
4  *
5  * Created: Fri Feb 07 16:02:11 2014
6  * Copyright 2006-2014 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "webview-ptzcam-thread.h"
23 #include "webview-ptzcam-processor.h"
24 
25 #include <webview/url_manager.h>
26 #include <webview/nav_manager.h>
27 #include <webview/request_manager.h>
28 #include <utils/time/time.h>
29 #include <utils/time/wait.h>
30 
31 #include <interfaces/PanTiltInterface.h>
32 #include <interfaces/SwitchInterface.h>
33 #include <interfaces/CameraControlInterface.h>
34 
35 using namespace fawkes;
36 
37 #define PTZCAM_URL_PREFIX "/ptzcam"
38 
39 /** @class WebviewPtzCamThread "webview-ptzcam-thread.h"
40  * Pan/tilt/zoom camera control via webview.
41  * @author Tim Niemueller
42  */
43 
44 /** Constructor. */
46  : Thread("WebviewPtzCamThread", Thread::OPMODE_CONTINUOUS)
47 {
49 }
50 
51 
52 /** Destructor. */
54 {
55 }
56 
57 
58 void
60 {
61  timeout_ = false;
62 
63  std::string pantilt_id = config->get_string("/webview/ptzcam/pantilt-id");
64  std::string camctrl_id = config->get_string("/webview/ptzcam/camctrl-id");
65  std::string power_id = config->get_string("/webview/ptzcam/power-id");
66  std::string image_id = config->get_string("/webview/ptzcam/image-id");
67  std::string camera_id = config->get_string("/webview/ptzcam/camera-id");
68 
69  float pan_increment = config->get_float("/webview/ptzcam/pan-increment");
70  float tilt_increment = config->get_float("/webview/ptzcam/tilt-increment");
71  unsigned int zoom_increment = config->get_uint("/webview/ptzcam/zoom-increment");
72  float post_powerup_time = config->get_float("/webview/ptzcam/post-power-up-time");
73 
74  std::string nav_entry = "PTZ Cam";
75  try {
76  nav_entry = config->get_string("/webview/ptzcam/nav-entry");
77  } catch (Exception &e) {} // ignored, use default
78 
79  float loop_interval = config->get_float("/webview/ptzcam/loop-interval");
80  long int loop_time = (long int)roundf(fabs(loop_interval) * 1000000.);
81 
82  cfg_inactivity_timeout_ = fabs(config->get_float("/webview/ptzcam/inactivity-timeout"));
83  cfg_park_pan_tolerance_ = fabs(config->get_float("/webview/ptzcam/park/pan-tolerance"));
84  cfg_park_pan_pos_ = fabs(config->get_float("/webview/ptzcam/park/pan"));
85  cfg_park_tilt_tolerance_ = fabs(config->get_float("/webview/ptzcam/park/tilt-tolerance"));
86  cfg_park_tilt_pos_ = fabs(config->get_float("/webview/ptzcam/park/tilt"));
87 
88  std::map<std::string, std::tuple<std::string, float, float, unsigned int>> presets;
89  std::string prefix = "/webview/ptzcam/presets/";
90 #if __cplusplus >= 201103L
91  std::unique_ptr<Configuration::ValueIterator> i(config->search(prefix.c_str()));
92 #else
93  std::auto_ptr<Configuration::ValueIterator> i(config->search(prefix.c_str()));
94 #endif
95  while (i->next()) {
96  std::string cfg_name = std::string(i->path()).substr(prefix.length());
97  cfg_name = cfg_name.substr(0, cfg_name.find("/"));
98 
99  if (presets.find(cfg_name) == presets.end()) {
100  std::string cfg_prefix = prefix + cfg_name + "/";
101  try {
102  std::string name = config->get_string((cfg_prefix + "name").c_str());
103  float pan = config->get_float((cfg_prefix + "pan").c_str());
104  float tilt = config->get_float((cfg_prefix + "tilt").c_str());
105  unsigned int zoom = config->get_uint((cfg_prefix + "zoom").c_str());
106  presets[cfg_name] = std::make_tuple(name, pan, tilt, zoom);
107  } catch (Exception &e) {
108  logger->log_warn(name(), "Invalid preset %s", cfg_name.c_str());
109  }
110  }
111  }
112 
113  web_proc_ = new WebviewPtzCamRequestProcessor(PTZCAM_URL_PREFIX, image_id,
114  pantilt_id, camctrl_id, power_id, camera_id,
115  pan_increment, tilt_increment,
116  zoom_increment, post_powerup_time,
117  presets,
118  blackboard, logger);
119  webview_url_manager->register_baseurl(PTZCAM_URL_PREFIX, web_proc_);
120  webview_nav_manager->add_nav_entry(PTZCAM_URL_PREFIX, nav_entry.c_str());
121 
122  ptu_if_ = blackboard->open_for_reading<PanTiltInterface>(pantilt_id.c_str());
123  power_if_ = blackboard->open_for_reading<SwitchInterface>(power_id.c_str());
124  camen_if_ = blackboard->open_for_reading<SwitchInterface>(camera_id.c_str());
125 
126  bool ceiling_mount = false;
127  try {
128  ceiling_mount = config->get_bool("/webview/ptzcam/ceiling-mount");
129  } catch (Exception &e) {} // ignored, use default
130 
131  if (ceiling_mount) {
132  logger->log_info(name(), "Ceiling mode, ordering image mirroring");
133  CameraControlInterface *camctrl_if =
134  blackboard->open_for_reading<CameraControlInterface>(camctrl_id.c_str());
135  if (camctrl_if->has_writer()) {
138  camctrl_if->msgq_enqueue(msg);
139  }
140  blackboard->close(camctrl_if);
141  }
142 
143  time_wait_ = new TimeWait(clock, loop_time);
144 }
145 
146 
147 void
149 {
150  webview_url_manager->unregister_baseurl(PTZCAM_URL_PREFIX);
151  webview_nav_manager->remove_nav_entry(PTZCAM_URL_PREFIX);
152  delete web_proc_;
153 
154  blackboard->close(ptu_if_);
155  blackboard->close(power_if_);
156  blackboard->close(camen_if_);
157  delete time_wait_;
158 }
159 
160 
161 void
163 {
164  time_wait_->mark_start();
165 
167  fawkes::Time now(clock);
168  try {
169  Time last_completion =
171 
172  if (now - &last_completion >= cfg_inactivity_timeout_) {
173  if (! timeout_) {
174  logger->log_info(name(), "Inactivity timeout");
175  timeout_ = true;
176  }
177  ptu_if_->read();
178  power_if_->read();
179  camen_if_->read();
180  if (fabs(cfg_park_pan_pos_ - ptu_if_->pan()) >= cfg_park_pan_tolerance_ ||
181  fabs(cfg_park_tilt_pos_ - ptu_if_->tilt()) >= cfg_park_tilt_tolerance_)
182  {
184  new PanTiltInterface::GotoMessage(cfg_park_pan_pos_, cfg_park_tilt_pos_);
185  ptu_if_->msgq_enqueue(gotomsg);
186  } else {
187  if (power_if_->has_writer() && power_if_->is_enabled()) {
189  }
190 
191  if (camen_if_->has_writer() && camen_if_->is_enabled()) {
193  }
194  }
195  } else {
196  timeout_ = false;
197  }
198  } catch (Exception &e) {} // ignore, a request got active
199  }
200  time_wait_->wait();
201 }
WebNavManager * webview_nav_manager
Webview navigation manager.
Definition: webview.h:52
void wait()
Wait until minimum loop time has been reached.
Definition: wait.cpp:81
unsigned int num_active_requests() const
Get number of currently active requests.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Pan/tilt/zoom camera request processor.
Fawkes library namespace.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
A class for handling time.
Definition: time.h:91
virtual bool next()=0
Check if there is another element and advance to this if possible.
Thread class encapsulation of pthreads.
Definition: thread.h:42
void set_prepfin_conc_loop(bool concurrent=true)
Set concurrent execution of prepare_finalize() and loop().
Definition: thread.cpp:727
CameraControlInterface Fawkes BlackBoard Interface.
float tilt() const
Get tilt value.
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:44
virtual ~WebviewPtzCamThread()
Destructor.
Clock * clock
By means of this member access to the clock is given.
Definition: clock.h:45
WebRequestManager * webview_request_manager
Webview request manager.
Definition: webview.h:54
SwitchInterface Fawkes BlackBoard Interface.
virtual void finalize()
Finalize the thread.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:477
WebUrlManager * webview_url_manager
Webview request processor manager.
Definition: webview.h:50
void unregister_baseurl(const char *url_prefix)
Remove a request processor.
Definition: url_manager.cpp:87
WebviewPtzCamThread()
Constructor.
bool has_writer() const
Check if there is a writer for the interface.
Definition: interface.cpp:834
DisableSwitchMessage Fawkes BlackBoard Interface Message.
const char * name() const
Get name of thread.
Definition: thread.h:95
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void init()
Initialize the thread.
virtual const char * path() const =0
Path of value.
bool is_enabled() const
Get enabled value.
GotoMessage Fawkes BlackBoard Interface Message.
float pan() const
Get pan value.
void add_nav_entry(std::string baseurl, std::string name)
Add a navigation entry.
Definition: nav_manager.cpp:61
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Definition: interface.cpp:903
void mark_start()
Mark start of loop.
Definition: wait.cpp:70
Time last_request_completion_time() const
Get time when last request was completed.
SetMirrorMessage Fawkes BlackBoard Interface Message.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
PanTiltInterface Fawkes BlackBoard Interface.
void remove_nav_entry(std::string baseurl)
Remove a navigation entry.
Definition: nav_manager.cpp:76
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:44
virtual float get_float(const char *path)=0
Get value from configuration which is of type float.
virtual void loop()
Code to execute in the thread.
Time wait utility.
Definition: wait.h:32
void register_baseurl(const char *url_prefix, WebRequestProcessor *processor)
Add a request processor.
Definition: url_manager.cpp:64
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
Definition: blackboard.h:44
virtual void close(Interface *interface)=0
Close interface.