概要
Plunkerで、Phaser.Physicsやってみた。
CartPoleを、立たせます。
エージェントを、導入します。
環境が、エージェントにポールの傾きを与え、エージェントがPID制御を計算して、方向量ベクトルを返します。
環境が、重力シミュレートして、カートを動かします。
Kp,Ki,Kdは、自分が決めました。それぞれ、1.0,0.2、0.2です。
←キー、→キーで、外乱を与えることができます。
写真
var Agent3 = function() {
this.err2 = 0;
this.err = 0;
this.P = 0;
this.I = 0;
this.D = 0;
};
Agent3.prototype.get_action = function(setPoint, input) {
var Kp = 1.0;
var Ki = 0.2;
var Kd = 0.2;
var dt = 0.01;
this.P = setPoint - input;
this.I += this.P * dt;
this.D = (this.P - this.err2) / dt;
var u = Kp * this.P + Ki * this.I + Kd * this.D;
this.err2 = this.err;
this.err = this.P;
return u;
}
function create() {
game.physics.startSystem(Phaser.Physics.BOX2D);
game.physics.box2d.debugDraw.joints = true;
game.physics.box2d.setBoundsToWorld();
game.physics.box2d.gravity.y = 100;
ground = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 275, 0);
ground.setRectangle(400, 50, 0, 0, 0);
cart = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 243);
cart.setRectangle(60, 10, 0, 0, 0);
cart.mass = 10;
pole = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 295);
pole.setRectangle(4, 100, 0, 0, 0);
pole.mass = 0.1;
pole.linearDamping = 4;
game.physics.box2d.revoluteJoint(cart, pole, 0, -5, 0, 50);
pole.angle = 5;
cursors = game.input.keyboard.createCursorKeys();
agent = new Agent3();
caption1 = game.add.text(5, 30, 'Angle: ' + pole.angle, {
fill: '#dddddd',
font: '10pt Arial'
});
}
function update() {
caption1.text = 'Angle: ' + pole.angle;
var u = agent.get_action(0, pole.angle);
cart.applyForce(-u, 0);
if (cursors.left.isDown)
{
cart.applyForce(-5, 0);
}
if (cursors.right.isDown)
{
cart.applyForce(5, 0);
}
}
function render() {
game.debug.box2dWorld();
}
var game = new Phaser.Game(400, 300, Phaser.CANVAS, 'phaser-example', {
create: create,
update: update,
render: render
});
成果物
以上。