Main Page | Data Structures | Directories | File List | Data Fields | Globals

drive.c

Go to the documentation of this file.
00001 #include <config.h>
00002 
00003 #include <stdio.h>
00004 #include <sys/time.h>
00005 #include <time.h>
00006 #include <errno.h>
00007 #include <string.h>
00008 #include <math.h>
00009 
00010 #include <drivers/drivers.h>
00011 #include <cartcomm/comm.h>
00012 #include <conf.h>
00013 
00014 #define DEBUG_LEVEL 2
00015 #include <debug.h>
00016 
00017 //#define KEEP_TIME
00018 
00019 #define SLEEP_OVERHEAD_US 850
00020 
00022 
00025 void drive(drivefunc_t func, void *data) {
00026     int sockfd = -1;
00027     int result = 0;
00028     int func_result = 0;
00029     char msg[MAX_MSG_SIZE];
00030     cframe_t cf;
00031     int next_msg = -1;
00032     int retries = 0;
00033     struct timespec req, rem;
00034 
00035 #ifdef KEEP_TIME
00036     struct timeval now, then;
00037     long passed_time;
00038 #endif
00039 
00040     while(func_result == 0) {
00041 #ifdef KEEP_TIME
00042         gettimeofday(&now, NULL);
00043 
00044         passed_time = now.tv_usec - then.tv_usec;
00045 
00046 //        adjustment = (long) ((0.9 * adjustment) + (0.1 * (COMM_PERIOD_US - passed_time)));
00047 
00048 //        DEBUG2("Actual loop time = %ld uS", passed_time);
00049 //        DEBUG2("Error of loop time = %ld uS", COMM_PERIOD_US - passed_time);
00050 
00051         gettimeofday(&then, NULL);
00052 #endif
00053 
00054         if(sockfd < 0) {
00055             req.tv_sec = 0;
00056             req.tv_nsec = COMM_PERIOD_US * 500;
00057             nanosleep(&req, &rem);
00058 
00059             DEBUG1("Trying to reconnect to server..");
00060             sockfd = cartcomm_connect_sync(conf.server, conf.port);
00061             if(sockfd < 0)
00062                 continue;
00063 
00064             next_msg = -1;
00065         }
00066 
00067         // This read will block, we have nothing better to be doing
00068         result = cartcomm_read_msg(sockfd, msg, sizeof(msg));
00069         if(result < 0) {
00070             DEBUG1("read_msg failed!");
00071             retries++;
00072 
00073             if(retries > MAX_RETRIES) {
00074                 cartcomm_disconnect(sockfd);
00075                 sockfd = -1;
00076                 retries = 0;
00077             }
00078 
00079             continue;
00080         }
00081         retries = 0;
00082 
00083         DEBUG3("\n<<< %s", msg);
00084 
00085         result = cartcomm_decode_msg(&cf, msg);
00086         if(result < 0) {
00087             DEBUG1("decode_msg failed");
00088             continue;
00089         }
00090 
00091         if(next_msg > -1) {
00092             if(cf.seqno != next_msg) {
00093                 DEBUG1("Missed message(s): %ld", cf.seqno - next_msg);
00094             }
00095         }
00096         next_msg = cf.seqno + 1;
00097 
00098         // XXX Mode switching, need to put something otherwise it's empty
00099         strcpy(cf.cmd_mode, "auto");
00100 
00101         // Patch up some values before calling the driver function
00102         cf.cmd_irad -= conf.steering_offset;
00103         cf.cur_irad -= conf.steering_offset;
00104 
00105         func_result = func(&cf, data);
00106 
00107         // Unpatch up those values (otherwise the cart will complain)
00108         cf.cmd_irad += conf.steering_offset;
00109         cf.cur_irad += conf.steering_offset;
00110 
00111         // If we are done, then make sure to tell the cart to stop
00112         if(func_result != 0) {
00113             cf.cmd_speed = 0.0;
00114             cf.cmd_irad = 0.0;
00115         }
00116 
00117         cartcomm_encode_msg(&cf, msg);
00118 
00119         DEBUG3("\n>>> %s", msg);
00120 
00121         result = cartcomm_send_msg(sockfd, msg);
00122         if(result < 0) {
00123             DEBUG1("send_msg failed");
00124             return;
00125         }
00126 
00127 #ifdef KEEP_TIME
00128         gettimeofday(&now, NULL);
00129 
00130         passed_time = now.tv_usec - then.tv_usec;
00131         DEBUG2("Took %ld usec to process", passed_time);
00132 
00133         gettimeofday(&now, NULL);
00134 
00135 /*
00136         rem.tv_sec = 0;
00137         rem.tv_nsec = (COMM_PERIOD_US - SLEEP_OVERHEAD_US - passed_time) * 1000;
00138 
00139 wait_more:
00140         req.tv_sec = 0;
00141         req.tv_nsec = rem.tv_nsec;
00142         result = nanosleep(&req, &rem);
00143         if(result < 0 && errno == EINTR)
00144             goto wait_more;
00145 */
00146 
00147 #endif
00148     }
00149 
00150     cartcomm_disconnect(sockfd);
00151 }

Generated on Thu Sep 6 13:13:11 2007 for driver by  doxygen 1.3.9.1