This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

IWR6843AOPEVM: MMWAVEICBOOST

Part Number:

我已经烧录成功官方给的people count demo,现在想编写一套matlab的代码,来处理返回的数据生成一个能够反映相对雷达具体位置的实施点云。

经过文档搜查,官方给出经过处理后的uart传输数据为数据包格式,数据包结构由固定大小的帧报头组成,后跟可变数量的 TLV。每个 TLV 都有固定的标头,后跟可变大小的有效负载。字节顺序为 Little Endian。  

TLV1         TLV2              TLVn

帧头是固定大小的 (40bytes)。结构体字段定义以下面的 MATLAB 语法显示。

 

既然知道是以数据包格式传输,并且帧头最开始的同步字也已经清楚。程序便有了思路,即从接收到的数据识别出同步字,随后以此为开始识别接下来的数据。并从中整理得到距离方位图。但是出现错误提示,发现接收到的数据没有与同步字相同的8个字节。

 

考虑到整个数据包的字节序为 小端(Little Endian)。这意味着在存储和传输时,低地址(或低字节)在前,高地址(或高字节)在后。如果我们将 0x0201040306050807 按照小端模式存储或传输,它的字节序会变成:0x07 0x08 0x05 0x06 0x03 0x04 0x01 0x02。更改程序发现问题依旧没有得到解决。

 

我让其显示丢失的字节

同步模式不匹配,丢弃一个字节数据。

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 03

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 02

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): FC

丢弃的数据(十六进制): 03

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 2C

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 00

丢弃的数据(十六进制): 0A

丢弃的数据(十六进制): D7

丢弃的数据(十六进制): 23

丢弃的数据(十六进制): 3C

丢弃的数据(十六进制): 0A

丢弃的数据(十六进制): D7

丢弃的数据(十六进制): 23

......................................................................................................................................................................................

