diff --git a/CM3020 Artificial Intelligence/Week 8/Files/creature.py b/CM3020 Artificial Intelligence/Week 8/Files/creature.py new file mode 100644 index 0000000..33aaf97 --- /dev/null +++ b/CM3020 Artificial Intelligence/Week 8/Files/creature.py @@ -0,0 +1,88 @@ +import genome +from xml.dom.minidom import getDOMImplementation +from enum import Enum +import numpy as np + + +class MotorType(Enum): + PULSE = 1 + SINE = 2 + + +class Motor: + def __init__(self, control_waveform, control_amp, control_freq): + if control_waveform <= 0.5: + self.motor_type = MotorType.PULSE + else: + self.motor_type = MotorType.SINE + self.amp = control_amp + self.freq = control_freq + self.phase = 0 + + def get_output(self): + self.phase = (self.phase + self.freq) % (np.pi * 2) + if self.motor_type == MotorType.PULSE: + if self.phase < np.pi: + output = 1 + else: + output = -1 + + if self.motor_type == MotorType.SINE: + output = np.sin(self.phase) + + return output + + +class Creature: + def __init__(self, gene_count): + self.spec = genome.Genome.get_gene_spec() + self.dna = genome.Genome.get_random_genome(len(self.spec), gene_count) + self.flat_links = None + self.exp_links = None + self.motors = None + + def get_flat_links(self): + if self.flat_links == None: + gdicts = genome.Genome.get_genome_dicts(self.dna, self.spec) + self.flat_links = genome.Genome.genome_to_links(gdicts) + return self.flat_links + + def get_expanded_links(self): + self.get_flat_links() + if self.exp_links is not None: + return self.exp_links + + exp_links = [self.flat_links[0]] + genome.Genome.expandLinks(self.flat_links[0], + self.flat_links[0].name, + self.flat_links, + exp_links) + self.exp_links = exp_links + return self.exp_links + + def to_xml(self): + self.get_expanded_links() + domimpl = getDOMImplementation() + adom = domimpl.createDocument(None, "start", None) + robot_tag = adom.createElement("robot") + for link in self.exp_links: + robot_tag.appendChild(link.to_link_element(adom)) + first = True + for link in self.exp_links: + if first: # skip the root node! + first = False + continue + robot_tag.appendChild(link.to_joint_element(adom)) + robot_tag.setAttribute("name", "pepe") # choose a name! + return '' + robot_tag.toprettyxml() + + def get_motors(self): + self.get_expanded_links() + if self.motors == None: + motors = [] + for i in range(1, len(self.exp_links)): + l = self.exp_links[i] + m = Motor(l.control_waveform, l.control_amp, l.control_freq) + motors.append(m) + self.motors = motors + return self.motors