グループロボットダンス





プロジェクト起源

このプロジェクトの期限は、魔人がアンダーワールドからDM&P本部に戻って来た後に開かれた忘年会に遡る。
「なんだって!?ようやく帰ってきたと思ったら、うちの部署が出し物する番だったの?」
魔人が逃げ出そうとすると、ボスは彼を捕まえて、言った。
「お前も帰ってきたんだし、だったら俺たちはロボットダンスを、忘年会の出し物にしようぜ!」
こうして魔人はこのプロジェクトの責任者となったのである。


機能說明


グループロボットダンスとは、ROSシステムを利用して全てのロボットを連動して動かすシステムのことであり、同時に86MEを使用しロボットダンスをコーディングする。
このプロジェクトではロボットスコーピオンスキャナ、人型ロボット2台、86スパイダー7台及びROSシステムをインストールしたノートパソコンを使用している。

其の外、ESP8266によりロボットがネットワークを通じ連動して作動するようにしている。



材料準備


ROSシステムをインストールしたパソコン
ロボット数台
ロボットの台数と一致する86Duino Zero/One
ロボットの台数と一致するESP8266


ハードウェア施行


ロボットのフォルムと耐性の為に、86DuinoのCrossBarを使用し、
UART Portを対応するピンに切り替え、ESP8266を直接SPI PORTに差しているので、
まず第一に一般的なESP8266の接続方法と使用をご紹介しよう:


一般的に私たちはESP8266と86Duinoを連接して使用するが、これはフォルムも美しくなく、耐性にも難がある。

もし各位が魔人のような特別な機能を使用したい場合は、まず第一にESP8266をSPIに繋がなくてはならない。
材料:
2×5 ROHS 2個
cable   1本
cableを1本用意しESP8266を 3.3v電源に繋ぐ。

SPIDIをTXに改め、SPICSをRXに改めると作業は楽である。

TX、RX、GNDのみを必要とするので、コネクタに3Pins,をはんだ付けし、3.3vを直接cableにはんだ付けすること。

完成後は、膠を流すことで固定し、脱落を防止することをお勧めする。

終了後ESP8266をSPIスロットに繋ぐことができるようになった!



環境設定


ROSのインストールはROS公式サイトを参照されたい


プログラミング解説


まず全体をコントロールするイーサネット(HOST)を確認する
irrKlangライブラリを利用し音楽を流し、
音楽を文字列に繋ぎロボットに伝送する指令出すと、
当然、指令がシンクロする率は高まる

long cmd_time[act] = {
		0,
		1920,
		5760,
		/* ...... */
		138240
};
char* cmd[act] = {
		"HOME",
		"DANCE01",
		"DANCE02",
		/* ...... */
		"END"
};

プログラムに、入力を行う。

int main(int argc, char **argv)
{
	/* ...... */
	
	while (ros::ok())
	{
		if((str[0] = getch()) != 0){
			if(s != NULL)
				s->drop();
			if(engine != NULL){
				engine->drop(); 
				engine = irrklang::createIrrKlangDevice();
			}
			switch(str[0]){
			case '1':
				s = engine->play2D("monster.wav", false, false, true);
				msg.data = "DANCEALL";
				chatter_pub.publish(msg);
				break;
			/* ...... */
			}
		}
		/* ...... */
		ros::spinOnce();
	}
	return 0;
}

異なるキーをたくさん設定したことが確認できると思うが、続いて数字の2を入力しシンクロモジュールのプログラミングを開始する。

case '2':
	s = engine->play2D("monster.wav", false, false, true);
	msg.data = cmd[0];
	chatter_pub.publish(msg);
	printf("Track time: %lu(ms)\t Command: %s\n",track_time,cmd[0]);
	RTmode=1;
	break;

RTmode起動後、ループを絶えずシンクロ状態とし、ループ内がミュージック時間を判断しロボットへ指令を出せるようにする。

if(RTmode!= -1){
	track_time = s->getPlayPosition();
	for(int i = RTmode; i < act; i++)
	if(track_time > cmd_time[i]-deviation && track_time < cmd_time[i]+deviation){
		msg.data = cmd[i];
		chatter_pub.publish(msg);
		printf("Track time: %lu(ms)\t Command: %s\n",track_time,cmd[i]);
		RTmode++;	
	}	
	if(RTmode >= act)
		RTmode = -1;
}

ロボットは86MEを使用し毎時の動作をコーディングし、
Githubにおいて86ME上の設定および動作を探す。
コーディング完了後動作はESP8266を選択しROSHOSTの指令を受け、
完成後All in One出力プログラミングを選択するが、
出力後はプログラミングを修正する必要が出てくるため、CrossBar機能をプログラミングへ加える。

86Duino librariesのioにはio_outpb関数が有り、
io_outpbは直接ハードウェアIOのfunctionに繋ぐことが可能であり、
このfunctionは非常にコントr-るしづらいため、取り除くことをお勧めするが、
これら機能がすなわちCrossBarであり、86Duinoの特殊機能なのである!

直接ハードウェアIOを主毒する場合は、ピンの切り替えをする必要があるので、
まず86DuinoのIO Portを理解する必要が有り、
公式サイトで86Duino CPUのDatasheetを捜したら、
私たちは文中でCrossBar Config Registers内で各機能のコーディングを見ることができるので、
私達が必要なCOM1のTX、RXをさらにSPのCS、DIとし,
並びにTX、RX機能のオンオフを忘れないこと

000001b COM1-TXD1
000010b COM1-RXD1
001001b SPI-CS1
001100b SPI-DI

COM1のTX、RX及びSPIのCS、DIのaddressを区分する:

0x0A12 COM1 TX
0x0A13 COM1 RX
0x0A20 SPICS
0x0A22 SPIDI

続いてテストプロブラミングを入力する:

void setup()
{
 io_outpb(0x0A12,0x00); //disable COM1 TX pin
 io_outpb(0x0A13,0x00); //disable COM1 RX pin
 io_outpb(0x0A20,0x02); //SPICS to RX
 io_outpb(0x0A22,0x01); //SPIDI to DX
 Serial.begin(9600);
 Serial1.begin(115200);
}
void loop()
{
 while (Serial1.available()) {
  Serial.write(Serial1.read());
 }
 while (Serial.available()) {
  Serial1.write(Serial.read());
 }
}

テストプログラミングを理解したら、プログラミング機能を組み込もう。

void setup()
{
  io_outpb(0x0A12,0x00); //disable COM1 TX pin
  io_outpb(0x0A13,0x00); //disable COM1 RX pin
  io_outpb(0x0A20,0x02); //SPICS to RX
  io_outpb(0x0A22,0x01); //SPIDI to DX
  nh.getHardware()->setESP8266(Serial1, 115200);
  nh.getHardware()->setWiFi("RoBoardGod", "00000000");
  nh.initNode("10.0.0.1");	//ROS-Host IP address
  nh.subscribe(sub);
  pinMode(13, OUTPUT);	//Skarner's eyes LED
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  Audio.begin(88200, 100);
  srand(time(NULL));
  /* ...... */
}



作製結果

— DEMOビデオ —



関連リンク


Skarner
86Hexapod
Github


The text of the 86Duino reference is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Code samples in the reference are released into the public domain.