예제 #1
0
class AvionicsLogger(KRCCModule):
    def __init__(self, root):
        super().__init__()
        self.root = root
        self.exception = None

        self.list_string = StringVar()
        self.listbox = Listbox(root,
                               listvariable=self.list_string,
                               font='TkFixedFont',
                               width=30)

        self.write_cache = ''
        self.logfile = None
        self.enable_logging = BooleanVar()
        self.enable_logging_checkbox = Checkbutton(
            root,
            var=self.enable_logging,
            text='Enable logging',
            command=self.enable_logging_changed)

        self.logfile_label = Label(root, text='Logfile name:')
        self.logfile_name = StringVar()
        self.logfile_name_entry = Entry(root, textvar=self.logfile_name)

        self.load()

    def write(self, string):
        if self.enable_logging.get() and self.logfile is None:
            if self.logfile_name.get() == '':
                self.logfile_name.set('logs/{}.log'.format(time.time()))
            self.logfile = io.open(self.logfile_name.get(), 'a')
            self.logfile.write(self.write_cache)
            self.write_cache = ''
        self.logfile.write(string)

    def cache(self, string):
        self.write_cache += string

    def enable_logging_changed(self):
        if not self.enable_logging.get():
            self.logfile_name_entry.configure(state=NORMAL)
            if self.logfile is not None:
                self.logfile.close()
                self.logfile = None
                self.logfile_name.set('')
        else:
            self.logfile_name_entry.configure(state=DISABLED)

    def establish_connection_and_run(self):
        error = None
        dots = 0
        connection = None
        while not self.terminate:
            try:
                if connection is None:
                    connection = krpc.connect(name=self.name)
                self.run_with_connection(connection)
                error = None
                dots = 0
            except Exception as e:
                if error != e.args[0]:
                    error = e.args[0]
                    print('\n')
                    print(traceback.format_exc())
                    sys.stdout.write('Retrying')
                if dots > 80:
                    dots = 0
                    sys.stdout.write('\n')
                sys.stdout.write('.')
                dots += 1
                sys.stdout.flush()
                time.sleep(1)
        if connection is not None:
            connection.close()

    def run_with_connection(self, connection):
        logging.debug('KRPC connection established')
        vessel = connection.space_center.active_vessel
        ref = vessel.orbit.body.reference_frame
        flight = connection.add_stream(vessel.flight, ref)
        floats = [
            'mean_altitude',
            'atmosphere_density',
            'ballistic_coefficient',
            'drag_coefficient',
        ]
        vectors = [
            'velocity',
        ]
        colon_pos_float = max([len(v) for v in floats])
        colon_pos_vec = max([len(v) + 3 for v in vectors])
        self.listbox.configure(width=max(colon_pos_float, colon_pos_vec) + 11)

        # Write the log file header.
        self.cache('time\t' + '\t'.join(floats) + '\t')
        s = '{}\t' + '\t'.join('{{}}[{}]'.format(x) for x in [0, 1, 2])
        self.cache('\t'.join(
            s.format(*(v for _ in [0, 1, 2, 3])) for v in vectors))
        self.cache('\n')
        log_sample_interval = 0.01
        next_log_sample = time.time()
        while not self.terminate:
            values = [time.time()]
            strings = []
            for name in floats:
                value = flight().__getattribute__(name)
                values.append(value)
                padding = colon_pos_float - len(name) + 9
                format_string = '{{}}: {{:>{}.3f}}'.format(padding)
                strings.append(format_string.format(name, value))
            for name in vectors:
                value = flight().__getattribute__(name)
                magnitude = value[0]
                padding = colon_pos_float - len(name) + 9
                format_string = '{{}}: {{:>{}.3f}}'.format(padding)
                strings.append(format_string.format(name, magnitude))
                values.append(magnitude)
                padding = colon_pos_vec - len(name) + 2
                format_string = '{{}}[{{}}]: {{:>{}.3f}}'.format(padding)
                for i in [0, 1, 2]:
                    values.append(value[i])
                    strings.append(format_string.format(name, i, value[i]))
            if self.enable_logging.get() and time.time() > next_log_sample:
                self.write('\t'.join(['{}'.format(v) for v in values]) + '\n')
                next_log_sample = time.time() + log_sample_interval
            self.list_string.set(tuple(strings))

    def run(self):
        try:
            self.establish_connection_and_run()
            self.logfile_name_entry.destroy()
            self.logfile_label.destroy()
            self.enable_logging_checkbox.destroy()
            self.listbox.destroy()
        except RuntimeError:
            # Should only happen when KeyboardInterrupt is thrown in the MainThread.
            pass
        if self.logfile is not None:
            self.logfile.close()

    @property
    def name(self):
        return 'Avionics Logger'

    def load(self):
        self.listbox.pack(side=LEFT, fill=BOTH)
        self.logfile_label.pack(side=LEFT, anchor=NW)
        self.logfile_name_entry.pack(side=LEFT, anchor=NE, fill=X, expand=True)
        self.enable_logging_checkbox.pack(side=LEFT, anchor=NW)
