4

現在、いくつかのセンサーが取り付けられたロボットを構築しています。ロボットのコントロール ユニットは ARM Cortex-M3 で、すべてのセンサーが取り付けられており、イーサネット経由で「地上局」に接続されています。

ここで、地上局を介してロボットの設定を読み書きしたいと考えています。そこで、地上局から操作できる「仮想レジスタ」をロボットに実装することを考えました。

構造体で構成され、次のようになります。

// accelerometer register
struct accel_reg {
  // accelerations
  int32_t accelX;
  int32_t accelY;
  int32_t accelZ;
};

// infrared distance sensor register 
struct ir_reg {
  uint16_t  dist; // distance
};

// robot's register table
struct {
  uint8_t     status;         // current state
  uint32_t    faultFlags;     // some fault flags
  accel_reg   accelerometer;  // accelerometer register
  ir_reg      ir_sensors[4];  // 4 IR sensors connected
} robot;

// usage example:

robot.accelerometer.accelX = -981;
robot.ir_sensors[1].dist = 1024;

ロボットでは、レジスタは常に新しい値で満たされ、構成設定は地上局によって設定され、ロボットによって適用されます。

地上局とロボットは C++ で記述されるため、どちらも同じ構造体データ型を使用できます。

私が今持っている質問は、大量のメタデータを書き込まずに、読み取り/書き込み操作をプロトコルにカプセル化する方法ですか?

register を読みたいとしましょうrobot.ir_sensors[2].dist。プロトコルでこのレジスタにどのように対処しますか?

バイト単位の相対オフセット (つまり、構造体内のメモリ内の相対位置) を送信することについては既に考えましたが、特に地上局が x86_64 アーキテクチャで実行され、ロボットが 32-で実行されているため、メモリの配置とパディングが問題を引き起こす可能性があると思います。ビット ARM プロセッサ。

ヒントをありがとう!:)

4

2 に答える 2

1

また、Google Protocol Buffers も提案します。

RobotState最も単純なケースでは、次のような1 つのメッセージを実装できます。

メッセージ RobotState {
   オプションの int32_t ステータス = 1;
   オプションの int32_t 距離 = 2;
   オプションの int32_t accelX = 3;
   ...
}

次に、ロボットがメッセージを受信すると、存在する任意のフィールドから新しい値を取得します。次に、すべてのフィールドの現在の値を含むメッセージで応答します。

このようにして、ほとんどの protobuf 実装の「マージ メッセージ」機能を使用して、フィールド更新を非常に簡単に実装できます。また、メッセージ タイプが 1 つしかないため、最初は非常にシンプルに保つことができますが、後で拡張する必要がある場合は、サブメッセージを追加できます。

protobuf がint8_torをサポートしていないのは事実ですint16_tint32_t代わりに使用してください。

于 2013-04-08T07:43:51.957 に答える