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
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
00047
00048
00049
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
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
00099 strcpy(cf.cmd_mode, "auto");
00100
00101
00102 cf.cmd_irad -= conf.steering_offset;
00103 cf.cur_irad -= conf.steering_offset;
00104
00105 func_result = func(&cf, data);
00106
00107
00108 cf.cmd_irad += conf.steering_offset;
00109 cf.cur_irad += conf.steering_offset;
00110
00111
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
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 #endif
00148 }
00149
00150 cartcomm_disconnect(sockfd);
00151 }