データ送信のためのクラス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バイトとなる。