00001
00002 #include <stdlib.h>
00003 #include <stdio.h>
00004 #include <string.h>
00005 #include <assert.h>
00006 #include <math.h>
00007 #include "canon_vbc50i/libCanon/CanonDriver.h"
00008
00009 CanonDriver::CanonDriver(const char * initseq_filename,
00010 const char * hostname)
00011 {
00012 Datagram dgm;
00013 ctrlsock = NULL;
00014 videosock = NULL;
00015 FILE * fp = fopen(initseq_filename,"r");
00016 assert(fp != NULL);
00017 host = strdup(hostname);
00018 while (1) {
00019 if (!dgm.read(fp)) break;
00020 init_seq.push_back(dgm);
00021 }
00022 init_reply.resize(init_seq.size());
00023 keepalive_seq.resize(4);
00024 keepalive_reply.resize(keepalive_seq.size());
00025 keepalive_seq[0].reset();
00026 keepalive_seq[0].setId(0x88);
00027 keepalive_seq[0].setStatus(0x80,0x00);
00028 keepalive_seq[1].reset();
00029 keepalive_seq[1].setId(0x82);
00030 keepalive_seq[1].setStatus(0x80,0x00);
00031 keepalive_seq[2].reset();
00032 keepalive_seq[2].setId(0x86);
00033 keepalive_seq[2].setStatus(0x80,0x00);
00034 keepalive_seq[3].reset();
00035 keepalive_seq[3].setId(0x85);
00036 keepalive_seq[3].setStatus(0x80,0x00);
00037 }
00038
00039 CanonDriver::~CanonDriver()
00040 {
00041 disconnect();
00042 }
00043
00044 bool CanonDriver::connect()
00045 {
00046 if (ctrlsock != NULL) delete ctrlsock;
00047 ctrlsock = new Socket(host,CONTROL_PORT);
00048 if (!ctrlsock->Open()) {
00049 printf("%s: Can't open Socket '%s:%d'\n",__FUNCTION__,
00050 host,CONTROL_PORT);
00051 return false;
00052 }
00053 if (videosock != NULL) delete videosock;
00054 videosock = new Socket(host,VIDEO_PORT);
00055 if (!videosock->Open()) {
00056 printf("%s: Can't open videosocket '%s:%d'\n",__FUNCTION__,
00057 host,VIDEO_PORT);
00058 return false;
00059 }
00060 unsigned int i;
00061 for (i=0;i<init_seq.size();i++) {
00062 if (!init_seq[i].send(ctrlsock)) {
00063 printf("%s: Can't send datagram %d:",__FUNCTION__,i);
00064 init_seq[i].write(stdout);
00065 printf("\n");
00066 return false;
00067 }
00068 if (!init_reply[i].receive(ctrlsock)) {
00069 printf("%s: Can't receive datagram %d\n",__FUNCTION__,i);
00070 return false;
00071 }
00072 }
00073 printf("Initialization completed\n");
00074 return requestCurrentPos();
00075 }
00076
00077 bool CanonDriver::disconnect()
00078 {
00079 if (ctrlsock != NULL) {
00080
00081 Datagram dgm;
00082 dgm.setId(0x21);
00083 dgm.setStatus(0x0000);
00084 if (!dgm.send(ctrlsock)) {
00085 printf("%s: Can't send datagram :",__FUNCTION__);
00086 dgm.print(stdout);
00087 printf("\n");
00088 return false;
00089 }
00090 dgm.reset();
00091 if (!dgm.receive(ctrlsock)) {
00092 printf("%s: Can't receive datagram\n",__FUNCTION__);
00093 return false;
00094 }
00095 if (dgm.getId() != 0x21) {
00096 printf("%s: received incorrect datagram\n",__FUNCTION__);
00097 return false;
00098 }
00099 ctrlsock->Close();
00100 delete ctrlsock;
00101 ctrlsock = NULL;
00102
00103 }
00104
00105 if (videosock != NULL) {
00106 videosock->Close();
00107 delete videosock;
00108 videosock = NULL;
00109 }
00110
00111 return true;
00112 }
00113
00114 bool CanonDriver::getframe()
00115 {
00116 unsigned int i;
00117 unsigned char b[1024];
00118 if (!keepalive()) return false;
00119 if (videosock == NULL) return false;
00120 if (videosock->WaitBuffer(b,1024,1000)) {
00121 for (i=0;i<80;i++) {
00122 printf("%02X ",b[i]);
00123 }
00124 } else {
00125 printf("%s: Cannot receive frame\n",__FUNCTION__);
00126 return false;
00127 }
00128 return true;
00129 }
00130
00131 bool CanonDriver::keepalive()
00132 {
00133 if (ctrlsock == NULL) return false;
00134
00135 unsigned int i;
00136 for (i=0;i<keepalive_seq.size();i++) {
00137 if (!keepalive_seq[i].send(ctrlsock)) {
00138 printf("%s: Can't send datagram %d:",__FUNCTION__,i);
00139 keepalive_seq[i].write(stdout);
00140 printf("\n");
00141 return false;
00142 }
00143 if (!keepalive_reply[i].receive(ctrlsock)) {
00144 printf("%s: Can't receive datagram %d\n",__FUNCTION__,i);
00145 return false;
00146 }
00147 }
00148 return true;
00149 }
00150
00151 bool CanonDriver::waitcompletion()
00152 {
00153 unsigned char data[8] = {0x0e,0x6b,0x0a,0xd0, 0x00,0x00,0xc0,0x00};
00154 Datagram dgm;
00155 dgm.setId(0x3b);
00156 dgm.setStatus(0x0000);
00157 dgm.setData(data,8);
00158
00159 if (!dgm.send(ctrlsock)) {
00160 printf("%s: Can't send datagram: ",__FUNCTION__);
00161 dgm.print(stdout);
00162 printf("\n");
00163 return false;
00164 }
00165 dgm.reset();
00166 if (!dgm.receive(ctrlsock,2000)) {
00167 printf("%s: Can't receive datagram\n",__FUNCTION__);
00168 return false;
00169 }
00170 if (dgm.getId() != 0x3b) {
00171 printf("%s: Received invalid datagram: ",__FUNCTION__);
00172 dgm.print(stdout);
00173 printf("\n");
00174 return false;
00175 }
00176 return true;
00177 }
00178
00179 bool CanonDriver::moveto(double pan, double tilt, double zoom)
00180 {
00181 if (ctrlsock == NULL) return false;
00182
00183 Datagram dgm;
00184 unsigned char data[6];
00185 signed short span,stilt,szoom;
00186
00187 span = (signed short)round(pan*100.0);
00188 stilt = (signed short)round(tilt*100.0);
00189 szoom = (signed short)round(zoom*100.0);
00190
00191 unsigned short upan,utilt,uzoom;
00192 upan = (unsigned short)span;
00193 utilt = (unsigned short)stilt;
00194 uzoom = (unsigned short)szoom;
00195
00196
00197 data[0] = upan >> 8;
00198 data[1] = (upan & 0xFF);
00199 data[2] = utilt >> 8;
00200 data[3] = (utilt & 0xFF);
00201 data[4] = uzoom >> 8;
00202 data[5] = (uzoom & 0xFF);
00203 dgm.reset();
00204 dgm.setId(0x33);
00205 dgm.setStatus(0x00,0xe0);
00206 dgm.setData(data,6);
00207
00208 if (!dgm.send(ctrlsock)) {
00209 printf("%s: Can't send datagram: ",__FUNCTION__);
00210 dgm.print(stdout);
00211 printf("\n");
00212 return false;
00213 }
00214
00215 dgm.reset();
00216 if (!dgm.receive(ctrlsock)) {
00217 printf("%s: Can't receive datagram\n",__FUNCTION__);
00218 return false;
00219 }
00220 if (dgm.getId() != 0x33) {
00221 printf("%s: Received invalid datagram: ",__FUNCTION__);
00222 dgm.print(stdout);
00223 printf("\n");
00224 return false;
00225 }
00226
00227 return waitcompletion();
00228 }
00229
00230 bool CanonDriver::panto(double pan)
00231 {
00232 requestCurrentPos();
00233 return moveto(pan,ctilt,czoom);
00234 }
00235
00236 bool CanonDriver::tiltto(double tilt)
00237 {
00238 requestCurrentPos();
00239 return moveto(cpan,tilt,czoom);
00240 }
00241
00242 bool CanonDriver::zoomto(double zoom)
00243 {
00244 requestCurrentPos();
00245 return moveto(cpan,ctilt,zoom);
00246 }
00247
00248 bool CanonDriver::center()
00249 {
00250 requestCurrentPos();
00251 return moveto(0,0,czoom);
00252 }
00253
00254 bool CanonDriver::movetoward(Direction dir)
00255 {
00256 Datagram dgm;
00257 dgm.reset();
00258 dgm.setId(0x3C);
00259 dgm.setStatus(0x00,0x00);
00260 dgm.setData((unsigned char)dir,0);
00261
00262 if (!dgm.send(ctrlsock)) {
00263 printf("%s: Can't send datagram: ",__FUNCTION__);
00264 dgm.print(stdout);
00265 printf("\n");
00266 return false;
00267 }
00268 dgm.reset();
00269 if (!dgm.receive(ctrlsock)) {
00270 printf("%s: Can't receive datagram\n",__FUNCTION__);
00271 return false;
00272 }
00273 if (dgm.getId() != 0x3C) {
00274 printf("%s: Received invalid datagram: ",__FUNCTION__);
00275 dgm.print(stdout);
00276 printf("\n");
00277 return false;
00278 }
00279 return true;
00280 }
00281
00282 bool CanonDriver::stop()
00283 {
00284 Datagram dgm;
00285 dgm.reset();
00286 dgm.setId(0x3C);
00287 dgm.setStatus(0x00,0x00);
00288
00289 if (!dgm.send(ctrlsock)) {
00290 printf("%s: Can't send datagram: ",__FUNCTION__);
00291 dgm.print(stdout);
00292 printf("\n");
00293 return false;
00294 }
00295 dgm.reset();
00296 if (!dgm.receive(ctrlsock)) {
00297 printf("%s: Can't receive datagram\n",__FUNCTION__);
00298 return false;
00299 }
00300 if (dgm.getId() != 0x3C) {
00301 printf("%s: Received invalid datagram: ",__FUNCTION__);
00302 dgm.print(stdout);
00303 printf("\n");
00304 return false;
00305 }
00306 if (!dgm.receive(ctrlsock,2000)) {
00307 printf("%s: Can't receive stop datagram\n",__FUNCTION__);
00308 return false;
00309 }
00310 if ((dgm.getId() != 0x33) || (dgm.getStatus() != 0x06E0)) {
00311 printf("%s: Received invalid datagram: ",__FUNCTION__);
00312 dgm.print(stdout);
00313 printf("\n");
00314 return false;
00315 }
00316 const unsigned char * rdata = dgm.bdata();
00317 cpan = (signed short)(((unsigned short)(rdata[0]) << 8) | rdata[1]);
00318 cpan /= 100.0;
00319 ctilt = (signed short)(((unsigned short)(rdata[2]) << 8) | rdata[3]);
00320 ctilt /= 100.0;
00321 czoom = (signed short)(((unsigned short)(rdata[4]) << 8) | rdata[5]);
00322 czoom /= 100.0;
00323 return true;
00324 }
00325
00326 bool CanonDriver::requestCurrentPos()
00327 {
00328 Datagram dgm;
00329 dgm.reset();
00330 dgm.setId(0x33);
00331 dgm.setStatus(0x8000);
00332
00333 if (!dgm.send(ctrlsock)) {
00334 printf("%s: Can't send datagram: ",__FUNCTION__);
00335 dgm.print(stdout);
00336 printf("\n");
00337 return false;
00338 }
00339 dgm.reset();
00340 if (!dgm.receive(ctrlsock)) {
00341 printf("%s: Can't receive datagram\n",__FUNCTION__);
00342 return false;
00343 }
00344 if ((dgm.getId() != 0x33) ||
00345 ((dgm.getStatus() & 0x00FF) != 0x00E0)) {
00346 printf("%s: Received invalid datagram: ",__FUNCTION__);
00347 dgm.print(stdout);
00348 printf("\n");
00349 return false;
00350 }
00351 const unsigned char * rdata = dgm.bdata();
00352 cpan = (signed short)(((unsigned short)(rdata[0]) << 8) | rdata[1]);
00353 cpan /= 100.0;
00354 ctilt = (signed short)(((unsigned short)(rdata[2]) << 8) | rdata[3]);
00355 ctilt /= 100.0;
00356 czoom = (signed short)(((unsigned short)(rdata[4]) << 8) | rdata[5]);
00357 czoom /= 100.0;
00358 return true;
00359 }
00360
00361 void CanonDriver::getCurrentPos(double * pan, double * tilt, double * zoom)
00362 {
00363 requestCurrentPos();
00364 if (pan != NULL) *pan = cpan ;
00365 if (tilt != NULL) *tilt = ctilt ;
00366 if (zoom != NULL) *zoom = czoom ;
00367 printf("At position: %f %f %f\n",
00368 cpan,ctilt,czoom);
00369 }
00370
00371
00372