apps/compass/compass.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : compass.c
00003 *! DESCRIPTION: converts output from the compass module (now OS5000) to Exif
00004 *!              in Elphel cameras 
00005 *! Copyright (C) 2002-2007 Elphel, Inc.
00006 *! -----------------------------------------------------------------------------**
00007 *!  This program is free software: you can redistribute it and/or modify
00008 *!  it under the terms of the GNU General Public License as published by
00009 *!  the Free Software Foundation, either version 3 of the License, or
00010 *!  (at your option) any later version.
00011 *!
00012 *!  This program is distributed in the hope that it will be useful,
00013 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 *!  GNU General Public License for more details.
00016 *!
00017 *!  You should have received a copy of the GNU General Public License
00018 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 *! -----------------------------------------------------------------------------**
00020 *!  $Log: compass.c,v $
00021 *!  Revision 1.1  2008/04/07 09:16:31  elphel
00022 *!  converting OS-5000 compass output to Exif
00023 *!
00024 */
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <fcntl.h>
00028 #include <stdio.h>
00029 #include <unistd.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <termios.h>
00033 #include <asm/elphel/exifa.h>
00034 #include <asm/byteorder.h> //endians
00035 
00036 #define EXIF_DEV "/dev/exif_meta"
00037 #define PROGRAM_SERIAL 0
00038 #define D(x)
00039 //#define D(x) x
00040 
00041 void exif_init_compass_meta(struct meta_CompassInfo_t *meta) {
00042    meta->CompassDirection_nom=   __cpu_to_be32((int) 0);
00043    meta->CompassDirection_denom= __cpu_to_be32((int) EXIF_GPS_COMPASS_DENOM);
00044    meta->CompassPitchRef=       'N';
00045    meta->CompassPitch_nom=       __cpu_to_be32((int) 0);
00046    meta->CompassPitch_denom=     __cpu_to_be32((int) EXIF_GPS_COMPASS_DENOM);
00047    meta->CompassRollRef=        'E';
00048    meta->CompassRoll_nom=        __cpu_to_be32((int) 0);
00049    meta->CompassRoll_denom=      __cpu_to_be32((int) EXIF_GPS_COMPASS_DENOM);
00050 }
00051 
00052 
00053 int main(int argc, char *argv[]) {
00054    FILE *fcompass;
00055    int fd_exif,i;
00056    char response[256];
00057    int  response_len;
00058    char * cp;
00059    char * cp_cs; // pointer to nmea CS 
00060    char * cp_c;  // course
00061    char * cp_r;  // roll
00062    char * cp_p;  // pitch
00063    char * cp_t;  // temperature
00064    double dc=0, dp=0,dr=0,dt=0;
00065    int icourse,ipitch,iroll;
00066    unsigned char cs_calc, cs_read;
00067    int    upside_down=-1; 
00068    struct meta_CompassInfo_t meta;
00069 #if PROGRAM_SERIAL
00070    int fd_compass;
00071    struct termios termio;
00072 #endif
00073    exif_init_compass_meta(&meta);
00074    if (argc < 2) {
00075       printf("Usage: %s compass_device [u]\n", argv[0]);
00076      exit (-1);
00077    }
00078    if (argc >2) {
00079      if (argv[2][0]=='u') upside_down=1;
00080    }
00081 
00082    fd_exif = open(EXIF_DEV, O_RDWR);
00083    if (fd_exif<=0) {
00084      fprintf(stderr,"Can not open device file "EXIF_DEV);
00085      exit (-1);
00086    }
00087 #if PROGRAM_SERIAL
00088    fd_compass = open(argv[1], O_RDWR);
00089    if (fd_compass == -1) {
00090       perror("Cannot open compass device");
00091      close(fd_exif);
00092      exit (-1);
00093    }
00094    tcgetattr(fd_compass, &termio);
00096 //int cfsetispeed(struct termios *termios_p, speed_t speed);
00097 //int cfsetospeed(struct termios *termios_p, speed_t speed);
00098 //B19200
00100    cfsetospeed(&termio, B19200);
00101    tcsetattr(fd_compass, TCIOFLUSH, &termio);
00102 #endif
00103 
00104 #if PROGRAM_SERIAL
00105    fcompass=fopen(argv[1], "r+"); // probably "r" is enough - we do not want to control it here
00106 #else
00107    fcompass=fopen(argv[1], "r");
00108 #endif
00109    if (!fcompass) {
00110       perror("Cannot open compass device!");
00111      exit (-1);
00112    }
00113    
00114    while (1) {
00115      fgets(response,sizeof(response),fcompass);
00116      if ((cp=strchr(response,'\n'))) cp[0]='\0';
00117      if ((cp=strchr(response,'\r'))) cp[0]='\0';
00118 //     D(printf("response: >>%s<<\n",response));
00120      response_len=strlen(response);
00121      if (response_len>0) {
00122        if (response_len>4) {
00123          if ((cp_cs=strchr(response,'*'))) {
00124            cp_cs[0]='\0';
00125            cp_cs++;
00126            cs_read= strtol(cp_cs, NULL, 16);
00127            cs_calc=0;
00128            for (i=1; response[i]; i++) cs_calc^=response[i];
00129 //   unsigned char cs_calc, cs_read;
00130            if (cs_calc==cs_read ) {
00131              D(printf ("Got NMEA string >>%s<<\n",response+1));
00132              cp_c=strchr(response,'C');  // course
00133              cp_r=strchr(response,'R');  // roll
00134              cp_p=strchr(response,'P');  // pitch
00135              cp_t=strchr(response,'T');  // temperature
00136              if (cp_c) {cp_c[0]='\0';cp_c++;}
00137              if (cp_r) {cp_r[0]='\0';cp_r++;}
00138              if (cp_p) {cp_p[0]='\0';cp_p++;}
00139              if (cp_t) {cp_t[0]='\0';cp_t++;}
00140 //need to be after all letters where found and zeroed
00141              if (cp_c) dc=strtod(cp_c, NULL);
00142              if (cp_r) dr=strtod(cp_r, NULL);
00143              if (cp_p) dp=strtod(cp_p, NULL);
00144              if (cp_t) dt=strtod(cp_t, NULL);
00145              D(printf("course=%f, roll=%f, pitch=%f, temperature=%f\n",dc,dr,dp,dt));
00146 //fill Exif fields (no temperature)
00147 //          int icourse,ipitch,iroll;
00148              if (upside_down<0) {
00149                upside_down= ((dr>90) || (dr<-90))? 1:0;
00150              }
00151              if (upside_down) {
00152                dr+=180.0;
00153                if (dr>180) dr-=360;
00154              }
00155              icourse= (dc* EXIF_GPS_COMPASS_DENOM) +0.5;
00156              ipitch=  (dp* EXIF_GPS_COMPASS_DENOM) +0.5;
00157              iroll=   (dr* EXIF_GPS_COMPASS_DENOM) +0.5;
00158              meta.CompassDirection_nom=   __cpu_to_be32((int) icourse);
00159              if (ipitch<0) {
00160                meta.CompassPitchRef=  EXIF_COMPASS_PITCH_ASCII[1];
00161                ipitch= -ipitch;
00162              } else meta.CompassPitchRef=  EXIF_COMPASS_PITCH_ASCII[0];
00163              meta.CompassPitch_nom=       __cpu_to_be32((int) ipitch);
00164              if (iroll<0) {
00165                meta.CompassRollRef=  EXIF_COMPASS_ROLL_ASCII[1];
00166                iroll= -iroll;
00167              } else meta.CompassRollRef=  EXIF_COMPASS_ROLL_ASCII[0];
00168              meta.CompassRoll_nom=       __cpu_to_be32((int) iroll);
00169 
00170              lseek (fd_exif,Exif_GPSInfo_CompassDirection,SEEK_END); // position file pointer at the beginning of the data field for Compass
00171              write (fd_exif, &meta, sizeof(meta));
00172            } else D(printf("Checksum mismatch: read 0x%x, calculated 0x%x\n",(int)cs_read,(int)cs_calc));
00173          } else D(printf("No '*' in response, ignoring\n"));
00174       } else D(printf("response to short (%d), ignoring\n",response_len));
00175     }
00176    }
00177 return 0;
00178 }

Generated on Thu Aug 7 16:18:59 2008 for elphel by  doxygen 1.5.1