26 #include <core/exceptions/system.h>
28 #include <sys/ioctl.h>
53 : Exception(_errno, msg)
107 Visca::Visca(
const char *device_file,
unsigned int def_timeout_ms,
bool blocking)
109 __inquire = VISCA_RUNINQ_NONE;
110 __device_file = strdup(device_file);
111 __blocking = blocking;
113 __default_timeout_ms = def_timeout_ms;
118 __nonblocking_sockets[i] = 0;
119 __nonblocking_running[i] =
false;
141 struct termios param;
143 __fd =
::open(__device_file, O_RDWR | O_NONBLOCK);
148 if (tcgetattr(__fd, ¶m) == -1) {
154 cfsetospeed(¶m, B9600);
155 cfsetispeed(¶m, B9600);
157 param.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
158 param.c_cflag |= CREAD;
159 param.c_cflag |= CLOCAL;
162 param.c_cc[VMIN] = 1;
163 param.c_cc[VTIME] = 0;
165 param.c_iflag |= IGNBRK;
166 param.c_iflag &= ~PARMRK;
167 param.c_iflag &= ~ISTRIP;
168 param.c_iflag &= ~INLCR;
169 param.c_iflag &= ~IGNCR;
170 param.c_iflag &= ~ICRNL;
171 param.c_iflag &= ~IXON;
172 param.c_iflag &= ~IXOFF;
174 param.c_lflag &= ~ECHO;
177 param.c_lflag |= IEXTEN;
178 param.c_oflag &= ~OPOST;
184 param.c_cflag &= ~CS5 & ~CS6 & ~CS7 & ~CS8;
186 param.c_cflag |= CS8;
189 param.c_cflag &=~(PARENB & PARODD);
192 param.c_cflag &= ~CSTOPB;
194 if (tcsetattr(__fd, TCSANOW, ¶m) != 0) {
202 __sender = VISCA_BUS_0;
203 __recipient = VISCA_BUS_1;
205 #ifdef TIMETRACKER_VISCA
206 __tt =
new TimeTracker();
207 __ttc_pantilt_get_send = __tt->addClass(
"getPanTilt: send");
208 __ttc_pantilt_get_read = __tt->addClass(
"getPanTilt: read");
209 __ttc_pantilt_get_handle = __tt->addClass(
"getPanTilt: handling responses");
210 __ttc_pantilt_get_interpret = __tt->addClass(
"getPanTilt: interpreting");
230 unsigned char recp_backup = __recipient;
231 __recipient = VISCA_BUS_BROADCAST;
234 __obuffer_length = 2;
240 __recipient = recp_backup;
244 __recipient = recp_backup;
257 __obuffer_length = 3;
263 e.
append(
"clear() failed");
277 __obuffer[0] |= (__sender << 4);
278 __obuffer[0] |= __recipient;
280 __obuffer[++__obuffer_length] = VISCA_TERMINATOR;
283 int written = write(__fd, __obuffer, __obuffer_length);
289 if (written < __obuffer_length) {
302 ioctl(__fd, FIONREAD, &num_bytes);
303 return (num_bytes > 0);
313 if (timeout_ms == 0xFFFFFFFF) timeout_ms = __default_timeout_ms;
315 recv_packet(timeout_ms);
317 e.
append(
"Receiving failed, recv_packet() call failed");
322 unsigned char type = __ibuffer[1] & 0xF0;
323 while (type == VISCA_RESPONSE_ACK) {
325 recv_packet(timeout_ms);
327 e.
append(
"Receiving failed, recv_packet() call 2 failed");
330 type = __ibuffer[1] & 0xF0;
334 case VISCA_RESPONSE_CLEAR:
335 case VISCA_RESPONSE_ADDRESS:
336 case VISCA_RESPONSE_COMPLETED:
337 case VISCA_RESPONSE_ERROR:
353 recv_packet(__default_timeout_ms);
359 unsigned char type = __ibuffer[1] & 0xF0;
360 while (type != VISCA_RESPONSE_ACK) {
364 recv_packet(__default_timeout_ms);
366 e.
append(
"Handling message of type %u failed", type);
369 type = __ibuffer[1] & 0xF0;
373 if (socket != NULL) {
374 *socket = __ibuffer[1] & 0x0F;
391 e.
append(
"Non-blocking send failed!");
401 Visca::finish_nonblocking(
unsigned int socket )
404 if (__nonblocking_sockets[i] == socket) {
405 __nonblocking_sockets[i] = 0;
406 __nonblocking_running[i] =
false;
411 throw ViscaException(
"finish_nonblocking() failed: socket not found");
422 if (item >= NONBLOCKING_NUM) {
425 return ! __nonblocking_running[item];
438 e.
append(
"Sending with reply failed");
448 Visca::recv_packet(
unsigned int timeout_ms)
451 timeval timeout = {0, timeout_ms * 1000};
455 FD_SET(__fd, &read_fds);
458 rv = select(__fd + 1, &read_fds, NULL, NULL, &timeout);
462 }
else if ( rv == 0 ) {
467 if (read(__fd, __ibuffer, 1) != 1) {
472 while (__ibuffer[pos] != VISCA_TERMINATOR) {
473 if (read(__fd, &__ibuffer[++pos], 1) != 1) {
478 __ibuffer_length = pos + 1;
490 Visca::handle_response()
492 unsigned int type = __ibuffer[1] & 0xF0;
493 unsigned int socket = __ibuffer[1] & 0x0F;
501 if ( type == VISCA_RESPONSE_COMPLETED ) {
504 finish_nonblocking( __ibuffer[1] & 0x0F );
510 }
else if ( type == VISCA_RESPONSE_ERROR ) {
511 finish_nonblocking( __ibuffer[1] & 0x0F );
529 unsigned char cancel_socket = socket & 0x0000000F;
531 __obuffer[1] = VISCA_CANCEL | cancel_socket;
532 __obuffer_length = 1;
537 e.
append(
"cancel_command() failed");
541 if ( ((__ibuffer[1] & 0xF0) == VISCA_RESPONSE_ERROR) &&
542 ((__ibuffer[1] & 0x0F) == cancel_socket) &&
543 ((__ibuffer[2] == VISCA_ERROR_CANCELLED)) ) {
556 __inquire = VISCA_RUNINQ_NONE;
591 unsigned short int tilt_val = 0 + tilt;
592 unsigned short int pan_val = 0 + pan;
594 __obuffer[1] = VISCA_COMMAND;
595 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
596 __obuffer[3] = VISCA_PT_ABSOLUTE_POSITION;
597 __obuffer[4] = __pan_speed;
598 __obuffer[5] = __tilt_speed;
601 __obuffer[6] = (pan_val & 0xf000) >> 12;
602 __obuffer[7] = (pan_val & 0x0f00) >> 8;
603 __obuffer[8] = (pan_val & 0x00f0) >> 4;
604 __obuffer[9] = (pan_val & 0x000f);
606 __obuffer[10] = (tilt_val & 0xf000) >> 12;
607 __obuffer[11] = (tilt_val & 0x0f00) >> 8;
608 __obuffer[12] = (tilt_val & 0x00f0) >> 4;
609 __obuffer[13] = (tilt_val & 0x000f);
611 __obuffer_length = 13;
621 e.
append(
"setPanTilt() failed");
642 __pan_speed = pan_speed;
643 __tilt_speed = tilt_speed;
654 pan_speed = __pan_speed;
655 tilt_speed = __tilt_speed;
665 __inquire = VISCA_RUNINQ_PANTILT;
667 __obuffer[1] = VISCA_INQUIRY;
668 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
669 __obuffer[3] = VISCA_PT_POSITION_INQ;
670 __obuffer_length = 3;
675 e.
append(
"startGetPanTilt() failed");
693 if ( __inquire != VISCA_RUNINQ_PANTILT ) {
694 throw ViscaException(
"Inquiry running, but it is not a pan/tilt inquiry");
696 #ifdef TIMETRACKER_VISCA
697 __tt->ping_start( __ttc_pantilt_get_read );
704 #ifdef TIMETRACKER_VISCA
705 __tt->ping_end( __ttc_pantilt_get_read );
710 __obuffer[1] = VISCA_INQUIRY;
711 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
712 __obuffer[3] = VISCA_PT_POSITION_INQ;
713 __obuffer_length = 3;
716 #ifdef TIMETRACKER_VISCA
717 __tt->ping_start( __ttc_pantilt_get_send );
719 __tt->ping_end( __ttc_pantilt_get_send );
720 __tt->ping_start( __ttc_pantilt_get_read );
722 __tt->ping_end( __ttc_pantilt_get_read );
731 #ifdef TIMETRACKER_VISCA
732 __tt->ping_start( __ttc_pantilt_get_handle );
735 while (__ibuffer[1] != VISCA_RESPONSE_COMPLETED) {
746 #ifdef TIMETRACKER_VISCA
747 __tt->ping_end( __ttc_pantilt_get_handle );
748 __tt->ping_start( __ttc_pantilt_get_interpret );
753 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
754 unsigned short int pan_val = 0;
755 unsigned short int tilt_val = 0;
757 pan_val |= (__ibuffer[2] & 0x0F) << 12;
758 pan_val |= (__ibuffer[3] & 0x0F) << 8;
759 pan_val |= (__ibuffer[4] & 0x0F) << 4;
760 pan_val |= (__ibuffer[5] & 0x0F);
762 tilt_val |= (__ibuffer[6] & 0x0F) << 12;
763 tilt_val |= (__ibuffer[7] & 0x0F) << 8;
764 tilt_val |= (__ibuffer[8] & 0x0F) << 4;
765 tilt_val |= (__ibuffer[9] & 0x0F);
767 if (pan_val < 0x8000) {
772 pan = pan_val - 0xFFFF;
775 if (tilt_val < 0x8000) {
780 tilt = tilt_val - 0xFFFF;
786 #ifdef TIMETRACKER_VISCA
787 __tt->ping_end( __ttc_pantilt_get_interpret );
788 __tt->print_to_stdout();
791 __inquire = VISCA_RUNINQ_NONE;
799 __obuffer[1] = VISCA_COMMAND;
800 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
801 __obuffer[3] = VISCA_PT_LIMITSET;
802 __obuffer[3] = VISCA_PT_LIMITSET_CLEAR;
803 __obuffer[4] = VISCA_PT_LIMITSET_SET_UR;
809 __obuffer[10] = 0x0F;
810 __obuffer[11] = 0x0F;
811 __obuffer[12] = 0x0F;
812 __obuffer_length = 12;
817 __obuffer[4] = VISCA_PT_LIMITSET_SET_DL;
821 e.
append(
"resetPanTiltLimit() failed");
837 __obuffer[1] = VISCA_COMMAND;
838 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
839 __obuffer[3] = VISCA_PT_LIMITSET;
840 __obuffer[3] = VISCA_PT_LIMITSET_SET;
841 __obuffer[4] = VISCA_PT_LIMITSET_SET_UR;
843 __obuffer[5] = (pan_right & 0xf000) >> 12;
844 __obuffer[6] = (pan_right & 0x0f00) >> 8;
845 __obuffer[7] = (pan_right & 0x00f0) >> 4;
846 __obuffer[8] = (pan_right & 0x000f);
848 __obuffer[9] = (tilt_up & 0xf000) >> 12;
849 __obuffer[10] = (tilt_up & 0x0f00) >> 8;
850 __obuffer[11] = (tilt_up & 0x00f0) >> 4;
851 __obuffer[12] = (tilt_up & 0x000f);
853 __obuffer_length = 12;
857 __obuffer[4] = VISCA_PT_LIMITSET_SET_DL;
859 __obuffer[5] = (pan_left & 0xf000) >> 12;
860 __obuffer[6] = (pan_left & 0x0f00) >> 8;
861 __obuffer[7] = (pan_left & 0x00f0) >> 4;
862 __obuffer[8] = (pan_left & 0x000f);
864 __obuffer[9] = (tilt_down & 0xf000) >> 12;
865 __obuffer[10] = (tilt_down & 0x0f00) >> 8;
866 __obuffer[11] = (tilt_down & 0x00f0) >> 4;
867 __obuffer[12] = (tilt_down & 0x000f);
871 e.
append(
"setPanTiltLimit() failed");
881 __obuffer[1] = VISCA_COMMAND;
882 __obuffer[2] = VISCA_CATEGORY_PAN_TILTER;
883 __obuffer[3] = VISCA_PT_HOME;
884 __obuffer_length = 3;
889 e.
append(
"resetPanTilt() failed");
899 __obuffer[1] = VISCA_COMMAND;
900 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
901 __obuffer[3] = VISCA_ZOOM;
902 __obuffer[4] = VISCA_ZOOM_STOP;
903 __obuffer_length = 4;
908 e.
append(
"resetZoom() failed");
920 __obuffer[1] = VISCA_COMMAND;
921 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
922 __obuffer[3] = VISCA_ZOOM;
923 __obuffer[4] = VISCA_ZOOM_TELE_SPEED;
925 __obuffer[5] = (speed & 0x000f) | 0x0020;
926 __obuffer_length = 5;
931 e.
append(
"setZoomSpeedTele() failed");
943 __obuffer[1] = VISCA_COMMAND;
944 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
945 __obuffer[3] = VISCA_ZOOM;
946 __obuffer[4] = VISCA_ZOOM_WIDE_SPEED;
948 __obuffer[5] = (speed & 0x000f) | 0x0020;
949 __obuffer_length = 5;
954 e.
append(
"setZoomSpeedWide() failed");
966 __obuffer[1] = VISCA_COMMAND;
967 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
968 __obuffer[3] = VISCA_ZOOM_VALUE;
970 __obuffer[4] = (zoom & 0xf000) >> 12;
971 __obuffer[5] = (zoom & 0x0f00) >> 8;
972 __obuffer[6] = (zoom & 0x00f0) >> 4;
973 __obuffer[7] = (zoom & 0x000f);
975 __obuffer_length = 7;
980 e.
append(
"setZoom() failed");
992 __obuffer[1] = VISCA_INQUIRY;
993 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
994 __obuffer[3] = VISCA_ZOOM_VALUE;
995 __obuffer_length = 3;
1000 e.
append(
"getZoom() failed");
1005 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
1006 unsigned short int zoom_val = 0;
1008 zoom_val |= (__ibuffer[2] & 0x0F) << 12;
1009 zoom_val |= (__ibuffer[3] & 0x0F) << 8;
1010 zoom_val |= (__ibuffer[4] & 0x0F) << 4;
1011 zoom_val |= (__ibuffer[5] & 0x0F);
1015 throw ViscaException(
"getZoom(): zoom inquiry failed, response code not VISCA_RESPONSE_COMPLETED");
1027 __obuffer[1] = VISCA_COMMAND;
1028 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
1029 __obuffer[3] = VISCA_DZOOM;
1031 __obuffer[4] = VISCA_DZOOM_ON;
1033 __obuffer[4] = VISCA_DZOOM_OFF;
1035 __obuffer_length = 4;
1040 e.
append(
"setZoomDigitalEnabled() failed");
1052 __obuffer[1] = VISCA_COMMAND;
1053 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
1054 __obuffer[3] = VISCA_PICTURE_EFFECT;
1055 __obuffer[4] = filter;
1056 __obuffer_length = 4;
1061 e.
append(
"applyEffect() failed");
1074 e.
append(
"resetEffect() failed");
1087 e.
append(
"applyEffectPastel() failed");
1100 e.
append(
"applyEffectNegArt() failed");
1113 e.
append(
"applyEffectSepia() failed");
1126 e.
append(
"applyEffectBnW() failed");
1139 e.
append(
"applyEffectSolarize() failed");
1152 e.
append(
"applyEffectMosaic() failed");
1165 e.
append(
"applyEffectSlim() failed");
1178 e.
append(
"applyEffectStretch() failed");
1190 __obuffer[1] = VISCA_INQUIRY;
1191 __obuffer[2] = VISCA_CATEGORY_CAMERA1;
1192 __obuffer[3] = VISCA_WB;
1193 __obuffer_length = 3;
1198 e.
append(
"getWhiteBalanceMode() failed");
1202 while (__ibuffer[1] != VISCA_RESPONSE_COMPLETED) {
1209 e.
append(
"getWhiteBalanceMode() failed");
1215 if ( __ibuffer[1] == VISCA_RESPONSE_COMPLETED ) {
1216 return __ibuffer[2];
1218 throw ViscaException(
"Did not get 'request completed' response");
void apply_effect_slim()
Apply slim effect.
void apply_effect_mosaic()
Apply mosaic effect.
static const unsigned int VISCA_WHITEBALANCE_ATW
ATW white balance preset.
bool is_nonblocking_finished(unsigned int item) const
Check if a non-blocking operation has been finished.
void set_pan_tilt_limit(int pan_left, int pan_right, int tilt_up, int tilt_down)
Set pan tilt limit.
static const unsigned int NONBLOCKING_PANTILT
Non-blocking pan/tilt item.
void set_pan_tilt(int pan, int tilt)
Set pan tilt.
void cancel_command(unsigned int socket)
Cancel a running command.
void apply_effect_solarize()
Apply solarize effect.
void set_address()
Set addresses of cameras.
static const unsigned int MAX_TILT_SPEED
Number of non-blocking items.
void start_get_pan_tilt()
Query for pan/tilt but do not wait until finished This will send an inquire to the camera that asks f...
static const unsigned int VISCA_WHITEBALANCE_MANUAL
Manual white balance.
void apply_effect_pastel()
Apply pastel effect.
void clear()
Clear command buffers.
void set_pan_tilt_speed(unsigned char pan_speed, unsigned char tilt_speed)
Set pan/tilt speed.
The current system call has timed out before completion.
static const unsigned int NONBLOCKING_ZOOM
Non-blocking zoom item.
void set_zoom_speed_wide(unsigned int speed)
Set zoom speed in wide angle.
Visca inquire running exception.
void set_zoom_speed_tele(unsigned int speed)
Set zoom speed in tele.
void reset_effect()
Reset effects.
void send_with_reply()
Send and wait for reply, blocking.
static const unsigned int VISCA_WHITEBALANCE_INDOOR
Indoor white balance preset.
virtual ~Visca()
Destructor.
static const unsigned int NONBLOCKING_NUM
Number of non-blocking items.
void reset_pan_tilt_limit()
Reset pan/tilt limit.
ViscaInquiryRunningException()
Constructor.
static const unsigned int VISCA_WHITEBALANCE_OUTDOOR
Outdoor white balance preset.
void recv_ack(unsigned int *socket=NULL)
Receive ACK packet.
void open()
Open serial port.
void reset_zoom()
Reset zoom.
Base class for exceptions in Fawkes.
void set_zoom_digital_enabled(bool enabled)
Enable or disable digital zoome.
void apply_effect_stretch()
Apply stretch effect.
void get_pan_tilt(int &pan, int &tilt)
Get pan and tilt values.
void apply_effect(unsigned char effect)
Apply effect.
static const unsigned int VISCA_WHITEBLANCE_AUTO
Automatic white balance.
void reset_pan_tilt()
Reset pan/tilt.
bool data_available()
Check data availability.
static const unsigned int MAX_PAN_SPEED
Number of non-blocking items.
void apply_effect_neg_art()
Apply negative art effect.
void apply_effect_sepia()
Apply sepia effect.
void get_zoom(unsigned int *zoom)
Get zoom.
void recv(unsigned int timeout_ms=0xFFFFFFFF)
Receive data.
unsigned int get_white_balance_mode()
Get white balance mode.
ViscaException(const char *msg)
Constructor.
void get_pan_tilt_speed(unsigned char &pan_speed, unsigned char &tilt_speed)
Get pan/tilt speed.
void set_zoom(unsigned int zoom)
Set zoom.
void apply_effect_bnw()
Apply B/W effect.
Visca(const char *device_file, unsigned int def_timeout_ms=10, bool blocking=true)
Constructor.
void send()
Send outbound queue.
static const unsigned int VISCA_WHITEBALANCE_ONE_PUSH
One push white balance preset.
void append(const char *format,...)
Append messages to the message list.
void send_nonblocking(unsigned int *socket=NULL)
Send non-blocking.
void process()
Process incoming data.