最近为智能移动小车编写上位机软件的过程中,遇到了文件读写处理的任务,文件是一般的文本文件.txt格式的,其内容由十六进制数据组成。文件内数据的格式如下:
FF FD 03 FD 77 FE 77 1C 27
FF FD 01 FE 00 FE 00 1E 28
FF FE 00 FE B4 FE B4 21 28
...
每一帧数据由9个十六进制数据组成,用于标识智能车运行过程的相对于参考轨迹的姿态偏差,以及运行过程的线速度与角速度值。
data[0]: 帧头,由FF标识(实际操作过程数据帧头并未使用到);
data[1],data[2]: 第一个有效数据,位置偏差aglErr,data[1]标识aglErr的符号,data[2]表示aglErr的数值;data[3],data[4]: 第二个有效数据,位置偏差xErr,data[3]标识xErr的符号,data[4]表示xErr的数值;data[5],data[6]: 第三个有效数据,航向角偏差yErr,data[5]标识yErr的符号,data[6]表示yErr的数值;
data[7]: 第四个有效数据,表示智能车实时线速度lineVct,显然为正值;
data[8]: 第五个有效数据,表示智能车实时角速度aglVct,显然也为正值;
首先,需要把文本文件中的数据读出来并保存在内存中,我使用的数据类型是vector<stirng>,代码如下:
void readFileToRawDatas(const char *p, std::vector<std::string> &m_rawDatas)
{
std::ifstream dataFile(p);
if (dataFile)
{
std::string str;
while (dataFile >> str)
m_rawDatas.push_back(str);
}
else
{
qDebug() << "Open file failed!";
}
}
其中,readFileToRawDatas函数接受两个参数,第一个参数是要读取文件的路径,第二个参数是数据存储的目的位置
然后,将字符串类型的十六进制数据转换为int型数据,可以由以下两个函数来实现:
int hexCharToNum(const char c); 将单个字符('A'('a')-'F'('f'))转换为对应的0-15范围内的数字
int hexCharToNum(const char c)
{
int temp;
switch (c)
{
case '0':
temp = 0;
break;
case '1':
temp = 1;
break;
case '2':
temp = 2;
break;
case '3':
temp = 3;
break;
case '4':
temp = 4;
break;
case '5':
temp = 5;
break;
case '6':
temp = 6;
break;
case '7':
temp = 7;
break;
case '8':
temp = 8;
break;
case '9':
temp = 9;
break;
case 'A':
case 'a':
temp = 10;
break;
case 'B':
case 'b':
temp = 11;
break;
case 'C':
case 'c':
temp = 12;
break;
case 'D':
case 'd':
temp = 13;
break;
case 'E':
case 'e':
temp = 14;
break;
case 'F':
case 'f':
temp = 15;
break;
default:
break;
}
return temp;
}
int hexStrToInt(const string &str); 将两个字符组成的十六进制字符串转换为对应的int型数据
int hexStrToInt(const string &str)
{
int highBit = 0;
char lowBit = 0;
highBit = hexCharToNum(str[0]);
lowBit = hexCharToNum(str[1]);
return lowBit + 16 * highBit;
}
最后,实现数据的分类存储
void dataAssort(const std::vector<std::string> &strVec)
{
int temp = 0;
for (auto iter = strVec.cbegin(); iter != strVec.cend(); iter += DATA_FRAME_BYTE)
{
//设置aglErrDatas
if ("FE" == *(iter + 1))
{
temp = hexStrToInt(*(iter + 2));
m_aglErrDatas.push_back(temp);
}
else
{
temp = -1 * hexStrToInt(*(iter + 2));
m_aglErrDatas.push_back(temp);
}
//设置xErrDatas
if ("FE" == *(iter + 3))
{
temp = hexStrToInt(*(iter + 4));
m_xErrDatas.push_back(temp);
}
else
{
temp = -1 * hexStrToInt(*(iter + 4));
m_xErrDatas.push_back(temp);
}
//设置yErrDatas
if ("FE" == *(iter + 5))
{
temp = hexStrToInt(*(iter + 6));
m_yErrDatas.push_back(temp);
}
else
{
temp = -1 * hexStrToInt(*(iter + 6));
m_yErrDatas.push_back(temp);
}
//设置lineVecDatas
temp = hexStrToInt(*(iter + 7));
m_lineVecDatas.push_back(temp);
//设置aglVecDatas
temp = hexStrToInt(*(iter + 8));
m_aglVecDatas.push_back(temp);
}
}
其中,DATA_FRAME_BYTE表示一帧数据的字节数,即数字9
m_aglErrDatas~m_aglVecDatas是已经定义过的vector<int>对象,即上文我们所说的5个有效数据
最后,放一张离线环境下,通过读取保存在文本文件中原始数据所绘制的智能车位姿以及速度值的波形图,如下: