優勝ロボの作り方大公開!第7回越前がにロボコン オープン部門 で活躍した チームOkaki のロボットを写真で解説、JSで描かれたコードもオープンソースに、改変自由!
こちら、第7回 越前がにロボコン オープン部門優勝ロボ「Okaki」!
激レアを狙って羽を広げるよ。
足回りは、
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) でこんな感じ。このソースはオープンソース、改変自由!
さぁ、おとな達、来年はこども達と一緒に ご当地ロボコン に挑戦しよう!