Skip to content

Commit 20048ac

Browse files
committed
separated build_dog in different files to increase readability; added a floor to the base xml; overall clean-up of the file
1 parent 0b11adb commit 20048ac

11 files changed

Lines changed: 1735 additions & 1758 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import collections
2+
from dm_control import mjcf
3+
4+
def add_motors(physics, model, lumbar_joints, cervical_joints, caudal_joints):
5+
#physics = mjcf.Physics.from_mjcf_model(model)
6+
# Fixed Tendons:
7+
spinal_joints = collections.OrderedDict()
8+
spinal_joints['lumbar_'] = lumbar_joints
9+
spinal_joints['cervical_'] = cervical_joints
10+
spinal_joints['caudal_'] = caudal_joints
11+
tendons = []
12+
for region in spinal_joints.keys():
13+
for direction in ['extend', 'bend', 'twist']:
14+
joints = [
15+
joint for joint in spinal_joints[region] if direction in joint.name
16+
]
17+
if joints:
18+
tendon = model.tendon.add(
19+
'fixed', name=region + direction, dclass=joints[0].dclass)
20+
tendons.append(tendon)
21+
joint_inertia = physics.bind(joints).M0
22+
coefs = joint_inertia ** .25
23+
coefs /= coefs.sum()
24+
coefs *= len(joints)
25+
for i, joint in enumerate(joints):
26+
tendon.add('joint', joint=joint, coef=coefs[i])
27+
28+
# Actuators:
29+
all_spinal_joints = [
30+
joint for region in spinal_joints.values() for joint in region # pylint: disable=g-complex-comprehension
31+
]
32+
root_joint = model.find('joint', 'root')
33+
actuated_joints = [
34+
joint for joint in model.find_all('joint')
35+
if joint not in all_spinal_joints and joint is not root_joint
36+
]
37+
for tendon in tendons:
38+
gain = 0.
39+
for joint in tendon.joint:
40+
# joint.joint.user = physics.bind(joint.joint).damping
41+
def_joint = model.default.find('default', joint.joint.dclass)
42+
j_gain = def_joint.general.gainprm or def_joint.parent.general.gainprm
43+
gain += j_gain[0] * joint.coef
44+
gain /= len(tendon.joint)
45+
46+
model.actuator.add(
47+
'general', tendon=tendon, name=tendon.name, dclass=tendon.dclass)
48+
49+
for joint in actuated_joints:
50+
model.actuator.add(
51+
'general', joint=joint, name=joint.name, dclass=joint.dclass)
52+
53+
return actuated_joints
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
from dm_control import mjcf
2+
import numpy as np
3+
4+
def create_back_legs(model, primary_axis, bone_position, bones, side_sign,
5+
bone_size, pelvic_bones, parent):
6+
7+
pelvis = parent
8+
# Hip joint sites:
9+
scale = np.asarray([bone_size[bone] for bone in pelvic_bones]).mean()
10+
hip_pos = np.array((-.23, -.6, -.16)) * scale
11+
for side in ['_L', '_R']:
12+
pelvis.add(
13+
'site', name='hip' + side, size=[0.011], pos=hip_pos * side_sign[side])
14+
15+
# Upper legs:
16+
upper_leg = {}
17+
femurs = [b for b in bones if 'Fem' in b]
18+
use_tendons = False
19+
if not use_tendons:
20+
femurs += [b for b in bones if 'Patella' in b]
21+
for side in ['_L', '_R']:
22+
body_pos = hip_pos * side_sign[side]
23+
leg = pelvis.add('body', name='upper_leg' + side, pos=body_pos)
24+
upper_leg[side] = leg
25+
for bone in [b for b in femurs if side in b]:
26+
leg.add(
27+
'geom',
28+
name=bone,
29+
mesh=bone,
30+
pos=-bone_position['Pelvis'] - body_pos,
31+
dclass='bone')
32+
33+
# Hip joints
34+
for dof in ['_supinate', '_abduct', '_extend']:
35+
axis = primary_axis[dof].copy()
36+
if dof != '_extend':
37+
axis *= 1. if side != '_R' else -1.
38+
leg.add('joint', name='hip' + side + dof, dclass='hip' + dof, axis=axis)
39+
40+
# Knee sites
41+
scale = bone_size['Femoris_L']
42+
knee_pos = np.array((-0.2, -0.27, -1.45)) * scale
43+
leg.add('site', type='cylinder', name='knee' + side, size=[0.003, .02],
44+
zaxis=(0, 1, 0), pos=knee_pos * side_sign[side])
45+
pos = np.array((-.01, -.02, -.08)) * side_sign[side]
46+
euler = [-10 * (1. if side == '_R' else -1.), 20, 0]
47+
leg.add(
48+
'geom',
49+
name=leg.name + '0_collision',
50+
pos=pos,
51+
size=[.04, .08],
52+
euler=euler,
53+
dclass='collision_primitive')
54+
pos = np.array((-.03, 0, -.05))
55+
euler = [-10 * (1. if side == '_R' else -1.), 5, 0]
56+
leg.add(
57+
'geom',
58+
name=leg.name + '1_collision',
59+
pos=pos,
60+
size=[.04, .04],
61+
euler=euler,
62+
dclass='collision_primitive')
63+
64+
# Patella
65+
if use_tendons:
66+
# Make patella body
67+
pass
68+
69+
# Lower legs:
70+
lower_leg = {}
71+
lower_leg_bones = [b for b in bones if 'Tibia_' in b or 'Fibula' in b]
72+
for side in ['_L', '_R']:
73+
body_pos = knee_pos * side_sign[side]
74+
leg = upper_leg[side].add('body', name='lower_leg' + side, pos=body_pos)
75+
lower_leg[side] = leg
76+
for bone in [b for b in lower_leg_bones if side in b]:
77+
leg.add(
78+
'geom',
79+
name=bone,
80+
mesh=bone,
81+
pos=-bone_position['Pelvis'] - upper_leg[side].pos - body_pos,
82+
dclass='bone')
83+
# Knee joints
84+
leg.add('joint', name='knee' + side, dclass='knee', axis=(0, -1, 0))
85+
86+
# Ankle sites
87+
scale = bone_size['Tibia_L']
88+
ankle_pos = np.array((-1.27, 0.04, -0.98)) * scale
89+
leg.add('site', type='cylinder', name='ankle' + side, size=[0.003, .013],
90+
zaxis=(0, 1, 0), pos=ankle_pos*side_sign[side])
91+
92+
# Feet:
93+
foot = {}
94+
foot_bones = [b for b in bones if 'tars' in b.lower() or 'tuber' in b]
95+
for side in ['_L', '_R']:
96+
body_pos = ankle_pos * side_sign[side]
97+
leg = lower_leg[side].add('body', name='foot' + side, pos=body_pos)
98+
foot[side] = leg
99+
for bone in [b for b in foot_bones if side in b]:
100+
leg.add(
101+
'geom',
102+
name=bone,
103+
mesh=bone,
104+
pos=-bone_position['Pelvis'] - upper_leg[side].pos -
105+
lower_leg[side].pos - body_pos,
106+
dclass='bone')
107+
# Ankle joints
108+
leg.add('joint', name='ankle' + side, dclass='ankle', axis=(0, 1, 0))
109+
pos = np.array((-.01, -.005, -.05)) * side_sign[side]
110+
leg.add(
111+
'geom',
112+
name=leg.name + '_collision',
113+
size=[.015, .07],
114+
pos=pos,
115+
dclass='collision_primitive')
116+
117+
# Toe sites
118+
scale = bone_size['Metatarsi_R_2']
119+
toe_pos = np.array((-.37, -.2, -2.95)) * scale
120+
leg.add('site', type='cylinder', name='toe' + side, size=[0.003, .025],
121+
zaxis=(0, 1, 0), pos=toe_pos*side_sign[side])
122+
123+
# Toes:
124+
toe_bones = [b for b in bones if 'Phalange' in b]
125+
toe_geoms = []
126+
sole_sites = []
127+
nails = []
128+
for side in ['_L', '_R']:
129+
body_pos = toe_pos * side_sign[side]
130+
foot_anchor = foot[side].add(
131+
'body', name='foot_anchor' + side, pos=body_pos)
132+
foot_anchor.add(
133+
'geom',
134+
name=foot_anchor.name,
135+
dclass='foot_primitive',
136+
type='box',
137+
size=(.005, .005, .005),
138+
contype=0,
139+
conaffinity=0)
140+
foot_anchor.add('site', name=foot_anchor.name, dclass='sensor')
141+
leg = foot_anchor.add('body', name='toe' + side)
142+
for bone in [b for b in toe_bones if side in b]:
143+
geom = leg.add(
144+
'geom',
145+
name=bone,
146+
mesh=bone,
147+
pos=-bone_position['Pelvis'] - upper_leg[side].pos -
148+
lower_leg[side].pos - foot[side].pos - body_pos,
149+
dclass='bone')
150+
if 'B_3' in bone:
151+
nails.append(bone)
152+
geom.dclass = 'visible_bone'
153+
else:
154+
toe_geoms.append(geom)
155+
# Toe joints
156+
leg.add('joint', name='toe' + side, dclass='toe', axis=(0, 1, 0))
157+
# Collision geoms
158+
leg.add(
159+
'geom',
160+
name=leg.name + '0_collision',
161+
size=[0.018, 0.012],
162+
pos=[.015, 0, -.02],
163+
euler=(90, 0, 0),
164+
dclass='foot_primitive')
165+
leg.add(
166+
'geom',
167+
name=leg.name + '1_collision',
168+
size=[0.01, 0.015],
169+
pos=[.035, 0, -.028],
170+
euler=(90, 0, 0),
171+
dclass='foot_primitive')
172+
leg.add(
173+
'geom',
174+
name=leg.name + '2_collision',
175+
size=[0.008, 0.01],
176+
pos=[.045, 0, -.03],
177+
euler=(90, 0, 0),
178+
dclass='foot_primitive')
179+
sole = leg.add(
180+
'site',
181+
name='sole' + side,
182+
size=(.025, .03, .008),
183+
pos=(.026, 0, -.033),
184+
type='box',
185+
dclass='sensor')
186+
187+
sole_sites.append(sole)
188+
189+
physics = mjcf.Physics.from_mjcf_model(model)
190+
191+
for side in ['_L', '_R']:
192+
# lower leg:
193+
leg = lower_leg[side]
194+
leg.add(
195+
'geom',
196+
name=leg.name + '_collision',
197+
pos=physics.bind(leg).ipos * 1.3,
198+
size=[.02, .1],
199+
quat=physics.bind(leg).iquat,
200+
dclass='collision_primitive')
201+
202+
return nails, sole_sites

0 commit comments

Comments
 (0)