Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * visca.cpp - Controller for Visca cams 00004 * 00005 * Generated: Wed Jun 08 12:08:17 2005 00006 * Copyright 2005-2009 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <cams/control/visca.h> 00025 00026 #include <sys/ioctl.h> 00027 #include <stdio.h> 00028 #include <sys/time.h> 00029 #include <termios.h> 00030 #include <fcntl.h> 00031 #include <errno.h> 00032 00033 #include <utils/system/console_colors.h> 00034 00035 namespace firevision { 00036 #if 0 /* just to make Emacs auto-indent happy */ 00037 } 00038 #endif 00039 00040 /** @class ViscaControlException <cams/control/visca.h> 00041 * Visca exception. 00042 */ 00043 00044 /** Constructor. 00045 * @param msg message of exception. 00046 */ 00047 ViscaControlException::ViscaControlException(const char *msg) 00048 : Exception(msg) 00049 { 00050 } 00051 00052 00053 /** Constructor with errno. 00054 * @param msg message prefix 00055 * @param _errno errno for additional error information. 00056 */ 00057 ViscaControlException::ViscaControlException(const char *msg, const int _errno) 00058 : Exception(msg, _errno) 00059 { 00060 } 00061 00062 /** @class ViscaControlInquiryRunningException <cams/control/visca.h> 00063 * Visca inquire running exception. 00064 */ 00065 00066 /** Constructor. */ 00067 ViscaControlInquiryRunningException::ViscaControlInquiryRunningException() 00068 : ViscaControlException("Inquiry already running") 00069 { 00070 } 00071 00072 /** Automatic white balance. */ 00073 const unsigned int ViscaControl::VISCA_WHITEBLANCE_AUTO = VISCA_WB_AUTO; 00074 /** Indoor white balance preset. */ 00075 const unsigned int ViscaControl::VISCA_WHITEBALANCE_INDOOR = VISCA_WB_INDOOR; 00076 /** Outdoor white balance preset. */ 00077 const unsigned int ViscaControl::VISCA_WHITEBALANCE_OUTDOOR = VISCA_WB_OUTDOOR; 00078 /** One push white balance preset. */ 00079 const unsigned int ViscaControl::VISCA_WHITEBALANCE_ONE_PUSH = VISCA_WB_ONE_PUSH; 00080 /** ATW white balance preset. */ 00081 const unsigned int ViscaControl::VISCA_WHITEBALANCE_ATW = VISCA_WB_ATW; 00082 /** Manual white balance. */ 00083 const unsigned int ViscaControl::VISCA_WHITEBALANCE_MANUAL = VISCA_WB_MANUAL; 00084 00085 /** @class ViscaControl <cams/control/visca.h> 00086 * Visca control protocol implementation over a serial line. 00087 * @author Tim Niemueller 00088 */ 00089 00090 00091 /** Constructor. 00092 * @param blocking if true, operate in blocking mode, false to operate in non-blocking mode. 00093 */ 00094 ViscaControl::ViscaControl(bool blocking) 00095 { 00096 opened = false; 00097 inquire = VISCA_RUNINQ_NONE; 00098 this->blocking = blocking; 00099 00100 for (unsigned int i = 0; i < VISCA_NONBLOCKING_NUM; ++i) { 00101 nonblocking_sockets[i] = 0; 00102 nonblocking_running[i] = false; 00103 } 00104 } 00105 00106 00107 /** Open serial port. 00108 * @param port port to open. 00109 */ 00110 void 00111 ViscaControl::open(const char *port) { 00112 00113 struct termios param; 00114 00115 dev = ::open(port, O_CREAT | O_RDWR | O_NONBLOCK); 00116 if (! dev) { 00117 throw ViscaControlException("Cannot open device", errno); 00118 } 00119 00120 if (tcgetattr(dev, ¶m) == -1) { 00121 ViscaControlException ve("Getting the port parameters failed", errno); 00122 ::close(dev); 00123 throw ve; 00124 } 00125 00126 cfsetospeed(¶m, B9600); 00127 cfsetispeed(¶m, B9600); 00128 00129 param.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 00130 param.c_cflag |= CREAD; 00131 param.c_cflag |= CLOCAL; 00132 //param.c_cflag |= CRTSCTS; 00133 00134 param.c_cc[VMIN] = 1; 00135 param.c_cc[VTIME] = 0; 00136 00137 param.c_iflag |= IGNBRK; 00138 param.c_iflag &= ~PARMRK; 00139 param.c_iflag &= ~ISTRIP; 00140 param.c_iflag &= ~INLCR; 00141 param.c_iflag &= ~IGNCR; 00142 param.c_iflag &= ~ICRNL; 00143 param.c_iflag &= ~IXON; 00144 param.c_iflag &= ~IXOFF; 00145 00146 param.c_lflag &= ~ECHO; 00147 00148 // hand shake 00149 param.c_lflag |= IEXTEN; 00150 param.c_oflag &= ~OPOST; //enable raw output 00151 00152 tcflow (dev, TCOON); 00153 tcflow (dev, TCION); 00154 00155 // number of data bits: 8 00156 param.c_cflag &= ~CS5 & ~CS6 & ~CS7 & ~CS8; 00157 00158 param.c_cflag |= CS8; 00159 00160 // parity: none 00161 param.c_cflag &=~(PARENB & PARODD); 00162 00163 // stop bits: 1 00164 param.c_cflag &= ~CSTOPB; 00165 00166 if (tcsetattr(dev, TCSANOW, ¶m) != 0) { 00167 ViscaControlException ve("Setting the port parameters failed", errno); 00168 ::close(dev); 00169 throw ve; 00170 } 00171 00172 opened = true; 00173 // Choose first camera by default 00174 sender = VISCA_BUS_0; 00175 recipient = VISCA_BUS_1; 00176 00177 #ifdef TIMETRACKER_VISCA 00178 tracker = new TimeTracker(); 00179 track_file.open("tracker_visca.txt"); 00180 ttcls_pantilt_get_send = tracker->addClass("getPanTilt: send"); 00181 ttcls_pantilt_get_read = tracker->addClass("getPanTilt: read"); 00182 ttcls_pantilt_get_handle = tracker->addClass("getPanTilt: handling responses"); 00183 ttcls_pantilt_get_interpret = tracker->addClass("getPanTilt: interpreting"); 00184 #endif 00185 00186 // success 00187 } 00188 00189 00190 /** Close port. */ 00191 void 00192 ViscaControl::close() 00193 { 00194 if (opened) { 00195 opened = false; 00196 ::close(dev); 00197 } 00198 } 00199 00200 00201 /** Set addresses of cameras. 00202 * @param num_cameras number of cameras on bus 00203 */ 00204 void 00205 ViscaControl::set_address(unsigned int num_cameras) 00206 { 00207 unsigned char recp_backup = recipient; 00208 recipient = VISCA_BUS_BROADCAST; 00209 obuffer[1] = 0x30; 00210 obuffer[2] = 0x01; 00211 obuffer_length = 2; 00212 00213 try { 00214 send(); 00215 recv(0); 00216 } catch (ViscaControlException &e) { 00217 e.append("set_address(%u) failed", num_cameras); 00218 throw; 00219 } 00220 00221 recipient = recp_backup; 00222 } 00223 00224 00225 /** Clear */ 00226 void 00227 ViscaControl::clear() 00228 { 00229 if (!opened) throw ViscaControlException("Serial port not open"); 00230 00231 obuffer[1] = 0x01; 00232 obuffer[2] = 0x00; 00233 obuffer[3] = 0x01; 00234 obuffer_length = 3; 00235 00236 try { 00237 send(); 00238 recv(0); 00239 } catch (ViscaControlException &e) { 00240 e.append("clear() failed"); 00241 throw; 00242 } 00243 } 00244 00245 00246 /** Send outbound queue. */ 00247 void 00248 ViscaControl::send() 00249 { 00250 if (!opened) throw ViscaControlException("Serial port not open"); 00251 00252 // Set first bit to 1 00253 obuffer[0] = 0x80; 00254 obuffer[0] |= (sender << 4); 00255 obuffer[0] |= recipient; 00256 00257 obuffer[++obuffer_length] = VISCA_TERMINATOR; 00258 ++obuffer_length; 00259 00260 int written = write(dev, obuffer, obuffer_length); 00261 //printf("ViscaControl sent: "); 00262 //for (int i = 0; i < obuffer_length; ++i) { 00263 // printf("%02X", obuffer[i]); 00264 //} 00265 //printf("\n"); 00266 if (written < obuffer_length) { 00267 throw ViscaControlException("Not all bytes send"); 00268 } 00269 } 00270 00271 00272 /** Check data availability. 00273 * @return true if data is available, false otherwise 00274 */ 00275 bool 00276 ViscaControl::data_available() 00277 { 00278 int num_bytes = 0; 00279 ioctl(dev, FIONREAD, &num_bytes); 00280 return (num_bytes > 0); 00281 } 00282 00283 00284 /** Receive data. 00285 * @param max_wait_ms maximum wait time in miliseconds 00286 */ 00287 void 00288 ViscaControl::recv(unsigned int max_wait_ms) 00289 { 00290 try { 00291 recv_packet(max_wait_ms); 00292 } catch (ViscaControlException &e) { 00293 e.append("Receiving failed, recv_packet() call failed"); 00294 throw; 00295 } 00296 00297 // Get type of message 00298 unsigned char type = ibuffer[1] & 0xF0; 00299 while (type == VISCA_RESPONSE_ACK) { 00300 try { 00301 recv_packet(max_wait_ms); 00302 } catch (ViscaControlException &e) { 00303 e.append("Receiving failed, recv_packet() call 2 failed"); 00304 throw; 00305 } 00306 type = ibuffer[1] & 0xF0; 00307 } 00308 00309 switch (type) { 00310 case VISCA_RESPONSE_CLEAR: 00311 case VISCA_RESPONSE_ADDRESS: 00312 case VISCA_RESPONSE_COMPLETED: 00313 case VISCA_RESPONSE_ERROR: 00314 break; 00315 default: 00316 throw ViscaControlException("Receiving failed, unexpected packet type received"); 00317 } 00318 } 00319 00320 00321 /** Receive ACK packet. 00322 * @param socket contains the socket that the ACK was received on upon return 00323 */ 00324 void 00325 ViscaControl::recv_ack(unsigned int *socket) 00326 { 00327 try { 00328 recv_packet(0); 00329 } catch (ViscaControlException &e) { 00330 throw ViscaControlException("recv_ack(): recv_packet() failed"); 00331 } 00332 00333 // Get type of message 00334 unsigned char type = ibuffer[1] & 0xF0; 00335 while (type != VISCA_RESPONSE_ACK) { 00336 00337 try { 00338 handle_response(); 00339 recv_packet(); 00340 } catch (ViscaControlException &e) { 00341 e.append("Handling message of type %u failed", type); 00342 throw; 00343 } 00344 type = ibuffer[1] & 0xF0; 00345 } 00346 00347 // Got an ack now 00348 if (socket != NULL) { 00349 *socket = ibuffer[1] & 0x0F; 00350 } 00351 00352 } 00353 00354 00355 /** Send non-blocking. 00356 * Does a non-blocking send. 00357 * @param socket the socket that was used to send the request. 00358 */ 00359 void 00360 ViscaControl::send_nonblocking(unsigned int *socket) 00361 { 00362 try { 00363 send(); 00364 recv_ack(socket); 00365 } catch (ViscaControlException &e) { 00366 e.append("Non-blocking send failed!"); 00367 throw; 00368 } 00369 } 00370 00371 00372 /** Send and wait for reply, blocking. 00373 */ 00374 void 00375 ViscaControl::send_with_reply() 00376 { 00377 try { 00378 send(); 00379 recv(); 00380 } catch (ViscaControlException &e) { 00381 e.append("Sending with reply failed"); 00382 throw; 00383 } 00384 } 00385 00386 00387 /** Receive a packet. 00388 * @param max_wait_ms maximum wait time in miliseconds 00389 */ 00390 void 00391 ViscaControl::recv_packet(unsigned int max_wait_ms) 00392 { 00393 // wait for message 00394 timeval start, now; 00395 unsigned int diff_msec = 0; 00396 gettimeofday(&start, NULL); 00397 00398 int num_bytes = 0; 00399 ioctl(dev, FIONREAD, &num_bytes); 00400 while ( ((max_wait_ms == 0) || (diff_msec < max_wait_ms)) && (num_bytes == 0)) { 00401 usleep(max_wait_ms / 100); 00402 ioctl(dev, FIONREAD, &num_bytes); 00403 00404 gettimeofday(&now, NULL); 00405 diff_msec = (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec - start.tv_usec) / 1000; 00406 } 00407 if (num_bytes == 0) { 00408 throw ViscaControlException("recv_packet() failed: no bytes to read"); 00409 } 00410 00411 // get octets one by one 00412 int bytes_read = read(dev, ibuffer, 1); 00413 int pos = 0; 00414 while (ibuffer[pos] != VISCA_TERMINATOR) { 00415 bytes_read = read(dev, &ibuffer[++pos], 1); 00416 usleep(0); 00417 } 00418 ibuffer_length = pos + 1; 00419 //printf("ViscaControl read: "); 00420 //for (int i = 0; i < ibuffer_length; ++i) { 00421 // printf("%02X", ibuffer[i]); 00422 //} 00423 //printf("\n"); 00424 } 00425 00426 00427 /** Finish a non-blocking operation. 00428 * @param socket socket that the non-blocking operation was sent to 00429 */ 00430 void 00431 ViscaControl::finish_nonblocking( unsigned int socket ) 00432 { 00433 for (unsigned int i = 0; i < VISCA_NONBLOCKING_NUM; ++i) { 00434 if (nonblocking_sockets[i] == socket) { 00435 nonblocking_sockets[i] = 0; 00436 nonblocking_running[i] = false; 00437 return; 00438 } 00439 } 00440 00441 throw ViscaControlException("finish_nonblocking() failed: socket not found"); 00442 } 00443 00444 00445 /** Handle incoming response. */ 00446 void 00447 ViscaControl::handle_response() 00448 { 00449 unsigned int type = ibuffer[1] & 0xF0; 00450 unsigned int socket = ibuffer[1] & 0x0F; 00451 00452 if (socket == 0) { 00453 // This is an inquire response, do NOT handle! 00454 throw ViscaControlException("handle_response(): Received an inquire response, can't handle"); 00455 } 00456 00457 if ( type == VISCA_RESPONSE_COMPLETED ) { 00458 // Command has been finished 00459 try { 00460 finish_nonblocking( ibuffer[1] & 0x0F ); 00461 } catch (ViscaControlException &e) { 00462 // Ignore, happens sometimes without effect 00463 // e.append("handle_response() failed, could not finish non-blocking"); 00464 // throw; 00465 } 00466 } else if ( type == VISCA_RESPONSE_ERROR ) { 00467 finish_nonblocking( ibuffer[1] & 0x0F ); 00468 throw ViscaControlException("handle_response(): got an error message from camera"); 00469 } else { 00470 ViscaControlException ve("Got unknown/unhandled response type"); 00471 ve.append("Received message of type %u", type); 00472 throw ve; 00473 } 00474 00475 } 00476 00477 00478 /** Cancel a running command. 00479 * @param socket socket that the command was send on 00480 */ 00481 void 00482 ViscaControl::cancel_command( unsigned int socket ) 00483 { 00484 unsigned char cancel_socket = socket & 0x0000000F; 00485 00486 obuffer[1] = VISCA_CANCEL | cancel_socket; 00487 obuffer_length = 1; 00488 00489 try { 00490 send_with_reply(); 00491 } catch (ViscaControlException &e) { 00492 e.append("cancel_command() failed"); 00493 throw; 00494 } 00495 00496 if ( ((ibuffer[1] & 0xF0) == VISCA_RESPONSE_ERROR) && 00497 ((ibuffer[1] & 0x0F) == cancel_socket) && 00498 ((ibuffer[2] == VISCA_ERROR_CANCELLED)) ) { 00499 return; 00500 } else { 00501 throw ViscaControlException("Command could not be cancelled"); 00502 } 00503 } 00504 00505 00506 /** Process incoming data. */ 00507 void 00508 ViscaControl::process() 00509 { 00510 00511 inquire = VISCA_RUNINQ_NONE; 00512 00513 while (data_available()) { 00514 try { 00515 recv(); 00516 handle_response(); 00517 } catch (ViscaControlException &e) { 00518 // Ignore this error 00519 return; 00520 } 00521 } 00522 } 00523 00524 00525 /** Set pan tilt. 00526 * @param pan pan 00527 * @param tilt tilt 00528 */ 00529 void 00530 ViscaControl::setPanTilt(int pan, int tilt) 00531 { 00532 00533 // we do not to check for blocking, could not be called at 00534 // the same time if blocking... 00535 /* 00536 if ( nonblocking_running[ VISCA_NONBLOCKING_PANTILT] ) { 00537 cout << "Cancelling old setPanTilt" << endl; 00538 if (cancel_command( nonblocking_sockets[ VISCA_NONBLOCKING_PANTILT ] ) != VISCA_SUCCESS) { 00539 cout << "ViscaControl: Could not cancel old non-blocking pan/tilt command. Not setting new pan/tilt." << endl; 00540 return VISCA_E_CANCEL; 00541 } 00542 nonblocking_running[ VISCA_NONBLOCKING_PANTILT ] = false; 00543 } 00544 */ 00545 00546 unsigned short int tilt_val = 0 + tilt; 00547 unsigned short int pan_val = 0 + pan; 00548 00549 obuffer[1] = VISCA_COMMAND; 00550 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00551 obuffer[3] = VISCA_PT_ABSOLUTE_POSITION; 00552 // pan speed 00553 obuffer[4] = 0x18; // max speed 00554 // tilt speed 00555 obuffer[5] = 0x14; // max speed 00556 00557 // pan 00558 obuffer[6] = (pan_val & 0xf000) >> 12; 00559 obuffer[7] = (pan_val & 0x0f00) >> 8; 00560 obuffer[8] = (pan_val & 0x00f0) >> 4; 00561 obuffer[9] = (pan_val & 0x000f); 00562 // tilt 00563 obuffer[10] = (tilt_val & 0xf000) >> 12; 00564 obuffer[11] = (tilt_val & 0x0f00) >> 8; 00565 obuffer[12] = (tilt_val & 0x00f0) >> 4; 00566 obuffer[13] = (tilt_val & 0x000f); 00567 00568 obuffer_length = 13; 00569 00570 try { 00571 if (! blocking) { 00572 nonblocking_running[ VISCA_NONBLOCKING_PANTILT ] = true; 00573 send_nonblocking( &(nonblocking_sockets[ VISCA_NONBLOCKING_PANTILT ]) ); 00574 } else { 00575 send_with_reply(); 00576 } 00577 } catch (ViscaControlException &e) { 00578 e.append("setPanTilt() failed"); 00579 throw; 00580 } 00581 } 00582 00583 00584 /** Initiate a pan/tilt request, but do not wait for the reply. */ 00585 void 00586 ViscaControl::startGetPanTilt() 00587 { 00588 00589 if ( inquire ) throw ViscaControlInquiryRunningException(); 00590 00591 inquire = VISCA_RUNINQ_PANTILT; 00592 00593 obuffer[1] = VISCA_INQUIRY; 00594 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00595 obuffer[3] = VISCA_PT_POSITION_INQ; 00596 obuffer_length = 3; 00597 00598 try { 00599 send(); 00600 } catch (ViscaControlException &e) { 00601 e.append("startGetPanTilt() failed"); 00602 throw; 00603 } 00604 } 00605 00606 00607 /** Get pan and tilt values. 00608 * If you used startGetPanTilt() to initiate the query the result is 00609 * received and returned, otherwise a request is sent and the method blocks 00610 * until the answer has been received. 00611 * @param pan contains pan upon return 00612 * @param tilt contains tilt upon return 00613 */ 00614 void 00615 ViscaControl::getPanTilt(int *pan, int *tilt) 00616 { 00617 00618 if ( inquire ) { 00619 if ( inquire != VISCA_RUNINQ_PANTILT ) { 00620 throw ViscaControlException("Inquiry running, but it is not a pan/tilt inquiry"); 00621 } else { 00622 #ifdef TIMETRACKER_VISCA 00623 tracker->pingStart( ttcls_pantilt_get_read ); 00624 #endif 00625 try { 00626 recv(); 00627 } catch (ViscaControlException &e) { 00628 // Ignore 00629 } 00630 #ifdef TIMETRACKER_VISCA 00631 tracker->pingEnd( ttcls_pantilt_get_read ); 00632 #endif 00633 } 00634 } else { 00635 00636 obuffer[1] = VISCA_INQUIRY; 00637 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00638 obuffer[3] = VISCA_PT_POSITION_INQ; 00639 obuffer_length = 3; 00640 00641 try { 00642 #ifdef TIMETRACKER_VISCA 00643 tracker->pingStart( ttcls_pantilt_get_send ); 00644 send(); 00645 tracker->pingEnd( ttcls_pantilt_get_send ); 00646 tracker->pingStart( ttcls_pantilt_get_read ); 00647 recv(); 00648 tracker->pingEnd( ttcls_pantilt_get_read ); 00649 #else 00650 send_with_reply(); 00651 #endif 00652 } catch (ViscaControlException &e) { 00653 // Ignore 00654 } 00655 } 00656 00657 #ifdef TIMETRACKER_VISCA 00658 tracker->pingStart( ttcls_pantilt_get_handle ); 00659 #endif 00660 00661 while (ibuffer[1] != VISCA_RESPONSE_COMPLETED) { 00662 // inquire return from socket 0, so this may occur if there 00663 // are other responses waiting, handle them... 00664 try { 00665 handle_response(); 00666 recv(); 00667 } catch (ViscaControlException &e) { 00668 // Ignore 00669 } 00670 } 00671 00672 #ifdef TIMETRACKER_VISCA 00673 tracker->pingEnd( ttcls_pantilt_get_handle ); 00674 tracker->pingStart( ttcls_pantilt_get_interpret ); 00675 #endif 00676 00677 00678 // Extract information from ibuffer 00679 if ( ibuffer[1] == VISCA_RESPONSE_COMPLETED ) { 00680 unsigned short int pan_val = 0; 00681 unsigned short int tilt_val = 0; 00682 00683 pan_val |= (ibuffer[2] & 0x0F) << 12; 00684 pan_val |= (ibuffer[3] & 0x0F) << 8; 00685 pan_val |= (ibuffer[4] & 0x0F) << 4; 00686 pan_val |= (ibuffer[5] & 0x0F); 00687 00688 tilt_val |= (ibuffer[6] & 0x0F) << 12; 00689 tilt_val |= (ibuffer[7] & 0x0F) << 8; 00690 tilt_val |= (ibuffer[8] & 0x0F) << 4; 00691 tilt_val |= (ibuffer[9] & 0x0F); 00692 00693 if (pan_val < 0x8000) { 00694 // The value must be positive 00695 *pan = pan_val; 00696 } else { 00697 // negative value 00698 *pan = pan_val - 0xFFFF; 00699 } 00700 00701 if (tilt_val < 0x8000) { 00702 // The value must be positive 00703 *tilt = tilt_val; 00704 } else { 00705 // negative value 00706 *tilt = tilt_val - 0xFFFF; 00707 } 00708 00709 } else { 00710 throw ViscaControlException("getPanTilt(): Wrong response received"); 00711 } 00712 #ifdef TIMETRACKER_VISCA 00713 tracker->pingEnd( ttcls_pantilt_get_interpret ); 00714 tracker->printToStream( track_file ); 00715 #endif 00716 00717 inquire = VISCA_RUNINQ_NONE; 00718 } 00719 00720 00721 /** Reset pan/tilt limit. */ 00722 void 00723 ViscaControl::resetPanTiltLimit() 00724 { 00725 obuffer[1] = VISCA_COMMAND; 00726 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00727 obuffer[3] = VISCA_PT_LIMITSET; 00728 obuffer[3] = VISCA_PT_LIMITSET_CLEAR; 00729 obuffer[4] = VISCA_PT_LIMITSET_SET_UR; 00730 obuffer[5] = 0x07; 00731 obuffer[6] = 0x0F; 00732 obuffer[7] = 0x0F; 00733 obuffer[8] = 0x0F; 00734 obuffer[9] = 0x07; 00735 obuffer[10] = 0x0F; 00736 obuffer[11] = 0x0F; 00737 obuffer[12] = 0x0F; 00738 obuffer_length = 12; 00739 00740 try { 00741 send_with_reply(); 00742 00743 obuffer[4] = VISCA_PT_LIMITSET_SET_DL; 00744 00745 send_with_reply(); 00746 } catch (ViscaControlException &e) { 00747 e.append("resetPanTiltLimit() failed"); 00748 throw; 00749 } 00750 } 00751 00752 00753 /** Set pan tilt limit. 00754 * @param pan_left most left pan value 00755 * @param pan_right most right pan value 00756 * @param tilt_up most up tilt value 00757 * @param tilt_down most down tilt value 00758 */ 00759 void 00760 ViscaControl::setPanTiltLimit(int pan_left, int pan_right, int tilt_up, int tilt_down) 00761 { 00762 try { 00763 obuffer[1] = VISCA_COMMAND; 00764 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00765 obuffer[3] = VISCA_PT_LIMITSET; 00766 obuffer[3] = VISCA_PT_LIMITSET_SET; 00767 obuffer[4] = VISCA_PT_LIMITSET_SET_UR; 00768 // pan 00769 obuffer[5] = (pan_right & 0xf000) >> 12; 00770 obuffer[6] = (pan_right & 0x0f00) >> 8; 00771 obuffer[7] = (pan_right & 0x00f0) >> 4; 00772 obuffer[8] = (pan_right & 0x000f); 00773 // tilt 00774 obuffer[9] = (tilt_up & 0xf000) >> 12; 00775 obuffer[10] = (tilt_up & 0x0f00) >> 8; 00776 obuffer[11] = (tilt_up & 0x00f0) >> 4; 00777 obuffer[12] = (tilt_up & 0x000f); 00778 00779 obuffer_length = 12; 00780 00781 send_with_reply(); 00782 00783 obuffer[4] = VISCA_PT_LIMITSET_SET_DL; 00784 // pan 00785 obuffer[5] = (pan_left & 0xf000) >> 12; 00786 obuffer[6] = (pan_left & 0x0f00) >> 8; 00787 obuffer[7] = (pan_left & 0x00f0) >> 4; 00788 obuffer[8] = (pan_left & 0x000f); 00789 // tilt 00790 obuffer[9] = (tilt_down & 0xf000) >> 12; 00791 obuffer[10] = (tilt_down & 0x0f00) >> 8; 00792 obuffer[11] = (tilt_down & 0x00f0) >> 4; 00793 obuffer[12] = (tilt_down & 0x000f); 00794 00795 send_with_reply(); 00796 } catch (ViscaControlException &e) { 00797 e.append("setPanTiltLimit() failed"); 00798 throw; 00799 } 00800 } 00801 00802 00803 /** Reset pan/tilt. */ 00804 void 00805 ViscaControl::resetPanTilt() 00806 { 00807 obuffer[1] = VISCA_COMMAND; 00808 obuffer[2] = VISCA_CATEGORY_PAN_TILTER; 00809 obuffer[3] = VISCA_PT_HOME; 00810 obuffer_length = 3; 00811 00812 try { 00813 send_with_reply(); 00814 } catch (ViscaControlException &e) { 00815 e.append("resetPanTilt() failed"); 00816 throw; 00817 } 00818 } 00819 00820 00821 /** Reset zoom. */ 00822 void 00823 ViscaControl::resetZoom() 00824 { 00825 obuffer[1] = VISCA_COMMAND; 00826 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00827 obuffer[3] = VISCA_ZOOM; 00828 obuffer[4] = VISCA_ZOOM_STOP; 00829 obuffer_length = 4; 00830 00831 try { 00832 send_with_reply(); 00833 } catch (ViscaControlException &e) { 00834 e.append("resetZoom() failed"); 00835 throw; 00836 } 00837 } 00838 00839 00840 /** Set zoom speed in tele. 00841 * @param speed speed 00842 */ 00843 void 00844 ViscaControl::setZoomSpeedTele(unsigned int speed) 00845 { 00846 obuffer[1] = VISCA_COMMAND; 00847 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00848 obuffer[3] = VISCA_ZOOM; 00849 obuffer[4] = VISCA_ZOOM_TELE_SPEED; 00850 // zoom speed 00851 obuffer[5] = (speed & 0x000f) | 0x0020; 00852 obuffer_length = 5; 00853 00854 try { 00855 send_with_reply(); 00856 } catch (ViscaControlException &e) { 00857 e.append("setZoomSpeedTele() failed"); 00858 throw; 00859 } 00860 } 00861 00862 00863 /** Set zoom speed in wide angle. 00864 * @param speed speed 00865 */ 00866 void 00867 ViscaControl::setZoomSpeedWide(unsigned int speed) 00868 { 00869 obuffer[1] = VISCA_COMMAND; 00870 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00871 obuffer[3] = VISCA_ZOOM; 00872 obuffer[4] = VISCA_ZOOM_WIDE_SPEED; 00873 // zoom speed 00874 obuffer[5] = (speed & 0x000f) | 0x0020; 00875 obuffer_length = 5; 00876 00877 try { 00878 send_with_reply(); 00879 } catch (ViscaControlException &e) { 00880 e.append("setZoomSpeedWide() failed"); 00881 throw; 00882 } 00883 } 00884 00885 00886 /** Set zoom. 00887 * @param zoom zoom value 00888 */ 00889 void 00890 ViscaControl::setZoom(unsigned int zoom) 00891 { 00892 obuffer[1] = VISCA_COMMAND; 00893 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00894 obuffer[3] = VISCA_ZOOM_VALUE; 00895 // zoom 00896 obuffer[4] = (zoom & 0xf000) >> 12; 00897 obuffer[5] = (zoom & 0x0f00) >> 8; 00898 obuffer[6] = (zoom & 0x00f0) >> 4; 00899 obuffer[7] = (zoom & 0x000f); 00900 00901 obuffer_length = 7; 00902 00903 try { 00904 send_with_reply(); 00905 } catch (ViscaControlException &e) { 00906 e.append("setZoom() failed"); 00907 throw; 00908 } 00909 } 00910 00911 00912 /** Get zoom. 00913 * @param zoom contains zoom upon return. 00914 */ 00915 void 00916 ViscaControl::getZoom(unsigned int *zoom) 00917 { 00918 obuffer[1] = VISCA_INQUIRY; 00919 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00920 obuffer[3] = VISCA_ZOOM_VALUE; 00921 obuffer_length = 3; 00922 00923 try { 00924 send_with_reply(); 00925 } catch (ViscaControlException &e) { 00926 e.append("getZoom() failed"); 00927 throw; 00928 } 00929 00930 // Extract information from ibuffer 00931 if ( ibuffer[1] == VISCA_RESPONSE_COMPLETED ) { 00932 unsigned short int zoom_val = 0; 00933 00934 zoom_val |= (ibuffer[2] & 0x0F) << 12; 00935 zoom_val |= (ibuffer[3] & 0x0F) << 8; 00936 zoom_val |= (ibuffer[4] & 0x0F) << 4; 00937 zoom_val |= (ibuffer[5] & 0x0F); 00938 00939 *zoom = zoom_val; 00940 } else { 00941 throw ViscaControlException("getZoom(): zoom inquiry failed, response code not VISCA_RESPONSE_COMPLETED"); 00942 } 00943 00944 } 00945 00946 00947 /** Enable or disable digital zoome. 00948 * @param enabled true to enable digital zoom, false to disable 00949 */ 00950 void 00951 ViscaControl::setZoomDigitalEnabled(bool enabled) 00952 { 00953 obuffer[1] = VISCA_COMMAND; 00954 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00955 obuffer[3] = VISCA_DZOOM; 00956 if (enabled) { 00957 obuffer[4] = VISCA_DZOOM_ON; 00958 } else { 00959 obuffer[4] = VISCA_DZOOM_OFF; 00960 } 00961 obuffer_length = 4; 00962 00963 try { 00964 send_with_reply(); 00965 } catch (ViscaControlException &e) { 00966 e.append("setZoomDigitalEnabled() failed"); 00967 throw; 00968 } 00969 } 00970 00971 00972 /** Apply effect. 00973 * @param filter filter 00974 */ 00975 void 00976 ViscaControl::applyEffect(unsigned char filter) 00977 { 00978 obuffer[1] = VISCA_COMMAND; 00979 obuffer[2] = VISCA_CATEGORY_CAMERA1; 00980 obuffer[3] = VISCA_PICTURE_EFFECT; 00981 obuffer[4] = filter; 00982 obuffer_length = 4; 00983 00984 try { 00985 send_with_reply(); 00986 } catch (ViscaControlException &e) { 00987 e.append("applyEffect() failed"); 00988 throw; 00989 } 00990 } 00991 00992 00993 /** Reset effects. */ 00994 void 00995 ViscaControl::resetEffect() 00996 { 00997 try { 00998 applyEffect(VISCA_PICTURE_EFFECT_OFF); 00999 } catch (ViscaControlException &e) { 01000 e.append("resetEffect() failed"); 01001 throw; 01002 } 01003 } 01004 01005 01006 /** Apply pastel effect. */ 01007 void 01008 ViscaControl::applyEffectPastel() 01009 { 01010 try { 01011 applyEffect(VISCA_PICTURE_EFFECT_PASTEL); 01012 } catch (ViscaControlException &e) { 01013 e.append("applyEffectPastel() failed"); 01014 throw; 01015 } 01016 } 01017 01018 01019 /** Apply negative art effect. */ 01020 void 01021 ViscaControl::applyEffectNegArt() 01022 { 01023 try { 01024 applyEffect(VISCA_PICTURE_EFFECT_NEGATIVE); 01025 } catch (ViscaControlException &e) { 01026 e.append("applyEffectNegArt() failed"); 01027 throw; 01028 } 01029 } 01030 01031 01032 /** Apply sepia effect. */ 01033 void 01034 ViscaControl::applyEffectSepia() 01035 { 01036 try { 01037 applyEffect(VISCA_PICTURE_EFFECT_SEPIA); 01038 } catch (ViscaControlException &e) { 01039 e.append("applyEffectSepia() failed"); 01040 throw; 01041 } 01042 } 01043 01044 01045 /**Apply B/W effect */ 01046 void 01047 ViscaControl::applyEffectBnW() 01048 { 01049 try { 01050 applyEffect(VISCA_PICTURE_EFFECT_BW); 01051 } catch (ViscaControlException &e) { 01052 e.append("applyEffectBnW() failed"); 01053 throw; 01054 } 01055 } 01056 01057 01058 /** Apply solarize effect. */ 01059 void 01060 ViscaControl::applyEffectSolarize() 01061 { 01062 try { 01063 applyEffect(VISCA_PICTURE_EFFECT_SOLARIZE); 01064 } catch (ViscaControlException &e) { 01065 e.append("applyEffectSolarize() failed"); 01066 throw; 01067 } 01068 } 01069 01070 01071 /** Apply mosaic effect. */ 01072 void 01073 ViscaControl::applyEffectMosaic() 01074 { 01075 try { 01076 applyEffect(VISCA_PICTURE_EFFECT_MOSAIC); 01077 } catch (ViscaControlException &e) { 01078 e.append("applyEffectMosaic() failed"); 01079 throw; 01080 } 01081 } 01082 01083 01084 /** Apply slim effect. */ 01085 void 01086 ViscaControl::applyEffectSlim() 01087 { 01088 try { 01089 applyEffect(VISCA_PICTURE_EFFECT_SLIM); 01090 } catch (ViscaControlException &e) { 01091 e.append("applyEffectSlim() failed"); 01092 throw; 01093 } 01094 } 01095 01096 01097 /** Apply stretch effect. */ 01098 void 01099 ViscaControl::applyEffectStretch() 01100 { 01101 try { 01102 applyEffect(VISCA_PICTURE_EFFECT_STRETCH); 01103 } catch (ViscaControlException &e) { 01104 e.append("applyEffectStretch() failed"); 01105 throw; 01106 } 01107 } 01108 01109 01110 /** Get white balance mode. 01111 * @return white balance mode 01112 */ 01113 unsigned int 01114 ViscaControl::getWhiteBalanceMode() 01115 { 01116 obuffer[1] = VISCA_INQUIRY; 01117 obuffer[2] = VISCA_CATEGORY_CAMERA1; 01118 obuffer[3] = VISCA_WB; 01119 obuffer_length = 3; 01120 01121 try { 01122 send_with_reply(); 01123 } catch (ViscaControlException &e) { 01124 e.append("getWhiteBalanceMode() failed"); 01125 throw; 01126 } 01127 01128 while (ibuffer[1] != VISCA_RESPONSE_COMPLETED) { 01129 // inquire return from socket 0, so this may occur if there 01130 // are other responses waiting, handle them... 01131 try { 01132 handle_response(); 01133 recv(); 01134 } catch (ViscaControlException &e) { 01135 e.append("getWhiteBalanceMode() failed"); 01136 throw; 01137 } 01138 } 01139 01140 // Extract information from ibuffer 01141 if ( ibuffer[1] == VISCA_RESPONSE_COMPLETED ) { 01142 return ibuffer[2]; 01143 } else { 01144 throw ViscaControlException("Did not get 'request completed' response"); 01145 } 01146 01147 } 01148 01149 } // end namespace firevision