優勝ロボの作り方大公開!第7回越前がにロボコン オープン部門 で活躍した チームOkaki のロボットを写真で解説、JSで描かれたコードもオープンソースに、改変自由!

こちら、第7回 越前がにロボコン オープン部門優勝ロボ「Okaki」!

激レアを狙って羽を広げるよ。

足回りは、

TAMIYA MECHANICAL TIGER

TIGER は前後にしか動けないので左右2頭立て。

グリップ力が足りず、スリップしまくったのでグリップスポンジ増し増し。

頭脳部は GIGA IchigoDake、OSは IchigoLatte JS

コンセプトは「こども達と同じパーツで」。

サーボもみんな大好き SG90 、

を4発。PWM信号は単に線を二股にすれば2サーボを同期させて動作可能。

コースの白黒認識も こども達が使っているのと同じCdS。

たまご はこの中に入れて運びます。

そして目玉はこちら、触手トンネル。

触手で捉えた レアメタル や 宇宙ウィルス はこのセンシングトンネルに飲み込まれる。

トンネル内で物体は WS2812B で白色に照らされ、カラーセンサー S13683-03DT(¥350) で色をセンシングされる。

トンネルを抜けると、面ファスナーガサガサによってキャッチ。

ただし、緑色の場合はキャッチャーが上がってスルーするよ!

IchigoLatte JS ソースコード

0.js

var LRT,LC,T0,f1,f2,isWks;

include (1);
include (2);
include (15);


while(btn());

T0=tick();
walk(0,0);
wing(0);
led(0);
ita(0);
initCS();
initLR();
while(tick()-T0<2500);

pwm(3,0);
log(LRT,"\n");

light(0xFFFFFF);
while( gpin(1) );

isWks=0;
f1=goPlnt;
f2=none;

while(1){
 var L=ana(0)-LRT;
 var R=ana(2)-LRT;
// log(L," ",R,"\n");

 f1=f1(L,R);
 f2=f2();
//log(isGrn(),"\n");

 sleep(33);
}

1.js

function none(){return none;}

function chkGrn(){
 if(isWks()){
  if(isGrn()){
   iS=2000;
   return itaSl;
  }  
 }
 return chkGrn;
}

function ita(down){
 if(down){
  pwm(3,1000);
 }else{
  pwm(3,2000);
 }
}

function initCS(){
 i2cw(0x2a,0x00,0x8a);
 i2cw(0x2a,0x00,0x0a);
}

function initLR(){
 var L1,L2,L3,R1,R2,R3;
 L1=ana(0);R1=ana(2);
 sleep(333);
 L2=ana(0);R2=ana(2);
 sleep(333);
 L3=ana(0);R3=ana(2);
 var L0=(L1+L2+L3)/3;
 var R0=(R1+R2+R3)/3;
 LRT=(L0+R0)/2;
 LC=(L0>R0);
}

function walk(sL,sR){
 if(sL<0) sL=0;
 if(sR<0) sR=0;
 if(100<sL) sL=100;
 if(100<sR) sR=100;
 pwm(5,20000*sL/100);
 pwm(2,20000*sR/100);
}

function walk2(sL,sR){
 if(100<sL) sL=100;
 if(100<sR) sR=100;
 if(sL<-100)sL=-100;
 if(sR<-100)sR=-100;
 var o=0;
 if(0<sL){
  pwm(5,20000*sL/100);
 }else{
  o=o+32;
  pwm(5,20000-20000*sL/100);
 }
 if(0<sR){
  pwm(2,20000*sR/100);
 }else{
  o=o+1;
  pwm(2,20000-20000*sR/100);
 }
 if(o) out(o);
}

function goEarth(L,R){
 walk(-L,-R);
 return goEarth;
}

function tnBack(L,R){
 if(LC){
  var l;
  if(0<-R) l=18; else l=40;
  walk(l,-R);
 }else{
  var r;
  if(0<-L) r=18; else r=40;
  walk(-L,r);
 }

 if((L<0)*(R<0)){
  wing(0);
  isWks=0;
  return goEarth;
 }else{
  return tnBack;
 }
}

function tnBack1(L,R){
 if(LC){
  walk2(-100,+66);
 }else{
  walk2(+66,-100);
 }

 if(1400<tick()-T0){
  ita(1);
  out(0);
  return tnBack;
 }else{
  return tnBack1;
 }
}

function goDeep(L,R){
 walk(33,33);
 if((L<0)*(R<0)){
  ita(0);
  T0=tick();
  return tnBack1;
 }else{
  return goDeep;
 }
}

