Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PanTiltAutoControl.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <Base/Common/BIASpragma.hh>
26 #include <PanTilt/DPPanTiltControl.hh>
27 #include <pthread.h>
28 
29 #include "PanTiltAutoControl.hh"
30 #include "PanTiltSoftMotion.hh"
31 
32 using namespace std;
33 using namespace BIAS;
34 
35 bool PanTiltAutoControl::waiting_;
36 bool PanTiltAutoControl::exiting_;
37 bool PanTiltAutoControl::started_;
38 bool PanTiltAutoControl::bSpeedMode_;
39 long int PanTiltAutoControl::des_pan;
40 long int PanTiltAutoControl::des_tilt;
41 pthread_mutex_t PanTiltAutoControl::condition_mutex = PTHREAD_MUTEX_INITIALIZER;
42 pthread_cond_t PanTiltAutoControl::condition_cond = PTHREAD_COND_INITIALIZER;
43 
44 
45 PanTiltAutoControl::PanTiltAutoControl(std::string device, bool heavyDutyMode):
46  PanTiltControlInterface(device, heavyDutyMode)
47 {
48  started_ = false;
49  bSpeedMode_ = false;
50 }
51 
53  if (waiting_)
54  ResumeControl();
55  if (started_) {
56  exiting_ = true;
57  while (started_)
58  pthread_cond_wait( &condition_cond, &condition_mutex );
59  }
61 }
62 
64  if (started_) return;
65 
66  started_ = true;
67  waiting_ = false;
68  exiting_ = false;
70  cout << "current pos: " << cur_pan << " " << cur_tilt << endl;
71  ptControl.SetMode(SPEEDMODE);
72  await_completion();
73  ptControl.SetSpeed(0,0);
74  await_completion();
76  bSpeedMode_ = true;
77  cout << "current pos: " << cur_pan << " " << cur_tilt << endl;
78  pthread_create(&control_thread, NULL, this->threadFunc_pan_tilt, &ptControl);
79 }
80 
82  pthread_mutex_lock( &condition_mutex );
83  waiting_ = true;
84  ptControl.SetSpeed(0,0);
85  pthread_mutex_unlock( &condition_mutex );
86 }
87 
89  pthread_mutex_lock( &condition_mutex );
90  waiting_ = false;
91  pthread_cond_signal( &condition_cond );
92  pthread_mutex_unlock( &condition_mutex );
93 }
94 
95 void PanTiltAutoControl::StartMoveTo(const long int pan, const long int tilt) {
96  if (!bSpeedMode_) {
98  ptControl.SetMode(SPEEDMODE);
99  ptControl.SetSpeed(0,0);
101  bSpeedMode_ = true;
102  }
103  // if moving new command will be skipped, use stopMoveTo() to stop first
104  if (started_ ) return;
105  started_ = true;
106  des_pan = pan;
107  des_tilt = tilt;
108  pthread_create(&control_thread, NULL, this->threadFunc_move_to, &ptControl);
109 }
110 
112  pthread_mutex_lock( &condition_mutex );
113  if (started_) {
114  exiting_ = true;
115  while (started_)
116  pthread_cond_wait( &condition_cond, &condition_mutex );
117  }
118  pthread_mutex_unlock( &condition_mutex );
119 }
120 
121 void* PanTiltAutoControl::threadFunc_pan_tilt(void *ptr)
122 {
123  DPPanTiltControl *ptc = (DPPanTiltControl*)ptr;
124  t_SoftMotion sm;
125  float speed_damp = 32.0f;
126  //sm.setLimits(-2000,2000,100,DPPTU_MAXSPEED/speed_damp,50,DPPTU_MAXSPEED/speed_damp);
127  int k=0;
128  int pspeed = 0;
129  int tspeed = 0;
130  int start_pan=0, start_tilt=0, end_pan=0, end_tilt=0, tilt_in_start=0, tilt_in_end=0;
131  bool loop = true;
132  while (loop) {
134  pthread_mutex_lock( &condition_mutex );
135  while (waiting_ && !exiting_)
136  pthread_cond_wait( &condition_cond, &condition_mutex );
137  pthread_mutex_unlock( &condition_mutex );
138 
139  if (exiting_) {
140  loop = false;
141  ptc->SetSpeed(0,0);
142  await_completion();
143  started_ = false;
144  pthread_cond_signal( &condition_cond );
145  break;
146  }
147 
148  int pmod = 1;
149  tilt_in_start = -600; tilt_in_end = -1000;
150  if (k%2==0) {
151  pmod = -1;
152  tilt_in_start = 600; tilt_in_end = 1000;
153  }
154  start_pan = -1*pmod*1000; end_pan = pmod*1000;
155  switch (k) {
156  case 0:
157  start_pan = 0; end_pan = -1000;
158  start_tilt = 0; end_tilt = -400;
159  tilt_in_start = 0; tilt_in_end = -1000;
160  break;
161  case 2:
162  start_tilt = -400; end_tilt = -200;
163  break;
164  case 3:
165  start_tilt = -200; end_tilt = 0;
166  break;
167  case 4:
168  start_tilt = 0; end_tilt = 200;
169  break;
170  case 5:
171  start_tilt = 200; end_tilt = 400;
172  break;
173  case 6:
174  start_tilt = 400; end_tilt = 600;
175  break;
176  case 7:
177  start_tilt = 600; end_tilt = 800;
178  break;
179  case 8:
180  //ptc->SetMode(ABSOLUTEMODE);
181  //ptc->SetPosition(0,0);
182  //k = 0;
183  exiting_ = true;
184  continue;
185  break;
186  }
187 
188  pspeed = sm.getPanSpeed(start_pan,end_pan,cur_pan,speed_damp);
189  tspeed = sm.getTiltSpeed(tilt_in_start,tilt_in_end,start_tilt,end_tilt,cur_pan,cur_tilt,speed_damp);
191  pthread_mutex_lock( &condition_mutex );
192  if (!waiting_) {
193  ptc->SetSpeed(pspeed,tspeed);
194  }
195  pthread_mutex_unlock( &condition_mutex );
196  if ( (pmod < 0 && cur_pan <= end_pan) ||( pmod > 0 && cur_pan >= end_pan)) {
197  k++;
198  }
200  }
201  return 0;
202 }
203 
204 void* PanTiltAutoControl::threadFunc_pan_only(void *ptr) {
205  DPPanTiltControl *ptc = (DPPanTiltControl*)ptr;
206  int min_pan = -2000;
207  int max_pan = 2000;
208  int pmod = 1;
209 
211  while (1) {
212  pthread_mutex_lock( &condition_mutex );
213  while (waiting_ && !exiting_)
214  pthread_cond_wait( &condition_cond, &condition_mutex );
215  pthread_mutex_unlock( &condition_mutex );
216 
217  if (exiting_) {
218  ptc->SetSpeed(0,0);
219  await_completion();
220  break;
221  }
222  if (cur_pan >=max_pan)
223  pmod = -1;
224  if (cur_pan <=min_pan)
225  pmod = 1;
226 
227  int pspeed = 0;
228  float speedmod = (1+cos((float)cur_pan*M_PI / 2000.0f)) / 2.0f;
229  pspeed = abs(DPPTU_MAXSPEED*speedmod) / 4;
230  pspeed = max(100,pspeed);
231  pspeed = min(DPPTU_MAXSPEED/2,pspeed);
232  pspeed *= pmod;
233  //pspeed = pmod*(DPPTU_MAXSPEED/4);
234  pthread_mutex_lock( &condition_mutex );
235  if (!waiting_)
236  ptc->SetSpeed(pspeed, 0);
237  pthread_mutex_unlock( &condition_mutex );
239  cout << cur_pan << " " << cur_tilt << endl;
240  }
241  return 0;
242 }
243 
244 void* PanTiltAutoControl::threadFunc_move_to(void *ptr) {
245  exiting_ = false;
246  DPPanTiltControl *ptc = (DPPanTiltControl*)ptr;
247  t_SoftMotion sm;
248  //sm.setLimits(-2000,2000,100,DPPTU_MAXSPEED/2,50,DPPTU_MAXSPEED/2);
249  long int start_pan, start_tilt;
250  int pspeed = 0, tspeed = 0;
251  ptc->GetCurrentPosition(start_pan, start_tilt);
252  while (1) {
254  if (abs(des_pan - cur_pan) < 10 && abs(des_tilt - cur_tilt) < 10)
255  exiting_ = true;
256  if (exiting_) {
257  ptc->SetSpeed(0,0);
258  await_completion();
259  started_ = false;
260  pthread_cond_signal( &condition_cond );
261  break;
262  }
263  pspeed = sm.getPanSpeed(start_pan, des_pan, cur_pan, 4);
264  tspeed = sm.getTiltSpeed(0, 0, start_tilt, des_tilt, cur_pan, cur_tilt, 8);
265  pthread_mutex_lock( &condition_mutex );
266  if (!waiting_)
267  ptc->SetSpeed(pspeed,tspeed);
268  pthread_mutex_unlock( &condition_mutex );
269  if (pspeed == 0 && tspeed == 0)
270  exiting_ = true;
272  }
273  return 0;
274 }
275 
276 int PanTiltAutoControl::abs(int val) {
277  return (val < 0) ? -val : val;
278 }
279 
280 int PanTiltAutoControl::min(int val1, int val2) {
281  return (val1 < val2) ? val1 : val2;
282 }
283 
284 int PanTiltAutoControl::max(int val1, int val2) {
285  return (val1 < val2) ? val2 : val1;
286 }
287 
void ResumeControl()
resume moving around
char SetSpeed(int nPanSpeed, int nTiltSpeed)
Set speed for movement.
void StopMoveTo()
stop move to desired position
abstract control class for control of Directed Perception Pan Tilt Unit.
Basic controller interface for Directed Perception Pan Tilt Unit.
~PanTiltAutoControl()
destructor moves to (0,0), then calls super-destructor to release ttyS0
void StartControl()
start moving around
void GetCurrentPosition(long &lPanPos, long &lTiltPos)
int getTiltSpeed(int start_pan, int end_pan, int start_tilt, int end_tilt, int cur_pan, int cur_tilt, int damp)
void StartMoveTo(const long int pan, const long int tilt)
move to desired position
int SetMode(int nMode)
Set the mode in which the camera is to operate.
void StopControl()
stop/pause moving around
void ClosePanTiltUnit()
closes the comport stream connected to PTU
int getPanSpeed(int start_pan, int end_pan, int cur_pan, int damp)