00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "visca.h"
00025
00026 #include <core/exceptions/system.h>
00027
00028 #include <sys/ioctl.h>
00029 #include <termios.h>
00030 #include <fcntl.h>
00031 #include <unistd.h>
00032 #include <cerrno>
00033 #include <cstring>
00034 #include <cstdlib>
00035
00036
00037
00038
00039
00040
00041
00042
00043 ViscaException::ViscaException(const char *msg)
00044 : Exception(msg)
00045 {}
00046
00047
00048
00049
00050
00051
00052 ViscaException::ViscaException(const char *msg, const int _errno)
00053 : Exception(_errno, msg)
00054 {}
00055
00056
00057
00058
00059
00060
00061 ViscaInquiryRunningException::ViscaInquiryRunningException()
00062 : ViscaException("Inquiry already running")
00063 {}
00064
00065
00066
00067 const unsigned int Visca::VISCA_WHITEBLANCE_AUTO = VISCA_WB_AUTO;
00068
00069 const unsigned int Visca::VISCA_WHITEBALANCE_INDOOR = VISCA_WB_INDOOR;
00070
00071 const unsigned int Visca::VISCA_WHITEBALANCE_OUTDOOR = VISCA_WB_OUTDOOR;
00072
00073 const unsigned int Visca::VISCA_WHITEBALANCE_ONE_PUSH = VISCA_WB_ONE_PUSH;
00074
00075 const unsigned int Visca::VISCA_WHITEBALANCE_ATW = VISCA_WB_ATW;
00076
00077 const unsigned int Visca::VISCA_WHITEBALANCE_MANUAL = VISCA_WB_MANUAL;
00078
00079
00080 const unsigned int Visca::NONBLOCKING_PANTILT = 0;
00081
00082 const unsigned int Visca::NONBLOCKING_ZOOM = 1;
00083
00084 const unsigned int Visca::NONBLOCKING_NUM = 2;
00085
00086
00087 const unsigned int Visca::MAX_PAN_SPEED = 0x18;
00088
00089
00090 const unsigned int Visca::MAX_TILT_SPEED = 0x14;
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 Visca::Visca(const char *device_file, unsigned int def_timeout_ms, bool blocking)
00108 {
00109 __inquire = VISCA_RUNINQ_NONE;
00110 __device_file = strdup(device_file);
00111 __blocking = blocking;
00112 __opened = false;
00113 __default_timeout_ms = def_timeout_ms;
00114 __pan_speed = MAX_PAN_SPEED;
00115 __tilt_speed = MAX_TILT_SPEED;
00116
00117 for (unsigned int i = 0; i < NONBLOCKING_NUM; ++i) {
00118 __nonblocking_sockets[i] = 0;
00119 __nonblocking_running[i] = false;
00120 }
00121
00122 open();
00123
00124 set_address();
00125 clear();
00126 }
00127
00128
00129
00130 Visca::~Visca()
00131 {
00132 close();
00133 free(__device_file);
00134 }
00135
00136
00137
00138 void
00139 Visca::open() {
00140
00141 struct termios param;
00142
00143 __fd = ::open(__device_file, O_RDWR | O_NONBLOCK);
00144 if (! __fd) {
00145 throw ViscaException("Cannot open device", errno);
00146 }
00147
00148 if (tcgetattr(__fd, ¶m) == -1) {
00149 ViscaException ve("Getting the port parameters failed", errno);
00150 ::close(__fd);
00151 throw ve;
00152 }
00153
00154 cfsetospeed(¶m, B9600);
00155 cfsetispeed(¶m, B9600);
00156
00157 param.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00158 param.c_cflag |= CREAD;
00159 param.c_cflag |= CLOCAL;
00160
00161
00162 param.c_cc[VMIN] = 1;
00163 param.c_cc[VTIME] = 0;
00164
00165 param.c_iflag |= IGNBRK;
00166 param.c_iflag &= ~PARMRK;
00167 param.c_iflag &= ~ISTRIP;
00168 param.c_iflag &= ~INLCR;
00169 param.c_iflag &= ~IGNCR;
00170 param.c_iflag &= ~ICRNL;
00171 param.c_iflag &= ~IXON;
00172 param.c_iflag &= ~IXOFF;
00173
00174 param.c_lflag &= ~ECHO;
00175
00176
00177 param.c_lflag |= IEXTEN;
00178 param.c_oflag &= ~OPOST;
00179
00180
00181
00182
00183
00184 param.c_cflag &= ~CS5 & ~CS6 & ~CS7 & ~CS8;
00185
00186 param.c_cflag |= CS8;
00187
00188
00189 param.c_cflag &=~(PARENB & PARODD);
00190
00191
00192 param.c_cflag &= ~CSTOPB;
00193
00194 if (tcsetattr(__fd, TCSANOW, ¶m) != 0) {
00195 ViscaException ve("Setting the port parameters failed", errno);
00196 ::close(__fd);
00197 throw ve;
00198 }
00199
00200 __opened = true;
00201
00202 __sender = VISCA_BUS_0;
00203 __recipient = VISCA_BUS_1;
00204
00205 #ifdef TIMETRACKER_VISCA
00206 __tt = new TimeTracker();
00207 __ttc_pantilt_get_send = __tt->addClass("getPanTilt: send");
00208 __ttc_pantilt_get_read = __tt->addClass("getPanTilt: read");
00209 __ttc_pantilt_get_handle = __tt->addClass("getPanTilt: handling responses");
00210 __ttc_pantilt_get_interpret = __tt->addClass("getPanTilt: interpreting");
00211 #endif
00212 }
00213
00214
00215
00216 void
00217 Visca::close()
00218 {
00219 if (__opened) {
00220 __opened = false;
00221 ::close(__fd);
00222 }
00223 }
00224
00225
00226
00227 void
00228 Visca::set_address()
00229 {
00230 unsigned char recp_backup = __recipient;
00231 __recipient = VISCA_BUS_BROADCAST;
00232 __obuffer[1] = 0x30;
00233 __obuffer[2] = 0x01;
00234 __obuffer_length = 2;
00235
00236 try {
00237 send();
00238 recv();
00239 } catch (ViscaException &e) {
00240 __recipient = recp_backup;
00241 throw;
00242 }
00243
00244 __recipient = recp_backup;
00245 }
00246
00247
00248
00249 void
00250 Visca::clear()
00251 {
00252 if (!__opened) throw ViscaException("Serial port not open");
00253
00254 __obuffer[1] = 0x01;
00255 __obuffer[2] = 0x00;
00256 __obuffer[3] = 0x01;
00257 __obuffer_length = 3;
00258
00259 try {
00260 send();
00261 recv();
00262 } catch (ViscaException &e) {
00263 e.append("clear() failed");
00264 throw;
00265 }
00266 }
00267
00268
00269
00270 void
00271 Visca::send()
00272 {
00273 if (!__opened) throw ViscaException("Serial port not open");
00274
00275
00276 __obuffer[0] = 0x80;
00277 __obuffer[0] |= (__sender << 4);
00278 __obuffer[0] |= __recipient;
00279
00280 __obuffer[++__obuffer_length] = VISCA_TERMINATOR;
00281 ++__obuffer_length;
00282
00283 int written = write(__fd, __obuffer, __obuffer_length);
00284
00285
00286
00287
00288
00289 if (written < __obuffer_length) {
00290 throw ViscaException("Not all bytes send");
00291 }
00292 }
00293
00294
00295
00296
00297
00298 bool
00299 Visca::data_available()
00300 {
00301 int num_bytes = 0;
00302 ioctl(__fd, FIONREAD, &num_bytes);
00303 return (num_bytes > 0);
00304 }
00305
00306
00307
00308
00309
00310 void
00311 Visca::recv(unsigned int timeout_ms)
00312 {
00313 if (timeout_ms == 0xFFFFFFFF) timeout_ms = __default_timeout_ms;
00314 try {
00315 recv_packet(timeout_ms);
00316 } catch (ViscaException &e) {
00317 e.append("Receiving failed, recv_packet() call failed");
00318 throw;
00319 }
00320
00321
00322 unsigned char type = __ibuffer[1] & 0xF0;
00323 while (type == VISCA_RESPONSE_ACK) {
00324 try {
00325 recv_packet(timeout_ms);
00326 } catch (ViscaException &e) {
00327 e.append("Receiving failed, recv_packet() call 2 failed");
00328 throw;
00329 }
00330 type = __ibuffer[1] & 0xF0;
00331 }
00332
00333 switch (type) {
00334 case VISCA_RESPONSE_CLEAR:
00335 case VISCA_RESPONSE_ADDRESS:
00336 case VISCA_RESPONSE_COMPLETED:
00337 case VISCA_RESPONSE_ERROR:
00338 break;
00339 default:
00340 throw fawkes::Exception("Receiving failed, unexpected packet type %u received",
00341 type);
00342 }
00343 }
00344
00345
00346
00347
00348
00349 void
00350 Visca::recv_ack(unsigned int *socket)
00351 {
00352 try {
00353 recv_packet(__default_timeout_ms);
00354 } catch (ViscaException &e) {
00355 throw ViscaException("recv_ack(): recv_packet() failed");
00356 }
00357
00358
00359 unsigned char type = __ibuffer[1] & 0xF0;
00360 while (type != VISCA_RESPONSE_ACK) {
00361
00362 try {
00363 handle_response();
00364 recv_packet(__default_timeout_ms);
00365 } catch (ViscaException &e) {
00366 e.append("Handling message of type %u failed", type);
00367 throw;
00368 }
00369 type = __ibuffer[1] & 0xF0;
00370 }
00371
00372
00373 if (socket != NULL) {
00374 *socket = __ibuffer[1] & 0x0F;
00375 }
00376
00377 }
00378
00379
00380
00381
00382
00383
00384 void
00385 Visca::send_nonblocking(unsigned int *socket)
00386 {
00387 try {
00388 send();
00389 recv_ack(socket);
00390 } catch (ViscaException &e) {
00391 e.append("Non-blocking send failed!");
00392 throw;
00393 }
00394 }
00395
00396
00397
00398
00399
00400 void
00401 Visca::finish_nonblocking( unsigned int socket )
00402 {
00403 for (unsigned int i = 0; i < NONBLOCKING_NUM; ++i) {
00404 if (__nonblocking_sockets[i] == socket) {
00405 __nonblocking_sockets[i] = 0;
00406 __nonblocking_running[i] = false;
00407 return;
00408 }
00409 }
00410
00411 throw ViscaException("finish_nonblocking() failed: socket not found");
00412 }
00413
00414
00415
00416
00417
00418
00419 bool
00420 Visca::is_nonblocking_finished(unsigned int item) const
00421 {
00422 if (item >= NONBLOCKING_NUM) {
00423 throw ViscaException("Invalid item number");
00424 }
00425 return ! __nonblocking_running[item];
00426 }
00427
00428
00429
00430
00431 void
00432 Visca::send_with_reply()
00433 {
00434 try {
00435 send();
00436 recv();
00437 } catch (ViscaException &e) {
00438 e.append("Sending with reply failed");
00439 throw;
00440 }
00441 }
00442
00443
00444
00445
00446
00447 void
00448 Visca::recv_packet(unsigned int timeout_ms)
00449 {
00450
00451 timeval timeout = {0, timeout_ms * 1000};
00452
00453 fd_set read_fds;
00454 FD_ZERO(&read_fds);
00455 FD_SET(__fd, &read_fds);
00456
00457 int rv = 0;
00458 rv = select(__fd + 1, &read_fds, NULL, NULL, &timeout);
00459
00460 if ( rv == -1 ) {
00461 throw fawkes::Exception(errno, "Select on FD failed");
00462 } else if ( rv == 0 ) {
00463 throw fawkes::TimeoutException("Timeout reached while waiting for incoming data");
00464 }
00465
00466
00467 int bytes_read = read(__fd, __ibuffer, 1);
00468 int pos = 0;
00469 while (__ibuffer[pos] != VISCA_TERMINATOR) {
00470 bytes_read = read(__fd, &__ibuffer[++pos], 1);
00471 usleep(0);
00472 }
00473 __ibuffer_length = pos + 1;
00474
00475
00476
00477
00478
00479 }
00480
00481
00482
00483
00484 void
00485 Visca::handle_response()
00486 {
00487 unsigned int type = __ibuffer[1] & 0xF0;
00488 unsigned int socket = __ibuffer[1] & 0x0F;
00489
00490 if (socket == 0) {
00491
00492
00493 return;
00494 }
00495
00496 if ( type == VISCA_RESPONSE_COMPLETED ) {
00497
00498 try {
00499 finish_nonblocking( __ibuffer[1] & 0x0F );
00500 } catch (ViscaException &e) {
00501
00502
00503
00504 }
00505 } else if ( type == VISCA_RESPONSE_ERROR ) {
00506 finish_nonblocking( __ibuffer[1] & 0x0F );
00507
00508 } else {
00509
00510
00511
00512
00513 }
00514
00515 }
00516
00517
00518
00519
00520
00521 void
00522 Visca::cancel_command( unsigned int socket )
00523 {
00524 unsigned char cancel_socket = socket & 0x0000000F;
00525
00526 __obuffer[1] = VISCA_CANCEL | cancel_socket;
00527 __obuffer_length = 1;
00528
00529 try {
00530 send_with_reply();
00531 } catch (ViscaException &e) {
00532 e.append("cancel_command() failed");
00533 throw;
00534 }
00535
00536 if ( ((__ibuffer[1] & 0xF0) == VISCA_RESPONSE_ERROR) &&
00537 ((__ibuffer[1] & 0x0F) == cancel_socket) &&
00538 ((__ibuffer[2] == VISCA_ERROR_CANCELLED)) ) {
00539 return;
00540 } else {
00541 throw ViscaException("Command could not be cancelled");
00542 }
00543 }
00544
00545
00546
00547 void
00548 Visca::process()
00549 {
00550
00551 __inquire = VISCA_RUNINQ_NONE;
00552
00553 while (data_available()) {
00554 try {
00555 recv();
00556 handle_response();
00557 } catch (ViscaException &e) {
00558
00559 return;
00560 }
00561 }
00562 }
00563
00564
00565
00566
00567
00568
00569 void
00570 Visca::set_pan_tilt(int pan, int tilt)
00571 {
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 unsigned short int tilt_val = 0 + tilt;
00587 unsigned short int pan_val = 0 + pan;
00588
00589 __obuffer[1] = VISCA_COMMAND;
00590 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00591 __obuffer[3] = VISCA_PT_ABSOLUTE_POSITION;
00592 __obuffer[4] = __pan_speed;
00593 __obuffer[5] = __tilt_speed;
00594
00595
00596 __obuffer[6] = (pan_val & 0xf000) >> 12;
00597 __obuffer[7] = (pan_val & 0x0f00) >> 8;
00598 __obuffer[8] = (pan_val & 0x00f0) >> 4;
00599 __obuffer[9] = (pan_val & 0x000f);
00600
00601 __obuffer[10] = (tilt_val & 0xf000) >> 12;
00602 __obuffer[11] = (tilt_val & 0x0f00) >> 8;
00603 __obuffer[12] = (tilt_val & 0x00f0) >> 4;
00604 __obuffer[13] = (tilt_val & 0x000f);
00605
00606 __obuffer_length = 13;
00607
00608 try {
00609 if (! __blocking) {
00610 __nonblocking_running[ NONBLOCKING_PANTILT ] = true;
00611 send_nonblocking( &(__nonblocking_sockets[ NONBLOCKING_PANTILT ]) );
00612 } else {
00613 send_with_reply();
00614 }
00615 } catch (ViscaException &e) {
00616 e.append("setPanTilt() failed");
00617 throw;
00618 }
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 void
00628 Visca::set_pan_tilt_speed(unsigned char pan_speed, unsigned char tilt_speed)
00629 {
00630 if (pan_speed > MAX_PAN_SPEED) {
00631 throw fawkes::Exception("Pan speed too hight, max: %u des: %u", MAX_PAN_SPEED, pan_speed);
00632 }
00633 if (tilt_speed > MAX_TILT_SPEED) {
00634 throw fawkes::Exception("Tilt speed too hight, max: %u des: %u", MAX_TILT_SPEED, tilt_speed);
00635 }
00636
00637 __pan_speed = pan_speed;
00638 __tilt_speed = tilt_speed;
00639 }
00640
00641
00642
00643
00644
00645
00646 void
00647 Visca::get_pan_tilt_speed(unsigned char &pan_speed, unsigned char &tilt_speed)
00648 {
00649 pan_speed = __pan_speed;
00650 tilt_speed = __tilt_speed;
00651 }
00652
00653
00654 void
00655 Visca::start_get_pan_tilt()
00656 {
00657
00658 if ( __inquire ) throw ViscaInquiryRunningException();
00659
00660 __inquire = VISCA_RUNINQ_PANTILT;
00661
00662 __obuffer[1] = VISCA_INQUIRY;
00663 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00664 __obuffer[3] = VISCA_PT_POSITION_INQ;
00665 __obuffer_length = 3;
00666
00667 try {
00668 send();
00669 } catch (ViscaException &e) {
00670 e.append("startGetPanTilt() failed");
00671 throw;
00672 }
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 void
00684 Visca::get_pan_tilt(int &pan, int &tilt)
00685 {
00686
00687 if ( __inquire ) {
00688 if ( __inquire != VISCA_RUNINQ_PANTILT ) {
00689 throw ViscaException("Inquiry running, but it is not a pan/tilt inquiry");
00690 } else {
00691 #ifdef TIMETRACKER_VISCA
00692 __tt->ping_start( __ttc_pantilt_get_read );
00693 #endif
00694 try {
00695 recv();
00696 } catch (ViscaException &e) {
00697
00698 }
00699 #ifdef TIMETRACKER_VISCA
00700 __tt->ping_end( __ttc_pantilt_get_read );
00701 #endif
00702 }
00703 } else {
00704
00705 __obuffer[1] = VISCA_INQUIRY;
00706 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00707 __obuffer[3] = VISCA_PT_POSITION_INQ;
00708 __obuffer_length = 3;
00709
00710 try {
00711 #ifdef TIMETRACKER_VISCA
00712 __tt->ping_start( __ttc_pantilt_get_send );
00713 send();
00714 __tt->ping_end( __ttc_pantilt_get_send );
00715 __tt->ping_start( __ttc_pantilt_get_read );
00716 recv();
00717 __tt->ping_end( __ttc_pantilt_get_read );
00718 #else
00719 send_with_reply();
00720 #endif
00721 } catch (ViscaException &e) {
00722
00723 }
00724 }
00725
00726 #ifdef TIMETRACKER_VISCA
00727 __tt->ping_start( __ttc_pantilt_get_handle );
00728 #endif
00729
00730 while (__ibuffer[1] != VISCA_RESPONSE_COMPLETED) {
00731
00732
00733 try {
00734 handle_response();
00735 recv();
00736 } catch (ViscaException &e) {
00737
00738 }
00739 }
00740
00741 #ifdef TIMETRACKER_VISCA
00742 __tt->ping_end( __ttc_pantilt_get_handle );
00743 __tt->ping_start( __ttc_pantilt_get_interpret );
00744 #endif
00745
00746
00747
00748 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
00749 unsigned short int pan_val = 0;
00750 unsigned short int tilt_val = 0;
00751
00752 pan_val |= (__ibuffer[2] & 0x0F) << 12;
00753 pan_val |= (__ibuffer[3] & 0x0F) << 8;
00754 pan_val |= (__ibuffer[4] & 0x0F) << 4;
00755 pan_val |= (__ibuffer[5] & 0x0F);
00756
00757 tilt_val |= (__ibuffer[6] & 0x0F) << 12;
00758 tilt_val |= (__ibuffer[7] & 0x0F) << 8;
00759 tilt_val |= (__ibuffer[8] & 0x0F) << 4;
00760 tilt_val |= (__ibuffer[9] & 0x0F);
00761
00762 if (pan_val < 0x8000) {
00763
00764 pan = pan_val;
00765 } else {
00766
00767 pan = pan_val - 0xFFFF;
00768 }
00769
00770 if (tilt_val < 0x8000) {
00771
00772 tilt = tilt_val;
00773 } else {
00774
00775 tilt = tilt_val - 0xFFFF;
00776 }
00777
00778 } else {
00779 throw ViscaException("getPanTilt(): Wrong response received");
00780 }
00781 #ifdef TIMETRACKER_VISCA
00782 __tt->ping_end( __ttc_pantilt_get_interpret );
00783 __tt->print_to_stdout();
00784 #endif
00785
00786 __inquire = VISCA_RUNINQ_NONE;
00787 }
00788
00789
00790
00791 void
00792 Visca::reset_pan_tilt_limit()
00793 {
00794 __obuffer[1] = VISCA_COMMAND;
00795 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00796 __obuffer[3] = VISCA_PT_LIMITSET;
00797 __obuffer[3] = VISCA_PT_LIMITSET_CLEAR;
00798 __obuffer[4] = VISCA_PT_LIMITSET_SET_UR;
00799 __obuffer[5] = 0x07;
00800 __obuffer[6] = 0x0F;
00801 __obuffer[7] = 0x0F;
00802 __obuffer[8] = 0x0F;
00803 __obuffer[9] = 0x07;
00804 __obuffer[10] = 0x0F;
00805 __obuffer[11] = 0x0F;
00806 __obuffer[12] = 0x0F;
00807 __obuffer_length = 12;
00808
00809 try {
00810 send_with_reply();
00811
00812 __obuffer[4] = VISCA_PT_LIMITSET_SET_DL;
00813
00814 send_with_reply();
00815 } catch (ViscaException &e) {
00816 e.append("resetPanTiltLimit() failed");
00817 throw;
00818 }
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828 void
00829 Visca::set_pan_tilt_limit(int pan_left, int pan_right, int tilt_up, int tilt_down)
00830 {
00831 try {
00832 __obuffer[1] = VISCA_COMMAND;
00833 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00834 __obuffer[3] = VISCA_PT_LIMITSET;
00835 __obuffer[3] = VISCA_PT_LIMITSET_SET;
00836 __obuffer[4] = VISCA_PT_LIMITSET_SET_UR;
00837
00838 __obuffer[5] = (pan_right & 0xf000) >> 12;
00839 __obuffer[6] = (pan_right & 0x0f00) >> 8;
00840 __obuffer[7] = (pan_right & 0x00f0) >> 4;
00841 __obuffer[8] = (pan_right & 0x000f);
00842
00843 __obuffer[9] = (tilt_up & 0xf000) >> 12;
00844 __obuffer[10] = (tilt_up & 0x0f00) >> 8;
00845 __obuffer[11] = (tilt_up & 0x00f0) >> 4;
00846 __obuffer[12] = (tilt_up & 0x000f);
00847
00848 __obuffer_length = 12;
00849
00850 send_with_reply();
00851
00852 __obuffer[4] = VISCA_PT_LIMITSET_SET_DL;
00853
00854 __obuffer[5] = (pan_left & 0xf000) >> 12;
00855 __obuffer[6] = (pan_left & 0x0f00) >> 8;
00856 __obuffer[7] = (pan_left & 0x00f0) >> 4;
00857 __obuffer[8] = (pan_left & 0x000f);
00858
00859 __obuffer[9] = (tilt_down & 0xf000) >> 12;
00860 __obuffer[10] = (tilt_down & 0x0f00) >> 8;
00861 __obuffer[11] = (tilt_down & 0x00f0) >> 4;
00862 __obuffer[12] = (tilt_down & 0x000f);
00863
00864 send_with_reply();
00865 } catch (ViscaException &e) {
00866 e.append("setPanTiltLimit() failed");
00867 throw;
00868 }
00869 }
00870
00871
00872
00873 void
00874 Visca::reset_pan_tilt()
00875 {
00876 __obuffer[1] = VISCA_COMMAND;
00877 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
00878 __obuffer[3] = VISCA_PT_HOME;
00879 __obuffer_length = 3;
00880
00881 try {
00882 send_with_reply();
00883 } catch (ViscaException &e) {
00884 e.append("resetPanTilt() failed");
00885 throw;
00886 }
00887 }
00888
00889
00890
00891 void
00892 Visca::reset_zoom()
00893 {
00894 __obuffer[1] = VISCA_COMMAND;
00895 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
00896 __obuffer[3] = VISCA_ZOOM;
00897 __obuffer[4] = VISCA_ZOOM_STOP;
00898 __obuffer_length = 4;
00899
00900 try {
00901 send_with_reply();
00902 } catch (ViscaException &e) {
00903 e.append("resetZoom() failed");
00904 throw;
00905 }
00906 }
00907
00908
00909
00910
00911
00912 void
00913 Visca::set_zoom_speed_tele(unsigned int speed)
00914 {
00915 __obuffer[1] = VISCA_COMMAND;
00916 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
00917 __obuffer[3] = VISCA_ZOOM;
00918 __obuffer[4] = VISCA_ZOOM_TELE_SPEED;
00919
00920 __obuffer[5] = (speed & 0x000f) | 0x0020;
00921 __obuffer_length = 5;
00922
00923 try {
00924 send_with_reply();
00925 } catch (ViscaException &e) {
00926 e.append("setZoomSpeedTele() failed");
00927 throw;
00928 }
00929 }
00930
00931
00932
00933
00934
00935 void
00936 Visca::set_zoom_speed_wide(unsigned int speed)
00937 {
00938 __obuffer[1] = VISCA_COMMAND;
00939 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
00940 __obuffer[3] = VISCA_ZOOM;
00941 __obuffer[4] = VISCA_ZOOM_WIDE_SPEED;
00942
00943 __obuffer[5] = (speed & 0x000f) | 0x0020;
00944 __obuffer_length = 5;
00945
00946 try {
00947 send_with_reply();
00948 } catch (ViscaException &e) {
00949 e.append("setZoomSpeedWide() failed");
00950 throw;
00951 }
00952 }
00953
00954
00955
00956
00957
00958 void
00959 Visca::set_zoom(unsigned int zoom)
00960 {
00961 __obuffer[1] = VISCA_COMMAND;
00962 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
00963 __obuffer[3] = VISCA_ZOOM_VALUE;
00964
00965 __obuffer[4] = (zoom & 0xf000) >> 12;
00966 __obuffer[5] = (zoom & 0x0f00) >> 8;
00967 __obuffer[6] = (zoom & 0x00f0) >> 4;
00968 __obuffer[7] = (zoom & 0x000f);
00969
00970 __obuffer_length = 7;
00971
00972 try {
00973 send_with_reply();
00974 } catch (ViscaException &e) {
00975 e.append("setZoom() failed");
00976 throw;
00977 }
00978 }
00979
00980
00981
00982
00983
00984 void
00985 Visca::get_zoom(unsigned int *zoom)
00986 {
00987 __obuffer[1] = VISCA_INQUIRY;
00988 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
00989 __obuffer[3] = VISCA_ZOOM_VALUE;
00990 __obuffer_length = 3;
00991
00992 try {
00993 send_with_reply();
00994 } catch (ViscaException &e) {
00995 e.append("getZoom() failed");
00996 throw;
00997 }
00998
00999
01000 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
01001 unsigned short int zoom_val = 0;
01002
01003 zoom_val |= (__ibuffer[2] & 0x0F) << 12;
01004 zoom_val |= (__ibuffer[3] & 0x0F) << 8;
01005 zoom_val |= (__ibuffer[4] & 0x0F) << 4;
01006 zoom_val |= (__ibuffer[5] & 0x0F);
01007
01008 *zoom = zoom_val;
01009 } else {
01010 throw ViscaException("getZoom(): zoom inquiry failed, response code not VISCA_RESPONSE_COMPLETED");
01011 }
01012
01013 }
01014
01015
01016
01017
01018
01019 void
01020 Visca::set_zoom_digital_enabled(bool enabled)
01021 {
01022 __obuffer[1] = VISCA_COMMAND;
01023 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
01024 __obuffer[3] = VISCA_DZOOM;
01025 if (enabled) {
01026 __obuffer[4] = VISCA_DZOOM_ON;
01027 } else {
01028 __obuffer[4] = VISCA_DZOOM_OFF;
01029 }
01030 __obuffer_length = 4;
01031
01032 try {
01033 send_with_reply();
01034 } catch (ViscaException &e) {
01035 e.append("setZoomDigitalEnabled() failed");
01036 throw;
01037 }
01038 }
01039
01040
01041
01042
01043
01044 void
01045 Visca::apply_effect(unsigned char filter)
01046 {
01047 __obuffer[1] = VISCA_COMMAND;
01048 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
01049 __obuffer[3] = VISCA_PICTURE_EFFECT;
01050 __obuffer[4] = filter;
01051 __obuffer_length = 4;
01052
01053 try {
01054 send_with_reply();
01055 } catch (ViscaException &e) {
01056 e.append("applyEffect() failed");
01057 throw;
01058 }
01059 }
01060
01061
01062
01063 void
01064 Visca::reset_effect()
01065 {
01066 try {
01067 apply_effect(VISCA_PICTURE_EFFECT_OFF);
01068 } catch (ViscaException &e) {
01069 e.append("resetEffect() failed");
01070 throw;
01071 }
01072 }
01073
01074
01075
01076 void
01077 Visca::apply_effect_pastel()
01078 {
01079 try {
01080 apply_effect(VISCA_PICTURE_EFFECT_PASTEL);
01081 } catch (ViscaException &e) {
01082 e.append("applyEffectPastel() failed");
01083 throw;
01084 }
01085 }
01086
01087
01088
01089 void
01090 Visca::apply_effect_neg_art()
01091 {
01092 try {
01093 apply_effect(VISCA_PICTURE_EFFECT_NEGATIVE);
01094 } catch (ViscaException &e) {
01095 e.append("applyEffectNegArt() failed");
01096 throw;
01097 }
01098 }
01099
01100
01101
01102 void
01103 Visca::apply_effect_sepia()
01104 {
01105 try {
01106 apply_effect(VISCA_PICTURE_EFFECT_SEPIA);
01107 } catch (ViscaException &e) {
01108 e.append("applyEffectSepia() failed");
01109 throw;
01110 }
01111 }
01112
01113
01114
01115 void
01116 Visca::apply_effect_bnw()
01117 {
01118 try {
01119 apply_effect(VISCA_PICTURE_EFFECT_BW);
01120 } catch (ViscaException &e) {
01121 e.append("applyEffectBnW() failed");
01122 throw;
01123 }
01124 }
01125
01126
01127
01128 void
01129 Visca::apply_effect_solarize()
01130 {
01131 try {
01132 apply_effect(VISCA_PICTURE_EFFECT_SOLARIZE);
01133 } catch (ViscaException &e) {
01134 e.append("applyEffectSolarize() failed");
01135 throw;
01136 }
01137 }
01138
01139
01140
01141 void
01142 Visca::apply_effect_mosaic()
01143 {
01144 try {
01145 apply_effect(VISCA_PICTURE_EFFECT_MOSAIC);
01146 } catch (ViscaException &e) {
01147 e.append("applyEffectMosaic() failed");
01148 throw;
01149 }
01150 }
01151
01152
01153
01154 void
01155 Visca::apply_effect_slim()
01156 {
01157 try {
01158 apply_effect(VISCA_PICTURE_EFFECT_SLIM);
01159 } catch (ViscaException &e) {
01160 e.append("applyEffectSlim() failed");
01161 throw;
01162 }
01163 }
01164
01165
01166
01167 void
01168 Visca::apply_effect_stretch()
01169 {
01170 try {
01171 apply_effect(VISCA_PICTURE_EFFECT_STRETCH);
01172 } catch (ViscaException &e) {
01173 e.append("applyEffectStretch() failed");
01174 throw;
01175 }
01176 }
01177
01178
01179
01180
01181
01182 unsigned int
01183 Visca::get_white_balance_mode()
01184 {
01185 __obuffer[1] = VISCA_INQUIRY;
01186 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
01187 __obuffer[3] = VISCA_WB;
01188 __obuffer_length = 3;
01189
01190 try {
01191 send_with_reply();
01192 } catch (ViscaException &e) {
01193 e.append("getWhiteBalanceMode() failed");
01194 throw;
01195 }
01196
01197 while (__ibuffer[1] != VISCA_RESPONSE_COMPLETED) {
01198
01199
01200 try {
01201 handle_response();
01202 recv();
01203 } catch (ViscaException &e) {
01204 e.append("getWhiteBalanceMode() failed");
01205 throw;
01206 }
01207 }
01208
01209
01210 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
01211 return __ibuffer[2];
01212 } else {
01213 throw ViscaException("Did not get 'request completed' response");
01214 }
01215
01216 }
01217