1

RTCM SC104 v3 メッセージを作成しようとしています。この規格では、最小数のビットのみを使用して、定義された最大範囲にデータを送信する必要があります。したがって、データを結合するために、ユニオンを使用するつもりでした。しかし、奇数サイズのユニオンを前の奇数サイズのユニオンに結合するにはどうすればよいでしょうか? たとえば、メッセージ 1002 では、各サテライトに 74 ビットが必要です。n 個のサテライトのすべてのデータが表示されてメッセージが完了するまで、パディング ビットはありません。以前のユニオンのユニオンを構築することはできますか?

 typedef union headerGPS
    {
    struct
    {
    unsigned int  msgNo    :12; // creates a 12 bit wide integral field
    unsigned int  baseID   :12; //base index number
    unsigned int  tow      :30; //time of measurement
    unsigned int  syncFlg  :1;  //1 if all GNSS readings same time
    unsigned int  no_gps   :5;  //number of gps readings
    unsigned int smoothInd :1;  //smoothing indicator
    unsigned int smoothInt :3;  //smoothing int rep
    } fields;
    unsigned char header[8];
} headerGPS;
typedef union data1002
{
    struct            //74 bits / 9.25 bytes per SV
    {
    INT8U      satID   :6;  //sat ID 6 bit
    INT8U      L1ind   :1;  //L1 indicator 1 bit set 1
    INT32U     L1range :24; //L1 psuedorange uint24
    int        diff    :20; //L1 phaserange - psuedorange int20
    INT8U      lockInd :7;  //L1 locktime indicator uint7
    INT8U      ambi    :8;  //L1 int ambiguity uint8
    INT8U      cnr     :8;  //L1 CNR uint8
    }fields;
    INT8U data[];
}data1002;

bool encode1002( int baseNumber, int gpsEpoch , int numberGpsSV, int numberGloSV, int  numberGalSV )
{
    std::string message1002;
    headerGPS h1002; //create header object
    h1002.fields.msgNo = 1002;
    h1002.fields.baseID = baseNumber;
    h1002.fields.tow = gpsEpoch;
    if(numberGloSV > 0 || numberGalSV > 0)
    {
        h1002.fields.syncFlg = 1;
    }
    else
   {
        h1002.fields.syncFlg = 0;
    }

    h1002.fields.no_gps = numberGpsSV;
    h1002.fields.smoothInd = 0;
    h1002.fields.smoothInt = 0;
    for(int n=0; n<8; n++)
    {
        message1002 += h1002.header[n];
    }//1002 header is complete







return true;
}

わかりましたので、送信するデータを準備するためにビットセットをセットアップしようとしています。私はこの種の文を使用して、余分なフィラービットを追加せずに必要な順序でビットセットを埋めています。これは、「for」ステートメントと「if channel data good」ステートメントにあります。

for(varPos = 0; varPos < 6; varPos ++) //start on 0, end on 5
        {
            data_1002.set(bitPos,datastream[baseNumber].channel[n].satID & (1<<varPos)); //test bit
            bitPos++;
        }
        data_1002.set(bitPos,1);
        bitPos++;
        for(varPos = 0; varPos < 24; varPos ++) //start on 0, end on 5
        {
            data_1002.set(bitPos,codeRange & (1<<varPos)); //test bit
            bitPos++;
        }

ビットセットのすべてのビット値をバイト配列にコピーして、次を使用して TCP/IP ポートを送信したいと考えています。

int noBytes = (bitPos+7)/8; //number of data bytes to copy to array
if(noBytes <=0)
{
    noBytes = 0;
}
cout << "number of bytes to process=  " << noBytes <<endl;
cout <<"completed bitset size= " << bitPos << endl;

//convert bits to bytes

bitPos = 0;
int byteCount;
for (int w=0; w<noBytes; w++)  //bitPos/8 = number of bytes; w+8 because 8 bytes in header
{
    for(int q=0; q<8; q++)
    {
        if(data_1002.test(bitPos+q) == 1)
        {
            BUFFER[(w+8)] = BUFFER[(w+8)] | (1<<q);
        }
        else
        {
            BUFFER[(w+8)] = BUFFER[(w+8)] & (0xFF & (0<<q));
        }
    }
    bitPos = bitPos +8;
    byteCount = w+8;
}
cout << "bytecounter=  " << byteCount << endl;
cout<<"number btes processed plus header=  "<< noBytes+8 <<endl;
for(int w=0; w<noBytes+8; w++)
{
   output += BUFFER[w];
}

これは機能するはずですが、これのコーディングに間違いがない場合は、助けていただければ幸いです。また、ビットセットをバイト配列に転送して送信する簡単な方法はありませんか? 読んで文字列ストリームにビットセットを挿入しようとしましたが、各ビットをビットではなく文字として挿入します。

4

2 に答える 2

0

奇数サイズの構造体の別の結合を作成してデータを結合したいと書いていましたか? これにより、2 つの奇数サイズの構造体が同じバイナリ データを参照することになります。あなたが望んでいたのは、2つのユニオンを含む新しい構造体を作成するなど、追加することだったと思います。そして、あなたが望んでいたのは、パディングビットなしでそれらを一緒に挟むことでしたか?

奇数サイズのビット パック構造体は、バイト、ワード、またはコンパイラが選択したものによって常に整列されます。これらのうち 2 つを別の構造体に配置すると、パディングされます。別の方法で対処する必要があります。

では、すべての宣言を 1 つの構造体にまとめてみませんか? おそらく、headerGPS と data1002 が複数表示されているためでしょうか。もしそうなら、1つの解決策は次のとおりです(プリプロセッサマクロがハックであることがわかっている限り、それが唯一の方法である場合があります)。

#define headerGPS(n) \
        unsigned int  msgNo_##n    :12; \
        unsigned int  baseID_##n   :12; \
        unsigned int  tow_##n      :30; \
        unsigned int  syncFlg_##n  :1;  \
        unsigned int  no_gps_##n   :5;  \
        unsigned int smoothInd_##n :1;  \
        unsigned int smoothInt_##n :3

#define data1002(n) \
        INT8U      satID_##n   :6; \
        INT8U      L1ind_##n   :1; \
        INT32U     L1range_##n :24;\
        int        diff_##n    :20;\
        INT8U      lockInd_##n :7; \
        INT8U      ambi_##n    :8; \
        INT8U      cnr_##n     :8

union gpsdata {
    struct {
    headerGPS(1);
    data1002(1);
    data1002(2);
    };
    INT8U data[];
};

名前がと##になるように、一意の拡張子を追加できるように、追加演算子 の使用法に注意してください。 satID_1satID_2

ただし、この解決策は少しハックです。IDE パーサーを混乱させる可能性があります。私がテストしたとき、Eclipse は適切にメンバーを提案してくれました。

于 2013-08-08T01:25:27.110 に答える