解析十六进制雷达数据格式:解析雷达FSPEC数据
以Cat62格式雷达数据为例,十六进制雷达数据部分代码:
3e0120bf7da4ffee0085
base_fspec_processor.h
//
// Created by qiaowei on 2024-02-03.
//
#ifndef RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H
#define RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H
#include <QVector>
#include <QString>
namespace processor {
class BaseFspecProcessor {
public:
virtual QVector<int>* processor(const QString& content,
int begin_position_index,
int& end_position_index) = 0;
};
} // processor
#endif //RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H
cat62_fspec_processor.h
//
// Created by qiaowei on 2024-01-25.
//
#ifndef RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H
#define RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H
#include <QObject>
#include <QVector>
#include <QList>
#include "../baseprocess/base_fspec_processor.h"
namespace processor {
/**
* @copyright 2003-2024
* @date 2024-02-09 22:40
* @author qiao wei
* @version 1.0
* @brief 处理十六进制雷达数据的FSPEC数据。
* @history
*/
class Cat62FspecProcessor : public QObject, public BaseFspecProcessor {
Q_OBJECT
public:
explicit Cat62FspecProcessor(QObject* parent = nullptr);
virtual ~Cat62FspecProcessor() override;
/**
* @author qiao wei
* @brief 从雷达数据hex_track_data中读取FSPEC数据。将FSPEC数据按照二进制格式保存到QVector<int>指针并返回。
* @param hex_track_data 十六进制雷达数据。
* @param begin_position FSPEC数据的起始索引。
* @param readed_data_end_position FSPEC数据的末位索引。
* @return QVector<int>指针。二进制格式保存的FSPEC数据。
* @history
*/
virtual QVector<int>* processor(const QString& hex_track_data,
int begin_position,
int& readed_data_end_position) override;
private:
/**
* @author qiao wei
* @brief 将存储FSPEC内容由十六进制的字符串转换为二进制的QVector<int>*。
* @param fspec_content FSPEC内容字符串。
* @param count FSPEC内容的字节数。因为参数content是2个字符组成1个字节,所以count数为字符串中字符数量的一半。
* @return FSPEC内容转换为二进制的QVector<int>*。
* @history
*/
QVector<int>* convertFspecToIntArray(QString fspec_content);
/**
* @author qiao wei
* @brief 将int数据value以二进制数的格式保存到容器vector的指定位置处。
* 传入的value是1个字节,将其转换为8位二进制数从左向右保存,因为每次只能保存1个字节的数据,保存多个
* 字节的数据需要依次保存到容器vector中。
* @param vector 存储二进制数的容器。
* @param value FSPES数据中的1个字节。
* @param begin_position 将字节value转换成二进制数保存到容器vector的第一位索引。
* @return
* @history
*/
virtual void replaceBinaryValueToContainer(QVector<int>* vector, int value, int begin_position);
/**
* @author qiao wei
* @brief 分步骤读取十六进制雷达数据track_data中的FSPEC数据,返回起始索引begin_position的1个字节FSPEC数据。
* @param track_data 十六进制雷达数据。
* @param begin_position 读取FSPEC数据的首位索引。
* @param readed_data_end_position 读取FSPEC数据的末位索引,该参数为引用类型。
* @return 返回读取的1个字节FSPEC数据,如果数据读取异常则返回""。
* @history
*/
QString readAByteFspec(const QString& track_data,
int begin_position,
int& readed_data_end_position);
/**
* @author qiao wei
* @brief 将完整的FSPEC数据从雷达数据中读取出。
* @param track_data 十六进制雷达数据。
* @param begin_position_index FSPEC在track_data中的起始索引。
* @return FSPEC数据。
* @history
*/
QString readFspecContent(const QString& track_data,
int begin_position_index);
/**
* @author qiao wei
* @brief 判断1个字节的数据是否是FSPEC数据的最后1个字节。
* @param a_byte_fspec_content 1个字节的FSPEC数据。
* @return true 已到FSPEC数据末位。
* @history
*/
bool isTheLastValueOfFspec(QString a_byte_fspec_content);
private:
/**
* @author qiao wei
* @brief 标识位,通过与运算判断字节最后一位是否为0。0b0000,0001。
*/
const static int THE_0_POSITION_VALUE;
/**
* @author qiao wei
* @brief 0b1000,0000。
*/
const static int THE_7_POSITION_VALUE;
};
} // processor
#endif //RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H
base_fspec_processor.cpp
//
// Created by qiaowei on 2024-01-25.
//
#include <QtDebug>
#include "cat62_fspec_processor.h"
namespace processor {
const int Cat62FspecProcessor::THE_0_POSITION_VALUE{1};
const int Cat62FspecProcessor::THE_7_POSITION_VALUE{128};
Cat62FspecProcessor::Cat62FspecProcessor(QObject* parent) : QObject(parent) {}
Cat62FspecProcessor::~Cat62FspecProcessor() {}
QVector<int>* Cat62FspecProcessor::processor(const QString& hex_track_data,
int begin_position,
int& readed_data_end_position) {
/**
* 1:从hex_track_data数据中读取完整的FSPEC数据。
* 1.1:从begin_position索引开始,依次读取2个字符(1个字节)。
* 1.2:判断读取的2个字符是否是FSPEC数据结尾。
* 1.3:将读取的2个字符依次添加到同一个字符串中,如果到了FSPEC数据结尾,则不再读取数据。
* 2:将FSPEC数据转换成int类型,保存到QVector<int>*容器。
* 3:返回QVect<int>*容器。
*/
readed_data_end_position = begin_position;
// 保存hex_track_data数据中指定位置的FSPEC数据。
QString fspec_content = readFspecContent(hex_track_data, begin_position);
readed_data_end_position = readed_data_end_position + fspec_content.length() - 1;
QVector<int>* fspec_vector = convertFspecToIntArray(fspec_content);
return fspec_vector;
}
QVector<int>* Cat62FspecProcessor::convertFspecToIntArray(QString fspec_content) {
/**
* 雷达数据中,2个字符表示1个字节。
* 根据字节数设置对应的QVector<int>*容量。1个字节是8位二进制数。
*/
// 获取FSPEC数据中字节个数。
int byte_count{fspec_content.length() / 2};
QVector<int>* vector{new QVector<int>(byte_count * 8)};
const int step{2};
int begin_position_index{0};
int value{0};
for (int index{0}; index != byte_count; ++index) {
value = fspec_content.mid(begin_position_index, step).toInt(nullptr, 16);
replaceBinaryValueToContainer(vector, value, index * 8);
begin_position_index += step;
}
return vector;
}
void Cat62FspecProcessor::replaceBinaryValueToContainer(QVector<int>* vector,
int value,
int begin_position) {
// 遍历1个字节所有位的次数。
const int count{8};
/**
* 1:依次遍历value值的每一位(8位二进制,从左侧高位开始依次遍历),并将二级制值保存到容器vector。
* 2:右移1位。依次读取value中每一位二进制值。
*/
for (int index{0}; index != 8; ++index) {
vector->replace(begin_position + index,
((THE_7_POSITION_VALUE == (value & THE_7_POSITION_VALUE)) ? 1 : 0));
value = value<<1;
}
}
QString Cat62FspecProcessor::readAByteFspec(const QString& track_data,
int begin_position,
int& readed_data_end_position) {
readed_data_end_position = begin_position;
QString content{track_data.mid(begin_position, 2)};
// 当前数据的末位索引。“+2”是当前数据末位下一位的索引,所以要减1。保证数据与参数名一致。
readed_data_end_position = begin_position + 2 - 1;
/**
* 判断读取的1个字节(2个字符)的FSPEC数据是否为空,是否读取到的是1个字节。如果以上条件满足,返回
* 字符串content,反之返回""。
*/
if (!content.isNull() && 2 == content.length()) {
return content;
} else {
return "";
}
}
QString Cat62FspecProcessor::readFspecContent(const QString& track_data,
int begin_position_index) {
int end_position_index{begin_position_index};
QString fspec_content;
QString a_byte_fspec_content;
/**
* 从雷达数据track_data中依次读取1个字节FSPEC数据,将数据保存到字符串fspec_content。
* 判断是否是FSPEC最后一个字节,如果不是继续读取FSPEC数据,反之退出循环。
*/
while (true) {
a_byte_fspec_content =
readAByteFspec(track_data,
begin_position_index,
end_position_index);
begin_position_index = end_position_index + 1;
fspec_content.append(a_byte_fspec_content);
if (isTheLastValueOfFspec(a_byte_fspec_content)) {
break;
}
}
return fspec_content;
}
bool Cat62FspecProcessor::isTheLastValueOfFspec(QString a_byte_fspec_content) {
int value{a_byte_fspec_content.toInt(nullptr, 16)};
return ((THE_0_POSITION_VALUE & value) == THE_0_POSITION_VALUE) ? false : true;
}
} // processor
main.cpp
#include <string>
#include <QApplication>
#include <QVector>
#include <QtDebug>
#include <QString>
#include "./form/main_window.h"
#include "./cat62process/cat62_fspec_processor.h"
#include "./cat62process/cat_62_length_processor.h"
#include "./cat62process/cat_62_header_processor.h"
using std::string;
using form::MainWindow;
using processor::Cat62FspecProcessor;
using processor::Cat62HeaderProcessor;
using processor::Cat62LengthProcessor;
int main(int argc,
char *argv[]) {
QApplication a(argc, argv);
// MainWindow* main_window{new MainWindow{nullptr}};
// main_window->show();
QString content = "3e0120bf7da4ffee00859880007205a0";
int begin_position{0};
int end_position = begin_position;
Cat62HeaderProcessor* header_processor{new Cat62HeaderProcessor{}};
qDebug()<< header_processor->processor(content, begin_position, end_position);
qDebug()<< "Header end position: " << end_position;
begin_position = end_position + 1;
Cat62LengthProcessor* lenght_processor{new Cat62LengthProcessor{}};
qDebug()<< lenght_processor->processor(content, begin_position, end_position);
qDebug()<< "Length end position: " << end_position;
begin_position = end_position + 1;
Cat62FspecProcessor* fspec_processor{new Cat62FspecProcessor{}};
QVector<int>* vector = fspec_processor->processor(content, begin_position, end_position);
for (int index = 0; index < vector->capacity(); ++index) {
qDebug()<< index << ": " << vector->at(index) << ", ";
}
qDebug()<< "FSPEC end position: " << end_position;
return QApplication::exec();
}
运行结果: