データ送信のためのクラスRCRegion

サブジェクトからnOVirtualRobotCommのオブザーバーに送る命令のデータには、RCReginという専用のクラスを使います。

RCRegion* Region;
//中略:regionの作成・・・・
subject[sbjSubject]->SetData(region);
subject[sbjSubject]->NotifyObservers();

RCRegionの「RC」とは、Reference Counter(参照カウンタ)のことです。RCRegionが生成された時点ではカウンタは1になっています。OVirtualRobotCommは、データの処理中はカウンタを2にします。参照カウンタの数値によって、命令データが使用中かそうでないかが分かります。
また、RCRegionは命令データへのポインタを保持します。/usr/local/OPEN_R_SDK/OPEN_R/include/OPENRの下にあるRCRegion.hを見てみましょう。refCounter_が参照カウンタで、baseAddr_がデータへのポインタです。メンバ関数NumberOfReference()やBase()によって参照カウンタやデータへのポインタを取り出せます。

class RCRegion {
  public:
//
   int NumberOfReference() const { return refCounter_; }

   char* Base() const;
//
  private:
//
   int refCounter_;
//
   char* baseAddr:
};

構造体OCommandVectorDataへのポインタを含むRCRegionをSetData()で送信することで、OVirtualRobotCommのオブザーバーにLEDを光らせたり、脚を動かしたりする命令を出せます。

RCRegion・OCommanVectorDataを作成する手順

1. OCommandVectorDataを作成し、RCRegionに保持する。

RCRegion* region;            ⇒RCリージョン
MemoryRegionID cmdVecDataID;
OCommandVectorData cmdVecData;     ⇒ベクターデータ

OPENR::NewCommandVectorData(7,&cmdVecDataID, &cmdVecData); @
region = new RCRegion(cmdVecData->vectorInfo.memRegionID,   ⇒RCリージョンを作成する。
            cmdVecData->vectorInfo.offset,
            (void*)cmdVecData,            ⇒ベクターデータのポイントをセット
            cmdVecData->vectorInfo.totalSize);
cmdVecData->SetNumData(7); A

@第1引数はプリミティブ数(LEDの数や関節の数)
 第2引数は共有メモリーに振られたID
 第3引数は作成されたOCommandVectorDataへのポインタ

Aプリミティブ数は改めて設定する必要がある

2. OCommandVectorDataにデータを格納する。

2.1 OCommandInfo

OCommandInfoに、OCommandDataに何のデータを入れるかをセットする。

OCommandInfo* info = cmdVecData->GetInfo(i);
info->Set(odataLED_COMMAND2, primID, 1);
 @

@第1引数はプリミティブの種類で決まる定数
 第2引数はCPCプリミティブのID
 第3引数はフレームの数(最大16)

第1引数には次の種類がある。

関節 odataJOINT_COMMAND2
LED odataLED_COMMAND2

2.2 OCommandData

OCommandDataは128バイトの広さを持ったデータで、納めるデータに合わせてキャストして使用する。

OCommandData* data = cmdVectData->GetData(i);
OLEDCommandValue2* val = (OLEDCommandValue2*)data->value;
val[0].led = oledON;
val[1].period = 64;

OCommandDataをキャストするデータ型はプリミティブにより数種類あり、以下のような種類がある。

構造体名 変数型名 単位 意味 単位時間
OJointCommandValue2 slongword マイクロラジアン 関節角度 8ms
OJointCommandValue3 OJointValue3 ojoint3_STATE0 / ojoint3_STATE1 -
OLEDCommandValue2 OLEDValue oledON / oledOFF LED
word 8ms LED時間

2-Appendex. OCommandVectorDataの構造
OCommandVectorDataは以下のように定義されている。
struct OCommandVectorData {
  ODataVectorInfo vectorInfo;
  OCommandInfo info[1];

  void SetNumData(size_t ndata) { vectorInfo.numData = ndata; }
  OCommandInfo* GetInfo(int index) { return &info[index]; }
  OCommandData* GetData(int index) {
    return (OCommandData*)((byte*)&vectorInfo + info[index].dataOffset);
  }
};
OCommandInfoとOCommandDataの配列数はプリミティブ数になる。
OCommandInfoにはプリミティブの情報(データタイプ・プリミティブID・フレーム数)
OCommandDataには実際のデータが格納される。
OCommandVectorData内のOCommandInfoはGetInfo(index)を使ってアクセスする。
OCommanDataにはGetData(index)を使ってアクセスする。
OCommandInfo* info = cmdVecdata->GetInfo(i);
OCommandData* data = cmdVecdata->GetData(i);
2-Appendex. OCommandDataの構造
struct OCommandData {
  OCommandValue value[ocommandMax_FRAMES];
};
OCommandValue型は8バイトの定数、ocommandMAX_FRAMESは16なのでOCommandDataは128バイトとなる。