其中出现大量00,不由得让我怀疑是否官方给出的数据接收格式有问题。同时也猜疑是否因为接受数据包过大,一个一个字节的丢弃工程量会相当之大。导致不能及时生成距离方位点云图。

  • clear;
    clc;
    % 配置串口参数
    portName = 'COM4'; % 串口名称
    baudRate = 921600; % 波特率
    timeout = 10; % 超时时间(秒)
    % 打开串口
    s = serial(portName, 'BaudRate', baudRate, 'Timeout', timeout);
    fopen(s);
    % 初始化变量
    frameHeaderSize = 40; % 帧头大小(字节)
    tlvHeaderSize = 8; % TLV 头大小(字节)
    packetBuffer = []; % 数据包缓冲区
    isFrameHeaderParsed = false; % 是否已解析帧头
    % 初始化点云图
    figure;
    h = scatter3([], [], [], 'filled');
    xlabel('X (m)');
    ylabel('Y (m)');
    zlabel('Z (m)');
    title('实时点云图');
    grid on;
    hold on;
    % 初始化目标位置图
    figure;
    hTarget = scatter([], [], [], 'filled');
    xlabel('X (m)');
    ylabel('Y (m)');
    zlabel('Z (m)');
    title('目标位置');
    grid on;
    hold on;
    % 循环接收数据
    while true
    % 读取数据
    data = fread(s, 512, 'uint8'); % 一次读取 512 字节
    if isempty(data)
    disp('未接收到数据,退出程序。');
    break;
    end
    % 将新数据追加到缓冲区
    packetBuffer = [packetBuffer; data];
    % 解析数据包
    while length(packetBuffer) >= frameHeaderSize
    % 解析帧头
    if ~isFrameHeaderParsed
    if length(packetBuffer) >= frameHeaderSize
    % 小端字节序处理
    frameHeader = typecast(packetBuffer(1:frameHeaderSize)', 'uint8');
    magicWordBytes = frameHeader(1:8); % 提取 magicWord 的 8 字节
    magicWord = typecast(magicWordBytes, 'uint64'); % 将字节转换为 uint64 类型
    % 定义小端模式下的 magicWord
    expectedMagicWord = uint64(hex2dec('0708050603040102')); % 小端模式下的 magicWord
    % 检查同步模式
    if magicWord == expectedMagicWord
    isFrameHeaderParsed = true;
    disp('帧头解析成功!');
    else
    disp('同步模式不匹配,丢弃数据。');
    fprintf('丢弃的数据(十六进制): ');
    fprintf('%02X ', packetBuffer(1));
    fprintf('\n');
    packetBuffer(1) = []; % 丢弃第一个字节,尝试重新同步
    continue;
    end
    % 提取总数据包长度
    totalPacketLenBytes = frameHeader(9:12); % 小端模式下总数据包长度字段
    totalPacketLen = typecast(totalPacketLenBytes, 'uint32'); % 转换为 uint32 类型
    else
    break;
    end
    end
    % 确保数据包完整
    if length(packetBuffer) >= totalPacketLen
    % 提取完整数据包
    packet = packetBuffer(1:totalPacketLen);
    packetBuffer = packetBuffer(totalPacketLen+1:end);
    isFrameHeaderParsed = false; % 重置帧头解析标志
    % 解析 TLV 数据
    tlvOffset = frameHeaderSize;
    while tlvOffset < totalPacketLen
    % 小端字节序处理
    tlvHeaderBytes = packet(tlvOffset+1:tlvOffset+tlvHeaderSize);
    tlvHeader = typecast(tlvHeaderBytes, 'uint32'); % 转换为 uint32 类型
    tlvType = tlvHeader(1); % TLV 类型
    tlvLength = tlvHeader(2); % TLV 长度
    if tlvType == 1 % 点云 TLV 类型
    pointCloudData = packet(tlvOffset+tlvHeaderSize+1:tlvOffset+tlvHeaderSize+tlvLength);
    pointCloudUnit = typecast(pointCloudData(1:20), 'single'); % 点云单位结构
    elevationUnit = pointCloudUnit(1);
    azimuthUnit = pointCloudUnit(2);
    dopplerUnit = pointCloudUnit(3);
    rangeUnit = pointCloudUnit(4);
    snrUnit = pointCloudUnit(5);
    % 提取点云数据
    pointData = pointCloudData(21:end);
    numPoints = length(pointData) / 8; % 每个点 8 字节
    pointData = reshape(pointData, 8, numPoints)';
    % 解析每个点
    elevations = typecast(pointData(:, 1), 'int8');
    azimuths = typecast(pointData(:, 2), 'int8');
    dopplers = typecast(pointData(:, 3:4)', 'int16');
    ranges = typecast(pointData(:, 5:6)', 'uint16');
    snrs = typecast(pointData(:, 7:8)', 'uint16');
    % 转换为实际物理量
    elevations = elevations * elevationUnit; % 弧度
    azimuths = azimuths * azimuthUnit; % 弧度
    dopplers = dopplers * dopplerUnit; % m/s
    ranges = ranges * rangeUnit; % 米
    snrs = snrs * snrUnit; % 无量纲
    % 转换为笛卡尔坐标系
    x = ranges .* cos(elevations) .* cos(azimuths);
    y = ranges .* cos(elevations) .* sin(azimuths);
    z = ranges .* sin(elevations);
    % 更新点云图
    h.XData = x;
    h.YData = y;
    h.ZData = z;
    drawnow;
    elseif tlvType == 2 % 目标列表 TLV 类型
    targetData = packet(tlvOffset+tlvHeaderSize+1:tlvOffset+tlvHeaderSize+tlvLength);
    numTargets = length(targetData) / 108; % 每个目标 108 字节
    targetData = reshape(targetData, 108, numTargets)';
    % 提取目标数据
    targetIDs = typecast(targetData(:, 1:4)', 'uint32');
    posX = typecast(targetData(:, 5:8)', 'single');
    posY = typecast(targetData(:, 9:12)', 'single');
    posZ = typecast(targetData(:, 13:16)', 'single');
    % 更新目标位置图
    hTarget.XData = posX;
    hTarget.YData = posY;
    hTarget.ZData = posZ;
    drawnow;
    end
    % 移动到下一个 TLV
    tlvOffset = tlvOffset + tlvHeaderSize + tlvLength;
    end
    else
    break;
    end
    end
    end
    % 关闭串口
    fclose(s);
    delete(s);
    clear s;
  • 这是我的代码,请问具体是哪里出了问题

  • 您好,

    已经收到了您的案例,调查需要些时间,感谢您的耐心等待

  • Hi 

    1. 首先建议使用串口助手 使用hex模式接收串口数据,串口数据中应当有 02 01 04 03 06 05 07 08的数据序列,

    如果没有,则检查您的波特率等串口设置。

    2. 建议使用char型数据进行magic word 的检索,可以提高magic word 的检索效率。

    barker_code = char([2 1 4 3 6 5 8 7]);

    startIdx = strfind(bytevecStr', barker_code);
    Ken
  • 你好,我用hex接收后存在大片的00数据请问合理吗?此外我检测到了你说的序列不过貌似有些不同,我的尾数是08 07

    • MMWDEMO_OUTPUT_MSG_COMPRESSED_POINTS(点云数据)
    • MMWDEMO_OUTPUT_MSG_TRACKERPROC_3D_TARGET_LIST(目标列表)
    • MMWDEMO_OUTPUT_MSG_TRACKERPROC_TARGET_INDEX(目标索引)
    • MMWDEMO_OUTPUT_MSG_TRACKERPROC_TARGET_HEIGHT(目标高度

    此外我阅读文档后发现TLV数据包存在多种类型,请问我接收到的TLV数据包类型是什么。如何从中得到具体的探测信息。02 01 04 03 06 05 08 07 04 00 05 03 34 00 00 00 43 68 0A 00 DC 0E 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 FD 03 00 00 04 00 00 00 00 00 00 00 02 01 04 03 06 05 08 07 04 00 05 03 34 00 00 00 43 68 0A 00 DD 0E 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 FD 03 00 00 04 00 00 00 00 00 00 00

  • Hi 

    在编写你的matlab 程序前,建议你首先手动根据代码解析 你的串口hex数据,

    我尝试解析了你的帧头,并没有发现明显的错误:

    02 01 04 03 06 05 08 07 Magic word
    04 00 05 03 Version 3.5.0.4
    34 00 00 00 totalPacketLen 54 bytes
    43 68 0A 00 platform 0A6843
    DC 0E 00 00 Frame NO.3804
    00 00 00 00 time Stamp 0
    00 00 00 00 Num of objects 0
    01 00 00 00 Number of TLvs 1
    00 00 00 00 subframe No 0

    关于TLV的取值问题,可以在源码中搜索相应的宏定义。或者参考examples/People_Tracking/3D_People_Tracking/docs/3d_people_tracking_user_guide.html

    Ken

  • 请问按您发的解释来看,并没有涉及到点云数据一类,是否我接受到的只有帧头,此外的TLV数据包我该如何接受呢?