spheroのapp-enabled droidには、パトロール・モードが存在するが、狭い部屋で動き回らせると、早い段階で家具や壁に突き当たって、身動きが取れなくなる。
「あったま悪いなあー...」
と、見ていてストレスが溜まるので、楽しくない。



なので、障害物を回避するようにプログラムを組んでみた。

といっても、距離センサーとか人感センサーなどはついていないので、内蔵の「加速度センサー」だけが頼りである。一応、「onCollision」という衝突イベントを感知するイベント処理機能を内蔵しているのだが、これが役に立たない。ぶつかろうと、引っかかろうと、まったく感知してくれないのだ。
仕方がないので、「加速度」を検知して制御しようとしたのだが、うまくいかない。そもそも、等速で運動しているときは「加速度=ゼロ」なので、検知のしようがないんじゃね?

悩んでいると、「速度」のセンサー項目も存在することに気づいた。
こっちでやってみよう。やってみた。
この「速度」は1秒あたりの移動距離をcmであらわしたものらしいのだが、どうも適当らしい。
色々試した結果、「SPEED=100」で動き回らせているときに「速度<13」になったら、障害物にぶつかったと判断させると、程よい結果になることが分かった。



結果は、下記のリンク先で確認できる。
JavaScriptであらわすと、こういうこと。
var time_elapsed1 = 0;
async function startProgram() {
await Animation.R2D2.Action.Scan.play();
while (true) {
setMainLed({ r: 109, g: 255, b: 113 });
setSpeed(100);
await delay(2);
await goforward(getRandomInt(2, 3));
setHeading(getRandomInt(0, 360));
Sound.R2D2.Chatty.play();
await delay(0.025);
}
}
async function evadeobstacle() {
stopRoll();
await strobe({ r: 255, g: 0, b: 8 }, 0.1, 5);
Sound.R2D2.Hit.play();
setDomePosition(180);
setSpeed(-50);
await delay(1);
stopRoll();
setDomePosition(0);
}
async function goforward(sec1) {
time_elapsed1 = getElapsedTime();
while (!(getElapsedTime() >= time_elapsed1 + sec1)) {
setSpeed(100);
await delay(0.01);
await checkCollision();
await delay(0.025);
}
}
async function checkCollision() {
if (Math.sqrt((getVelocity().x ** 2) + (getVelocity().y ** 2)) <= 13) {
await evadeobstacle();
}
}
async function onCollision() {
await evadeobstacle();
}
registerEvent(EventType.onCollision, onCollision);
動き回る様子は、YouTubeで。
結構苦労したわ。