diff --git a/js/agent.js b/js/agent.js index f5661a8..8300138 100644 --- a/js/agent.js +++ b/js/agent.js @@ -1,9 +1,9 @@ -function Agent(opt, world) { - this.walker = new Walker(world.world) +function Agent(opt, globals) { + this.walker = new Walker(globals.world, globals.floor) this.options = opt - this.world = world + this.globals = globals this.frequency = 20 this.loaded = false @@ -15,7 +15,7 @@ function Agent(opt, world) { this.timerFrequency = 60 / this.frequency if (this.options.dynamicallyLoaded !== true) { - this.init(world.brains.actor.newConfiguration(), null) + this.init(globals.brains.actor.newConfiguration(), null) } }; @@ -54,8 +54,8 @@ Agent.prototype.init = function (actor, critic) { this.brain.algorithm.critic.optim.regularization.l2 = 0.0001 this.brain.algorithm.actor.optim.regularization.l2 = 0.0001 - // this.world.brains.shared.add('actor', this.brain.algorithm.actor) - this.world.brains.shared.add('critic', this.brain.algorithm.critic) + // this.globals.brains.shared.add('actor', this.brain.algorithm.actor) + this.globals.brains.shared.add('critic', this.brain.algorithm.critic) this.actions = actions this.loaded = true diff --git a/js/floor.js b/js/floor.js index 3e48fb4..3dce45c 100644 --- a/js/floor.js +++ b/js/floor.js @@ -1,6 +1,6 @@ -function createFloor() { +function createFloor(world) { var body_def = new b2.BodyDef(); - var body = globals.world.CreateBody(body_def); + var body = world.CreateBody(body_def); body.SetUserData('floor') var fix_def = new b2.FixtureDef(); fix_def.friction = 0.8; diff --git a/js/game.js b/js/game.js index f753a74..4fda97c 100644 --- a/js/game.js +++ b/js/game.js @@ -9,7 +9,7 @@ config = { max_zoom_factor: 130, min_motor_speed: -2, max_motor_speed: 2, - population_size: 4, + population_size: 1, walker_health: 100, max_floor_tiles: 50, round_length: 1000, @@ -100,7 +100,7 @@ gameInit = function() { chooseQoute() globals.world = new b2.World(new b2.Vec2(0, -10)); - globals.floor = createFloor(); + globals.floor = createFloor(globals.world); [globals.agents, globals.walkers] = createPopulation(); drawInit(); @@ -118,6 +118,7 @@ gameInit = function() { } loop = function () { + drawFrame() simulationStep() drawFrame() if (globals.running) requestAnimFrame(loop); // start next timer @@ -127,11 +128,19 @@ loop = function () { resetSimulation = function () { // turn training off temporarlity to avoid NaN's updateIfLearning(false) - console.log('resetting walkers') - for(var k = 0; k < config.population_size; k++) { - globals.agents[k].walker = globals.walkers[k] = new Walker(globals.world) + // globals.running = false + + globals.world.Destroy() // this way we get rid of listeners and body parts and joints + globals.world = new b2.World(new b2.Vec2(0, -10)); + globals.floor = createFloor(globals.world); + for (var k = 0; k < config.population_size; k++) { + globals.agents[k].walker = globals.walkers[k] = new Walker(globals.world, globals.floor) } - setTimeout(()=>updateIfLearning(true), 1000) + + // globals.running = true + setTimeout(() => updateIfLearning(true), 1000) + // setTimeout(() => requestAnimFrame(loop), 1000) + } simulationStep = function () { @@ -139,10 +148,10 @@ simulationStep = function () { // step world globals.world.Step(1/config.time_step, config.velocity_iterations, config.position_iterations); + populationSimulationStep(); globals.world.ClearForces(); // step agents (only after step 50 when they are on the ground) - populationSimulationStep(); } updateCharts = function () { @@ -157,24 +166,6 @@ updateCharts = function () { } } -// setSimulationFps = function(fps) { -// config.simulation_fps = fps; -// clearInterval(globals.simulation_interval); -// if(fps > 0) { -// globals.simulation_interval = setInterval(simulationStep, Math.round(1000/config.simulation_fps)); -// if(globals.paused) { -// globals.paused = false; -// if(config.draw_fps > 0) { -// globals.draw_interval = setInterval(drawFrame, Math.round(1000/config.draw_fps)); -// } -// } -// } else { -// // pause the drawing as well -// clearInterval(globals.draw_interval); -// globals.paused = true; -// } -// } - createPopulation = function(genomes) { var walkers = []; var agents = [] diff --git a/js/walker.js b/js/walker.js index 5888b2d..8dd3468 100644 --- a/js/walker.js +++ b/js/walker.js @@ -13,8 +13,9 @@ var Walker = function() { } -Walker.prototype.__constructor = function(world) { - this.world = globals.world; +Walker.prototype.__constructor = function(world, floor) { + this.world = world; + this.floor = floor this.density = 106.2; // common for all fixtures, no reason to be too specific @@ -77,6 +78,8 @@ Walker.prototype.__constructor = function(world) { } this.joints = []; + this.otherJoints = [] + this.otherBodies = [] this.grips = [false, false, false, false] // this.frictionJoints = [] @@ -144,10 +147,17 @@ Walker.prototype.__constructor = function(world) { } } } - globals.world.SetContactListener(this.contactListener) + this.world.SetContactListener(this.contactListener) } +// Walker.prototype.destroy = function () { +// this.bodies.map(body=>body.DestroyFixture(body.GetFixtureList())) +// this.bodies.map(body=>this.world.DestroyBody(body)) +// this.joints.map(joint => this.world.DestroyJoint(joint)) +// this.otherJoints.map(joint => this.world.DestroyJoint(joint)) +// } + Walker.prototype.createTorso = function() { // upper torso this.bd.position.Set(0.5 - this.leg_def.foot_length/2 + this.leg_def.tibia_width/2, this.leg_def.foot_height/2 + this.leg_def.foot_height/2 + this.leg_def.tibia_length + this.leg_def.femur_length + this.torso_def.lower_height + this.torso_def.upper_height/2); @@ -213,12 +223,13 @@ Walker.prototype.createLeg = function(label) { var fjd = new b2.FrictionJointDef(); var position = new b2.Vec2(0,0) - fjd.Initialize(foot, globals.floor, position) + fjd.Initialize(foot, this.floor, position) fjd.maxForce = 0; //This the most force the joint will apply to your object. The faster its moving the more force applied fjd.maxTorque = 0; //Set to 0 to prevent rotation fjd.userData = label+'foot_friction_joint' fjd.collideConnected = true var frictionJoint = this.world.CreateJoint(fjd) + this.otherJoints.push(frictionJoint) // leg joints var jd = new b2.RevoluteJointDef(); @@ -273,7 +284,6 @@ Walker.prototype.createArm = function(label) { // hand this.bd.position.Set(0.5 - this.leg_def.foot_length/2 + this.leg_def.tibia_width/2, this.leg_def.foot_height/2 + this.leg_def.foot_height/2 + this.leg_def.tibia_length + this.leg_def.femur_length + this.torso_def.lower_height + this.torso_def.upper_height - this.arm_def.arm_length - this.arm_def.forearm_length - this.arm_def.hand_length/2); - // this.bd.position.Set(0.5, this.arm_def.hand_height/2); var hand = this.world.CreateBody(this.bd); this.fd.shape.SetAsBox(this.arm_def.hand_height/2, this.arm_def.hand_length/2); @@ -283,12 +293,13 @@ Walker.prototype.createArm = function(label) { var fjd = new b2.FrictionJointDef(); var position = new b2.Vec2(0,0) - fjd.Initialize(hand, globals.floor, position) + fjd.Initialize(hand, this.floor, position) fjd.maxForce = 0; //This the most force the joint will apply to your object. The faster its moving the more force applied fjd.maxTorque = 0; //Set to 0 to prevent rotation fjd.userData = label+'hand_friction_joint' fjd.collideConnected = true var frictionJoint = this.world.CreateJoint(fjd) + this.otherJoints.push(frictionJoint) // arm join @@ -550,7 +561,7 @@ Walker.prototype.simulationStep = function (motorSpeeds) { // listener.PostSolve = function (contact, impulse) { // if (contact) console.log(contact) // } - // globals.world.SetContactListener(listener) + // this.world.SetContactListener(listener) // } var contacts = this.bodies.map(b => b.GetContactList()).filter(b => b).length quad_contact_cost = -Math.min(contacts - 4, 10)/2