ClementRomac's picture
ClementRomac HF staff
Added interactive demo with some policies
09a6f7f
raw
history blame
8.76 kB
const MAIN_BODY_POLYGONS = [
[[-10, +10], [+10, +10], [+10, -10], [-10, -10]]
]
const MAIN_BODY_BOTTOM_WIDTH = 20
const SPIDER_SPEED_HIP = 4
const SPIDER_SPEED_KNEE = 6
/**
* @classdesc Spider morphology.
*/
class SpiderBody extends WalkerAbstractBody {
constructor(scale, motors_torque=100, nb_pairs_of_legs=2,
nb_steps_under_water=600, reset_on_hull_critical_contact=false){
super(scale, motors_torque, nb_steps_under_water);
this.LEG_DOWN = 4 / this.SCALE;
this.LEG_W = 6 / this.SCALE;
this.LEG_H = 20 / this.SCALE;
this.reset_on_critical_contact = reset_on_hull_critical_contact;
this.nb_pairs_of_legs = nb_pairs_of_legs;
this.TORQUE_PENALTY = 0.00035 / this.nb_pairs_of_legs;
// not exacts but works
this.AGENT_WIDTH = MAIN_BODY_BOTTOM_WIDTH / this.SCALE + this.LEG_H * 4;
this.AGENT_HEIGHT = 20 / this.SCALE + this.LEG_H * 2;
this.AGENT_CENTER_HEIGHT = this.LEG_H + this.LEG_DOWN;
}
draw(world, init_x, init_y, force_to_center){
let fd_polygon;
let vertices;
/* Creates the different fixtures */
let MAIN_BODY_FIXTURES = [];
for(let polygon of MAIN_BODY_POLYGONS){
fd_polygon = new b2.FixtureDef();
fd_polygon.shape = new b2.PolygonShape();
vertices = [];
for(let vertex of polygon){
vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE));
}
fd_polygon.shape.Set(vertices, polygon.length);
fd_polygon.density = 5.0;
fd_polygon.friction = 0.1;
fd_polygon.filter.categoryBits = 0x20;
fd_polygon.filter.maskBits = 0x000F;
MAIN_BODY_FIXTURES.push(fd_polygon);
}
let LEG_FD = new b2.FixtureDef();
LEG_FD.shape = new b2.PolygonShape();
LEG_FD.shape.SetAsBox(this.LEG_W / 2, this.LEG_H / 2);
LEG_FD.density = 1.0;
LEG_FD.restitution = 0.0;
LEG_FD.filter.categoryBits = 0x20;
LEG_FD.filter.maskBits = 0x000F;
let LOWER_FD = new b2.FixtureDef();
LOWER_FD.shape = new b2.PolygonShape();
LOWER_FD.shape.SetAsBox(0.8 * this.LEG_W / 2, this.LEG_H / 2);
LOWER_FD.density = 1.0;
LOWER_FD.restitution = 0.0;
LOWER_FD.filter.categoryBits = 0x20;
LOWER_FD.filter.maskBits = 0x000F;
/* Creates the different bodies */
// Main body
let main_body_bd = new b2.BodyDef();
main_body_bd.type = b2.Body.b2_dynamicBody;
main_body_bd.position.Set(init_x, init_y);
let main_body = world.CreateBody(main_body_bd);
for(let fd of MAIN_BODY_FIXTURES){
main_body.CreateFixture(fd);
}
main_body.color1 = "#803366"; // [0.5, 0.2, 0.4]
main_body.color2 = "#4D1A33"; // [0.3, 0.1, 0.2]
main_body.ApplyForceToCenter(new b2.Vec2(force_to_center, 0), true);
main_body.SetUserData(new CustomBodyUserData(true, this.reset_on_hull_critical_contact, "main_body"));
this.body_parts.push(main_body);
this.reference_head_object = main_body;
// Legs bodies and joints
let legs_coef = [];
for(let i = 0; i < this.nb_pairs_of_legs; i++){
legs_coef.push(+1, -1);
}
for(let i of legs_coef){
// First part of the leg
let upper_leg_angle = 0.25 * Math.PI * i;
let upper_leg_x_distance = Math.sin(upper_leg_angle) * this.LEG_H / 2;
let upper_leg_y_distance = Math.cos(upper_leg_angle) * this.LEG_H / 2;
let upper_leg_x = init_x - i * MAIN_BODY_BOTTOM_WIDTH / this.SCALE / 2 - upper_leg_x_distance;
let upper_leg_y = init_y + upper_leg_y_distance - this.LEG_DOWN;
let upper_leg_bd = new b2.BodyDef();
upper_leg_bd.type = b2.Body.b2_dynamicBody;
upper_leg_bd.position.Set(upper_leg_x, upper_leg_y);
upper_leg_bd.angle = upper_leg_angle;
let upper_leg = world.CreateBody(upper_leg_bd);
upper_leg.CreateFixture(LEG_FD);
upper_leg.color1 = "#B36699"; // [0.7, 0.4, 0.6]
upper_leg.color2 = "#804D66"; // [0.5, 0.3, 0.4]
upper_leg.SetUserData(new CustomBodyUserData(false, false,"upper_leg"));
this.body_parts.push(upper_leg);
// Upper leg joint motor
let upper_leg_rjd = new b2.RevoluteJointDef();
upper_leg_rjd.Initialize(main_body, upper_leg, new b2.Vec2(init_x - i * MAIN_BODY_BOTTOM_WIDTH / this.SCALE / 2, init_y - this.LEG_DOWN));
upper_leg_rjd.enableMotor = true;
upper_leg_rjd.enableLimit = true;
upper_leg_rjd.maxMotorTorque = this.MOTORS_TORQUE;
upper_leg_rjd.motorSpeed = 1;
upper_leg_rjd.lowerAngle = - 0.1 * Math.PI;
upper_leg_rjd.upperAngle = 0.1 * Math.PI;
let joint_motor = world.CreateJoint(upper_leg_rjd);
joint_motor.SetUserData(new CustomMotorUserData("hip", SPIDER_SPEED_HIP, false));
this.motors.push(joint_motor);
// Second part of the leg
let middle_leg_angle = 0.7 * Math.PI * i;
let middle_leg_x_distance = Math.sin(middle_leg_angle) * this.LEG_H / 2;
let middle_leg_y_distance = - Math.cos(middle_leg_angle) * this.LEG_H / 2;
let middle_leg_x = upper_leg_x - upper_leg_x_distance - middle_leg_x_distance;
let middle_leg_y = upper_leg_y + upper_leg_y_distance - middle_leg_y_distance;
let middle_leg_bd = new b2.BodyDef();
middle_leg_bd.type = b2.Body.b2_dynamicBody;
middle_leg_bd.position.Set(middle_leg_x, middle_leg_y);
middle_leg_bd.angle = middle_leg_angle;
let middle_leg = world.CreateBody(middle_leg_bd);
middle_leg.CreateFixture(LEG_FD);
middle_leg.color1 = "#B36699"; // [0.7, 0.4, 0.6]
middle_leg.color2 = "#804D66"; // [0.5, 0.3, 0.4]
middle_leg.SetUserData(new CustomBodyUserData(false, false,"middle_leg"));
this.body_parts.push(middle_leg);
// middle_leg joint motor
let middle_leg_rjd = new b2.RevoluteJointDef();
middle_leg_rjd.Initialize(upper_leg, middle_leg, new b2.Vec2(upper_leg_x - upper_leg_x_distance, upper_leg_y + upper_leg_y_distance));
middle_leg_rjd.enableMotor = true;
middle_leg_rjd.enableLimit = true;
middle_leg_rjd.maxMotorTorque = this.MOTORS_TORQUE;
middle_leg_rjd.motorSpeed = 1;
middle_leg_rjd.lowerAngle = - 0.15 * Math.PI;
middle_leg_rjd.upperAngle = 0.15 * Math.PI;
joint_motor = world.CreateJoint(middle_leg_rjd);
joint_motor.SetUserData(new CustomMotorUserData("hip", SPIDER_SPEED_HIP,false));
this.motors.push(joint_motor);
// Third part of the leg
let lower_leg_angle = 0.9 * Math.PI * i;
let lower_leg_x_distance = Math.sin(lower_leg_angle) * this.LEG_H / 2;
let lower_leg_y_distance = - Math.cos(lower_leg_angle) * this.LEG_H / 2;
let lower_leg_x = middle_leg_x - middle_leg_x_distance - lower_leg_x_distance;
let lower_leg_y = middle_leg_y - middle_leg_y_distance - lower_leg_y_distance;
let lower_leg_bd = new b2.BodyDef();
lower_leg_bd.type = b2.Body.b2_dynamicBody;
lower_leg_bd.position.Set(lower_leg_x, lower_leg_y);
lower_leg_bd.angle = lower_leg_angle;
let lower_leg = world.CreateBody(lower_leg_bd);
lower_leg.CreateFixture(LOWER_FD);
lower_leg.color1 = "#B36699"; // [0.7, 0.4, 0.6]
lower_leg.color2 = "#804D66"; // [0.5, 0.3, 0.4]
lower_leg.SetUserData(new CustomBodyUserData(true, false,"lower_leg"));
this.body_parts.push(lower_leg);
// lower_leg joint motor
let lower_leg_rjd = new b2.RevoluteJointDef();
lower_leg_rjd.Initialize(middle_leg, lower_leg, new b2.Vec2(middle_leg_x - middle_leg_x_distance, middle_leg_y - middle_leg_y_distance));
lower_leg_rjd.enableMotor = true;
lower_leg_rjd.enableLimit = true;
lower_leg_rjd.maxMotorTorque = this.MOTORS_TORQUE;
lower_leg_rjd.motorSpeed = 1;
lower_leg_rjd.lowerAngle = - 0.2 * Math.PI;
lower_leg_rjd.upperAngle = 0.2 * Math.PI;
joint_motor = world.CreateJoint(lower_leg_rjd);
joint_motor.SetUserData(new CustomMotorUserData("knee", SPIDER_SPEED_KNEE,true, 0.0, lower_leg));
this.motors.push(joint_motor);
}
}
};