Revision: 7803
http://playerstage.svn.sourceforge.net/playerstage/?rev=7803&view=rev
Author: thjc
Date: 2009-06-06 10:23:35 +0000 (Sat, 06 Jun 2009)
Log Message:
-----------
applied patch 2666932 Allow Control of Canon VCC4 Camera through P2OS Driver
fixed sign of var in writelog
Modified Paths:
--------------
code/player/trunk/server/drivers/mixed/p2os/p2os.cc
code/player/trunk/server/drivers/mixed/p2os/p2os.h
code/player/trunk/server/drivers/shell/writelog.cc
Modified: code/player/trunk/server/drivers/mixed/p2os/p2os.cc
===================================================================
--- code/player/trunk/server/drivers/mixed/p2os/p2os.cc 2009-06-06 09:51:04 UTC
(rev 7802)
+++ code/player/trunk/server/drivers/mixed/p2os/p2os.cc 2009-06-06 10:23:35 UTC
(rev 7803)
@@ -355,6 +355,7 @@
memset(&this->audio_id, 0, sizeof(player_devaddr_t));
memset(&this->actarray_id, 0, sizeof(player_devaddr_t));
memset(&this->limb_id, 0, sizeof(player_devaddr_t));
+ memset(&this->ptz_id, 0, sizeof(player_devaddr_t));
this->position_subscriptions = this->sonar_subscriptions =
this->actarray_subscriptions = 0;
this->pulse = -1;
@@ -496,6 +497,19 @@
}
}
+ // Do We create the PTZ Interface
+ if(cf->ReadDeviceAddr(&(this->ptz_id), section, "provides",
+ PLAYER_PTZ_CODE, -1, NULL) == 0)
+ {
+ if(this->AddInterface(this->ptz_id) != 0)
+ {
+ this->SetError(-1);
+ return;
+ }
+ this->minfov = (int)rint(RTOD(cf->ReadTupleAngle(section, "fov", 0,
DTOR(3))));
+ this->maxfov = (int)rint(RTOD(cf->ReadTupleAngle(section, "fov", 1,
DTOR(30))));
+ }
+
// Do we create a limb interface?
if(cf->ReadDeviceAddr(&(this->limb_id), section, "provides",
PLAYER_LIMB_CODE, -1, NULL) == 0)
{
@@ -1278,7 +1292,12 @@
}
}
+ // Set up the PTZ Camera
+ if(this->ptz_id.interf){
+ SetupPtz();
+ }
+
// TODO: figure out what the right behavior here is
#if 0
// zero position command buffer
@@ -1291,6 +1310,11 @@
return(0);
}
+
+
+
+
+
void P2OS::MainQuit()
{
unsigned char command[20],buffer[20];
@@ -1301,6 +1325,16 @@
if(this->psos_fd == -1)
return;
+ // Shut Down the PTZ camera
+ if(this->ptz_id.interf){
+ usleep(PTZ_SLEEP_TIME_USEC);
+ SendAbsPanTilt(0,0);
+ usleep(PTZ_SLEEP_TIME_USEC);
+ SendAbsZoom(0);
+ setPower(0);
+ puts("PTZ camera has been shutdown");
+ }
+
command[0] = STOP;
packet.Build(command, 1);
packet.Send(this->psos_fd);
@@ -1473,6 +1507,12 @@
(void*)&(this->p2os_data.compass),
sizeof(player_position2d_data_t),
×tampStandardSIP);
+
+ // put PTZ data
+ this->Publish(this->ptz_id,
+ PLAYER_MSGTYPE_DATA,
+ PLAYER_PTZ_DATA_STATE,
+ (void*)&(this->ptz_data));
}
void
@@ -1599,6 +1639,44 @@
}
}
+ if(this->ptz_id.interf)
+ {
+ int pan,tilt;
+ int zoom;
+ //fprintf(stderr, "PTZ MAIN LOOP\n");
+ //fprintf(stderr, "Getting Pan/Tilt Data\n");
+ if(GetAbsPanTilt(&pan,&tilt) < 0)
+ {
+ fputs("canonvcc4:Main():GetAbsPanTilt() errored. bailing.\n",
+ stderr);
+ pthread_exit(NULL);
+ }
+
+ usleep(30000);
+ //fprintf(stderr, "Getting Zoom Data\n");
+ zoom = 0;
+ if(GetAbsZoom(&zoom) < 0)
+ {
+ fputs("canonvcc4:Main():GetAbsZoom() errored. bailing.\n", stderr);
+ pthread_exit(NULL);
+ }
+ // Do the necessary coordinate conversions. Camera's natural pan
+ // coordinates increase clockwise; we want them the other way, so
+ // we negate pan here. Zoom values are converted from arbitrary
+ // units to a field of view (in degrees).
+ pan = -pan;
+
+ //printf("before zoom = %i\n", zoom);
+ //zoom = this->maxfov + (zoom * (this->maxfov - this->minfov)) /
maxzoom;
+ //printf("after zoom = %i\n", zoom);
+
+ ptz_data.pan = DTOR((unsigned short)pan);
+ ptz_data.tilt = DTOR((unsigned short)tilt);
+
+ //double m = (double)(this->minfov - this->maxfov) /
(double)this->maxzoom;
+ ptz_data.zoom = DTOR(this->maxfov+(zoom * (double)(this->minfov -
this->maxfov) / (double)this->maxzoom));
+ }
+
// handle pending messages
if(!this->InQueue->Empty())
{
@@ -1664,6 +1742,29 @@
packet.packet[3] == SERAUX)
{
// This is an AUX serial packet
+ if(ptz_id.interf)
+ {
+ /* It is an extended SIP (ptz) packet, so process it */
+ /* Be sure to pass data size too (packet[2])! */
+ //fprintf(stderr,"Got a PTZ packet\n");
+ int len;
+ //printf("Got ptz packet\n");
+
+ len = packet.packet[2] - 3;
+ //packet.PrintHex();
+ //fprintf(stderr, "Got PTZ Packet of length %i\n",len);
+
+ if ( cb.gotPacket() ){
+ fprintf(stderr, "ptz_error: got a message, but we already have
the complete packet.\n");
+ }
+ else {
+ for ( int i = 4; i < 4+len ; i++ )
+ {
+ cb.putOnBuf(packet.packet[i]);
+ }
+ }
+
+ }
}
else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
packet.packet[3] == SERAUX2)
@@ -2598,11 +2699,41 @@
this->Publish(this->armgripper_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK,
PLAYER_GRIPPER_REQ_GET_GEOM, &geom, sizeof (geom), NULL);
return 0;
}
+ // PTZ Stuff now.
+ else if (Message::MatchMessage(hdr,
+ PLAYER_MSGTYPE_REQ,
+ PLAYER_PTZ_REQ_GENERIC, device_addr))
+ {
+ assert(hdr->size == sizeof(player_ptz_req_generic_t));
+
+ player_ptz_req_generic_t *cfg = (player_ptz_req_generic_t *)data;
+
+ // check whether command or inquiry...
+ if (cfg->config[0] == 0x01)
+ {
+ if (SendCommand((uint8_t *)cfg->config, cfg->config_count) < 0)
+ Publish(device_addr, resp_queue, PLAYER_MSGTYPE_RESP_NACK,
hdr->subtype);
+ else
+ Publish(device_addr, resp_queue, PLAYER_MSGTYPE_RESP_ACK,
hdr->subtype);
+ return 0;
+ }
+ else
+ {
+ // this is an inquiry, so we have to send data back
+ cfg->config_count = SendRequest((uint8_t*)cfg->config,
+ cfg->config_count,
+ (uint8_t*)cfg->config);
+ Publish(device_addr, resp_queue, PLAYER_MSGTYPE_RESP_ACK,
hdr->subtype);
+ }
+ return 0;
+ }
else
{
PLAYER_WARN("unknown config request to p2os driver");
return(-1);
}
+
+ return 0;
}
void P2OS::SendPulse (void)
@@ -3049,6 +3180,7 @@
return -1;
}
+
///////////////////////////////////////////////////////////////////////////////
// Lift commands
@@ -3101,6 +3233,7 @@
// becomes travel time / 0.02.
// It is important to remember that the LIFTcarry is (if my reading of
the manul is correct)
// an offset command, not absolute position command. So we have to track
the last commanded
+
// position of the lift and work from that to get the correct travel
time (and direction).
double offset = cmd.position - lastLiftPosCmd.position;
@@ -3371,3 +3504,957 @@
}
return retVal;
}
+
+
+// I'm going to put my PTZ stuff down here for now.
+/************************************************************************/
+
+int
+P2OS::SetupPtz()
+{
+ int err;
+ int error_code;
+ int pan, tilt;
+ fprintf(stderr, "Setting up the Canon PTZ Camera.\n");
+
+ //err = setPower(0);
+
+ do {
+ //fprintf(stderr, "\nPowering off/on the camera!!!!!!!!!!!!!!\n");
+ fprintf(stderr, "\nPowering On the Camera.\n");
+ err = setPower(1);
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ fprintf(stdout, "power on busy: %x\n", error_code);
+ err = setPower(1);
+ }
+ if ((err != 0) &&
+ (error_code != CAM_ERROR_NONE) && (error_code != CAM_ERROR_MODE))
+ {
+ printf("Could not set power on: %x\n", error_code);
+ setPower(0);
+ //close(ptz_fd);
+ return -1;
+ }
+
+ /* Set Host Mode Control */
+ fprintf(stderr, "\nSeting Host Control mode.\n");
+ err = setControlMode();
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ printf("control mode busy: %x\n", error_code);
+ err = setControlMode();
+ }
+ if (err)
+ {
+ printf("Could not set control mode\n");
+ setPower(0);
+ //close(ptz_fd);
+ return -1;
+ }
+
+
+ /* Send Init Command */
+ fprintf(stderr, "\nSendInit()\n");
+ err = sendInit();
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ fprintf(stdout, "sendInit busy: %x\n", error_code);
+ err = sendInit();
+ }
+ if ((err != 0) && (error_code != CAM_ERROR_NONE) && (error_code !=
CAM_ERROR_MODE))
+ {
+ printf("Could not sendInit off: %x\n", error_code);
+ setPower(0);
+ return -1;
+ }
+ }while (error_code == CAM_ERROR_MODE);
+
+ /* Turn on Notify Command */
+ /*
+ fprintf(stderr, "Setting Notify Command on\n");
+ err = setNotifyCommand();
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ printf("notify command busy: %x\n", error_code);
+ err = setNotifyCommand();
+ }
+ if (err)
+ {
+ printf("Could not set notify command\n");
+ setPower(0);
+ //close(ptz_fd);
+ return -1;
+ }
+ */
+
+ /* Now Turn Power on. */
+ /*
+ fprintf(stderr, "Powering On the Camera.\n");
+ err = setPower(1);
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ fprintf(stdout, "power on busy: %x\n", error_code);
+ err = setPower(1);
+ }
+ if ((err != 0) &&
+ (error_code != CAM_ERROR_NONE) && (error_code != CAM_ERROR_MODE))
+ {
+ printf("Could not set power on: %x\n", error_code);
+ setPower(0);
+ return -1;
+ }
+ */
+ fprintf(stderr, "\nSetting the default tilt range.\n");
+ err = setDefaultTiltRange();
+ while (error_code == CAM_ERROR_BUSY)
+ {
+ printf("control mode busy: %x\n", error_code);
+ err = setDefaultTiltRange();
+ }
+ if (err)
+ {
+ printf("Could not set default tilt range\n");
+ setPower(0);
+ //close(ptz_fd);
+ return -1;
+ }
+
+ /* try to get current state, just to make sure we actually have a camera */
+ fprintf(stderr, "\nGetting the Abs Pan Tilt\n");
+ err = GetAbsPanTilt(&pan,&tilt);
+ if (err)
+ {
+ printf("Couldn't connect to PTZ device most likely because the
camera\n"
+ "is not connected or is connected not to AUX1: %x\n",
+ error_code);
+ setPower(0);
+ //close(ptz_fd);
+ //ptz_fd = -1;
+ return(-1);
+ }
+ fprintf(stderr, "getAbsPantilt: %d %d\n", pan, tilt);
+
+ // Get the Zoom Range. 0 to what
+ fprintf(stderr, "Getting Max Zoom Range.\n");
+ err = GetMaxZoom(&maxzoom);
+ if (err)
+ {
+ fprintf(stderr, "Couldn't get max zoom range.\n");
+ setPower(0);
+ //close(ptz_fd);
+ //ptz_fd = -1;
+ return(-1);
+ }
+ fprintf(stderr, "maxzoom value = %i \n", maxzoom);
+ fprintf(stderr, "Done Initializing the PTZ Camera.\n");
+ return 0;
+}
+
+
+int
+P2OS::SendCommand(unsigned char *str, int len)
+{
+ int err = 0;
+ P2OSPacket ptz_packet;
+ P2OSPacket request_pkt;
+ unsigned char request[4];
+
+ // Zero out the Receive Buffer
+ request[0] = GETAUX;
+ request[1] = ARGINT;
+ request[2] = 0;
+ request[3] = 0;
+ request_pkt.Build(request,4);
+ SendReceive(&request_pkt,false);
+
+ if(len > MAX_PTZ_COMMAND_LENGTH)
+ {
+ fprintf(stderr,
+ "CANNONvcc4::SendCommand(): message is too large (%d bytes)\n",
+ len);
+ return(-1);
+ }
+
+ //err = write(ptz_fd, str, len);
+ // Since I'm hardcoding this to AUX1, basically we gotta stick the AUX1DATA
+ // header on this and then give it to the p2os send command.
+ unsigned char mybuf[MAX_PTZ_COMMAND_LENGTH];
+ mybuf[0] = TTY2;
+ mybuf[1] = ARGSTR;
+ mybuf[2] = len;
+ // Copy the command
+ memcpy(&mybuf[3], str, len);
+ //for (int i = 0; i < len+3; i ++)
+ // fprintf(stderr, "0x%x ", mybuf[i]);
+ //fprintf(stderr,"\n");
+ ptz_packet.Build(mybuf, len+3);
+
+ /*
+ printf("ptz_command packet = ");
+ ptz_packet.PrintHex();
+ */
+
+ // Send the packet
+ this->SendReceive(&ptz_packet, false);
+
+ if (err != 0)
+ {
+ perror("canonvcc4::Send():write():");
+ return(-1);
+ }
+ return(0);
+}
+/************************************************************************/
+//int
+//canonvcc4::SendRequest(unsigned char* str, int len)
+
+int P2OS::SendRequest(unsigned char* str, int len, unsigned char* reply,
uint8_t camera)
+{
+ return this->SendCommand(str,len);
+}
+
+/************************************************************************/
+void
+P2OS::PrintPacket(char* str, unsigned char* cmd, int len)
+{
+ for(int i=0;i<len;i++)
+ printf(" %.2x", cmd[i]);
+ puts("");
+}
+/************************************************************************/
+
+int
+P2OS::SendAbsPanTilt(int pan, int tilt)
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ int convpan, convtilt;
+ unsigned char buf[5];
+ int ppan, ttilt;
+
+ ppan = pan; ttilt = tilt;
+ if (abs(pan) > PTZ_PAN_MAX)
+ {
+ if(pan < -PTZ_PAN_MAX)
+ ppan = (int)-PTZ_PAN_MAX;
+ else
+ if(pan > PTZ_PAN_MAX)
+ ppan = (int)PTZ_PAN_MAX;
+ //puts("Camera pan angle thresholded");
+ }
+ if (tilt > PTZ_TILT_MAX)
+ ttilt = (int)PTZ_TILT_MAX;
+ else
+ if(tilt < PTZ_TILT_MIN)
+ ttilt = (int)PTZ_TILT_MIN;
+ //puts("Camera pan angle thresholded");
+
+ //puts("Camera tilt angle thresholded");
+
+ convpan = (int)floor(ppan/.1125) + 0x8000;
+ convtilt = (int)floor(ttilt/.1125) + 0x8000;
+// fprintf(stdout, "ppan: %d ttilt: %d conpan: %d contilt: %d\n",
+// ppan,ttilt,convpan,convtilt);
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x62;
+ // pan position
+
+ sprintf((char *)buf, "%X", convpan);
+
+ command[5] = buf[0];
+ command[6] = buf[1];
+ command[7] = buf[2];
+ command[8] = buf[3];
+ // tilt position
+ sprintf((char *)buf, "%X", convtilt);
+ command[9] = buf[0];
+ command[10] = buf[1];
+ command[11] = buf[2];
+ command[12] = buf[3];
+ command[13] = (unsigned char) 0xEF;
+ SendCommand(command, 14);
+ // PrintPacket( "sendabspantilt: ", command, 14);
+ return(ReceiveCommandAnswer(6));
+}
+/************************************************************************/
+int
+P2OS::setDefaultTiltRange()
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ unsigned char buf[8];
+ int maxtilt, mintilt;
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x64;
+ command[5] = 0x31;
+
+ mintilt = (int)(floor(PTZ_TILT_MIN/.1125) + 0x8000);
+ sprintf((char *)buf, "%X", mintilt);
+
+ command[6] = buf[0];
+ command[7] = buf[1];
+ command[8] = buf[2];
+ command[9] = buf[3];
+ // tilt position
+ maxtilt = (int)(floor(PTZ_TILT_MAX/.1125) + 0x8000);
+ sprintf((char *)buf, "%X", maxtilt);
+
+ command[10] = buf[0];
+ command[11] = buf[1];
+ command[12] = buf[2];
+ command[13] = buf[3];
+ command[14] = (unsigned char) 0xEF;
+
+ SendCommand(command, 15);
+ // PrintPacket( "setDefaultRange: ", command, 15);
+ return(ReceiveCommandAnswer(6));
+
+}
+
+/************************************************************************/
+int
+P2OS::GetAbsPanTilt(int* pan, int* tilt)
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ unsigned char reply[MAX_PTZ_REQUEST_LENGTH];
+ int reply_len;
+ unsigned char buf[4];
+ char byte;
+ unsigned int u_val;
+ int val;
+ int i;
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x63;
+ command[5] = 0xEF;
+
+ if (SendRequest(command, 6, reply))
+ return(-1);
+ // PrintPacket("getabspantilt: ", command, 6);
+ //reply_len = ReceiveRequestAnswer(reply,6,14);
+ reply_len = ReceiveRequestAnswer(reply,14,0);
+
+ if ( reply_len != 14 ) {
+ fprintf(stderr, "Reply Len = %i\n", reply_len);
+ return -1;
+ }
+
+ // remove the ascii encoding, and put into 4-byte array
+ for (i = 0; i < 4; i++)
+ {
+ byte = reply[i+5];
+ if (byte < 0x40)
+ byte = byte - 0x30;
+ else
+ byte = byte - 'A' + 10;
+ buf[i] = byte;
+ }
+
+ // convert the 4-bytes into a number
+ u_val = buf[0] * 0x1000 + buf[1] * 0x100 + buf[2] * 0x10 + buf[3];
+
+ // convert the number to a value that's meaningful, based on camera specs
+ val = (int)(((int)u_val - (int)0x8000) * 0.1125);
+
+ // now set myPan to the response received for where the camera thinks it is
+ *pan = val;
+
+ // repeat the steps for the tilt value
+ for (i = 0; i < 4; i++)
+ {
+ byte = reply[i+9];
+ if (byte < 0x40)
+ byte = byte - 0x30;
+ else
+ byte = byte - 'A' + 10;
+ buf[i] = byte;
+ }
+ u_val = buf[0] * 0x1000 + buf[1] * 0x100 + buf[2] * 0x10 + buf[3];
+ val =(int)(((int)u_val - (int)0x8000) * 0.1125);
+ *tilt = val;
+
+ return(0);
+}
+
+/************************************************************************/
+int
+P2OS::GetAbsZoom(int* zoom)
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ unsigned char reply[MAX_PTZ_REQUEST_LENGTH];
+ int reply_len;
+ char byte;
+ unsigned char buf[4];
+ unsigned int u_zoom;
+ int i;
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0xB4;
+ command[5] = 0x30;
+ command[6] = 0xEF;
+
+ if (SendRequest(command, 7, reply))
+ return(-1);
+ // PrintPacket( "getabszoom: ", command, 6);
+
+ reply_len = ReceiveRequestAnswer(reply,10,0);
+
+ if (reply_len == 6)
+ return -1;
+
+ // remove the ascii encoding, and put into 2 bytes
+ for (i = 0; i < 4; i++)
+ {
+ byte = reply[i + 5];
+ if (byte < 0x40)
+ byte = byte - 0x30;
+ else
+ byte = byte - 'A' + 10;
+ buf[i] = byte;
+ }
+
+ // convert the 2 bytes into a number
+ u_zoom = 0;
+ for (i = 0; i < 4; i++)
+ u_zoom += buf[i] * (unsigned int) pow(16.0, (double)(3 - i));
+ *zoom = u_zoom;
+ return(0);
+}
+
+/************************************************************************/
+int
+P2OS::SendAbsZoom(int zoom)
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ unsigned char buf[5];
+ int i;
+
+ if(zoom < 0)
+ zoom = 0;
+ //puts("Camera zoom thresholded");
+
+ else
+ if(zoom > maxzoom){
+ zoom = maxzoom;
+ //printf("putting zoom at MAX_ZOOM\n");
+ }
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0xB3;
+
+ sprintf((char *)buf, "%4X", zoom);
+
+ for (i=0;i<3;i++)
+ if (buf[i] == ' ')
+ buf[i] = '0';
+
+ // zoom position
+ command[5] = buf[0];
+ command[6] = buf[1];
+ command[7] = buf[2];
+ command[8] = buf[3];
+ command[9] = 0xEF;
+
+ if (SendCommand(command, 10))
+ return -1;
+ //PrintPacket( "setabszoom: ", command, 10);
+ return (ReceiveCommandAnswer(6));
+}
+
+void P2OS::get_ptz_packet(int s1, int s2)
+{
+ //printf("get_ptz_packet()\n");
+ static const int TIMEOUT = 100;
+ int packetCount = 0;
+ unsigned char request[4];
+ P2OSPacket request_pkt;
+ bool secondSent = false;
+
+ request[0] = GETAUX;
+ request[1] = ARGINT;
+ request[2] = s1;
+ request[3] = 0;
+
+ // Reset our receiving buffer.
+ cb.reset();
+
+ //sleep(1);
+ //Request the request-size back
+ request_pkt.Build(request,4);
+ SendReceive(&request_pkt,false);
+
+ while ( !cb.gotPacket() )
+ {
+ if ( packetCount++ > TIMEOUT ) {
+ // Give Up We're not getting it.
+ fprintf(stderr, "Waiting for packet timed out.\n");
+ return;
+ }
+ if ( cb.size() == s1 && !secondSent)
+ {
+ if ( s2 > s1 )
+ {
+ // We got the first packet size, but we don't have a full
packet.
+ int newsize = s2 - s1;
+ fprintf(stderr, "Requesting Second Packet of size %i\n",
newsize);
+ request[2] = newsize;
+ request_pkt.Build(request,4);
+ secondSent = true;
+ //cb.printBuf();
+ SendReceive(&request_pkt,false);
+ }
+ else
+ {
+ // We got the first packet but don't have a full packet, this
is an error.
+ fprintf(stderr, "Error: Got reply from AUX1 But don't have a
full packet.\n");
+ break;
+ }
+ }
+
+ // Keep reading data until we get a response from the camera.
+ //fprintf(stderr, "foo\n");
+ SendReceive(NULL,false);
+ }
+ //fprintf(stderr, "Got ptz_packet: ");
+ //cb.printBuf();
+}
+
+/************************************************************************/
+int
+P2OS::ReceiveCommandAnswer(int asize)
+{
+ int num;
+ unsigned char reply[MAX_PTZ_REQUEST_LENGTH];
+ int len = 0;
+ unsigned char byte;
+ int t;
+ int error_code;
+ // puts("Receivecommandanswer begin\n");
+ memset(reply, 0, COMMAND_RESPONSE_BYTES);
+
+ get_ptz_packet(asize);
+ //fprintf(stderr, "Recieved Packet: ");
+ //cb.printBuf();
+
+ for (num = 0; num <= COMMAND_RESPONSE_BYTES + 1; num++)
+ {
+ // if we don't get any bytes, or if we've just exceeded the limit
+ // then return null
+ //err = read_ptz(&byte, 1);
+ t = cb.getFromBuf();
+ if ( t < 0 ) { // Buf Error!
+ printf("circbuf error!\n");
+ }
+ else {
+ byte = (unsigned char)t;
+ }
+ if (byte == (unsigned char)0xFE)
+ {
+ reply[0] = byte;
+ len ++;
+ break;
+ }
+ }
+ if (len == 0)
+ return -1;
+
+ // we got the header character so keep reading bytes for
MAX_RESPONSE_BYTES more
+ for(num = 1; num <= MAX_PTZ_REQUEST_LENGTH; num++)
+ {
+ t = cb.getFromBuf();
+ if (t < 0)
+ {
+ // there are no more bytes, so check the last byte for the footer
+ if (reply[len - 1] != (unsigned char)0xEF)
+ {
+ fputs("canonvcc4::receiveCommandAnswer: Discarding bad
packet.",
+ stderr);
+ return -1;
+ }
+ else
+ break;
+ }
+ else
+ {
+ // add the byte to the array
+ reply[len] = (unsigned char)t;
+ len ++;
+ }
+ }
+
+ // Check the response
+ if (len != 6)
+ {
+ fputs("canonvcc4::receiveCommandAnswer:Incorrect number of bytes in
response packet.",
+ stderr);
+ return -1;
+ }
+
+ // check the header and footer
+ if (reply[0] != (unsigned char)0xFE || reply[5] != (unsigned char)0xEF)
+ {
+ fputs("canonvcc4::receiveCommandAnswer: Bad header or footer character
in response packet.", stderr);
+ return -1;
+ }
+ // so far so good. Set myError to the error byte
+ error_code = reply[3];
+ //PrintPacket("receivecommandasnwer: ", reply, 6);
+ if (error_code == CAM_ERROR_NONE)
+ return 0;
+ else {
+ switch(error_code){
+ case CAM_ERROR_BUSY:
+ fputs("Error: CAM_ERROR_BUSY\n", stderr);
+ break;
+ case CAM_ERROR_PARAM:
+ fputs("Error: CAM_ERROR_PARAM\n", stderr);
+ break;
+ case CAM_ERROR_MODE:
+ fputs("Error: CAM_ERROR_MODE\n", stderr);
+ break;
+ default:
+ fputs("Error: Unknown error response from camera.\n",stderr);
+ break;
+ }
+ }
+
+ return -1;
+}
+
+/************************************************************************/
+/* These commands often have variable packet lengths, if there is an error,
+ * there is a smaller packet size. If we request the larger packet size first,
+ * then we will never get a response back. Because of this, we have to first
+ * request the smaller size, check if its a full packet, if it's not, request
+ * the rest of the packet. Also according to the source code for ARIA, we can
+ * not do more than 2 requests for a single packet, therefor, we can't just
+ * request 1 byte over and over again.
+ *
+ * So here, s1 is the size of the smaller packet.
+ * And s2 is the size of the larger packet.
+ */
+int
+P2OS::ReceiveRequestAnswer(unsigned char *data, int s1, int s2)
+{
+ int num;
+ unsigned char reply[MAX_PTZ_REQUEST_LENGTH];
+ int len = 0;
+ unsigned char byte;
+ int t;
+ int error_code;
+
+ memset(reply, 0, MAX_PTZ_REQUEST_LENGTH);
+ get_ptz_packet(s1, s2);
+ //cb.printBuf();
+
+ for (num = 0; num <= COMMAND_RESPONSE_BYTES + 1; num++)
+ {
+ // if we don't get any bytes, or if we've just exceeded the limit
+ // then return null
+ t = cb.getFromBuf();
+ if ( t < 0 ) { // Buf Error!
+ printf("circbuf error!\n");
+ }
+ else {
+ byte = (unsigned char)t;
+ }
+ if (byte == (unsigned char)0xFE)
+ {
+ reply[0] = byte;
+ len ++;
+ break;
+ }
+ }
+ if (len == 0)
+ return -1;
+ // we got the header character so keep reading bytes for
MAX_RESPONSE_BYTES more
+ for(num = 1; num <= MAX_PTZ_REQUEST_LENGTH; num++)
+ {
+ t = cb.getFromBuf();
+ if (t < 0)
+ {
+ // there are no more bytes, so check the last byte for the footer
+ if (reply[len - 1] != (unsigned char)0xEF)
+ {
+ fputs("canonvcc4::receiveRequest: Discarding bad packet.",
+ stderr);
+ return -1;
+ }
+ else
+ break;
+ }
+ else
+ {
+ // add the byte to the array
+ reply[len] = (unsigned char)t;
+ len ++;
+ }
+ }
+ // Check the response length: pt: 14; zoom: 10
+ if (len != 6 && len != 8 && len != 10 && len != 14)
+ {
+ fputs("Arvcc4::packetHandler: Incorrect number of bytes in response
packet.", stderr);
+ return -1;
+ }
+
+ if (reply[0] != (unsigned char)0xFE ||
+ reply[len - 1] != (unsigned char)0xEF)
+ {
+ fputs("canonvcc4::receiveRequestArvcc4: Bad header or footer character
in response packet.", stderr);
+ return -1;
+ }
+
+ // so far so good. Set myError to the error byte
+ error_code = reply[3];
+ // PrintPacket("receiverequestasnwer: ", reply, len);
+ if (error_code == CAM_ERROR_NONE)
+ {
+ memcpy(data, reply, len);
+ return len;
+ }
+ return -1;
+}
+
+/************************************************************************/
+int
+P2OS::setControlMode()
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x90;
+ command[5] = 0x30;
+ command[6] = 0xEF;
+
+ if (SendCommand(command, 7))
+ return -1;
+ // usleep(5000000);
+ return (ReceiveCommandAnswer(6));
+}
+/************************************************************************/
+int
+P2OS::setNotifyCommand()
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x94;
+ command[5] = 0x31;
+ command[6] = 0xEF;
+
+ if (SendCommand(command, 7))
+ return -1;
+ // usleep(5000000);
+ return (ReceiveCommandAnswer(6));
+}
+/************************************************************************/
+int
+P2OS::setPower(int on)
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0xA0;
+ if (on)
+ command[5] = 0x31;
+ else
+ command[5] = 0x30;
+ command[6] = 0xEF;
+
+ if (SendCommand(command, 7))
+ return -1;
+ // usleep(5000000);
+ return (ReceiveCommandAnswer(6));
+}
+/************************************************************************/
+int
+P2OS::setOnScreenOff()
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x91;
+ command[5] = 0x30;
+ command[6] = 0x30;
+ command[7] = 0xEF;
+
+ if (SendCommand(command, 8))
+ return -1;
+ // usleep(5000000);
+ return (ReceiveCommandAnswer(6));
+}
+
+int P2OS::sendInit()
+{
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0x58;
+ command[5] = 0x30;
+ command[6] = 0xEF;
+
+ if (SendCommand(command, 7))
+ return -1;
+ // usleep(5000000);
+ return (ReceiveCommandAnswer(6));
+}
+
+int P2OS::GetMaxZoom(int * maxzoom){
+ unsigned char command[MAX_PTZ_COMMAND_LENGTH];
+ unsigned char reply[MAX_PTZ_REQUEST_LENGTH];
+ int reply_len;
+ char byte;
+ unsigned char buf[4];
+ unsigned int u_zoom;
+ int i;
+
+ command[0] = 0xFF;
+ command[1] = 0x30;
+ command[2] = 0x30;
+ command[3] = 0x00;
+ command[4] = 0xB4;
+ command[5] = 0x33;
+ command[6] = 0xEF;
+
+ if (SendCommand(command, 7))
+ return -1;
+ // usleep(5000000);
+
+ reply_len = ReceiveRequestAnswer(reply,10,0);
+
+ if ( reply_len == 6 ){
+ return -1;
+ }
+
+ // remove the ascii encoding, and put into 2 bytes
+ for (i = 0; i < 4; i++)
+ {
+ byte = reply[i + 5];
+ if (byte < 0x40)
+ byte = byte - 0x30;
+ else
+ byte = byte - 'A' + 10;
+ buf[i] = byte;
+ }
+
+ // convert the 2 bytes into a number
+ u_zoom = 0;
+ for (i = 0; i < 4; i++)
+ u_zoom += buf[i] * (unsigned int) pow(16.0, (double)(3 - i));
+ *maxzoom = u_zoom;
+
+ return 0;
+}
+
+/* Circular Buffer To deal with getting data back from AUX */
+circbuf::circbuf(int size)
+{
+ this->buf = new unsigned char[size];
+ this->mysize = size;
+ this->start = this->end = 0;
+}
+
+void circbuf::printBuf(){
+ int i = start;
+ printf("circbuf: ");
+ while ( i != end ){
+ printf("0x%x ", buf[i]);
+ i = (i+1)%mysize;
+ }
+ printf("\n");
+}
+
+
+void circbuf::putOnBuf(unsigned char c)
+{
+ buf[end] = c;
+ end = (end+1)%mysize;
+ if ( end == start )
+ {
+ // We're overwriting old data.
+ start = (start + 1)%mysize;
+ }
+
+ // Check to see if we have the whole packet now. (ends with 0xEF)
+ if ( c == 0xEF )
+ {
+ gotPack = true;
+ }
+}
+
+bool circbuf::haveData()
+{
+ return !(this->start == this->end);
+}
+
+int circbuf::getFromBuf()
+{
+ if ( start != end ){
+ unsigned char ret = buf[start];
+ start = (start+1)%mysize;
+ return (int)ret;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+int circbuf::size()
+{
+ if ( end > start )
+ {
+ return end-start;
+ }
+ else if ( start > end )
+ {
+ return mysize - start - end - 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+bool circbuf::gotPacket()
+{
+ return gotPack;
+}
+
+void circbuf::reset()
+{
+ memset(buf, 0, mysize);
+ gotPack = false;
+ start = end = 0;
+}
+
Modified: code/player/trunk/server/drivers/mixed/p2os/p2os.h
===================================================================
--- code/player/trunk/server/drivers/mixed/p2os/p2os.h 2009-06-06 09:51:04 UTC
(rev 7802)
+++ code/player/trunk/server/drivers/mixed/p2os/p2os.h 2009-06-06 10:23:35 UTC
(rev 7803)
@@ -41,6 +41,7 @@
#include "packet.h"
#include "robot_params.h"
+
// Default max speeds
#define MOTOR_DEF_MAX_SPEED 0.5
#define MOTOR_DEF_MAX_TURNSPEED DTOR(100)
@@ -143,6 +144,28 @@
#define DEFAULT_P2OS_TCP_REMOTE_HOST "localhost"
#define DEFAULT_P2OS_TCP_REMOTE_PORT 8101
+/* Canon PTZ (VC-C4) Stuff */
+#define CAM_ERROR_NONE 0x30
+#define CAM_ERROR_BUSY 0x31
+#define CAM_ERROR_PARAM 0x35
+#define CAM_ERROR_MODE 0x39
+
+#define PTZ_SLEEP_TIME_USEC 100000
+
+#define MAX_PTZ_COMMAND_LENGTH 19
+#define MAX_PTZ_REQUEST_LENGTH 17
+#define COMMAND_RESPONSE_BYTES 6
+
+#define PTZ_PAN_MAX 98.0 // 875 units 0x36B
+#define PTZ_TILT_MAX 88.0 // 790 units 0x316
+#define PTZ_TILT_MIN -30.0 // -267 units 0x10B
+#define MAX_ZOOM 1960 //1900
+#define ZOOM_CONV_FACTOR 17
+
+#define PT_BUFFER_INC 512
+#define PT_READ_TIMEOUT 10000
+#define PT_READ_TRIALS 2
+
typedef struct player_p2os_data
{
//Standard SIP
@@ -174,6 +197,28 @@
class SIP;
+// Circular Buffer Used by PTZ camera
+class circbuf{
+ public:
+ circbuf(int size=512);
+
+ void putOnBuf(unsigned char c);
+ int getFromBuf();
+ bool haveData();
+ int size();
+ void printBuf();
+
+ bool gotPacket();
+ void reset();
+
+ private:
+ unsigned char* buf;
+ int start;
+ int end;
+ int mysize;
+ bool gotPack;
+};
+
// Forward declaration of the KineCalc_Base class declared in kinecalc_base.h
//class KineCalc;
@@ -196,6 +241,7 @@
player_devaddr_t audio_id;
player_devaddr_t actarray_id;
player_devaddr_t limb_id;
+ player_devaddr_t ptz_id;
player_devaddr_t armgripper_id;
// Book keeping to only send new commands
@@ -219,6 +265,7 @@
int position_subscriptions;
int sonar_subscriptions;
int actarray_subscriptions;
+ int ptz_subscriptions;
SIP* sippacket;
@@ -242,6 +289,10 @@
int HandleArmGripperCommand (player_msghdr *hdr, void *data);
void HandleAudioCommand(player_audio_sample_item_t audio_cmd);
+ /////// PTZ Stuff
+ void get_ptz_packet(int s1, int s2=0);
+ int SetupPtz();
+
/////////////////
// Gripper stuff
player_pose3d_t gripperPose;
@@ -314,6 +365,31 @@
int joystickp; // are we using a joystick?
int bumpstall; // should we change the bumper-stall behavior?
+ // PTZ Camera Stuff
+ player_ptz_data_t ptz_data;
+ int maxfov, minfov;
+ int maxzoom;
+ int pandemand, tiltdemand, zoomdemand;
+ int SendCommand(unsigned char *str, int len);
+ int SendRequest(unsigned char* str, int len, unsigned char* reply, uint8_t
camera = 1);
+ void PrintPacket(char* str, unsigned char* cmd, int len);
+ int SendAbsPanTilt(int pan, int tilt);
+ int setDefaultTiltRange();
+ int GetAbsPanTilt(int* pan, int* tilt);
+ int GetAbsZoom(int* zoom);
+ int SendAbsZoom(int zoom);
+ int read_ptz(unsigned char *reply, int size);
+ int ReceiveCommandAnswer(int asize);
+ int ReceiveRequestAnswer(unsigned char *data, int s1, int s2);
+ int setControlMode();
+ int setNotifyCommand();
+ int setPower(int on);
+ int setOnScreenOff();
+ int CheckHostControlMode();
+ int sendInit();
+ int GetMaxZoom(int * maxzoom);
+ circbuf cb;
+
float pulse; // Pulse time
double lastPulseTime; // Last time of sending a pulse or command to the
robot
void SendPulse (void);
Modified: code/player/trunk/server/drivers/shell/writelog.cc
===================================================================
--- code/player/trunk/server/drivers/shell/writelog.cc 2009-06-06 09:51:04 UTC
(rev 7802)
+++ code/player/trunk/server/drivers/shell/writelog.cc 2009-06-06 10:23:35 UTC
(rev 7803)
@@ -2275,7 +2275,7 @@
fiducial_data = (player_fiducial_data_t*) data;
// format: <count> [<id> <x> <y> <z> <roll> <pitch> <yaw>
<ux> <uy> <uz> <uroll> <upitch> <uyaw>] ...
fprintf(this->file, "%d", fiducial_data->fiducials_count);
- for (int i = 0; i < fiducial_data->fiducials_count; i++) {
+ for (unsigned i = 0; i < fiducial_data->fiducials_count;
i++) {
fprintf(this->file, " %d"
" %+07.3f %+07.3f %+07.3f %+07.3f %+07.3f
%+07.3f"
" %+07.3f %+07.3f %+07.3f %+07.3f %+07.3f
%+07.3f",
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit