Browse Source

New robot shape

master
Yorick van Pelt 5 years ago
parent
commit
ddc8b023d4
  1. 57
      lemming_sim_student.js
  2. 32
      robotbody.svg
  3. 3
      sensors.js

57
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() {

32
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)"><metadata
sodipodi:docname="robotbody.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"><metadata
id="metadata17"><rdf:RDF><ns:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><cc:Work
@ -34,32 +34,32 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-width="2225"
inkscape:window-height="1736"
id="namedview13"
showgrid="false"
inkscape:zoom="1.5742187"
inkscape:cx="193.78259"
inkscape:cy="72.49728"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:cx="256.30163"
inkscape:cy="152.71994"
inkscape:window-x="963"
inkscape:window-y="52"
inkscape:window-maximized="0"
inkscape:current-layer="svg11"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-center="true"
inkscape:snap-page="true"
inkscape:snap-global="false"><sodipodi:guide
position="87.480965,95.186771"
position="150,150"
orientation="1,0"
id="guide863"
inkscape:locked="false" /><sodipodi:guide
position="87.480965,95.186771"
position="150,150"
orientation="0,1"
id="guide867"
inkscape:locked="false" /></sodipodi:namedview><path
id="robotbody"
d="m 21.840805,32.282261 c -29.4070742,38.075324 -29.2031002,89.304329 1.126302,124.879399 28.308167,33.20432 96.216923,41.60047 129.034143,9.08347 18.43503,-12.80861 9.62964,-4.23612 16.52932,-15.43367 4.97497,-8.07393 7.20296,-16.17729 7.39509,-18.53562 2.47109,-30.33143 1.21949,-67.484605 -2.03551,-83.758545 -0.8545,-4.27227 74.1647,3.74803 65.19284,-6.66691 C 229.23764,30.421398 158.23428,27.099346 155.90436,24.175764 133.57052,-3.8490539 58.313014,-14.940787 21.840805,32.282261 Z"
d="m 88.171256,119.27453 c -29.407074,38.07533 -33.014515,60.71872 -2.685113,96.29379 55.938447,12.90349 100.292307,13.25531 121.424507,-19.69014 -3.18086,-13.76064 -74.25605,-18.32839 54.67152,-94.9859 -49.03531,-7.370402 -134.17651,15.5306 -173.410914,18.38225 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sscssssss"
sodipodi:nodetypes="ccccc"
style="stroke-width:0.99999988" /></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

3
sensors.js

@ -10,7 +10,8 @@ class Sensor {
value: null,
valueStr: "<uninit>",
minVal: 0,
maxVal: 50
maxVal: 50,
attachAngle: 0,
}, props)
this.info = this
this.setAngle(this.attachAngle)

Loading…
Cancel
Save