diff --git a/lemming_sim_student.js b/lemming_sim_student.js index 6967dc5..2a5d542 100644 --- a/lemming_sim_student.js +++ b/lemming_sim_student.js @@ -21,7 +21,7 @@ var simInfo = { maxSteps: 50000, // maximal number of simulation steps to run airDrag: 0.1, // "air" friction of enviroment; 0 is vacuum, 0.9 is molasses - boxFric: 0.005, // friction between boxes during collisions + boxFric: 0.001, // friction between boxes during collisions boxMass: 0.01, // mass of boxes boxSize: 10, // size of the boxes, in pixels robotSize: 13, // approximate robot radius, in pixels (note the SVG gets scaled down) @@ -30,25 +30,20 @@ var simInfo = { bayScale: 2, // scale within 2nd, inset canvas showing robot in it's "bay" debugSensors: true, // plot sensor rays and mark detected objects debugMouse: true, // allow dragging any object with the mouse + wanderRate: 0.0002, }; class Lemming extends Robot { constructor(props) { super(Object.assign({ sensors: [ - new DistanceSensor('distR', { - attachAngle: Math.PI/(2.5), // where the sensor is mounted on robot body - color: [150, 0, 0], // sensor color [in RGB], to distinguish them - lookAngle: (Math.PI/7 - Math.PI/(2.5)), - attachRadius: 20 - }), // define another sensor - new DistanceSensor('distL', { + new DistanceSensor('dist', { attachAngle: -Math.PI/7, color: [0, 150, 0], - attachRadius: 20 + attachRadius: 20, + lookAngle: Math.PI/4, }), new Gyroscope('gyro', { - attachAngle: 0, attachRadius: 5, color: [100,100,0] }), @@ -60,33 +55,26 @@ class Lemming extends Robot { dist: 5, width: 15, }), - new DistanceSensor('wallR', { - attachAngle: Math.PI/2.5, // where the sensor is mounted on robot body - color: [150, 0, 0], // sensor color [in RGB], to distinguish them - filter: x => x.role == 'wall', - lookAngle: (Math.PI/7 - Math.PI/2.5), - attachRadius: 20, - - }), // define another sensor - new DistanceSensor('wallL', { + new DistanceSensor('wall', { attachAngle: -Math.PI/7, color: [0, 150, 0], - filter: x => x.role == 'wall', - attachRadius: 20 + filter: x => x.role != 'box', + attachRadius: 20, + lookAngle: Math.PI/4, }), ].concat(props.sensors || []) }, props)) } - turnDeg(rads, cb) { - if (Math.abs(rads) >= 320) - return this.turnDeg(320, x => this.turnDeg(rads -320, cb)) - const torque = Math.sign(rads) * 0.01 + turnDeg(degs, cb) { + if (Math.abs(degs) >= 320) + return this.turnDeg(320, x => this.turnDeg(degs -320, cb)) + const torque = Math.sign(degs) * 0.002 const start = this.getSensorValById('gyro') this.move = function() { const curAngle = this.getSensorValById('gyro') - const turned = ((curAngle - start) * Math.sign(rads) + 360) % 360 - if (turned < 340 && (turned - Math.abs(rads) > 0)) { + const turned = ((curAngle - start) * Math.sign(degs) + 360) % 360 + if (turned < 340 && (turned - Math.abs(degs) > 0)) { delete this.move if (cb) cb() } else { @@ -97,7 +85,7 @@ class Lemming extends Robot { move() { //if (sim.curSteps % 250 == 0) this.turnDeg(-90) // TODO: Define Lemming program here. - const {carry: [r,g,b], distL, distR, wallL, wallR} = this.getSensors() + const {carry: [r,g,b], dist, wall} = this.getSensors() let block = 0 if (r > (g+b)) { block = 'red' @@ -105,13 +93,13 @@ class Lemming extends Robot { block = 'blue' } this.block = block - if (distL < wallL - 5 || distR < wallR - 5) { + if (dist < wall - 5) { this.state = 'block' // if it senses a block if (!block) return this.drive(2e-4) // no block: drive towards block? if (block == 'blue') void 0; // if blue: ignore if (block == 'red') return this.turnDeg(-90) // if red: leave block - } else if (wallL < Infinity || wallR < Infinity) { + } else if (wall < Infinity) { this.state = 'wall' // no block: turn left or right if (!block) return this.turnDeg(90 * (Math.random() < 0.5 ? -1 : 1)) @@ -121,14 +109,16 @@ class Lemming extends Robot { this.state = 'nothing' } // by default: wander - this.rotate(+0.001); + this.rotate(simInfo.wanderRate); this.drive(0.0002); } getDisplay() { - return "carrying " + this.block + "\nseeing " + this.state + return "carrying " + (this.block || "no") + " block seeing " + this.state } } var sim = null +var resultsTable = null +let sim_id_counter = 0 class Simulation { constructor() { this.bay = null @@ -139,6 +129,7 @@ class Simulation { this.curSteps = 0 this.doContinue = false this.robots = [] + this.id = sim_id_counter++ } init() { const arena = document.getElementById("arenaLemming"), @@ -229,7 +220,7 @@ class Simulation { padnumber(simInfo.maxSteps, 5); } else { - this.toggle() + this.stop() } } draw() { diff --git a/robotbody.svg b/robotbody.svg index b188e59..539cbd7 100644 --- a/robotbody.svg +++ b/robotbody.svg @@ -13,13 +13,13 @@ version="1.1" x="0px" y="0px" - width="239.8282" - height="186.78011" - viewBox="0 0 239.8282 186.78011" + width="300" + height="300" + viewBox="0 0 300 300" xml:space="preserve" id="svg11" - sodipodi:docname="robotbody_noright.svg" - inkscape:version="0.92.2 (unknown)">image/svg+xml \ No newline at end of file diff --git a/sensors.js b/sensors.js index 83be1e1..ac48bf1 100644 --- a/sensors.js +++ b/sensors.js @@ -10,7 +10,8 @@ class Sensor { value: null, valueStr: "", minVal: 0, - maxVal: 50 + maxVal: 50, + attachAngle: 0, }, props) this.info = this this.setAngle(this.attachAngle)