mirror of
https://github.com/wassname/rl_2d_walker.js.git
synced 2026-09-09 11:33:20 +08:00
balls
This commit is contained in:
@@ -20,19 +20,22 @@ TODO: Write usage instructions
|
||||
|
||||
## TODO
|
||||
|
||||
- make walker into an env, with reset, done etc
|
||||
- display save loss curves... everything from info
|
||||
- make diff env's, copy humanoidwalker, humanoid, learning2run etc
|
||||
- display
|
||||
- display/save time for each agent
|
||||
- globals.step_counter
|
||||
- x progress
|
||||
- smile frown?
|
||||
- save checkpoints
|
||||
- [x] make walker into an env, with reset, done etc
|
||||
- [x] display save loss curves... everything from info
|
||||
- [x] make diff env's, copy humanoidwalker, humanoid, learning2run etc
|
||||
- [ ] display
|
||||
- [x] display/save time for each agent
|
||||
- [x] globals.step_counter
|
||||
- [x] x progress
|
||||
- [ ] smile frown?
|
||||
- [ ] fix my frameskip
|
||||
- [x] save checkpoints
|
||||
- [ ] obstacles later on
|
||||
- [ ] load pretrained
|
||||
- [ ] reward hacking
|
||||
- [ ] head high, feet on ground, legs crossing, moving forward, angles near 0
|
||||
- [x] balls
|
||||
- [ ] Allow user to chuck bouncing balls. Some can remain as obstacles
|
||||
- [x] load pretrained
|
||||
- [x] reward hacking
|
||||
- [x] head high, feet on ground, legs crossing, moving forward, angles near 0
|
||||
|
||||
# Credits
|
||||
|
||||
@@ -41,6 +44,10 @@ TODO: Write usage instructions
|
||||
|
||||
# Notes
|
||||
|
||||
- Without node: Training: 52732.152ms
|
||||
- With node: Training: 17211.739ms
|
||||
- With cuda LoopTime: 12583.449ms
|
||||
- Training times:
|
||||
- Without node: Training: 52732.152ms
|
||||
- With node: Training: 17211.739ms
|
||||
- With cuda LoopTime: 12583.449ms
|
||||
- tfjs-node-gpu needs python2 to compile
|
||||
|
||||
- is is slipping, what about with more friction?
|
||||
|
||||
+32
-4
@@ -25,9 +25,11 @@ class Renderer {
|
||||
}
|
||||
|
||||
drawFrame() {
|
||||
// clear
|
||||
this.ctx.clearRect(0, 0, this.main_screen.width, this.main_screen.height);
|
||||
this.ctx.save();
|
||||
|
||||
// camera
|
||||
var minmax = this.getMinMaxDistance();
|
||||
this.target_zoom = Math.min(this.config.max_zoom_factor, this.getZoom(minmax.min_x, minmax.max_x + 4, minmax.min_y + 2, minmax.max_y + 2.5));
|
||||
this.zoom += 0.1 * (this.target_zoom - this.zoom);
|
||||
@@ -36,13 +38,36 @@ class Renderer {
|
||||
this.ctx.translate(this.translate_x * this.zoom, this.translate_y);
|
||||
this.ctx.scale(this.zoom, -this.zoom);
|
||||
|
||||
// bodies
|
||||
this.drawFloor();
|
||||
|
||||
for (var k = this.config.population_size - 1; k >= 0; k--) {
|
||||
this.drawWalker(this.walkers[k]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.walkers[0].balls.length; i++) {
|
||||
const ball = this.walkers[0].balls[i];
|
||||
this.drawCircle(ball)
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.ctx.restore();
|
||||
}
|
||||
|
||||
drawCircle(body) {
|
||||
// set strokestyle and fillstyle before call
|
||||
this.ctx.beginPath();
|
||||
var fixture = body.GetFixtureList();
|
||||
var shape = fixture.GetShape();
|
||||
var p0 = body.GetWorldPoint(shape.m_p);
|
||||
let radius = shape.m_radius
|
||||
// this.ctx.moveTo(p0.x, p0.y);
|
||||
this.ctx.arc(p0.x, p0.y, radius, 0, Math.PI*2)
|
||||
this.ctx.fill();
|
||||
this.ctx.stroke();
|
||||
}
|
||||
|
||||
drawFloor() {
|
||||
this.ctx.strokeStyle = "#444";
|
||||
this.ctx.lineWidth = 1 / this.zoom;
|
||||
@@ -62,10 +87,7 @@ class Renderer {
|
||||
this.ctx.lineWidth = 1 / this.zoom;
|
||||
|
||||
// left legs and arms first
|
||||
this.drawRect(walker.left_leg.lower_leg);
|
||||
this.drawRect(walker.left_leg.upper_leg);
|
||||
this.drawRect(walker.left_arm.upper_arm);
|
||||
this.drawRect(walker.left_arm.lower_arm);
|
||||
|
||||
|
||||
this.ctx.lineWidth = walker.left_leg.frictionJoint.maxForce ? 4 / this.zoom : 1 / this.zoom;
|
||||
this.drawRect(walker.left_leg.foot);
|
||||
@@ -75,6 +97,12 @@ class Renderer {
|
||||
this.drawRect(walker.left_arm.hand);
|
||||
this.ctx.lineWidth = 1 / this.zoom;
|
||||
|
||||
this.drawRect(walker.left_leg.lower_leg);
|
||||
this.drawRect(walker.left_leg.upper_leg);
|
||||
this.drawRect(walker.left_arm.lower_arm);
|
||||
this.drawRect(walker.left_arm.upper_arm);
|
||||
|
||||
|
||||
// head
|
||||
this.drawRect(walker.head.neck);
|
||||
this.drawRect(walker.head.head);
|
||||
|
||||
+56
-4
@@ -95,13 +95,14 @@ class Walker {
|
||||
this.fd = new b2.FixtureDef();
|
||||
this.fd.density = this.density;
|
||||
this.fd.restitution = 0.1; // bounciness
|
||||
this.fd.friction = 100; // only on contact (grip)
|
||||
this.fd.friction = 10000; // only on contact (grip)
|
||||
this.fd.shape = new b2.PolygonShape();
|
||||
this.fd.filter.groupIndex = -1;
|
||||
|
||||
this.joints = [];
|
||||
this.otherJoints = []
|
||||
this.otherBodies = []
|
||||
this.balls = []
|
||||
this.grips = [false, false, false, false]
|
||||
// this.frictionJoints = []
|
||||
|
||||
@@ -170,10 +171,16 @@ class Walker {
|
||||
destroy() {
|
||||
this.joints.map(joint => this.world.DestroyJoint(joint))
|
||||
this.otherJoints.map(joint => this.world.DestroyJoint(joint))
|
||||
|
||||
this.bodies.map(body => body.DestroyFixture(body.GetFixtureList()))
|
||||
this.bodies.map(body => this.world.DestroyBody(body))
|
||||
|
||||
this.balls.map(body => body.DestroyFixture(body.GetFixtureList()))
|
||||
this.balls.map(body => this.world.DestroyBody(body))
|
||||
|
||||
this.bodies = []
|
||||
this.joints = []
|
||||
this.balls = []
|
||||
this.otherJoints = []
|
||||
}
|
||||
|
||||
@@ -473,6 +480,33 @@ class Walker {
|
||||
this.joints.push(j);
|
||||
}
|
||||
|
||||
addBall(x, y, r) {
|
||||
var bodyDef = new b2.BodyDef()
|
||||
bodyDef.type = b2.Body.b2_dynamicBody
|
||||
bodyDef.position.x = x
|
||||
bodyDef.position.y = y
|
||||
var ball = this.world.CreateBody(bodyDef);
|
||||
|
||||
// Create a circle shape and set its radius to 6
|
||||
var circle = new b2.CircleShape();
|
||||
// circle.setRadius(6)
|
||||
circle.m_radius=r
|
||||
|
||||
|
||||
// Create a fixture definition to apply our shape to
|
||||
var fixtureDef = new b2.FixtureDef();
|
||||
fixtureDef.shape = circle;
|
||||
fixtureDef.density = 0.5;
|
||||
fixtureDef.friction = 0.4;
|
||||
fixtureDef.restitution = 0.6; // Make it bounce a little bit
|
||||
|
||||
// Create our fixture and attach it to the body
|
||||
var fixture = ball.CreateFixture(fixtureDef);
|
||||
// circle.dispose();
|
||||
|
||||
this.balls.push(ball)
|
||||
}
|
||||
|
||||
getBodies() {
|
||||
|
||||
return [
|
||||
@@ -491,7 +525,7 @@ class Walker {
|
||||
this.left_leg.foot,
|
||||
this.right_leg.upper_leg,
|
||||
this.right_leg.lower_leg,
|
||||
this.right_leg.foot
|
||||
this.right_leg.foot,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -554,7 +588,12 @@ class Walker {
|
||||
@action: (Integer) The action to take (can be null if no action)
|
||||
*/
|
||||
|
||||
if (Math.random() < 0.05) {
|
||||
this.addBallOnWalker()
|
||||
}
|
||||
|
||||
// repeat actions
|
||||
// FIXME I need to delay between drawing each frame. Right now action repeat makes it look like frames are skipping
|
||||
for (let i = 0; i < this.config.action_repeat; i++) {
|
||||
// TODO add sitcky actions once it's working
|
||||
this.world.ClearForces();
|
||||
@@ -612,7 +651,8 @@ class Walker {
|
||||
leg_switch_reward,
|
||||
head_height: (this.head.head.GetPosition().y - mean_foot_height),
|
||||
center_x: this.torso.upper_torso.GetPosition().x,
|
||||
center_y: this.torso.upper_torso.GetPosition().y
|
||||
center_y: this.torso.upper_torso.GetPosition().y,
|
||||
mean_foot_height
|
||||
}
|
||||
|
||||
this.reward = Object.values(this.rewards).reduce((tot, v) => tot + v, 0) / 3
|
||||
@@ -642,16 +682,28 @@ class Walker {
|
||||
this.steping = false;
|
||||
}
|
||||
}
|
||||
|
||||
addBallOnWalker() {
|
||||
let p = this.torso.upper_torso.GetPosition()
|
||||
this.addBall(p.x, randf(1, 4), randf(0.03,0.3))
|
||||
}
|
||||
|
||||
|
||||
reset() {
|
||||
/** Reset position to initial or random position TODO */
|
||||
// console.log('reset not implemented')
|
||||
if (this.bodies) this.destroy();
|
||||
this.build();
|
||||
this.initGrip()
|
||||
|
||||
this.episodeSteps = 0
|
||||
|
||||
this.randomise(0.5)
|
||||
|
||||
this.addBallOnWalker()
|
||||
this.addBallOnWalker()
|
||||
this.addBallOnWalker()
|
||||
|
||||
// run for a few warm up steps (to let it fall over... we don't want to reward it just for restarting the episode upright)
|
||||
for (let i = 0; i < 200; i++) {
|
||||
this.world.Step(1 / this.config.time_step, this.config.velocity_iterations, this.config.position_iterations);
|
||||
@@ -659,7 +711,7 @@ class Walker {
|
||||
this.world.Step(1 / this.config.time_step, this.config.velocity_iterations, this.config.position_iterations);
|
||||
if (typeof WEB !== "undefined") this.renderer.drawFrame()
|
||||
}
|
||||
console.debug('warm up finished')
|
||||
// console.debug('warm up finished')
|
||||
}
|
||||
shuffle() {
|
||||
/** Reset position to initial or random position TODO */
|
||||
|
||||
Reference in New Issue
Block a user