4

これは、以前の質問「Python でネストされた C 構造体をアンパックする」のフォローアップの質問です。それ以来、私が扱っている構造体はより複雑になり、それらを完全に展開して処理する方法が再びわかりません。

C 側では、ヘッダーの関連部分は次のようになります。

typedef struct {
    uint8_t seq;
    uint8_t type;
    uint16_t flags;
    uint16_t upTimestamp;
}__attribute__ ((packed)) mps_packet_header;

typedef struct {
    mps_packet_header header;
    int16_t x[6];
    int16_t y[6];
    int16_t z[6];
    uint16_t lowTimestmp[6];
}__attribute__ ((packed)) mps_acc_packet_t;
typedef mps_acc_packet_t accpacket_t;

typedef struct {
    int16_t hb1;
    int16_t hb2;
} acam_hb_data_set;

typedef struct __attribute__ ((packed)) {
    mps_packet_header header;
    uint16_t temp;
    uint16_t lowTimestmp[8];
    acam_hb_data_set dms_data[8];
} mps_dms_packet_t;

ここから 2 つの課題が生じます。まず、受信したパケット (バイナリ形式) は、またはのいずれmps_acc_packet_tかです。それらを区別する唯一の方法は、両方のパケット タイプが持つのフィールドmps_dms_packet_tを読み取ることです。これは、完全な内容を知る前にパケットを解凍する必要があることを意味します.2つのパケットタイプは異なる(それぞれ54と56)ので、(私が間違っていなければ)きれいに行う方法がわかりません. 2 番目の課題は、アンパックです。構造体の定義からわかるように、このパケットには の 8 つのインスタンスで構成される配列があり、これは 2 つの値で構成される構造体です。このための正しいフォーマット文字列を作成する方法がわかりません。typemps_packet_headercalcsizemps_dms_packet_tacam_hb_data_setint16

以前のコード (mps_dms_packet_t導入前) は、falsetru が以前の質問に対する回答で示唆したように、次のようになりました。

s = struct.Struct('= B B H H 6h 6h 6h 6H')
fields = s.unpack(packet_data)
seq, _type, flags, upTimestamp = fields[:4]
x = fields[4:10]
y = fields[10:16]
z = fields[16:22]
lowTimestamp = fields[22:]

これはうまくいきました。ここで、何らかの方法でヘッダー (構造体をアンパックする必要があります) を読み取ってから、そのタイプに応じて構造体を正しくアンパックできるようにする必要があります。

どうすればこれを行うことができますか?

4

1 に答える 1

4

試してみてくださいctypes。データのパック/アンパックがより読みやすく、簡単になります。

import ctypes

class mps_packet_header(ctypes.Structure):
    _fields_ = [
        ("seq", ctypes.c_uint8),
        ("type", ctypes.c_uint8),
        ("flags", ctypes.c_uint16),
        ("upTimestamp", ctypes.c_uint16)
    ]

class mps_acc_packet_t(ctypes.Structure):
    _fields_ = [
        ("header", mps_packet_header),
        ("x", ctypes.c_int16 * 6),
        ("y", ctypes.c_int16 * 6),
        ("z", ctypes.c_int16 * 6),
        ("lowTimestmp", ctypes.c_uint16 * 6)
    ]

class acam_hb_data_set(ctypes.Structure):
    _fields_ = [
        ("hb1", ctypes.c_int16),
        ("hb2", ctypes.c_int16),
    ]


class mps_dms_packet_t(ctypes.Structure):
    _fields_ = [
        ("header", mps_packet_header),
        ("temp", ctypes.c_uint16),
        ("lowTimestmp", ctypes.c_uint16 * 8),
        ("dms_data", acam_hb_data_set * 8)
    ]
于 2016-02-24T03:09:05.343 に答える