Generates an xml string defining a swimmer with `n_bodies` bodies.
(n_bodies)
| 81 | |
| 82 | |
| 83 | def _make_model(n_bodies): |
| 84 | """Generates an xml string defining a swimmer with `n_bodies` bodies.""" |
| 85 | if n_bodies < 3: |
| 86 | raise ValueError('At least 3 bodies required. Received {}'.format(n_bodies)) |
| 87 | mjcf = etree.fromstring(common.read_model('swimmer.xml')) |
| 88 | head_body = mjcf.find('./worldbody/body') |
| 89 | actuator = etree.SubElement(mjcf, 'actuator') |
| 90 | sensor = etree.SubElement(mjcf, 'sensor') |
| 91 | |
| 92 | parent = head_body |
| 93 | for body_index in range(n_bodies - 1): |
| 94 | site_name = 'site_{}'.format(body_index) |
| 95 | child = _make_body(body_index=body_index) |
| 96 | child.append(etree.Element('site', name=site_name)) |
| 97 | joint_name = 'joint_{}'.format(body_index) |
| 98 | joint_limit = 360.0/n_bodies |
| 99 | joint_range = '{} {}'.format(-joint_limit, joint_limit) |
| 100 | child.append(etree.Element('joint', {'name': joint_name, |
| 101 | 'range': joint_range})) |
| 102 | motor_name = 'motor_{}'.format(body_index) |
| 103 | actuator.append(etree.Element('motor', name=motor_name, joint=joint_name)) |
| 104 | velocimeter_name = 'velocimeter_{}'.format(body_index) |
| 105 | sensor.append(etree.Element('velocimeter', name=velocimeter_name, |
| 106 | site=site_name)) |
| 107 | gyro_name = 'gyro_{}'.format(body_index) |
| 108 | sensor.append(etree.Element('gyro', name=gyro_name, site=site_name)) |
| 109 | parent.append(child) |
| 110 | parent = child |
| 111 | |
| 112 | # Move tracking cameras further away from the swimmer according to its length. |
| 113 | cameras = mjcf.findall('./worldbody/body/camera') |
| 114 | scale = n_bodies / 6.0 |
| 115 | for cam in cameras: |
| 116 | if cam.get('mode') == 'trackcom': |
| 117 | old_pos = cam.get('pos').split(' ') |
| 118 | new_pos = ' '.join([str(float(dim) * scale) for dim in old_pos]) |
| 119 | cam.set('pos', new_pos) |
| 120 | |
| 121 | return etree.tostring(mjcf, pretty_print=True) |
| 122 | |
| 123 | |
| 124 | def _make_body(body_index): |
no test coverage detected
searching dependent graphs…