-
[GPS]NMEA Parsing and Saving with CRobot, Autonomous Vehicle 2022. 11. 7. 11:54
u-blox GPS 장치를 serial로 연결하여 NMEA message parsing 및 csv 파일 형식으로 저장하기
https://kkastory.tistory.com/37
+) ublox hex-command로 configuration 하기
https://portal.u-blox.com/s/question/0D52p00008HKCh8CAH/ublox-8-configuration-using-hex-commands
Terminal에서 ublox GPS 세팅하기
sudo chmod 777 /dev/ttyACM0 #Additional, set baudrate sudo echo -e n'\xB5\x62\x06\x08\x06\x00\x64\x00\x01\x00\x01\x00\x7A\x12\xB5\x62\x06\x08\x00\x00\x0E\x30' > /dev/ttyACM0
Parsing & Saving 코드
gps_parser.c
#include "Linux_keyboard.h" #include "Timestamp.h" #include "Strtok_m.h" #include "Can_serial.h" #include "Speed_spec.h" using namespace std; Speed_spec speeds[] = { {"1200", B1200}, {"2400", B2400}, {"4800", B4800}, {"9600", B9600}, {"19200", B19200}, {"38400", B38400}, {"57600", B57600}, {"115200", B115200}, {NULL, 0} }; int main(int argc, char *argv[]){ Linux_keyboard lk; Timestamp ts; Strtok_m stm; Can_serial cs; int iDev = 0; int iRet = 0; sleep(3); const char *devicename = argv[1]; int speed = B9600; //default iDev = open(devicename, O_RDWR | O_NOCTTY); if(0>iDev){ perror(devicename); exit(-100); } if(argc > 2) { Speed_spec *s; for(s = speeds; s->name; s++) { if(strcmp(s->name, argv[2]) == 0) { //same brate in speed_spec speed = s->flag; //change spped value to user input //fprintf(stderr, "setting speed %s\n", s->name); break; } } } cs.init_serial(iDev,speed); char cBuff[255]; char path[256]; lk.init_keyboard(); const char * mtime = ts.p_time(); sprintf(path, "/home/kanakim/Documents/GPS/i30_GPS_%s.csv", mtime); printf("The GPS file saved [%s]\n", path); FILE* fp = fopen(path, "w+"); while(1){ const char *nmea[50]={NULL, }; iRet = read(iDev, cBuff, 255); cBuff[iRet] = 0; const char *ptr = stm.strtok_f(cBuff, ','); int cnt = 0; if(strcmp(ptr,"$GNGGA") == 0 ){ while(ptr!=NULL){ if(cnt == 1){ nmea[1] = ts.p_time(); }else{ nmea[cnt] = ptr; } cnt++; ptr = stm.strtok_f(NULL, ','); } fprintf(fp, "%s,%s,%s,%s,%s,%s,%s\n",nmea[1], nmea[2], nmea[3], nmea[4], nmea[5], nmea[9], nmea[10]); } if(lk._kbhit()){ int ch = lk._getch(); if(ch>=10) break; } } lk.close_keyboard(); fclose(fp); cs.close_serial(iDev); return 0; }
더보기Linux_keyboard.h
#ifndef Linux_keyboard_h #define Linux_keyboard_h #include <stdlib.h> #include <stdio.h> #include <iostream> #include <unistd.h> #include <sys/select.h> #include <termios.h> class Linux_keyboard{ public: struct termios initial_settings, new_settings; int peek_character = -1; void init_keyboard() { tcgetattr(0,&initial_settings); new_settings = initial_settings; new_settings.c_lflag &= ~ICANON; new_settings.c_lflag &= ~ECHO; new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &new_settings); } void close_keyboard() { tcsetattr(0, TCSANOW, &initial_settings); } int _kbhit() { unsigned char ch; int nread; if (peek_character != -1) return 1; new_settings.c_cc[VMIN]=0; tcsetattr(0, TCSANOW, &new_settings); nread = read(0,&ch,1); new_settings.c_cc[VMIN]=1; tcsetattr(0, TCSANOW, &new_settings); if(nread == 1) { peek_character = ch; return 1; } return 0; } int _getch() { char ch; if(peek_character != -1) { ch = peek_character; peek_character = -1; return ch; } read(0,&ch,1); return ch; } }; #endif
Can_serial.h
#ifndef Can_serial_h #define Can_serial_h #include <stdlib.h> #include <stdio.h> #include <iostream> #include <fcntl.h> #include <termios.h> #include <sys/types.h> #include <sys/stat.h> #include <stdbool.h> class Can_serial{ public: struct termios stOldState; struct termios stNewState; void init_serial(int iDev, int speed){ tcgetattr(iDev, &stOldState); bzero(&stNewState, sizeof(stNewState)); stNewState.c_cflag = speed | CRTSCTS | CS8 | CLOCAL | CREAD; stNewState.c_iflag = IGNPAR | ICRNL; stNewState.c_oflag = 0; stNewState.c_lflag = ICANON; bzero(stNewState.c_cc, NCCS); stNewState.c_cc[VMIN] = 1; tcflush(iDev, TCIFLUSH); tcsetattr(iDev, TCSANOW, &stNewState); } void close_serial(int iDev){ tcsetattr(iDev, TCSANOW, &stOldState); close(iDev); } }; #endif
Timestamp.h
#ifndef Timestamp_h #define Timestamp_h #include <stdlib.h> #include <stdio.h> #include <iostream> #include <chrono> #include <fstream> #include <sstream> #include <istream> #include <string.h> #include <string> #include <cstring> using namespace std; class Timestamp{ public: string getMilliTime(){ auto time = chrono::system_clock::now(); auto mill = chrono::duration_cast<chrono::milliseconds>(time.time_since_epoch()); long long currentTimeMillis = mill.count(); int msc = currentTimeMillis % 1000; long nowTime = currentTimeMillis/1000; tm *ts = localtime(&nowTime); char buffer[80]; strftime(buffer, 80, "%Y%m%d%H%M%S", ts); string s(buffer); string str; if(stoi(to_string(msc)) < 10){ str = s+"00"+to_string(msc); } else if(stoi(to_string(msc)) < 100){ str = s+"0"+to_string(msc); }else{ str = s+to_string(msc); } return str; } const char *p_time(){ string get_time = getMilliTime(); char * mtime = new char[get_time.size()]; strcpy(mtime, get_time.c_str()); return mtime; } const char *utc_to_kst(char*s){ char *buf = new char[256]; float utc = atof(s); float kst = utc + 90000; int result = kst*100; sprintf(buf, "%d", result); return buf; } }; #endif
Strtok_m.h
#ifndef Strtok_m_h #define Strtok_m_h #include <stdio.h> class Strtok_m{ public: char *strtok_fr (char *s, char delim, char **save_ptr) { char *tail; char c; if (s == NULL) { s = *save_ptr; } tail = s; if ((c = *tail) == '\0') { s = NULL; } else { do { if (c == delim) { *tail++ = '\0'; break; } }while ((c = *++tail) != '\0'); } *save_ptr = tail; return s; } char *strtok_f(char *s, char delim) { static char *save_ptr; return strtok_fr(s, delim, &save_ptr); } }; #endif
Speed_spec.h
#ifndef SPEED_SPEC_H #define SPEED_SPEC_H typedef struct { const char *name; int flag; } Speed_spec; #endif
'Robot, Autonomous Vehicle' 카테고리의 다른 글
[GPS]NMEA Output Message (0) 2022.11.07 [Jetson Nano] Jetson Nano 에서 Object Detection ( DetectNet, SSD-MobileNetv2, Pytorch ) (0) 2021.03.24 [Python OpenCV ROS] cv.cap으로 딴 이미지 compressedImage msg로 publish하기 (0) 2021.03.02 [ROS USB_CAM] 한 머신에서 multi usb_cam node 켜기 (0) 2021.03.02 [Darknet ROS] darknet_ros yolov3 코드 이것 저것 수정 (2) 2021.03.02