Commit 88063fae authored by David A.. Werner's avatar David A.. Werner
Browse files

Added some of the basic Manduca code

parent 9588dee5
import numpy
import functools
class ManducaDeformity(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
class Manduca(object):
def __init__(self, legs, muscles, time_step):
self.legs = np.copy(legs)
self.muscles = np.copy(muscles)
self._time_step = time_step
self._fitness = None
def legs(self):
return self._legs
def legs(self, legs):
new_legs = np.array(legs)
if self._legs:
if new_legs.shape != self._legs.shape:
msg = 'Ill-defined leg shape. Expected {} but got {}'
e = msg.format(self._legs.shape, new_legs.shape)
self._legs = new_legs
self._fitness = None
def muscles(self):
return self._muscles
def muscles(self, muscles):
new_muscles = np.array(muscles)
if self._muscles:
if new_muscles.shape != self._muscles.shape:
msg = 'Ill-defined muscles shape. Expected {} but got {}'
e = msg.format(self._muscles.shape, new_muscles.shape)
self._muscles = new_muscles
self._fitness = None
def time_step(self):
return self._time_step
def time_step(self, time_step):
self._time_step = time_step
self._fitness = None
def num_legs(self):
return self.legs.shape[1]
def num_muscles(self):
return self.muscles.shape[1]
def num_time_steps(self):
leg_ts, muscle_ts = self.legs.shape[0], self.muscles.shape[0]
if leg_ts != muscle_ts:
msg = 'Arbitrary number of time-steps. {} in legs, {} in muscles'
e = msg.format(leg_ts, muscle_ts)
return leg_ts
def fitness(self):
if (self._fitness is None):
results = self.simulate()
self._fitness = 0
return (self._fitness)
def initial_position(self):
return numpy.arange(self.num_legs)*500
def check_consistancy(self):
if self.num_muscles != self.num_legs - 1:
msg = 'Ill-defined manduca has {} legs and {} muscles'
e = msg.format(self.num_legs, self.num_muscles))
# Make sure the number of time steps is consistant
def __repr__(self):
output = StringIO.StringIO()
output.write("\n legs | muscles")
for leg_t, musc_t in zip(self.legs,self.muscles):
leg_str = " ".join("{:>1}".format(int(l)) for l in leg_t)
musc_str = " ".join("{:>3}".format(int(m)) for m in musc_t)
output.write("\n{} | {}".format(leg_str, musc_str))
val = output.getvalue()
return val
def __eq__ (self, other):
return (self.time_step==other.time_step and
np.array_equal(self.legs, other.legs) and
np.array_equal(self.muscles,other.muscles) )
def __ne__(self, other):
return (self.time_step!=other.time_step or
not(np.array_equal(self.legs, other.legs)) or
def __hash__(self):
return hash(self.legs.tostring()+self.muscles.tostring()+str(self.time_step))
def simulate(self):
def save(self, file_name, compressed=True):
if compressed:
save_fn = np.savez_compressed
save_fn = np.savez
save_fn(file_name, legs=self.legs, muscles=self.muscles,
def load(cls, file_name):
results = np.load(file_name)
except IOError, ValueError as e:
print('Error loading {} from file {}'.format(cls.__name__, file_name)
def clone(self):
return (self.__class__(np.copy(self.legs), np.copy(self.muscles)))
class SimpleManduca(Manduca):
"""A Manduca that has legs and muscles that are either ON/OFF"""
def __init__(self, legs, muscles, time_step, muscle_strength=100):
super().__init__(legs, muscles, time_step)
assert ((self.legs==1)|(self.legs==0)).all(), "Legs must be 0 or 1"
assert ((self.muscles==0)|(self.muscles==muscle_strength)).all(), \
"Muscles must be 0 or {}".format(muscle_strength)
def random_individual(num_legs, time_segments, time_step, muscle_strength, rng=numpy.random):
legs = rng.choice([0,1],size=(time_segments, num_legs))
muscles = rng.choice([0,muscle_strength],size=(time_segments, num_legs-1))
return SimpleManduca(legs, muscles, time_step, muscle_strength=muscle_strength)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment