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

cframe.c

Go to the documentation of this file.
00001 #include <config.h>
00002 
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <math.h>
00006 #include <string.h>
00007 
00008 #define DEBUG_LEVEL 1
00009 #include "debug.h"
00010 #include <cartcomm/cframe.h>
00011 #include <cartcomm/nmea.h>
00012 #include <cartcomm/comm.h>
00013 
00014 // Provided by cframe_parser.c
00015 int parse_msg(cframe_t *cf, char *msg);
00016 
00017 //#define SANITY_CHECK
00018 
00020 
00025 static unsigned char compute_checksum(char *msg, int start, int stop) {
00026     int i;
00027     unsigned int checksum = 0;
00028 
00029     for(i = start; i < stop; i++) {
00030         checksum += (unsigned int) msg[i];
00031     }
00032 
00033     checksum %= 255; // Gag.. Vomit.. Gavomit!
00034     return checksum;
00035 }
00036 
00038 
00043 int cartcomm_encode_msg(cframe_t *cf, char *outMsg) {
00044     char field[80];
00045     char nmea[NMEA_MAXSIZE];
00046     char msg[MAX_MSG_SIZE];
00047     int len;
00048 
00049     strcpy(msg, "");
00050 
00051 #define APPEND(fmt, val) sprintf(field, fmt, val); strcat(msg, field);
00052 
00053     // Header
00054     APPEND("VehMsgCount=%ld,", cf->seqno);
00055     APPEND("TimeStamp=%ld,", cf->timestamp);
00056 
00057     // Steering
00058     APPEND("CmdTurnRadius=%.5f,", cf->cmd_irad);
00059     APPEND("StatusTurnRadius=%.5f,", cf->cur_irad);
00060     APPEND("StatusSteeringPosLimitError=%s,", cf->steer_limit_error);
00061 
00062     // Speed
00063     APPEND("CmdVehSpeed=%.2f,", cf->cmd_speed);
00064     APPEND("StatusVehSpeed=%.2f,", cf->cur_speed);
00065     APPEND("StatusPercentThrottle=%.2f,", cf->cur_throttle);
00066     APPEND("StatusVehSpeedLimitError=%s,", cf->speed_limit_error);
00067 
00068     // GPS
00069     deg_to_nmea(cf->gps_lat, nmea, sizeof(nmea));
00070     APPEND("GPSLat=%s,", nmea);
00071     deg_to_nmea(cf->gps_lon, nmea, sizeof(nmea));
00072     APPEND("GPSLon=%s,", nmea);
00073     APPEND("GPSSpdE=%.3f,", cf->gps_speed_east);
00074     APPEND("GPSSpdN=%.3f,", cf->gps_speed_north);
00075 //  APPEND("GPSEstPositionError=%.2f,", cf->GPSEpe);
00076     APPEND("GPSEstimatedPositionError=%.2f,", cf->gps_epe);
00077     APPEND("GPSStatus=%s,", cf->gps_status);
00078 
00079     // Status of the driver/cart connection
00080     APPEND("StatusComm=%s,", cf->status);
00081 
00082     // Desired system mode
00083     APPEND("CmdSystemMode=%s,", cf->cmd_mode);
00084 
00085     // System mode
00086     APPEND("StatusSystemMode=%s,", cf->cur_mode);
00087 
00088     // Error code
00089     APPEND("StatusErrorCode=%d,", cf->error_code);
00090 
00091     // Message length (header and data) in bytes
00092     len = strlen(msg) + 11;
00093 
00094     // Why oh why does MsgLength include itself?!
00095     if(len + 1 <= 9) {
00096         APPEND("MsgLength=%1d,", len + 1);
00097     } else if(len + 2 <= 99) {
00098         APPEND("MsgLength=%2d,", len + 2);
00099     } else if(len + 3 <= 999) {
00100         APPEND("MsgLength=%3d,", len + 3);
00101     } else if(len + 4 <= 9999) {
00102         APPEND("MsgLength=%4d,", len + 4);
00103     }
00104 
00105     // Checksum of header and data
00106     sprintf(outMsg, "{%s%02x}", msg, compute_checksum(msg, 0, strlen(msg)));
00107 
00108     DEBUG3(">>> %s", outMsg);
00109 
00110 #ifdef SANITY_CHECK
00111     cframe_t tcf;
00112     int result;
00113     result = cartcomm_decode_msg(&tcf, outMsg);
00114     ASSERT_EQUAL(result, 0);
00115 #endif
00116 
00117     return 0;
00118 }
00119 
00121 
00126 int cartcomm_decode_msg(cframe_t *cf, char *inMsg) {
00127     int msgLen;
00128     int checksum;
00129 
00130     DEBUG3("<<< %s", inMsg);
00131 
00132     parse_msg(cf, inMsg);
00133 
00134 //    print_cframe(stderr, cf);
00135 
00136     // don't count the guards or the checksum
00137     msgLen = strlen(inMsg) - 4;
00138 
00139     if(cf->msg_len != msgLen) {
00140         DEBUG2("wrong message length (theirs: %d, ours: %d)",
00141                cf->msg_len, msgLen);
00142 //        return -1;
00143     }
00144 
00145     // truncate to appropriate message for checksumming
00146     checksum = compute_checksum(inMsg, 1, strlen(inMsg) - 3);
00147 
00148     if(cf->checksum != checksum) {
00149         DEBUG2("checksum failed  (theirs: %d, ours: %d)",
00150                cf->checksum, checksum);
00151 //        return -1;
00152     }
00153 
00154     return 0;
00155 }
00156 
00158 
00161 void print_cframe(FILE *file, cframe_t *cf) {
00162 #define PRINT(...) fprintf(file, "\t" __VA_ARGS__); fputc('\n', file);
00163 
00164     fprintf(file, "{\n");
00165 
00166     PRINT("seqno = %ld\t", cf->seqno);
00167     PRINT("timestamp = %ld\t", cf->timestamp);
00168 
00169     PRINT("cmd_irad = %.5f\t", cf->cmd_irad);
00170     PRINT("cur_irad = %.5f\t", cf->cur_irad);
00171     PRINT("steer_limit_error = %s\t", cf->steer_limit_error);
00172 
00173     PRINT("cmd_speed = %.2f\t", cf->cmd_speed);
00174     PRINT("cur_speed = %.2f\t", cf->cur_speed);
00175     PRINT("cur_throttle = %.2f\t", cf->cur_throttle);
00176     PRINT("speed_limit_error = %s\t", cf->speed_limit_error);
00177 
00178     PRINT("gps_lat = %.6f\t", cf->gps_lat);
00179     PRINT("gps_lon = %.6f\t", cf->gps_lon);
00180     PRINT("gps_speed_east = %.3f\t", cf->gps_speed_east);
00181     PRINT("gps_speed_north = %.3f\t", cf->gps_speed_north);
00182     PRINT("gps_epe = %.2f\t", cf->gps_epe);
00183     PRINT("gps_status = %s\t", cf->gps_status);
00184 
00185     PRINT("status = %s\t", cf->status);
00186     PRINT("cmd_mode = %s\t", cf->cmd_mode);
00187     PRINT("cur_mode = %s\t", cf->cur_mode);
00188     PRINT("error_code = %d\t", cf->error_code);
00189 
00190     fprintf(file, "}\n");
00191 }

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