def __init__(self, file, atlas): self.root_bone = None self.bones = {} self.slots = OrderedDict() self.skins = {} self.animations = {} self.events = {} #self.to_draw = OrderedDict() self.current_skin = None if type(atlas) is str: self.atlas = Atlas(atlas) elif isinstance(atlas, Atlas): self.atlas = atlas else: raise Exception("Invalid atlas") if type(file) is str: self.load_from_json(file) else: self.load_from_file(file) # if not self.current_skin: # self.current_skin = self.skins.values()[0] self.set_skin(self.skins.keys()[0]) #self.prepare_to_draw() self.update_transform()
def calculate_atlas(self): """Calculating the "Atlas" Commences calculations and creates as many maps as chosen by the user. """ self.label_complete.grid_forget() self.progress_bar.grid(row=10, pady=10) self.progress_bar.start(10) self.Atlas = Atlas(int(self.position_entry.get()), self.start_scale.get(), self.step_scale.get(), self.end_scale.get(), self.mag_scale.get(), int(self.neighbors_entry.get())) self.Atlas.createAtlas() # print("Testing:") # print(f"Magnitude: {self.Atlas.mag_limit}") # print(f"Time Scale: From {self.Atlas.ybp_min} to {self.Atlas.ybp_max} with {self.Atlas.step_size}-year steps") # print(f"Position: {self.Atlas.latitude}°N") # print(f"Neighbors: {self.Atlas.neighbours}") self.progress_bar.stop() self.progress_bar.grid_forget() self.label_complete.grid(row=10, pady=10)
def main(): device = Atlas.AtlasI2C() # creates the I2C port object, specify the address or bus if necessary conn = sqlite3.connect('atlas.db') c = conn.cursor() ph_set_value = 6.0 ph_minus_dose = 0 ph_plus_dose = 0 ec_set_value = 0.0 ec_current = 0 ec_dose = 0 temperature_current = 0.0 controlling_down = 0 controlling_up = 0 ph_hysteresis = 0.1 control = "" i = 1 # main loop while True: start_loop_time = time.time() device.set_i2c_address(PH_SENSOR_ADDR) response = device.query("R") # Get a reading from the sensor # response is now a string of the pH value if everything is ok try: p = float(response) except: print("No pH response...") else: ph_current = p device.set_i2c_address(TEMP_SENSOR_ADDR) response = device.query("R") # Get a reading from the sensor # response is now a string of the pH value if everything is ok try: temperature_current = float(response) except: temperature_current = -273.0 if i % CONTROL_LOOP_DIVISOR == 0: # Controlling DOWN if (ph_current > (ph_set_value + ph_hysteresis)) and controlling_up == 0: # inject pH-minus by running the pump ph_minus_dose = 1 device.set_i2c_address(PH_MINUS_PUMP_ADDR) device.write("D," + str(ph_minus_dose)) time.sleep(0.5) response = device.read() controlling_down = DAMPING i = 1 control = "DOWN" #Controlling UP if (ph_current < (ph_set_value - ph_hysteresis)) and controlling_down == 0: # inject pH-plus by running the pump ph_plus_dose = 1 device.set_i2c_address(PH_PLUS_PUMP_ADDR) device.write("D," + str(ph_plus_dose)) time.sleep(0.5) response = device.read() controlling_up = DAMPING i = 1 control = "UP" print("pH= ", ph_current, "temperature= ", temperature_current," ", control) control = "" i += 1 if controlling_down > 0: controlling_down -=1 if controlling_up > 0: controlling_up -=1 current_time = time.time() # Write data to database.... c.execute('INSERT INTO pH_data VALUES (datetime("now"), ?, ?, ?, ?)', (ph_current, ph_set_value, ph_minus_dose, ph_plus_dose)) c.execute('INSERT INTO Ec_data VALUES (datetime("now"), ?, ?, ?)', (ec_current, ec_set_value, ec_dose)) c.execute('INSERT INTO temperature_data VALUES (datetime("now"), ?)', (temperature_current,)) c.execute('UPDATE temp SET createdAt = datetime("now") ,measured_pH = ?,target_pH = ?,PMP_pH_minus = ?,PMP_pH_plus = ?,measured_Ec = ?,target_Ec = ?,PMP_nutrition = ?, measured_temperature = ? WHERE rowid = 1', (ph_current, ph_set_value, ph_minus_dose, ph_plus_dose, ec_current, ec_set_value, ec_dose,temperature_current)) conn.commit() loop_time = current_time - start_loop_time # wait until we have MEASUREMENT_LOOP_TIME of seconds if loop_time < MEASUREMENT_LOOP_TIME: time.sleep(MEASUREMENT_LOOP_TIME - loop_time) conn.close()
class StarMapPage(tk.Frame): """User Map Page Where users input their own pattern. Args: location (:obj:`tk.Frame`): "Master"-Frame into which the frame is loaded. controller (:obj:`class`): Controller-class in which the frame-switching function is defined. """ def __init__(self, location, controller): self.c_background = '#04003F' #: Background color of the frame. self.c_label = "#04003F" #: Text color of the labels self.c_button = "#06005D" #: Background color of the buttons self.c_text = "white" #: Text color of the buttons tk.Frame.__init__(self, location, bg=self.c_background) # Magnitude group self.mag_scale = tk.Scale(self, label='Magnitude', from_=1.0, to=6.5, resolution=0.5, orient='horizontal') self.mag_scale.set(4.5) self.mag_scale.grid(row=1, pady=20) # Timescale group self.timescale = tk.Label(self, text='Timescale', bg=self.c_label, fg=self.c_text) self.start_scale = tk.Scale(self, label='Initial Year (ybp)', from_=0, to=60000, resolution=1000, orient='horizontal', command=self.update_start) self.end_scale = tk.Scale(self, label='Final Year (ybp)', from_=0, to=60000, resolution=1000, orient='horizontal', command=self.update_end) self.end_scale.set(60000) self.step_scale = tk.Scale(self, label='Step Size', from_=500, to=60000, resolution=500, orient='horizontal') # Geographical position group self.position = tk.Label(self, text='Position in °N (int)', bg=self.c_label, fg=self.c_text) vpos = (self.register(self.validate_latitude), "%P") self.position_entry = tk.Entry(self, validate="key", validatecommand=vpos) # Number of neighbours group self.neighbors = tk.Label( self, text='Number of nearest neighbours for each star to check', bg=self.c_label, fg=self.c_text) vnei = (self.register(self.validate_neighbors), "%P") self.ngh = tk.StringVar() self.ngh.set(100) self.neighbors_entry = tk.Entry(self, validate="key", validatecommand=vnei, textvariable=self.ngh) # Progress bar self.progress_bar = ttk.Progressbar(self, orient='horizontal', length=100, mode='indeterminate') self.label_complete = tk.Label(self, text='Complete!', fg='green') button_start = tk.Button(self, text="Start", command=self.commence, bg=self.c_button, fg=self.c_text) # button_stop = tk.Button(self, text="Stop", command=self.stop_calculations.set) # button_stop.grid(row=12, pady=5) self.timescale.grid(row=2) self.start_scale.grid(row=3) self.end_scale.grid(row=4) self.step_scale.grid(row=5) self.position.grid(row=6, pady=(20, 0)) self.position_entry.grid(row=7) self.neighbors.grid(row=8, pady=(20, 0)) self.neighbors_entry.grid(row=9) button_start.grid(row=11, pady=5) self.grid_columnconfigure(0, weight=1) def menubar(self, root): """Defines the menu bar. Is repeated accordingly on other pages. Returns: :obj:`tk.Menu`: Returns a tk-object because function does not draw menubar itself. Drawing happens in App-class. """ menubar = tk.Menu(root) menubar.add_command(label="Star Map") pagemenu = tk.Menu(menubar, tearoff=0) pagemenu.add_command(label="Start Page", command=lambda: root.show_frame('StartPage')) pagemenu.add_command(label="User Map", command=lambda: root.show_frame('UserMapPage')) pagemenu.add_command(label="Astrolabe", command=lambda: root.show_frame('AstrolabePage')) menubar.add_cascade(label='Pages', menu=pagemenu) return menubar def commence(self): """A separate "commence" function is needed to check conditions and intialize threading """ if (self.position_entry.get() == ""): messagebox.showwarning( "Missing Latitude", "Please input a position between 0°N and 90°N") elif (int(self.neighbors_entry.get()) > 100): neighbors_warning = messagebox.askyesno( "Large Number", "The number of nearest neighbours you set may result in excessively large file sizes and little additional benefit over a value of 100. Continue?" ) if neighbors_warning is True: Thread(target=self.calculate_atlas).start() else: total_size = int((self.end_scale.get() - self.start_scale.get()) / (self.step_scale.get() + 1) * 150 + 150) # print(total_size) start = messagebox.askyesno( "Commence?", f"Start the calculated with the parameters specified? Calculations may take several minutes to complete. \nThe total file size may be {total_size} MB or more. Make sure enough space is available." ) if start is True: # Threading is needed to have the progress bar work Thread(target=self.calculate_atlas).start() def calculate_atlas(self): """Calculating the "Atlas" Commences calculations and creates as many maps as chosen by the user. """ self.label_complete.grid_forget() self.progress_bar.grid(row=10, pady=10) self.progress_bar.start(10) self.Atlas = Atlas(int(self.position_entry.get()), self.start_scale.get(), self.step_scale.get(), self.end_scale.get(), self.mag_scale.get(), int(self.neighbors_entry.get())) self.Atlas.createAtlas() # print("Testing:") # print(f"Magnitude: {self.Atlas.mag_limit}") # print(f"Time Scale: From {self.Atlas.ybp_min} to {self.Atlas.ybp_max} with {self.Atlas.step_size}-year steps") # print(f"Position: {self.Atlas.latitude}°N") # print(f"Neighbors: {self.Atlas.neighbours}") self.progress_bar.stop() self.progress_bar.grid_forget() self.label_complete.grid(row=10, pady=10) # These two update functions are needed to adjust the BP-sliders in real time and make sure only logical conditions can be set def update_start(self, val): """Timeframe sanity check update_start and update_end functions are needed to adjust the BP-sliders in real time and make sure only logical conditions can be set. Args: val (int): Current value of the slider. """ self.end_scale.config(from_=val) year_diff = self.end_scale.get() - int(val) self.step_scale.config(to=year_diff) if (year_diff == 0): self.step_scale.config(from_=0) def update_end(self, val): """Timeframe sanity check update_start and update_end functions are needed to adjust the BP-sliders in real time and make sure only logical conditions can be set. Args: val (int): Current value of the slider. """ self.start_scale.config(to=val) year_diff = int(val) - self.start_scale.get() self.step_scale.config(to=year_diff) if (year_diff == 0): self.step_scale.config(from_=0) def validate_latitude(self, input): """Validate latitude Real-time validation of the input field for the latitude. Makes sure that neither non-numeric characters nor values over 90 can be entered. """ if input.isnumeric() and int(input) <= 90 or input == "": return True else: return False def validate_neighbors(self, input): """Validate number of neighbors Real-time validation of the input field for the neighbors. Makes sure that neither non-numeric characters nor values over 5000 can be entered. """ if input.isnumeric() and int(input) <= 5000 or input == "": return True else: return False
class Skeleton_Data(object): def __init__(self, file, atlas): self.root_bone = None self.bones = {} self.slots = OrderedDict() self.skins = {} self.animations = {} self.events = {} #self.to_draw = OrderedDict() self.current_skin = None if type(atlas) is str: self.atlas = Atlas(atlas) elif isinstance(atlas, Atlas): self.atlas = atlas else: raise Exception("Invalid atlas") if type(file) is str: self.load_from_json(file) else: self.load_from_file(file) # if not self.current_skin: # self.current_skin = self.skins.values()[0] self.set_skin(self.skins.keys()[0]) #self.prepare_to_draw() self.update_transform() def update_transform(self): self.root_bone.update_childs() for slot in self.slots.itervalues(): bone = slot.bone #print bone.name, bone.rotation attach_to_draw = slot.to_draw attach_data = self.current_skin.get_attachment(slot.name, slot.attachment) #print slot.name, slot.attachment, attach_data if slot.to_draw: #slot.to_draw.debug = True #attach_data = attach.attachment_data # x, y = attach.position # bx, by = bone.position # attach.position = (x+bx, y+by) # attach.rotation += bone.rotation par_tsr = bone.global_tsr #print bone.global_tsr, bone.name new_tsr = attach_data.tsr.tsr_transform(par_tsr) #if slot.name == "R_wing": #print attach_data.name, attach_data.tsr #print slot.bone.global_tsr #print new_tsr #print attach_to_draw.get_rect() #child_tsr = (attach_data.position, attach_data.scale_x, attach_data.scale_y, attach_data.rotation) attach_to_draw.set_tsr_by_named_pack(new_tsr) #print attach.attachment_data.name, attach.rotation #attach.rotation *= -1 def set_skin(self, skin_name): if not self.current_skin or self.current_skin.name is not skin_name: self.current_skin = self.skins[skin_name] self.prepare_to_draw() # for slot in self.slots.itervalues(): # #print slot.name, slot.attachment # attach = self.current_skin.get_attachment(slot.name, slot.attachment) # if slot.name == "right hand item 2": # print "!!!!", attach.texture_name # if attach: # #print self.current_skin.name, attach.name # self.set_attachment(slot, attach.name) # else: # slot.to_draw = None def prepare_to_draw(self): # for slot_name, slot in self.slots.items(): # attach = self.current_skin.get_attachment(slot_name, slot.attachment) # if attach: # image = self.atlas.get_attachment_region(attach.texture_name) # slot.set_attachment(image, attach) for slot in self.slots.itervalues(): #print slot.name, slot.attachment attach = self.current_skin.get_attachment(slot.name, slot.attachment) #if slot.name == "right hand item 2": #print "!!!!", attach if attach: #print self.current_skin.name, attach.name self.set_attachment(slot, attach.name) else: slot.to_draw = None #print slot.attachment.position def load_from_json(self, file): if file: with open(file) as fp: data = json.load(fp) self.load_bones(data['bones']) if 'slots' in data: self.load_slots(data['slots']) if 'skins' in data: self.load_skins(data['skins']) if 'events' in data: self.load_events(data['events']) if 'animations' in data: self.load_animations(data['animations']) else: pass def load_from_file(self, data): self.load_bones(data['bones']) self.load_slots(data['slots']) self.load_skins(data['skins']) self.load_animations(data['animations']) def load_bones(self, bones): for bone in bones: if self.root_bone: parent_name = bone['parent'] bone['parent'] = self.bones[parent_name] new_bone = Bone.Bone(**bone) self.bones[bone['name']] = new_bone self.bones[parent_name].add_bone(new_bone) bone['parent'] = parent_name else: self.root_bone = Bone.Bone(**bone) self.bones[bone['name']] = self.root_bone self.bones[bone['name']].apply_bone_data() def load_slots(self, slots): for slot in slots: slot_bone_name = slot['bone'] slot['bone'] = self.bones[slot_bone_name] self.slots[slot['name']] = Slot.Slot(**slot) self.slots[slot['name']].apply_slot_data() slot['bone'] = slot_bone_name def load_skins(self, skins): for skin_name, skin in skins.items(): new_skin = Skin.Skin(skin_name) self.skins[skin_name] = new_skin #if skin_name == 'default': # self.current_skin = new_skin for slot_name, attachments in skin.items(): for attach_name, attach in attachments.items(): #attach['image'] = self.atlas.get_attachment_region(attach_name) if 'type' not in attach: attach_type = 'region' else: attach_type = attach['type'] if attach_type == 'region': if 'name' not in attach: attach['name'] = attach_name attach['texture_name'] = attach_name attach_data = Attachment.Attachment(**attach) new_skin.add_attachment(slot_name, attach_name, attach_data) else: data_attach_name = attach['name'] attach['texture_name'] = data_attach_name attach['name'] = attach_name attach_data = Attachment.Attachment(**attach) new_skin.add_attachment(slot_name, attach_name, attach_data) attach['name'] = data_attach_name elif attach_type == 'regionsequence': print "Warning: unsupported attachment type regionsequence" elif attach_type == 'boundingbox': print "Warning: unsupported attachment type boundingbox" else: print "Error: unknown attachment type" def load_events(self, events): for event_name, event in events: event_int = event['int'] if 'int' in event else 0 event_float = event['float'] if 'float' in event else 0 event_string = event['string'] if 'string' in event else "" self.events[event_name] = Event(event_int, event_float, event_string) def load_animations(self, animations): for animation in animations: loaded_animation = Animation(animation, animations[animation]) self.animations[animation] = loaded_animation loaded_animation.apply_bones_and_slots_data(self) def set_attachment(self, slot, attachment_name): #print attachment_name #print self.current_skin.attachments attach = self.current_skin.get_attachment(slot.name, attachment_name) #print attachment_name image = self.atlas.get_attachment_region(attach.texture_name) slot.attachment = attach.name if slot.to_draw: slot.to_draw.set_new_attachment(image, attach) else: #print "LOLOLO", attach.name slot.to_draw = Attachment.Sprite_Attachment(image, attach) def find_animation(self, animation_name): return self.animations[animation_name]