Module TeachMyAgent.environments.envs.bodies.walkers.SpiderBody
Expand source code
import numpy as np
from Box2D.b2 import edgeShape, circleShape, fixtureDef, polygonShape, revoluteJointDef, contactListener
from TeachMyAgent.environments.envs.bodies.walkers.WalkerAbstractBody import WalkerAbstractBody
from TeachMyAgent.environments.envs.utils.custom_user_data import CustomBodyUserData, CustomMotorUserData
MAIN_BODY_POLYGONS = [
[(-10, +10), (+10, +10),
(+10, -10), (-10, -10)]
]
MAIN_BODY_BOTTOM_WIDTH = 20
SPEED_HIP = 4
SPEED_KNEE = 6
class SpiderBody(WalkerAbstractBody):
'''
Walking spider embodiment.
'''
def __init__(self, scale, motors_torque=100, nb_pairs_of_legs=2, nb_steps_under_water=600,
reset_on_hull_critical_contact=False):
'''
Creates a spider with `n` pair of legs.
Each legs has 3 parts.
Args:
scale: Scale value used in the environment (to adapt the embodiment to its environment)
motors_torque: Maximum torque the embodiment can use on its motors
nb_pairs_of_legs: Number of pair of legs the agent has
nb_steps_under_water: How many consecutive steps the embodiment can survive under water
reset_on_hull_critical_contact: Whether a contact detected with the head should stop the episode
'''
super(SpiderBody, self).__init__(scale, motors_torque, nb_steps_under_water)
self.LEG_DOWN = 4 / self.SCALE
self.LEG_W, self.LEG_H = 6 / self.SCALE, 20 / self.SCALE
self.reset_on_hull_critical_contact = reset_on_hull_critical_contact
self.nb_pairs_of_legs = nb_pairs_of_legs
self.TORQUE_PENALTY = 0.00035 / self.nb_pairs_of_legs
# not exact but works
self.AGENT_WIDTH = MAIN_BODY_BOTTOM_WIDTH / self.SCALE + \
self.LEG_H * 4
self.AGENT_HEIGHT = 20 / self.SCALE + \
self.LEG_H * 2
self.AGENT_CENTER_HEIGHT = self.LEG_H + self.LEG_DOWN
def draw(self, world, init_x, init_y, force_to_center):
''' Circular body
MAIN_BODY_FIXTURES = fixtureDef(
shape=circleShape(radius=0.4),
density=1.0,
restitution=0.0,
categoryBits=0x20,
maskBits=0x000F
)
'''
MAIN_BODY_FIXTURES = [
fixtureDef(
shape=polygonShape(vertices=[(x / self.SCALE, y / self.SCALE) for x, y in polygon]),
density=5.0,
friction=0.1,
categoryBits=0x20,
maskBits=0x000F)
for polygon in MAIN_BODY_POLYGONS
]
LEG_FD = fixtureDef(
shape=polygonShape(box=(self.LEG_W / 2, self.LEG_H / 2)),
density=1.0,
restitution=0.0,
categoryBits=0x20,
maskBits=0x000F)
LOWER_FD = fixtureDef(
shape=polygonShape(box=(0.8 * self.LEG_W / 2, self.LEG_H / 2)),
density=1.0,
restitution=0.0,
categoryBits=0x20,
maskBits=0x000F)
main_body = world.CreateDynamicBody(
position=(init_x, init_y),
fixtures=MAIN_BODY_FIXTURES
)
basis_color1 = (0.6, 0.3, 0.5)
basis_color2 = (0.4, 0.2, 0.3)
main_body.color1 = tuple([c - 0.1 for c in basis_color1])
main_body.color2 = tuple([c - 0.1 for c in basis_color2])
leg_color1 = tuple([c + 0.1 for c in basis_color1])
leg_color2 = tuple([c + 0.1 for c in basis_color2])
main_body.ApplyForceToCenter((force_to_center, 0), True)
main_body.userData = CustomBodyUserData(True, is_contact_critical=self.reset_on_hull_critical_contact, name="main_body")
self.body_parts.append(main_body)
self.reference_head_object = main_body
for i in [+1, -1] * self.nb_pairs_of_legs:
##### First part of the leg #####
upper_leg_angle = 0.25 * np.pi * i
upper_leg_x_distance = np.sin(upper_leg_angle) * self.LEG_H / 2
upper_leg_y_distance = np.cos(upper_leg_angle) * self.LEG_H / 2
upper_leg_x = init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2 - upper_leg_x_distance
upper_leg_y = init_y + upper_leg_y_distance - self.LEG_DOWN
upper_leg = world.CreateDynamicBody(
position=(upper_leg_x, upper_leg_y),
angle=upper_leg_angle,
fixtures=LEG_FD
)
upper_leg.color1 = leg_color1
upper_leg.color2 = leg_color2
rjd = revoluteJointDef(
bodyA=main_body,
bodyB=upper_leg,
anchor=(init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2,
init_y - self.LEG_DOWN),
enableMotor=True,
enableLimit=True,
maxMotorTorque=self.MOTORS_TORQUE,
motorSpeed=1,
lowerAngle=-0.1*np.pi,
upperAngle=0.1*np.pi,
)
upper_leg.userData = CustomBodyUserData(False, name="upper_leg")
self.body_parts.append(upper_leg)
joint_motor = world.CreateJoint(rjd)
joint_motor.userData = CustomMotorUserData(SPEED_HIP, False)
self.motors.append(joint_motor)
##### Second part of the leg #####
middle_leg_angle = 0.7 * np.pi * i
middle_leg_x_distance = np.sin(middle_leg_angle) * self.LEG_H / 2
middle_leg_y_distance = -np.cos(middle_leg_angle) * self.LEG_H / 2
middle_leg_x = upper_leg_x - upper_leg_x_distance - middle_leg_x_distance
middle_leg_y = upper_leg_y + upper_leg_y_distance - middle_leg_y_distance
middle_leg = world.CreateDynamicBody(
position=(middle_leg_x, middle_leg_y),
angle=middle_leg_angle,
fixtures=LEG_FD
)
middle_leg.color1 = leg_color1
middle_leg.color2 = leg_color2
rjd = revoluteJointDef(
bodyA=upper_leg,
bodyB=middle_leg,
anchor=(upper_leg_x - upper_leg_x_distance,
upper_leg_y + upper_leg_y_distance),
enableMotor=True,
enableLimit=True,
maxMotorTorque=self.MOTORS_TORQUE,
motorSpeed=1,
lowerAngle=-0.15*np.pi,
upperAngle=0.15*np.pi,
)
middle_leg.userData = CustomBodyUserData(False, name="middle_leg")
self.body_parts.append(middle_leg)
joint_motor = world.CreateJoint(rjd)
joint_motor.userData = CustomMotorUserData(SPEED_HIP, False)
self.motors.append(joint_motor)
##### Third part of the leg #####
lower_leg_angle = 0.9 * np.pi * i
lower_leg_x_distance = np.sin(lower_leg_angle) * self.LEG_H / 2
lower_leg_y_distance = -np.cos(lower_leg_angle) * self.LEG_H / 2
lower_leg_x = middle_leg_x - middle_leg_x_distance - lower_leg_x_distance
lower_leg_y = middle_leg_y - middle_leg_y_distance - lower_leg_y_distance
lower_leg = world.CreateDynamicBody(
position=(lower_leg_x, lower_leg_y),
angle=lower_leg_angle,
fixtures=LOWER_FD
)
lower_leg.color1 = leg_color1
lower_leg.color2 = leg_color2
rjd = revoluteJointDef(
bodyA=middle_leg,
bodyB=lower_leg,
anchor=(middle_leg_x - middle_leg_x_distance,
middle_leg_y - middle_leg_y_distance ),
enableMotor=True,
enableLimit=True,
maxMotorTorque=self.MOTORS_TORQUE,
motorSpeed=1,
lowerAngle=-0.2*np.pi,
upperAngle=0.2*np.pi,
)
lower_leg.userData = CustomBodyUserData(True, name="lower_leg")
self.body_parts.append(lower_leg)
joint_motor = world.CreateJoint(rjd)
joint_motor.userData = CustomMotorUserData(SPEED_KNEE,
True,
contact_body=lower_leg)
self.motors.append(joint_motor)
Classes
class SpiderBody (scale, motors_torque=100, nb_pairs_of_legs=2, nb_steps_under_water=600, reset_on_hull_critical_contact=False)
-
Walking spider embodiment.
Creates a spider with
n
pair of legs.Each legs has 3 parts.
Args
scale
- Scale value used in the environment (to adapt the embodiment to its environment)
motors_torque
- Maximum torque the embodiment can use on its motors
nb_pairs_of_legs
- Number of pair of legs the agent has
- nb_steps_under_water: How many consecutive steps the embodiment can survive under water
reset_on_hull_critical_contact
- Whether a contact detected with the head should stop the episode
Expand source code
class SpiderBody(WalkerAbstractBody): ''' Walking spider embodiment. ''' def __init__(self, scale, motors_torque=100, nb_pairs_of_legs=2, nb_steps_under_water=600, reset_on_hull_critical_contact=False): ''' Creates a spider with `n` pair of legs. Each legs has 3 parts. Args: scale: Scale value used in the environment (to adapt the embodiment to its environment) motors_torque: Maximum torque the embodiment can use on its motors nb_pairs_of_legs: Number of pair of legs the agent has nb_steps_under_water: How many consecutive steps the embodiment can survive under water reset_on_hull_critical_contact: Whether a contact detected with the head should stop the episode ''' super(SpiderBody, self).__init__(scale, motors_torque, nb_steps_under_water) self.LEG_DOWN = 4 / self.SCALE self.LEG_W, self.LEG_H = 6 / self.SCALE, 20 / self.SCALE self.reset_on_hull_critical_contact = reset_on_hull_critical_contact self.nb_pairs_of_legs = nb_pairs_of_legs self.TORQUE_PENALTY = 0.00035 / self.nb_pairs_of_legs # not exact but works self.AGENT_WIDTH = MAIN_BODY_BOTTOM_WIDTH / self.SCALE + \ self.LEG_H * 4 self.AGENT_HEIGHT = 20 / self.SCALE + \ self.LEG_H * 2 self.AGENT_CENTER_HEIGHT = self.LEG_H + self.LEG_DOWN def draw(self, world, init_x, init_y, force_to_center): ''' Circular body MAIN_BODY_FIXTURES = fixtureDef( shape=circleShape(radius=0.4), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F ) ''' MAIN_BODY_FIXTURES = [ fixtureDef( shape=polygonShape(vertices=[(x / self.SCALE, y / self.SCALE) for x, y in polygon]), density=5.0, friction=0.1, categoryBits=0x20, maskBits=0x000F) for polygon in MAIN_BODY_POLYGONS ] LEG_FD = fixtureDef( shape=polygonShape(box=(self.LEG_W / 2, self.LEG_H / 2)), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F) LOWER_FD = fixtureDef( shape=polygonShape(box=(0.8 * self.LEG_W / 2, self.LEG_H / 2)), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F) main_body = world.CreateDynamicBody( position=(init_x, init_y), fixtures=MAIN_BODY_FIXTURES ) basis_color1 = (0.6, 0.3, 0.5) basis_color2 = (0.4, 0.2, 0.3) main_body.color1 = tuple([c - 0.1 for c in basis_color1]) main_body.color2 = tuple([c - 0.1 for c in basis_color2]) leg_color1 = tuple([c + 0.1 for c in basis_color1]) leg_color2 = tuple([c + 0.1 for c in basis_color2]) main_body.ApplyForceToCenter((force_to_center, 0), True) main_body.userData = CustomBodyUserData(True, is_contact_critical=self.reset_on_hull_critical_contact, name="main_body") self.body_parts.append(main_body) self.reference_head_object = main_body for i in [+1, -1] * self.nb_pairs_of_legs: ##### First part of the leg ##### upper_leg_angle = 0.25 * np.pi * i upper_leg_x_distance = np.sin(upper_leg_angle) * self.LEG_H / 2 upper_leg_y_distance = np.cos(upper_leg_angle) * self.LEG_H / 2 upper_leg_x = init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2 - upper_leg_x_distance upper_leg_y = init_y + upper_leg_y_distance - self.LEG_DOWN upper_leg = world.CreateDynamicBody( position=(upper_leg_x, upper_leg_y), angle=upper_leg_angle, fixtures=LEG_FD ) upper_leg.color1 = leg_color1 upper_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=main_body, bodyB=upper_leg, anchor=(init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2, init_y - self.LEG_DOWN), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.1*np.pi, upperAngle=0.1*np.pi, ) upper_leg.userData = CustomBodyUserData(False, name="upper_leg") self.body_parts.append(upper_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_HIP, False) self.motors.append(joint_motor) ##### Second part of the leg ##### middle_leg_angle = 0.7 * np.pi * i middle_leg_x_distance = np.sin(middle_leg_angle) * self.LEG_H / 2 middle_leg_y_distance = -np.cos(middle_leg_angle) * self.LEG_H / 2 middle_leg_x = upper_leg_x - upper_leg_x_distance - middle_leg_x_distance middle_leg_y = upper_leg_y + upper_leg_y_distance - middle_leg_y_distance middle_leg = world.CreateDynamicBody( position=(middle_leg_x, middle_leg_y), angle=middle_leg_angle, fixtures=LEG_FD ) middle_leg.color1 = leg_color1 middle_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=upper_leg, bodyB=middle_leg, anchor=(upper_leg_x - upper_leg_x_distance, upper_leg_y + upper_leg_y_distance), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.15*np.pi, upperAngle=0.15*np.pi, ) middle_leg.userData = CustomBodyUserData(False, name="middle_leg") self.body_parts.append(middle_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_HIP, False) self.motors.append(joint_motor) ##### Third part of the leg ##### lower_leg_angle = 0.9 * np.pi * i lower_leg_x_distance = np.sin(lower_leg_angle) * self.LEG_H / 2 lower_leg_y_distance = -np.cos(lower_leg_angle) * self.LEG_H / 2 lower_leg_x = middle_leg_x - middle_leg_x_distance - lower_leg_x_distance lower_leg_y = middle_leg_y - middle_leg_y_distance - lower_leg_y_distance lower_leg = world.CreateDynamicBody( position=(lower_leg_x, lower_leg_y), angle=lower_leg_angle, fixtures=LOWER_FD ) lower_leg.color1 = leg_color1 lower_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=middle_leg, bodyB=lower_leg, anchor=(middle_leg_x - middle_leg_x_distance, middle_leg_y - middle_leg_y_distance ), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.2*np.pi, upperAngle=0.2*np.pi, ) lower_leg.userData = CustomBodyUserData(True, name="lower_leg") self.body_parts.append(lower_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_KNEE, True, contact_body=lower_leg) self.motors.append(joint_motor)
Ancestors
Methods
def draw(self, world, init_x, init_y, force_to_center)
-
Circular body MAIN_BODY_FIXTURES = fixtureDef( shape=circleShape(radius=0.4), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F )
Expand source code
def draw(self, world, init_x, init_y, force_to_center): ''' Circular body MAIN_BODY_FIXTURES = fixtureDef( shape=circleShape(radius=0.4), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F ) ''' MAIN_BODY_FIXTURES = [ fixtureDef( shape=polygonShape(vertices=[(x / self.SCALE, y / self.SCALE) for x, y in polygon]), density=5.0, friction=0.1, categoryBits=0x20, maskBits=0x000F) for polygon in MAIN_BODY_POLYGONS ] LEG_FD = fixtureDef( shape=polygonShape(box=(self.LEG_W / 2, self.LEG_H / 2)), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F) LOWER_FD = fixtureDef( shape=polygonShape(box=(0.8 * self.LEG_W / 2, self.LEG_H / 2)), density=1.0, restitution=0.0, categoryBits=0x20, maskBits=0x000F) main_body = world.CreateDynamicBody( position=(init_x, init_y), fixtures=MAIN_BODY_FIXTURES ) basis_color1 = (0.6, 0.3, 0.5) basis_color2 = (0.4, 0.2, 0.3) main_body.color1 = tuple([c - 0.1 for c in basis_color1]) main_body.color2 = tuple([c - 0.1 for c in basis_color2]) leg_color1 = tuple([c + 0.1 for c in basis_color1]) leg_color2 = tuple([c + 0.1 for c in basis_color2]) main_body.ApplyForceToCenter((force_to_center, 0), True) main_body.userData = CustomBodyUserData(True, is_contact_critical=self.reset_on_hull_critical_contact, name="main_body") self.body_parts.append(main_body) self.reference_head_object = main_body for i in [+1, -1] * self.nb_pairs_of_legs: ##### First part of the leg ##### upper_leg_angle = 0.25 * np.pi * i upper_leg_x_distance = np.sin(upper_leg_angle) * self.LEG_H / 2 upper_leg_y_distance = np.cos(upper_leg_angle) * self.LEG_H / 2 upper_leg_x = init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2 - upper_leg_x_distance upper_leg_y = init_y + upper_leg_y_distance - self.LEG_DOWN upper_leg = world.CreateDynamicBody( position=(upper_leg_x, upper_leg_y), angle=upper_leg_angle, fixtures=LEG_FD ) upper_leg.color1 = leg_color1 upper_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=main_body, bodyB=upper_leg, anchor=(init_x - i * MAIN_BODY_BOTTOM_WIDTH / self.SCALE / 2, init_y - self.LEG_DOWN), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.1*np.pi, upperAngle=0.1*np.pi, ) upper_leg.userData = CustomBodyUserData(False, name="upper_leg") self.body_parts.append(upper_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_HIP, False) self.motors.append(joint_motor) ##### Second part of the leg ##### middle_leg_angle = 0.7 * np.pi * i middle_leg_x_distance = np.sin(middle_leg_angle) * self.LEG_H / 2 middle_leg_y_distance = -np.cos(middle_leg_angle) * self.LEG_H / 2 middle_leg_x = upper_leg_x - upper_leg_x_distance - middle_leg_x_distance middle_leg_y = upper_leg_y + upper_leg_y_distance - middle_leg_y_distance middle_leg = world.CreateDynamicBody( position=(middle_leg_x, middle_leg_y), angle=middle_leg_angle, fixtures=LEG_FD ) middle_leg.color1 = leg_color1 middle_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=upper_leg, bodyB=middle_leg, anchor=(upper_leg_x - upper_leg_x_distance, upper_leg_y + upper_leg_y_distance), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.15*np.pi, upperAngle=0.15*np.pi, ) middle_leg.userData = CustomBodyUserData(False, name="middle_leg") self.body_parts.append(middle_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_HIP, False) self.motors.append(joint_motor) ##### Third part of the leg ##### lower_leg_angle = 0.9 * np.pi * i lower_leg_x_distance = np.sin(lower_leg_angle) * self.LEG_H / 2 lower_leg_y_distance = -np.cos(lower_leg_angle) * self.LEG_H / 2 lower_leg_x = middle_leg_x - middle_leg_x_distance - lower_leg_x_distance lower_leg_y = middle_leg_y - middle_leg_y_distance - lower_leg_y_distance lower_leg = world.CreateDynamicBody( position=(lower_leg_x, lower_leg_y), angle=lower_leg_angle, fixtures=LOWER_FD ) lower_leg.color1 = leg_color1 lower_leg.color2 = leg_color2 rjd = revoluteJointDef( bodyA=middle_leg, bodyB=lower_leg, anchor=(middle_leg_x - middle_leg_x_distance, middle_leg_y - middle_leg_y_distance ), enableMotor=True, enableLimit=True, maxMotorTorque=self.MOTORS_TORQUE, motorSpeed=1, lowerAngle=-0.2*np.pi, upperAngle=0.2*np.pi, ) lower_leg.userData = CustomBodyUserData(True, name="lower_leg") self.body_parts.append(lower_leg) joint_motor = world.CreateJoint(rjd) joint_motor.userData = CustomMotorUserData(SPEED_KNEE, True, contact_body=lower_leg) self.motors.append(joint_motor)
Inherited members