00001 /*!@file Devices/Visca.C Interface to ptz cameras via the VISCA protocol */ 00002 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/Visca.C $ 00036 // $Id: Visca.C 12962 2010-03-06 02:13:53Z irock $ 00037 // 00038 00039 #include "Devices/Visca.H" 00040 00041 #include "Component/OptionManager.H" 00042 #include "Devices/Serial.H" 00043 00044 // ###################################################################### 00045 Visca::Visca(OptionManager& mgr, const std::string& descrName, 00046 const std::string& tagName, const char *defdev, const int cameraAddr) : 00047 ModelComponent(mgr, descrName, tagName), 00048 itsPort(new Serial(mgr)), 00049 itsCameraAddr(cameraAddr), 00050 itsCurrentZoom(500) 00051 { 00052 // set a default config for our serial port: 00053 itsPort->configure(defdev, 9600 , "8N1", false, false, 1); 00054 00055 // attach our port as a subcomponent: 00056 addSubComponent(itsPort); 00057 00058 } 00059 00060 // ###################################################################### 00061 Visca::~Visca() 00062 { 00063 } 00064 00065 int Visca::sendRawCmd(const unsigned char* cmd, const int length) 00066 { 00067 // write command buffer 00068 itsPort->write(cmd, length); 00069 00070 if (false) 00071 { 00072 LINFO("Sending: "); 00073 for(int i=0; i<length; i++) 00074 printf("%x ", cmd[i]); 00075 printf("\n"); 00076 } 00077 00078 bool found = false; 00079 int size=10; 00080 unsigned char cmdResults[size]; 00081 int r = itsPort->read(cmdResults, size); 00082 while (r<size) 00083 { 00084 for(int i=0; i<r; i++) 00085 { 00086 if (cmdResults[i] == 0xff) 00087 found = true; 00088 } 00089 if (found) break; 00090 r += itsPort->read(&cmdResults[r], size-r); 00091 usleep(10000); 00092 } 00093 00094 if (true) 00095 { 00096 LINFO("Got %i:", r); 00097 for(int i=0; i<r; i++) 00098 printf("%x ", cmdResults[i]); 00099 printf("\n"); 00100 } 00101 00102 return r; 00103 00104 } 00105 00106 void Visca::start2() 00107 { 00108 } 00109 00110 // ###################################################################### 00111 bool Visca::movePanTilt(const int pan, const int tilt, 00112 const bool relative, 00113 const int panSpeed, const int tiltSpeed) 00114 { 00115 unsigned char command[15]; 00116 command[0] = 0x80 + itsCameraAddr; 00117 command[1] = 0x01; 00118 command[2] = 0x06; 00119 00120 LINFO("Pan %i tilt %i", pan, tilt); 00121 if (relative) 00122 command[3] = 0x03; 00123 else 00124 command[3] = 0x02; 00125 00126 command[4] = panSpeed; 00127 command[5] = tiltSpeed; 00128 00129 command[6] = (pan >> 4*3) & 0x0F; 00130 command[7] = (pan >> 4*2) & 0x0F; 00131 command[8] = (pan >> 4*1) & 0x0F; 00132 command[9] = (pan >> 4*0) & 0x0F; 00133 00134 command[10] = (tilt >> 4*3) & 0x0F; 00135 command[11] = (tilt >> 4*2) & 0x0F; 00136 command[12] = (tilt >> 4*1) & 0x0F; 00137 command[13] = (tilt >> 4*0) & 0x0F; 00138 00139 command[14] = 0xFF; 00140 00141 return sendRawCmd(command, 15); 00142 } 00143 00144 // ###################################################################### 00145 bool Visca::getPanTilt(short int &pan, short int &tilt) 00146 { 00147 unsigned char command[15]; 00148 command[0] = 0x80 + itsCameraAddr; 00149 command[1] = 0x09; 00150 command[2] = 0x06; 00151 command[3] = 0x12; 00152 command[4] = 0xFF; 00153 00154 // write command buffer 00155 itsPort->flush(); 00156 itsPort->write(command, 5); 00157 00158 int size=255; 00159 bool found = false; 00160 unsigned char cmdResults[size]; 00161 int r = itsPort->read(cmdResults, size); 00162 while (r<size) 00163 { 00164 for(int i=0; i<r; i++) //look for termination 00165 if (cmdResults[i] == 0xff) 00166 found = true; 00167 00168 if (found) break; 00169 r += itsPort->read(&cmdResults[r], size-r); 00170 usleep(10000); 00171 } 00172 00173 if (true) 00174 { 00175 LINFO("Got %i:", r); 00176 for(int i=0; i<r; i++) 00177 printf("%x ", cmdResults[i]); 00178 printf("\n"); 00179 } 00180 00181 if(cmdResults[r-1] != 0xff) 00182 { 00183 LINFO("Bad pan tilt"); 00184 return false; 00185 } else { 00186 pan = (cmdResults[2] << 4*3); 00187 pan += (cmdResults[3] << 4*2); 00188 pan += (cmdResults[4] << 4*1); 00189 pan += (cmdResults[5] << 4*0); 00190 00191 tilt = (cmdResults[6] << 4*3); 00192 tilt += (cmdResults[7] << 4*2); 00193 tilt += (cmdResults[8] << 4*1); 00194 tilt += (cmdResults[9] << 4*0); 00195 00196 } 00197 00198 00199 00200 return true; 00201 } 00202 00203 00204 // ###################################################################### 00205 bool Visca::resetPanTilt() 00206 { 00207 unsigned char command[5]; 00208 command[0] = 0x80 + itsCameraAddr; 00209 command[1] = 0x01; 00210 command[2] = 0x06; 00211 command[3] = 0x05; 00212 command[4] = 0xFF; 00213 00214 return sendRawCmd(command, 5); 00215 00216 } 00217 00218 // ###################################################################### 00219 bool Visca::zoom(const int val, const bool relative) 00220 { 00221 00222 int zoomVal = itsCurrentZoom; 00223 00224 if (relative) 00225 zoomVal += val; 00226 else 00227 zoomVal = val; 00228 00229 if (zoomVal > 1023) return false; 00230 LINFO("Zoom to %i", zoomVal); 00231 00232 unsigned char command[9]; 00233 command[0] = 0x80 + itsCameraAddr; 00234 command[1] = 0x01; 00235 command[2] = 0x04; 00236 command[3] = 0x47; 00237 00238 command[4] = (zoomVal >> 4*3) & 0x0F; 00239 command[5] = (zoomVal >> 4*2) & 0x0F; 00240 command[6] = (zoomVal >> 4*1) & 0x0F; 00241 command[7] = (zoomVal >> 4*0) & 0x0F; 00242 00243 command[8] = 0xFF; 00244 00245 int ret = sendRawCmd(command, 9); 00246 00247 if (!relative) 00248 itsCurrentZoom = zoomVal; 00249 00250 if (ret == 6 || ret == 7) 00251 { 00252 itsCurrentZoom = zoomVal; 00253 return true; 00254 } 00255 00256 return false; 00257 00258 } 00259 00260 // ###################################################################### 00261 bool Visca::setFocus(const int val, const bool relative) 00262 { 00263 00264 LINFO("focus to %i", val); 00265 unsigned char command[9]; 00266 command[0] = 0x80 + itsCameraAddr; 00267 command[1] = 0x01; 00268 command[2] = 0x04; 00269 command[3] = 0x48; 00270 00271 command[4] = (val >> 4*3) & 0x0F; 00272 command[5] = (val >> 4*2) & 0x0F; 00273 command[6] = (val >> 4*1) & 0x0F; 00274 command[7] = (val >> 4*0) & 0x0F; 00275 00276 command[8] = 0xFF; 00277 00278 if( sendRawCmd(command, 9)) 00279 { 00280 return true; 00281 } 00282 00283 return false; 00284 } 00285 00286 bool Visca::setAutoFocus(const bool val) 00287 { 00288 00289 LINFO("autoFocus to %i", val); 00290 unsigned char command[9]; 00291 command[0] = 0x80 + itsCameraAddr; 00292 command[1] = 0x01; 00293 command[2] = 0x04; 00294 command[3] = 0x38; 00295 00296 if (val) 00297 command[4] = 0x02; 00298 else 00299 command[4] = 0x03; 00300 00301 command[5] = 0xFF; 00302 00303 if( sendRawCmd(command, 6)) 00304 { 00305 return true; 00306 } 00307 00308 return false; 00309 } 00310 00311 00312 // ###################################################################### 00313 bool Visca::setTargetTracking() 00314 { 00315 unsigned char command[6]; 00316 command[0] = 0x80 + itsCameraAddr; 00317 command[1] = 0x01; 00318 command[2] = 0x06; 00319 command[3] = 0x06; 00320 command[4] = 0x02; 00321 command[5] = 0xFF; 00322 00323 sendRawCmd(command, 6); 00324 00325 command[0] = 0x80 + itsCameraAddr; 00326 command[1] = 0x01; 00327 command[2] = 0x07; 00328 command[3] = 0x07; 00329 command[4] = 0x03; 00330 command[5] = 0xFF; 00331 00332 return sendRawCmd(command, 6); 00333 00334 } 00335 00336 00337 00338 // ###################################################################### 00339 /* So things look consistent in everyone's emacs... */ 00340 /* Local Variables: */ 00341 /* indent-tabs-mode: nil */ 00342 /* End: */