function goDeep1(L,R){
 walk(25,25);
 if(2000<tick()-T0){
  return goDeep;
 }else{
  return goDeep1;
 }
}

function goPlnt(L,R){
 walk(-L,-R);
 if((0<L)*(0<R)){
  f2=itaSl;
  T0=tick();
  wing(1);
  return goDeep1;
 }else{
  return goPlnt;
 }
}

var iS=2000;
function itaSl(){
 iS=iS-12;
 pwm(3,iS);
 if(iS<=1000){
  pwm(3,0);
  isWks=1;
  return chkGrn;
 }else{
  return itaSl;
 }
}

2.js

function isGrn(){
 var rh,rl,gh,gl,bh,bl,xh,xl;
 i2cw(0x2a,0x03);
 i2cr(0x2a,rh,rl,gh,gl,bh,bl,
   xh,xl);
 var r=((rh<<8)+rl)*100/100;
 var g=((gh<<8)+gl)* 58/100;
 var b=((bh<<8)+bl)* 55/100;
 var x=(xh<<8)+xl;
 log(r," ",g," ",b,"\n");
 return (r<g)*(b<g)*
  (100<(r+g+b))*((r+g+b)<400);
}

function light(c){
 var pln=new Array(3);
 pln[0] = c;
 pln[1] = c;
 pln[2] = c;
 ws2812b(pln);
}

function wing(on){
 if(on){
  pwm(4,1800);
 }else{
  pwm(4, 800);
 }
}

15.js

// ws2812b-driver

//# How to use
// var plan=new Array(4);
//
// plan[0] = 0xFF0000; //Green
// plan[1] = 0x00FF00; //Red
// plan[2] = 0x0000FF; //Blue
// plan[3] = 0xFFFFFF; //White
// 
// ws2812b(plan);

//---
{
 var a=mem(" ");
 mem(a,0x5D,0x71,0x86,0xC6,0xA2,0xC4,0xA6,0xC2,0xCA,0xC0,0x4E,0xDE,0x52,0xDC,0x56,0xDA);a=a+16;
 mem(a,0x5A,0xD8,0x5E,0xD6,0x62,0xD4,0x66,0xD2,0x6A,0xD0,0x6E,0xCE,0xF3,0x77,0x04,0x30);a=a+16;
 mem(a,0x80,0x41,0xB7,0x09,0x00,0x08,0x01,0x49,0x5C,0x44,0x93,0x89,0xC9,0x15,0x71,0x04);a=a+16;
 mem(a,0x3E,0xC6,0x7D,0x5C,0xB2,0x47,0x63,0x14,0xF9,0x02,0xF3,0x67,0x04,0x30,0xB6,0x40);a=a+16;
 mem(a,0x26,0x44,0x96,0x44,0xF2,0x59,0x62,0x5A,0xD2,0x5A,0x42,0x5B,0xB2,0x5B,0x22,0x5C);a=a+16;
 mem(a,0x92,0x5C,0x02,0x5D,0xF2,0x4D,0x4A,0x85,0x06,0x49,0x61,0x61,0x82,0x80,0x83,0xAD);a=a+16;
 mem(a,0xC9,0x04,0x41,0x4A,0x61,0x5D,0x04,0x40,0xA1,0x4B,0x93,0x0C,0x00,0x08,0xB3,0xD4);a=a+16;
 mem(a,0x44,0x41,0x93,0xF4,0xF4,0x0F,0x33,0xF7,0x94,0x01,0x15,0xEB,0x91,0x4A,0x05,0x4B);a=a+16;
 mem(a,0x05,0x45,0x82,0x9D,0x7D,0x1B,0x63,0x17,0x8B,0x03,0x03,0xA7,0xC9,0x04,0x01,0x45);a=a+16;
 mem(a,0x02,0x97,0xFD,0x1A,0x63,0x92,0x8A,0x03,0xFD,0x1B,0x93,0xDC,0x1C,0x00,0xE3,0x9C);a=a+16;
 mem(a,0x0B,0xFC,0x61,0x1A,0xE3,0x11,0xAA,0xFD,0x05,0x09,0x21,0x04,0x61,0xB7,0x85,0x4A);a=a+16;
 mem(a,0x11,0x4B,0xF9,0xB7,0x01,0x00,0xF9,0xB7,0x01,0x00,0xE1,0xBF);
}
// send lighting plan to LED
function ws2812b(p){env(p);return mem();}

プログラムは JavaScript(MINIScript) でこんな感じ。このソースはオープンソース、改変自由!


さぁ、おとな達、来年はこども達と一緒に ご当地ロボコン に挑戦しよう!