예제 #2
0
        class A_DWI:
            def __init__(self, container, frame, label='', text='', row=0, column=0):
                self.container = container
                self.is_b0 = BooleanVar(container.parent)
                self.is_dw = BooleanVar(container.parent)
                self.column = column
                self.direction = StringVar(container.parent)

                self.label_from = Label(frame, text='from')
                self.text_from = Entry(frame)
                self.text_from.insert(0, text)
                self.button_file_from = Button(frame, text='...', command=lambda:filenameDialog_text(self.text_from))
                self.button_rm = Button(frame, text='remove', command=self.click_remove)
                self.radio_ap = Radiobutton(frame, text='AP', variable=self.direction, value='AP', command=self.set_direction)
                self.radio_pa = Radiobutton(frame, text='PA', variable=self.direction, value='PA', command=self.set_direction)

                self.label_to = Label(frame, text='to')
                self.text_to = Entry(frame)
                #self.text_to.insert(0, text)
                self.button_file_to = Button(frame, text='Gen', command=self.set_filename_to)
                self.check_b0 = Checkbutton(frame, text='B0',   variable=self.is_b0)
                self.check_dw = Checkbutton(frame, text='DWI',  variable=self.is_dw)

                self.button_up = Button(frame, text='up', width=3, command=self.click_up)
                self.button_dn = Button(frame, text='down', width=3, command=self.click_dn)

                self.row = -1
                self.change_row(row)
                if text != '':
                    self.set_appa()
                    self.set_filename_to()

            def prefix(self):
                return self.container.parent.prefix()

            def set_direction(self):
                pass

            def get_dwi_filenames(self):
                '''
                :return: [('from', 'to'), ('from', 'to')]
                '''
                filename_from = self.text_from.get()
                filename_to = self.text_to.get()
                if self.is_dw.get():
                    rtn = [ [filename_from, filename_to] ]
                    filename_b_from = filename_wo_ext(filename_from)
                    filename_b_to = filename_wo_ext(filename_to)
                    rtn.append( [filename_b_from+'.bval', filename_b_to+'.bval'] )
                    rtn.append( [filename_b_from+'.bvec', filename_b_to+'.bvec'] )
                    return rtn
                return []

            def get_b0_filename(self):
                '''
                :return: [('from', 'to')]
                '''
                filename_from = self.text_from.get()
                filename_to = self.text_to.get()
                ext = extname(filename_to)
                if self.is_b0.get():
                    if self.is_dw.get():
                        filename_to = '%s_B0%s' % (filename_wo_ext(filename_to), ext)
                    return [ [filename_from, filename_to] ]
                return []

            def set_appa(self):
                filename_from = self.text_from.get()
                basename_from = os.path.basename(filename_from)
                basename_b_from = filename_wo_ext(basename_from)
                if 'pa' in basename_b_from.lower():
                    self.direction.set('PA')
                elif 'ap' in basename_b_from.lower():
                    self.direction.set('AP')
                else:
                    pass

            def set_filename_to(self, middle=None):
                filename_from = self.text_from.get()
                basename_from = os.path.basename(filename_from)
                number = os.path.dirname(filename_from).split('/')[-1].split('_')[0]
                if number == '':
                    number = str(self.row)
                else:
                    try:
                        int(number)
                    except:
                        number = str(self.row)


                ext = extname(basename_from)
                intermediate = self.direction.get()
                if intermediate == '':
                    intermediate = 'DWI'

                if self.is_b0.get() and not self.is_dw.get():
                    intermediate += '_B0'

                self.text_to.delete(0, len(self.text_to.get()))
                self.text_to.insert(0, '%s%s_%s%s' % (self.prefix(), number, intermediate, ext))

            def change_row(self, row):
                if self.row == row:
                    return
                self.row = row
                i = 2*row
                j = self.column
                j += 0; self.button_up.grid(row=i, column=j)
                j += 1; self.label_from.grid(row=i, column=j)
                j += 1; self.text_from.grid(row=i, column=j, sticky=EW)
                j += 1; self.button_file_from.grid(row=i, column=j)
                j += 1; self.button_rm.grid(row=i, column=j)
                j += 1; self.radio_ap.grid(row=i, column=j)
                j += 1; self.radio_pa.grid(row=i, column=j)
                i += 1
                j = 0
                j += 0; self.button_dn.grid(row=i, column=j)
                j += 1; self.label_to.grid(row=i, column=j)
                j += 1; self.text_to.grid(row=i, column=j, sticky=EW)
                j += 1; self.button_file_to.grid(row=i, column=j)
                j += 1
                j += 1; self.check_b0.grid(row=i, column=j)
                j += 1; self.check_dw.grid(row=i, column=j)

            def click_remove(self):
                self.container.remove(self.row)

                self.button_up.destroy()
                self.label_from.destroy()
                self.text_from.destroy()
                self.button_file_from.destroy()
                self.button_rm.destroy()
                self.radio_ap.destroy()
                self.radio_pa.destroy()
                self.button_dn.destroy()
                self.label_to.destroy()
                self.text_to.destroy()
                self.button_file_to.destroy()
                self.check_b0.destroy()
                self.check_dw.destroy()

            def click_up(self):
                self.container.up(self.row)
            def click_dn(self):
                self.container.dn(self.row)