Line trace Simulator
ライントレースカーのシミュレータ
Robotクラスでコントロール
Robotクラスのupdateメソッドの引数は左センサと右センサの値。線を検出すればtrueになる
戻り値はCommandクラスのインスタンス。new Command(左モーターの速度、右モーターの速度)
モーターの速度は0.0から1.0
createDataメソッドやRobotクラスをいろいろ書き換えてみるといろいろな動作ができます。
計算は適当なので変なところがあるかもしれません。
/**
* Copyright tana ( http://wonderfl.net/user/tana )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kyvJ
*/
// ライントレースカーのシミュレータ
// Robotクラスでコントロール
// Robotクラスのupdateメソッドの引数は左センサと右センサの値。線を検出すればtrueになる
// 戻り値はCommandクラスのインスタンス。new Command(左モーターの速度、右モーターの速度)
// モーターの速度は0.0から1.0
// createDataメソッドやRobotクラスをいろいろ書き換えてみるといろいろな動作ができます。
// 計算は適当なので変なところがあるかもしれません。
package {
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
public class LineTrace extends Sprite {
private var box:Sprite = new Sprite();
private var data:BitmapData;
private var robot:Robot;
private function drawLinesAndBG():void {
graphics.beginFill(0x505050, 1.0);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill();
graphics.beginFill(0x00552E, 1.0);
graphics.lineStyle(1, 0x00552E);
for (var i:Number = 0; i < 15; i++) {
graphics.moveTo(0, i * 31);
graphics.lineTo(465, i * 31);
graphics.moveTo(i * 31, 0);
graphics.lineTo(i * 31, 465);
}
graphics.endFill();
}
public function LineTrace() {
// write as3 code here..
// 最初の描画
drawLinesAndBG();
box.x = 200;
box.y = 400;
addChild(box);
var g:Graphics = box.graphics;
g.beginFill(0xE6E6FA, 0.5);
g.drawRect(-10, -15, 20, 30);
g.endFill();
g.beginFill(0x0000D0, 1.0);
g.lineStyle(1, 0x0000D0);
g.moveTo(-10, -15);
g.lineTo(10, -15);
g.endFill();
lx = 100 - 10;
ly = 400 - 15;
rx = 100 + 10;
ry = 400 + 15;
data = createData();
graphics.beginBitmapFill(data);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill();
robot = new Robot(this);
addEventListener(Event.ENTER_FRAME, update);
}
private function createData():BitmapData {
// ラインの作成
var b:BitmapData = new BitmapData(465, 465, true, 0x000000);
var sprite:Sprite = new Sprite();
var g:Graphics = sprite.graphics;
g.beginFill(0x000000, 0.0);
g.drawRect(0, 0, 465, 465);
g.endFill();
g.beginFill(0xD00000, 1.0);
g.lineStyle(5.0, 0xD00000);
g.moveTo(100, 30);
g.lineTo(100, 400);
g.endFill();
g.beginFill(0xD00000, 1.0);
g.lineStyle(5.0, 0xD00000);
g.moveTo(100, 100);
g.lineTo(300, 50);
g.endFill();
g.beginFill(0xD00000, 1.0);
g.lineStyle(5.0, 0xD00000);
g.moveTo(200, 50);
g.lineTo(300, 200);
g.endFill();
g.beginFill(0xD00000, 1.0);
g.lineStyle(5.0, 0xD00000);
g.moveTo(300, 180);
g.lineTo(250, 300);
g.moveTo(300, 250);
g.lineTo(150, 400);
g.moveTo(150, 400);
g.lineTo(100, 380);
g.endFill();
b.draw(sprite);
return b;
}
private function deg2rad(deg:Number):Number {
return (deg / 180) * Math.PI;
}
private var lx:Number;
private var ly:Number;
private var rx:Number;
private var ry:Number;
private var angle:Number = 0;
private function update(e:Event):void {
// センサーの判定 適当なので自信ない
var lsensorx:Number = box.x + 15 * Math.cos(deg2rad(angle - 90 + 40));
var lsensory:Number = box.y + 20 * Math.sin(deg2rad(angle - 90 + 40));
var rsensorx:Number = box.x + 15 * Math.cos(deg2rad(angle - 90 - 40));
var rsensory:Number = box.y + 20 * Math.sin(deg2rad(angle - 90 - 40));
var l:Boolean = false;
var r:Boolean = false;
//if (data.getPixel(lsensor, box.y + 15) != 0x000000) {
if (data.getPixel(lsensorx, lsensory) != 0x000000) {
l = true;
}
if (data.getPixel(rsensorx, rsensory) != 0x000000) {
r = true;
}
var command:Command = robot.update(l, r);
var lspeed:Number = command.left;
var rspeed:Number = command.right;
angle = angle + (lspeed - rspeed);
box.rotation = angle;
lx = lx + lspeed * Math.cos(deg2rad(angle - 90));
ly = ly + lspeed * Math.sin(deg2rad(angle - 90));
rx = rx + rspeed * Math.cos(deg2rad(angle - 90));
ry = ry + rspeed * Math.sin(deg2rad(angle - 90));
box.x = (rx - lx) / 2 + lx;
box.y = (ry - ly) / 2 + ly;
}
}
}
import flash.display.Sprite;
class Robot {
// ロボットのコントロール
private var screen:Sprite;
public function Robot(s:Sprite) {
screen = s;
}
public function update(lsensor:Boolean, rsensor:Boolean):Command {
if (lsensor) {
return (new Command(1.0, 0.0));
}
else if (rsensor) {
return (new Command(0.0, 1.0));
}
else {
return (new Command(1.0, 1.0));
}
}
}
class Command {
// ロボットの操作
public var left:Number;
public var right:Number;
public function Command(l:Number, r:Number) {
left = l;
right = r;
}
}