class DashieSampler: def __init__(self, app, interval): self._app = app self._timer = RepeatedTimer(interval, self._sample) def stop(self): self._timer.stop() def start(self): self._timer.start() def name(self): """ Child class implements this function """ return "UnknownSampler" def sample(self): """ Child class implements this function """ return {} def _send_event(self, widget_id, body): body["id"] = widget_id body["updatedAt"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S +0000") formatted_json = "data: %s\n\n" % (json.dumps(body)) self._app.last_events[widget_id] = formatted_json for event_queue in self._app.events_queue.values(): event_queue.put(formatted_json) def _sample(self): data = self.sample() if data: self._send_event(self.name(), data)
def start_asteroid_creation_timer(ai_settings, screen, stats, sb, ship, asteroids): if stats.level >= stats.MIN_HARD_LEVEL: timer = RepeatedTimer( ai_settings.base_asteroids_timer_interval / stats.level, create_asteroid, ai_settings, screen, asteroids, ) timer.start() return timer return None
class DashieSampler: def __init__(self, app, interval): self._app = app self._timer = RepeatedTimer(interval, self._sample) def stop(self): self._timer.stop() def start(self): self._timer.start() def name(self): ''' Child class implements this function ''' return 'UnknownSampler' def sample(self): ''' Child class implements this function ''' return {} def _send_event(self, widget_id, body): body['id'] = widget_id body['updatedAt'] = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S +0000') formatted_json = 'data: %s\n\n' % (json.dumps(body)) self._app.last_events[widget_id] = formatted_json for event_queue in self._app.events_queue.values(): event_queue.put(formatted_json) def _sample(self): data = self.sample() if data: self._send_event(self.name(), data)
class HandCockpit: MIN_VALUE = 0 MAX_VALUE = 1 INITIAL_SET = 0 SCAN_INTERVAL_SEC = 0.1 # 操作対象用インデックス WAIST = 0 # 左右に回転する部分 BOOM = 1 # 台座から伸びる部分。left servo ARM = 2 # boomからcrawまでの部分。right servo CRAW = 3 # バケットに相当する部分。先端の爪 # 物理的な可動範囲[min, max] 0〜180の範囲内であること # サンプルを参考にする # see: https://www.mearm.com/blogs/news/74739717-mearm-on-the-raspberry-pi-work-in-progress RANGE = ( (0, 180), # waist (60, 165), # boom (40, 180), # arm (60, 180), # craw ) # コントローラーの感度係数 SENSITIVITY = ( -50.0, # waist -50.0, # boom 50.0, # arm 50.0, # craw ) # 定義済み位置(WAIST, BOOM, ARM, CRAW) 0〜180の範囲 PRESET = ( (90, 112, 90, 60), # initial position (20, 30, 40, 50), # topキー用 ) def __init__(self, controller, pad): # initial servo position self.position = list(HandCockpit.PRESET[HandCockpit.INITIAL_SET]) # controllerはapplyメソッドを持っている必要がある self.controller = controller self.pad = pad self.lastUpdateAt = time.time() self.isStartedAxisScanThread = False self.isEnabledDebugPad = True # 初期位置設定 self._apply() def update(self, powerList, delay): for index in self.controller.getIndexes(): self.position[index] += powerList[index] * delay * HandCockpit.SENSITIVITY[index] if self.position[index] < HandCockpit.RANGE[index][HandCockpit.MIN_VALUE]: self.position[index] = HandCockpit.RANGE[index][HandCockpit.MIN_VALUE] elif self.position[index] > HandCockpit.RANGE[index][HandCockpit.MAX_VALUE]: self.position[index] = HandCockpit.RANGE[index][HandCockpit.MAX_VALUE] self._apply() def usePreset(self, number): self.position = list(HandCockpit.PRESET[number]) self._apply() def _apply(self): self.controller.apply(self.position) def startAxisScanThread(self): pygame.event.set_blocked(pygame.JOYAXISMOTION) self.axisScanThread = RepeatedTimer(HandCockpit.SCAN_INTERVAL_SEC, self.scanAxis) self.axisScanThread.start() self.isStartedAxisScanThread = True def stopAxisScanThread(self): if True == self.isStartedAxisScanThread: self.isStartedAxisScanThread = False self.axisScanThread.cancel() pygame.event.set_blocked(None) def scanAxis(self): now = time.time() delay = now - self.lastUpdateAt self.lastUpdateAt = now x1 = self.pad.getAnalog(PS3PadPygame.L3_AX) y1 = self.pad.getAnalog(PS3PadPygame.L3_AY) x2 = self.pad.getAnalog(PS3PadPygame.R3_AX) y2 = self.pad.getAnalog(PS3PadPygame.R3_AY) if self.isEnabledDebugPad: log = ('delay: %.3f, x1: %.3f, y1: %.3f, x2: %.3f, y2: %.3f' % (delay, x1, y1, x2, y2)) print log # バックホーの操作レバー割当はJIS方式だと以下のようになっている # (左レバー) (右レバー) # アーム伸ばし ブーム下げ # 左旋回 ○ 右旋回 バケット掘削 ○ バケット開放 # アーム曲げ ブーム上げ # よってバケットをクローに置き換えて # (WAIST, BOOM, ARM, CRAW)の順に整理する self.update((x1, y1, y2, x2), delay) def consumeEvents(self): events = self.pad.getEvents() # print 'events: ' + str(len(events)) for e in events: if e.type == pygame.locals.JOYBUTTONDOWN: if self.pad.isPressed(PS3PadPygame.START): print 'start button pressed. exit.' return False elif self.pad.isPressed(PS3PadPygame.TOP): # pre-set 1 print 'top button pressed.' self.usePreset(1) elif self.pad.isPressed(PS3PadPygame.CIRCLE): self.switchDebugPad() elif self.pad.isPressed(PS3PadPygame.BOX): self.controller.switchDebugPosition() elif False == self.isStartedAxisScanThread and e.type == pygame.locals.JOYAXISMOTION: self.scanAxis() return True def switchDebugPad(self): self.isEnabledDebugPad = not self.isEnabledDebugPad
tlc_serial = oasis_serial.OasisSerial("/dev/ttyS2", debug_mode=DEBUG_MODE, debug_tx_port=TLC_TX_PORT, debug_rx_port=TLC_RX_PORT) tlc = TLC(tlc_serial) rover = roverio.Rover(packet_manager, fm) laser = laserio.Laser(oasis_serial=rover_serial) spectrometer = spectrometerio.Spectrometer(serial=rover_serial, file_manager=fm) def log_timer_callback(): """This is the callback function that repeatedly logs the current status to the status log.""" status_array = rover.get_status_array(laser.states_laser, spectrometer.states_spectrometer, tlc.get_temperatures(), tlc.get_duty_cycles(), active_errors, past_two_commands[1]) fm.log_status(status_array, 0) log_data_timer = RepeatedTimer(LOGGING_INTERVAL, log_timer_callback) log_data_timer.start() while True: main_loop() packet_manager.running = False
class BettingDisplay(): def __init__(self, parent, meeting): self.parent = parent self.display_type = 'odds' self.date = datetime.date.today().strftime("%Y-%m-%d") #Currently will need to be restarted each day self.meeting = meeting #PLACEHOLDER self.schedule = Schedule(self.date, self.meeting) self.races = self.schedule.meetings[0].races self.next_race = None self.set_next_race() self.odds_var = StringVar() self.title_var = StringVar() self.dets_var = StringVar() self.build_display() self.start_timer() print("STARTED SUCCESSFULLY") def set_next_race(self): next_race = None found = False for race in self.races: cur_time = int(datetime.datetime.now().strftime("%H%M%S")) race_time = int(re.sub('[:]', '', race.time)) if race_time > cur_time and not found: next_race = race found = True if next_race is not self.next_race: self.next_race = next_race def start_timer(self): self.threading_timer = RepeatedTimer(3, self.refresh) self.threading_timer.start() def refresh(self): if self.display_type == 'odds': self.set_next_race() self.next_race.load_odds() #---TEMP---# horse_nums = ['']*20 for i in range(min(20, len(self.next_race.entries))): horse_nums[i] = str(self.next_race.entries[i].number) horse_names = ['']*20 for i in range(min(20, len(self.next_race.entries))): horse_names[i] = str(self.next_race.entries[i].name) win_odds = ['']*20 for i in range(min(20, len(self.next_race.entries))): win_odds[i] = str(self.next_race.entries[i].odds_win) lst = horse_nums + horse_names + win_odds odds_str = TEST_TEMPLATE.format(lst) title_str = TITLE_TEMPLATE.format(name=self.next_race.name) dets_str = TIME_TEMPLATE.format(time=self.next_race.time, venue=self.next_race.meeting.venue, meet_no=self.next_race.meeting.number, country=self.next_race.meeting.country) self.title_var.set(title_str) self.dets_var.set(dets_str) self.odds_var.set(odds_str) #---TEMP END---# elif self.display_type == 'test': self.title_var.set('test') self.dets_var.set('') self.odds_var.set('') def build_display(self): #----TEMP---- self.cur_race_name = StringVar() self.cur_race_time = StringVar() self.title_text = Label(self.parent, fg="white", bg="black", font=("Courier", 40, "bold"), textvariable=self.title_var) self.title_text.place(relx = 0.5, rely = 0, anchor=N, height = 80, width=1100) self.dets_text = Label(self.parent, textvariable=self.dets_var, fg="white", bg="black", font=("Courier", 20, "bold")) self.dets_text.place(relx = 0.5, y = 80, anchor=N, height = 30, width=1100) self.odds_text = Label(self.parent, textvariable=self.odds_var, fg="white", bg="black", font=("Courier", 20, "bold")) self.odds_text.place(relx = 0.5, y = 110, anchor=N, width=1100, height = 600) self.quitbutton = Button(self.parent, text='quit', command=self.quitclick) self.quitbutton.place(relx = 0.5, rely = 1, anchor=S) #---TEMP END ---# def quitclick(self): self.threading_timer.stop() self.parent.destroy()
class OpenSlides(tk.Tk): cmd_runner = None server_running = False gui_settings_path = None gui_initialized = False backupdb_enabled = False backupdb_destination = "" backupdb_interval = 15 backupdb_interval_unit = "minutes" last_backup = None backup_timer = None _host = "0.0.0.0" _port = "8000" def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) tk.Tk.title(self, 'OpenSlides') tk.Tk.resizable(self, width=False, height=False) self.protocol('WM_DELETE_WINDOW', self.on_close_app) self.root = tk.Frame(self, bg=self.cget('bg')) self.root.pack(side="top", fill="both", expand = True) self.btn_settings = None self.btn_db_backup = None self.btn_sync_db = None self.btn_reset_admin = None self.chb_auto_svr = None self.btn_server = None self.backup_timer = RepeatedTimer(self.on_backup_timer) self.lbl_host = None self.lbl_port = None if not self.initialize_gui(): self.quit() self.createMenuBar() self.createMainframe() def initialize_gui(self): # Set path for gui settings to default user data according to the # OpenSlides type. This does not depend on any argument the user might # type in. openslides_type = detect_openslides_type() try: default_user_data_path = get_default_user_data_path(openslides_type) except PortableDirNotWritable: messagebox.showerror( _("Error: Portable directory not writable"), _("The portable directory is not writable. Please copy the " "openslides portable to a writeable location and start it " "again from there") ) return False self.gui_settings_path = os.path.join( default_user_data_path, 'openslides', 'gui_settings.json') self.load_gui_settings() self.apply_backup_settings() return True def load_gui_settings(self): if self.gui_settings_path is None: return try: f = open(self.gui_settings_path, "r", encoding="utf-8") except IOError as e: if e.errno == errno.ENOENT: return raise with f: settings = json.load(f) def setattr_unless_none(attr, value): if not value is None: setattr(self, attr, value) backup_settings = settings.get("database_backup", {}) setattr_unless_none("backupdb_enabled", backup_settings.get("enabled")) setattr_unless_none( "backupdb_destination", backup_settings.get("destination")) setattr_unless_none( "backupdb_interval", backup_settings.get("interval")) setattr_unless_none( "backupdb_interval_unit", backup_settings.get("interval_unit")) last_backup = backup_settings.get("last_backup") if not last_backup is None: self.last_backup = datetime.datetime.strptime( last_backup, "%Y-%m-%d %H:%M:%S") server_settings = settings.get("server_settings", {}) setattr_unless_none("_host", server_settings.get("host")) setattr_unless_none("_port", server_settings.get("port")) def save_gui_settings(self): if self.last_backup is None: last_backup = None else: last_backup = self.last_backup.strftime("%Y-%m-%d %H:%M:%S") settings = { "database_backup": { "enabled": self.backupdb_enabled, "destination": self.backupdb_destination, "internal": self.backupdb_interval, "interval_unit": self.backupdb_interval_unit, "last_backup": last_backup }, "server_settings": { "host": self.host, "port": self.port, }, } dp = os.path.dirname(self.gui_settings_path) if not os.path.exists(dp): os.makedirs(dp) with open(self.gui_settings_path, "w", encoding="utf-8") as f: json.dump(settings, f, ensure_ascii=False, indent=4) def createMenuBar(self): menubar = tk.Menu(self) appmenu = tk.Menu(menubar, name='apple') menubar.add_cascade(menu=appmenu) appmenu.add_command(label='About OpenSlides', command=self.about_dialog) appmenu.add_separator() self['menu'] = menubar def createMainframe(self): button_frame = ttk.Frame(self.root) button_frame.grid(row=0, column=1, sticky='WENS') lfb = ttk.LabelFrame(button_frame, text='Actions') lfb.pack() self.btn_db_backup = ttk.Button(lfb, text="Backup databse...", command=self.db_backup_dialog) self.btn_db_backup.grid(row=0, column=1, sticky='WENS') self.btn_sync_db = ttk.Button(lfb, text="Sync databse", command=self.on_sync_database) self.btn_sync_db.grid(row=1, column=1, sticky='WENS') self.btn_reset_admin = ttk.Button(lfb, text="Reset admin", command=self.on_reset_admin) self.btn_reset_admin.grid(row=2, column=1, sticky='WENS') settings_frame = ttk.Frame(self.root) settings_frame.grid(row=0, column=0, sticky='WENS') lf = ttk.LabelFrame(settings_frame, text='Server Settings') lf.pack() self.lbl_host = ttk.Label(lf, text=_("Host: {0}").format(self.host)) self.lbl_host.grid(row=0, column=0, sticky='W') self.lbl_port = ttk.Label(lf, text=_("Port: {0}").format(self.port)) self.lbl_port.grid(row=0, column=1, sticky='W') self.btn_settings = ttk.Button(lf, text="Settings", command=self.settings_dialog) self.btn_settings.grid(row=0, column=4) self.auto_start_svr = tk.BooleanVar() self.auto_start_svr.set(True) self.chb_auto_svr = ttk.Checkbutton(lf, text='Automatically open browser', variable=self.auto_start_svr, onvalue=True, offvalue=False) self.chb_auto_svr.grid(row=1) self.btn_server = ttk.Button(lf, text="Start Server", command=self.on_start_server) self.btn_server.grid(row=2, columnspan=5, sticky='NSEW') text_frame = ttk.Frame(self.root) text_frame.grid(row=1, columnspan=2) lft = ttk.LabelFrame(text_frame, text='Server Logs') lft.pack() xscrollbar = ttk.Scrollbar(lft, orient=tk.HORIZONTAL) xscrollbar.grid(row=1, column=0, sticky=tk.N+tk.S+tk.E+tk.W) yscrollbar = ttk.Scrollbar(lft) yscrollbar.grid(row=0, column=1, sticky=tk.N+tk.S+tk.E+tk.W) text = TextControl(lft, wrap=tk.NONE, state='disabled', xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set) text.grid(row=0, column=0) xscrollbar.config(command=text.xview) yscrollbar.config(command=text.yview) self.root.bind("<<EVT_CMD_START>>", self.on_cmd_start) self.root.bind("<<EVT_CMD_STOP>>", self.on_cmd_stop) self.cmd_runner = CommandRunner(text.append_message, self.root) @property def host(self): return self._host @host.setter def host(self, host): self._host = host self.lbl_host.config(text=_("Host: {0}").format(host)) @property def port(self): return self._port @port.setter def port(self, port): self._port = port self.lbl_port.config(text=_("Port: {0}").format(port)) @property def backup_interval_seconds(self): factor = 0 if self.backupdb_interval_unit == "seconds": factor = 1 elif self.backupdb_interval_unit == "minutes": factor = 60 elif self.backupdb_interval_unit == "hours": factor = 3600 return self.backupdb_interval * factor def db_backup_dialog(self): dialog = DbBackupDialog(self.root, enabled=self.backupdb_enabled, destination=self.backupdb_destination, interval=self.backupdb_interval, interval_unit=self.backupdb_interval_unit) if dialog.result: self.backupdb_enabled = dialog.result['enabled'] self.backupdb_destination = dialog.result['destination'] self.backupdb_interval = dialog.result['interval'] self.backupdb_interval_unit = dialog.result['interval_unit'] self.apply_backup_settings() def settings_dialog(self): dialog = SettingsDialog(self.root, title='Settings', host=self.host, port=self.port) if dialog.result: self.host = dialog.result['host'] self.port = dialog.result['port'] def about_dialog(self): AboutDialog(self.root) def on_sync_database(self): self.cmd_runner.append_message(_("Syncing database...")) self.cmd_runner.run_command("migrate") def on_reset_admin(self): self.cmd_runner.append_message(_("Resetting admin user...")) self.cmd_runner.run_command("createsuperuser") def on_start_server(self): if self.server_running: self.cmd_runner.cancel_command() return args = ["{0}:{1}".format(self.host, self.port)] if not self.auto_start_svr.get(): args.append("--no-browser") self.server_running = True self.cmd_runner.run_command("start", *args) # initiate backup_timer if backup is enabled self.apply_backup_settings() self.btn_server.config(text='Stop Server') def on_backup_timer(self): if not self.backupdb_enabled: return self.do_backup() self.backup_timer.start(1000 * self.backup_interval_seconds) def on_close_app(self): self.cmd_runner.cancel_command() self.save_gui_settings() self.destroy() def apply_backup_settings(self): if self.backupdb_enabled and self.server_running: now = datetime.datetime.utcnow() delta = datetime.timedelta(seconds=self.backup_interval_seconds) ref = self.last_backup if ref is None: ref = now ref += delta d = ref - now seconds = d.days * 86400 + d.seconds if seconds < 1: seconds = 30 # avoid backup immediatly after start self.backup_timer.start(seconds * 1000) else: self.backup_timer.stop() def do_backup(self): cmd = [ sys.executable, "-u", "-m", "openslides", "backupdb", self.backupdb_destination, ] p = subprocess.Popen( cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) p.stdin.close() output = p.stdout.read().strip() exitcode = p.wait() if output: self.cmd_runner.append_message(output) time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") if exitcode == 0: self.cmd_runner.append_message(_("{0}: Database backup successful.").format(time)) else: self.cmd_runner.append_message(_("{0}: Database backup failed!").format(time)) self.last_backup = datetime.datetime.utcnow() def on_cmd_start(self, event): self.btn_settings.config(state='disabled') self.btn_db_backup.config(state='disabled') self.btn_sync_db.config(state='disabled') self.btn_reset_admin.config(state='disabled') self.chb_auto_svr.config(state='disabled') def on_cmd_stop(self, event): if self.server_running: self.btn_server.config(text='Start Server') self.server_running = False self.backup_timer.stop() if self.backupdb_enabled: self.do_backup() else: if self.cmd_runner.exitcode == 0: text = _("Operation successfully completed.") else: text = _("Operation failed (exit code = {0})").format(self.cmd_runner.exitcode) self.cmd_runner.append_message(text) self.btn_settings.config(state='normal') self.btn_db_backup.config(state='normal') self.btn_sync_db.config(state='normal') self.btn_reset_admin.config(state='normal') self.chb_auto_svr.config(state='normal')
def main(): global _motion_timer _motion_timer = RepeatedTimer(_motion_timer_period, _handle_motion_timer) _motion_timer.start() global _odom_timer _odom_timer = RepeatedTimer(_odom_timer_period, _handle_odom_timer) _odom_timer.start() global _ctrl_timer _ctrl_timer = RepeatedTimer(_ctrl_timer_period, _handle_ctrl_timer) _ctrl_timer.start() use_rcv3 = os.environ['USE_RCV3'] == 'true' w.init(use_rcv3=use_rcv3) # TODO: Okay, so Controller.init(None) will automagically load in some PID # values for each of the x, y, theta position controllers. However, since # `teleop` is run in real life on different robots, really it should read # the correct YAML robot config file and load in the PID constants and # pass them into Controller.init(gains) as in the controller_node.py. # Two ways to do this: (1) do like os.environ['USE_RCV3'], where the odroid_setup.bash # script loads up the PID constants as environment variables (this seems messy). # (2) find a python YAML reading library and just read the file directly from here # based on which robot this is (you can use os.environ['ROBOT']) Controller.init() print 'Started.' global _velocities, _set_speed, _smooth, _odom_on, _previous_action, _ctrl_on while(1): action = get_action() if action == 'UP': _set_speed = True _velocities = (0, _vy, 0) elif action == 'DOWN': _set_speed = True _velocities = (0, -_vy, 0) elif action == 'RIGHT': _set_speed = True _velocities = (_vx, 0, 0) elif action == 'LEFT': _set_speed = True _velocities = (-_vx, 0, 0) elif action == 'SPIN_CW': _set_speed = True _velocities = (0, 0, _w) elif action == 'SPIN_CCW': _set_speed = True _velocities = (0, 0, -_w) elif action == 'SET_HOME': Odometry.init() elif action == 'GO_HOME': _motion_timer.stop() motion.stop() time.sleep(1) _go_home() time.sleep(1) _set_speed = True _velocities = (0, 0, 0) _motion_timer.start() elif action == 'GO_TO_POINT': _toggle_timers(False) motion.stop() time.sleep(1) _ask_for_point() time.sleep(1) _ctrl_on = True _odom_on = True _toggle_timers(True) elif action == 'TOGGLE_CNTRL': _ctrl_on = not _ctrl_on print("Controller: {}".format(_ctrl_on)) elif action == 'TOGGLE_SMOOTH': _smooth = not _smooth print("Smooth: {}".format(_smooth)) elif action == 'TOGGLE_ODOM': _odom_on = not _odom_on print("Odom: {}".format(_odom_on)) elif action == 'BATTERY': print("\n\r*** Battery: {} ***\n\r".format(get_battery())) elif action == 'BREAKPOINT': _toggle_timers(False) import ipdb; ipdb.set_trace() _toggle_timers(True) elif action == 'CALIBRATION_MODE': _toggle_timers(False) _deal_with_calibration() time.sleep(1) _toggle_timers(True) elif action == 'DIE': _toggle_timers(False) motion.stop() w.kill() return sys.exit(0) else: _set_speed = True _velocities = (0, 0, 0) # handle stopping before changing directions if _action_requires_stop(action): _set_speed = False motion.stop() time.sleep(0.4) _set_speed = True _previous_action = action print "{}\r".format(_velocities)
class BettingDisplay(): def __init__(self, parent, meeting): self.parent = parent self.display_type = 'odds' self.date = datetime.date.today().strftime( "%Y-%m-%d") #Currently will need to be restarted each day self.meeting = meeting #PLACEHOLDER self.schedule = Schedule(self.date, self.meeting) self.races = self.schedule.meetings[0].races self.next_race = None self.set_next_race() self.odds_var = StringVar() self.title_var = StringVar() self.dets_var = StringVar() self.build_display() self.start_timer() print("STARTED SUCCESSFULLY") def set_next_race(self): next_race = None found = False for race in self.races: cur_time = int(datetime.datetime.now().strftime("%H%M%S")) race_time = int(re.sub('[:]', '', race.time)) if race_time > cur_time and not found: next_race = race found = True if next_race is not self.next_race: self.next_race = next_race def start_timer(self): self.threading_timer = RepeatedTimer(3, self.refresh) self.threading_timer.start() def refresh(self): if self.display_type == 'odds': self.set_next_race() self.next_race.load_odds() #---TEMP---# horse_nums = [''] * 20 for i in range(min(20, len(self.next_race.entries))): horse_nums[i] = str(self.next_race.entries[i].number) horse_names = [''] * 20 for i in range(min(20, len(self.next_race.entries))): horse_names[i] = str(self.next_race.entries[i].name) win_odds = [''] * 20 for i in range(min(20, len(self.next_race.entries))): win_odds[i] = str(self.next_race.entries[i].odds_win) lst = horse_nums + horse_names + win_odds odds_str = TEST_TEMPLATE.format(lst) title_str = TITLE_TEMPLATE.format(name=self.next_race.name) dets_str = TIME_TEMPLATE.format( time=self.next_race.time, venue=self.next_race.meeting.venue, meet_no=self.next_race.meeting.number, country=self.next_race.meeting.country) self.title_var.set(title_str) self.dets_var.set(dets_str) self.odds_var.set(odds_str) #---TEMP END---# elif self.display_type == 'test': self.title_var.set('test') self.dets_var.set('') self.odds_var.set('') def build_display(self): #----TEMP---- self.cur_race_name = StringVar() self.cur_race_time = StringVar() self.title_text = Label(self.parent, fg="white", bg="black", font=("Courier", 40, "bold"), textvariable=self.title_var) self.title_text.place(relx=0.5, rely=0, anchor=N, height=80, width=1100) self.dets_text = Label(self.parent, textvariable=self.dets_var, fg="white", bg="black", font=("Courier", 20, "bold")) self.dets_text.place(relx=0.5, y=80, anchor=N, height=30, width=1100) self.odds_text = Label(self.parent, textvariable=self.odds_var, fg="white", bg="black", font=("Courier", 20, "bold")) self.odds_text.place(relx=0.5, y=110, anchor=N, width=1100, height=600) self.quitbutton = Button(self.parent, text='quit', command=self.quitclick) self.quitbutton.place(relx=0.5, rely=1, anchor=S) #---TEMP END ---# def quitclick(self): self.threading_timer.stop() self.parent.destroy()
class Scheduler(metaclass=ABCMeta): jobs_to_peek_arg = 7 activate_random_arrival = False waiting_limit = -1 def __init__(self, estimation: ComplementarityEstimation, cluster: Cluster, update_interval=60): self.queue = [] self.estimation = estimation self.cluster = cluster self._timer = RepeatedTimer(update_interval, self.update_estimation) self.scheduler_lock = Lock() self.started_at = None self.stopped_at = None self.print_estimation = False self.waiting_time = {} self.scheduled_apps_num = 0 self.jobs_to_peek = self.jobs_to_peek_arg self.random_arrival_rate = [0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 2, 0, 2, 1, 0, 2, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0] def start(self): self.schedule() self._timer.start() self.started_at = time.time() - 3600 def stop(self): self._timer.cancel() self.stopped_at = time.time() - 3600 def update_estimation(self): for (apps, usage) in self.cluster.apps_usage(): if len(apps) > 0 and usage.is_not_idle(): for rest, out in LeaveOneOut(len(apps)): self.estimation.update_app(apps[out[0]], [apps[i] for i in rest], usage.rate()) if self.print_estimation: self.estimation.print() def add(self, app: Application): self.queue.append(app) def add_all(self, apps: List[Application]): self.queue.extend(apps) def schedule(self): while len(self.queue) > 0: try: app = self.schedule_application() if app.waiting_time != 0: app.waiting_time = app.waiting_time - 1 if app.waiting_time in self.waiting_time.keys(): self.waiting_time[app.waiting_time] = self.waiting_time[app.waiting_time] + 1 else: self.waiting_time[app.waiting_time] = 1 except NoApplicationCanBeScheduled: print("No Application can be scheduled right now") break app.start(self.cluster.resource_manager, self._on_app_finished) if self.jobs_to_peek < len(self.queue) and self.activate_random_arrival: print("Update random arrival rate") self.jobs_to_peek = self.jobs_to_peek + self.random_arrival_rate[self.scheduled_apps_num] print("Scheduler round: {}".format(self.scheduled_apps_num)) print("Jobs_to_peek = {}".format(self.jobs_to_peek)) self.scheduled_apps_num = self.scheduled_apps_num + 1 time.sleep(1) # add a slight delay so jobs could be submitted to yarn in order self.cluster.print_nodes() def schedule_application(self) -> Application: if self.cluster.available_containers()==0: raise NoApplicationCanBeScheduled app = self.get_application_to_schedule() if app.n_containers > self.cluster.available_containers(): self.queue = [app] + self.queue raise NoApplicationCanBeScheduled self.place_containers(app) return app def _on_app_finished(self, app: Application): self.scheduler_lock.acquire() self.cluster.remove_applications(app) if len(self.queue) == 0 and self.cluster.has_application_scheduled() == 0: self.stop() self.on_stop() else: self.schedule() self.scheduler_lock.release() def on_stop(self): delta = self.stopped_at - self.started_at print("Queue took {:.0f}'{:.0f} to complete".format(delta // 60, delta % 60)) self.estimation.save(self.estimation.output_folder) self.export_experiment_data() print("\n\n\n(((((((((( Waiting times ))))))))))") for (key, value) in self.waiting_time.items(): print("{} rounds waiting - {}".format(key,value)) print(str(self.waiting_time)) def export_experiment_data(self): print("\n\n\n=======Generate experiment output=======\n\n\n") host_list = "|".join([address for address in self.cluster.nodes.keys()]) cmd_query_cpu = "\ninflux -precision rfc3339 -username root -password root" \ " -database 'telegraf' -host 'localhost' -execute 'SELECT usage_user,usage_iowait " \ "FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "AND cpu = '\\''cpu-total'\\'' GROUP BY host' -format 'csv' > /data/vinh.tran/new/expData/{}/cpu_{}.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, Application.experiment_name, Application.experiment_name) print(cmd_query_cpu) # subprocess.Popen(cmd_query_cpu, shell=True) cmd_query_cpu_mean = "\ninflux -precision rfc3339 -username root -password root" \ " -database 'telegraf' -host 'localhost' -execute 'SELECT mean(usage_user) as \"mean_cpu_percent\",mean(usage_iowait) as \"mean_io_wait\" " \ "FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "AND cpu = '\\''cpu-total'\\'' GROUP BY time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/cpu_{}_mean.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, Application.experiment_name, Application.experiment_name) print(cmd_query_cpu_mean) cmd_query_mem = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT used_percent " \ "FROM \"telegraf\".\"autogen\".\"mem\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY host' -format 'csv' > /data/vinh.tran/new/expData/{}/mem_{}.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, Application.experiment_name, Application.experiment_name) print(cmd_query_mem) cmd_query_mem_mean = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT mean(used_percent) " \ "FROM \"telegraf\".\"autogen\".\"mem\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/mem_{}_mean.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, Application.experiment_name, Application.experiment_name) print(cmd_query_mem_mean) cmd_query_disk = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT sum(read_bytes),sum(write_bytes) " \ "FROM (SELECT derivative(last(\"read_bytes\"),1s) as \"read_bytes\",derivative(last(\"write_bytes\"),1s) as \"write_bytes\",derivative(last(\"io_time\"),1s) as \"io_time\" " \ "FROM \"telegraf\".\"autogen\".\"diskio\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY \"host\",\"name\",time(10s)) WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' GROUP BY host,time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/disk_{}.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), Application.experiment_name, Application.experiment_name) print(cmd_query_disk) cmd_query_disk_mean = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT sum(read_bytes),sum(write_bytes) " \ "FROM (SELECT derivative(last(\"read_bytes\"),1s) as \"read_bytes\",derivative(last(\"write_bytes\"),1s) as \"write_bytes\",derivative(last(\"io_time\"),1s) as \"io_time\" " \ "FROM \"telegraf\".\"autogen\".\"diskio\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY \"host\",\"name\",time(10s)) WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' GROUP BY time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/disk_{}_mean.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), Application.experiment_name, Application.experiment_name) print(cmd_query_disk_mean) cmd_query_net = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT sum(download_bytes),sum(upload_bytes) FROM (SELECT derivative(first(\"bytes_recv\"),1s) " \ "as \"download_bytes\",derivative(first(\"bytes_sent\"),1s) as \"upload_bytes\"" \ "FROM \"telegraf\".\"autogen\".\"net\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY \"host\",time(10s)) WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' GROUP BY host,time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/net_{}.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), Application.experiment_name, Application.experiment_name) print(cmd_query_net) cmd_query_net_mean = "\ninflux -precision rfc3339 -username root -password root " \ "-database 'telegraf' -host 'localhost' -execute 'SELECT sum(download_bytes),sum(upload_bytes) FROM (SELECT derivative(first(\"bytes_recv\"),1s) " \ "as \"download_bytes\",derivative(first(\"bytes_sent\"),1s) as \"upload_bytes\"" \ "FROM \"telegraf\".\"autogen\".\"net\" WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' AND host =~ /{}/ " \ "GROUP BY \"host\",time(10s)) WHERE time > '\\''{}'\\'' and time < '\\''{}'\\'' GROUP BY time(10s)' -format 'csv' > /data/vinh.tran/new/expData/{}/net_{}_mean.csv" \ .format(time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), host_list, time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.started_at)), time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime(self.stopped_at)), Application.experiment_name, Application.experiment_name) print(cmd_query_net_mean) subprocess.Popen( cmd_query_cpu + " && " + cmd_query_mem + " && " + cmd_query_disk + " && " + cmd_query_net + " && " + cmd_query_cpu_mean + " && " + cmd_query_mem_mean + " && " + cmd_query_disk_mean + " && " + cmd_query_net_mean, shell=True) time.sleep(1) with open("/data/vinh.tran/new/expData/{}/cmd.txt".format(Application.experiment_name), 'a') as file: file.write("{}\n\n{}\n\n{}\n\n{}\n\n\n\n{}\n\n{}\n\n{}\n\n{}\n". format(cmd_query_cpu, cmd_query_mem, cmd_query_disk, cmd_query_net, cmd_query_cpu_mean, cmd_query_mem_mean, cmd_query_disk_mean, cmd_query_net_mean)) def get_application_to_schedule(self) -> Application: app = self.queue[0] if app.n_containers > self.cluster.available_containers(): raise NoApplicationCanBeScheduled return self.queue.pop(0) @abstractmethod def place_containers(self, app: Application): pass def _place_random(self, app: Application, n_containers=4): nodes = self.cluster.non_full_nodes() good_nodes = [ n for n in nodes if len(n.applications()) == 0 or n.applications()[0] != app ] if len(good_nodes) == 0: good_nodes = nodes node = good_nodes[np.random.randint(0, len(good_nodes))] return self._place(app, node, n_containers) @staticmethod def _place(app: Application, node: Node, n_containers=4): if n_containers <= 0: raise ValueError("Can not place {} containers".format(n_containers)) # print("Place {} on {} ({})".format(app, node, node.available_containers())) n = len([t for t in app.tasks if t.node is not None]) n += 1 if app.node is not None else 0 for k in range(n, n + n_containers): if k < app.n_containers: node.add_container(app.containers[k]) print("Place a task of {} on node {}".format(app, node)) return k - n + 1
class BlockChainServer(db_pb2_grpc.BlockChainMinerServicer): def __init__(self, serverId, addr, peers, dataDir): super() if not os.path.exists(dataDir): os.makedirs(dataDir) self.serverId = serverId self.addr = addr self.database = DBEngine(dataDir) self.miner = MinerThreading() self.daemonTimer = RepeatedTimer(0.5, self.daemon) self.peers = peers self.stubs = [] for peer in self.peers: logging.info('added peer {}'.format(peer)) channel = grpc.insecure_channel(peer) self.stubs.append(db_pb2_grpc.BlockChainMinerStub(channel)) self.stubs[-1].addr = peer self.miner.daemon = True self.miner.start() self.daemonTimer.start() def daemon(self): if self.miner.block is not None and self.miner.success: self.database.addBlock(self.miner.block) if len(self.database.curChain) != 0: for stub in self.stubs: try: stub.PushBlock( db_pb2.JsonBlockString( Json=self.database.curChain[-1].toJson())) except grpc.RpcError: pass block = self.database.packToBlock('Server{:02}'.format(self.serverId)) if block is not None: self.miner.setBlock(block) def Get(self, request, context): logging.info("query balance of {}".format(request.UserID)) value = self.database.get(request.UserID) return db_pb2.GetResponse(Value=value) def Transfer(self, request, context): if not self.database.pushTransaction(Transaction(request)): return db_pb2.BooleanResponse(Success=False) logging.info("transfer {} from {} to {}".format( request.Value, request.FromID, request.ToID)) success = False for stub in self.stubs: try: stub.PushTransaction(request, timeout=10) success = True except grpc.RpcError: continue return db_pb2.BooleanResponse(Success=success) def Verify(self, request, context): trans = Transaction(request) logging.info("verify transfer ({} from {} to {})".format( request.Value, request.FromID, request.ToID)) res = self.database.verify(Transaction(request)) if res == 'SUCCEEDED': return db_pb2.VerifyResponse( Result=db_pb2.VerifyResponse.SUCCEEDED, BlockHash=self.database.blockByTrans(trans).hash) elif res == 'PENDING': return db_pb2.VerifyResponse( Result=db_pb2.VerifyResponse.PENDING, BlockHash=self.database.blockByTrans(trans).hash) else: return db_pb2.VerifyResponse(Result=db_pb2.VerifyResponse.FAILED, BlockHash="") def PushTransaction(self, request, context): self.database.pushTransaction(Transaction(request)) return db_pb2.Null() def PushBlock(self, request, context): blockJsonString = request.Json try: block = Block(blockJsonString) except (json.JSONDecodeError, AttributeError): return db_pb2.Null() if len(block.MinerID) != 8 or \ block.MinerID[:6] != 'Server' or \ not block.MinerID[6:8].isdigit() or \ not checkHash(block.hash): return db_pb2.Null() self.database.addBlock(block) last = block while True: if last.PrevHash == BlockChain.NullHash or last.PrevHash in self.database.blocks: break found = False for stub in self.stubs: try: logging.info("acquire block from {} with hash {}".format( stub.addr, last.PrevHash[:12])) J = stub.GetBlock( db_pb2.GetBlockRequest(BlockHash=last.PrevHash), timeout=10).Json if J == "": continue reqBlock = Block(J) except (grpc.RpcError, json.JSONDecodeError, AttributeError): continue self.database.addBlock(reqBlock) last = reqBlock found = True break if not found: break self.database.updateLongestBlockChain() return db_pb2.Null() def GetHeight(self, request, context): self.database.updateLongestBlockChain() length = len(self.database.curChain) if length == 0: hash = "" else: hash = self.database.curChain[-1].hash time.sleep(2) return db_pb2.GetHeightResponse(Height=length, LeafHash=hash) def GetBlock(self, request, context): return db_pb2.GetBlockRequest( BlockHash=self.database.getBlockByHash(request.BlockHash))
class RPiServoblasterController: # ServoBlasterへの反映間隔 COMMIT_INTERVAL_SEC = 0.1 # ./servodを実行した時のピン番号を使う(GPIOの番号でも、物理位置番号でもない) WAIST_SERVO_PIN = 7 BOOM_SERVO_PIN = 6 ARM_SERVO_PIN = 5 CRAW_SERVO_PIN = 4 # 操作対象とピン番号のマップ PIN_MAP = { 0: WAIST_SERVO_PIN, 1: BOOM_SERVO_PIN, 2: ARM_SERVO_PIN, 3: CRAW_SERVO_PIN, } def __init__(self): # GPIO番号でピンを指定 # ServoBlasterの起動(rootで実行する必要あり) # 50%指定時の中間位置を--maxで調整する。--max=200がちょうどよかった os.system('sudo /home/pi/PiBits/ServoBlaster/user/servod --idle-timeout=2000 --max=200') self.servos = [] for index in RPiServoblasterController.PIN_MAP.iterkeys(): pin = RPiServoblasterController.PIN_MAP[index] # サーボを作る self.servos.append(SG90Servoblaster(pin, self.getPartName(index))) # self.positionの内容を定期的にcommit()を使ってservoblasterで反映する self.positions = [] self.timer = RepeatedTimer(RPiServoblasterController.COMMIT_INTERVAL_SEC, self.commit) self.timer.start() # 直接同期的にservoblasterを呼ぶのではなく、 # 一度内容をインスタンス変数に格納しておき、定期的にservoblasterで反映させる def apply(self, positions): self.positions = positions def shutdown(self): # if self.timer is not None: self.timer.cancel() def getIndexes(self): return RPiServoblasterController.PIN_MAP.keys() def switchDebugPosition(self): for index in RPiServoblasterController.PIN_MAP.iterkeys(): self.servos[index].switchDebugPosition() # マルチスレッド下でタイマーから実行される def commit(self): if 0 == len(self.positions): return for index in RPiServoblasterController.PIN_MAP.iterkeys(): degree = self.positions[index] self.servos[index].rotateTo(degree) def getPartName(self, index): if(0 == index): return 'WAIST' elif(1 == index): return 'BOOM' elif(2 == index): return 'ARM' elif(3 == index): return 'CRAW' else: return 'unknown'
class Scheduler(metaclass=ABCMeta): def __init__(self, estimation: ComplementarityEstimation, cluster: Cluster, update_interval=60): self.queue = [] self.estimation = estimation self.cluster = cluster self._timer = RepeatedTimer(update_interval, self.update_estimation) self.scheduler_lock = Lock() self.started_at = None self.stopped_at = None self.print_estimation = False def start(self): self.schedule() self._timer.start() self.started_at = time.time() def stop(self): self._timer.cancel() self.stopped_at = time.time() def update_estimation(self): for (apps, usage) in self.cluster.apps_usage(): if len(apps) > 0 and usage.is_not_idle(): for rest, out in LeaveOneOut(len(apps)): self.estimation.update_app(apps[out[0]], [apps[i] for i in rest], usage.rate()) if self.print_estimation: self.estimation.print() def add(self, app: Application): self.queue.append(app) def add_all(self, apps: List[Application]): self.queue.extend(apps) def schedule(self): while len(self.queue) > 0: try: app = self.schedule_application() except NoApplicationCanBeScheduled: print("No Application can be scheduled right now") break app.start(self.cluster.resource_manager, self._on_app_finished) self.cluster.print_nodes() def schedule_application(self) -> Application: app = self.get_application_to_schedule() if app.n_containers > self.cluster.available_containers(): self.queue = [app] + self.queue raise NoApplicationCanBeScheduled self.place_containers(app) return app def _on_app_finished(self, app: Application): self.scheduler_lock.acquire() self.cluster.remove_applications(app) if len(self.queue) == 0 and self.cluster.has_application_scheduled( ) == 0: self.stop() self.on_stop() else: self.schedule() self.scheduler_lock.release() def on_stop(self): delta = self.stopped_at - self.started_at print("Queue took {:.0f}'{:.0f} to complete".format( delta // 60, delta % 60)) self.estimation.save('estimation') def get_application_to_schedule(self) -> Application: app = self.queue[0] if app.n_containers > self.cluster.available_containers(): raise NoApplicationCanBeScheduled return self.queue.pop(0) @abstractmethod def place_containers(self, app: Application): pass def _place_random(self, app: Application, n_containers=3): nodes = self.cluster.non_full_nodes() good_nodes = [ n for n in nodes if len(n.applications()) == 0 or n.applications()[0] != app ] if len(good_nodes) == 0: good_nodes = nodes node = good_nodes[np.random.randint(0, len(good_nodes))] return self._place(app, node, n_containers) @staticmethod def _place(app: Application, node: Node, n_containers=3): if n_containers <= 0: raise ValueError( "Can not place {} containers".format(n_containers)) # print("Place {} on {} ({})".format(app, node, node.available_containers())) n = len([t for t in app.tasks if t.node is not None]) n += 1 if app.node is not None else 0 for k in range(n, n + n_containers): if k < app.n_containers: node.add_container(app.containers[k]) return k - n + 1
class RPiPCA9685Controller: # 反映間隔 COMMIT_INTERVAL_SEC = 0.1 # ./servodを実行した時のピン番号を使う(GPIOの番号でも、物理位置番号でもない) WAIST_SERVO_PIN = 0 BOOM_SERVO_PIN = 1 ARM_SERVO_PIN = 2 CRAW_SERVO_PIN = 3 # 操作対象とピン番号のマップ PIN_MAP = { 0: WAIST_SERVO_PIN, 1: BOOM_SERVO_PIN, 2: ARM_SERVO_PIN, 3: CRAW_SERVO_PIN, } def __init__(self, address=0x40): # I2C経由でのコントロール用ライブラリ # https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git self.pwm = Adafruit_PCA9685.PCA9685(address, busnum=1) self.pwm.set_pwm_freq(SG90PCA9685.PWM_FREQ) self.servos = [] for index in RPiPCA9685Controller.PIN_MAP.iterkeys(): pin = RPiPCA9685Controller.PIN_MAP[index] # サーボを作る self.servos.append(SG90PCA9685(pin, self.getPartName(index), self.pwm)) # self.positionの内容を定期的にcommit()を使ってservoblasterで反映する self.positions = [] self.timer = RepeatedTimer(RPiPCA9685Controller.COMMIT_INTERVAL_SEC, self.commit) self.timer.start() # 直接同期的にservoblasterを呼ぶのではなく、 # 一度内容をインスタンス変数に格納しておき、定期的にservoblasterで反映させる def apply(self, positions): self.positions = positions def shutdown(self): # if self.timer is not None: self.timer.cancel() def getIndexes(self): return RPiPCA9685Controller.PIN_MAP.keys() def switchDebugPosition(self): for index in RPiPCA9685Controller.PIN_MAP.iterkeys(): self.servos[index].switchDebugPosition() # マルチスレッド下でタイマーから実行される def commit(self): if 0 == len(self.positions): return for index in RPiPCA9685Controller.PIN_MAP.iterkeys(): degree = self.positions[index] self.servos[index].rotateTo(degree) def getPartName(self, index): if(0 == index): return 'WAIST' elif(1 == index): return 'BOOM' elif(2 == index): return 'ARM' elif(3 == index): return 'CRAW' else: return 'unknown'
def run(self): # get the first pending update_id, this is so we can skip over it in case # we get an "Unauthorized" exception. try: self.update_id = self.bot.get_updates()[0].update_id except IndexError: self.update_id = None # Create repeated timer to check for new file if self.bot_log_enabled: new_file_timer = RepeatedTimer(self.check_file_ts, self.new_file_timer_callback) new_file_timer.start() line_count = 0 info_ready = False info_msg = "" loss_list = [] # Loop checking for user message and new useful log line while True: try: if self.log_file_found and self.bot_log_enabled: logging.info("Check log") message = "" figure_name = "" while len(message) < 100 * 40: where = self.log_file.tell() line = self.log_file.readline() if line: if line_count < 35: #TODO: check if line == "Done!" for support network with different layers number info_msg += line line_count += 1 if line_count > 34: try: self.bot.sendMessage( self.chat_id, info_msg) except: logging.info( "Failed to send INFO message!") else: # Check if the row match the ITER lane data_match = re.findall(self.line_regex, line) if data_match: # Lane report ITER result data_match = data_match[0] iter_n = int(data_match[0]) loss_v = float(data_match[1]) loss_list.append(loss_v) logging.info("ITERATION NUMBER: " + str(iter_n)) if iter_n == 1 or ( iter_n % self.log_evry_iter) == 0: loss_np = np.asarray(loss_list, dtype=np.float32) # Create training loss graph figure_name = self.bkup_folder + "/iter" + data_match[ 0] + ".png" plt.clf() plt.plot(loss_np, 'o-') plt.title('Iteration: ' + data_match[0]) plt.ylabel('Loss') plt.xlabel('Iteration') #plt.show() plt.savefig(figure_name, bbox_inches='tight') message += "|----> ITER " + data_match[ 0] + "\n" message += "| |--> loss " + data_match[ 1] + "\n" message += "| |--> avg " + data_match[ 2] + "\n" message += "| |--> sec " + data_match[ 4] + "\n" message += "| '--> img " + data_match[ 5] + "\n" else: self.log_file.seek(where) if len(message) > 0: logging.info("Sending ITERATION message!") try: self.bot.sendMessage(self.chat_id, message) except: logging.info( "Iteratino message skipped can not send!" ) break time.sleep(1) logging.info("check file in backup folder") try: self.echo() except NetworkError: logging.info("NETWORK ERROR") sleep(1) except Unauthorized: # The user has removed or blocked the bot. logging.info("UNAUTHORIZED") update_id += 1 except KeyboardInterrupt: # TODO: maybe add a big could be needed to ensure all file are loaded logging.info("ctrl C caught terminating") break new_file_timer.stop() self.log_file.close()
class Core: REFRESH_INTERVAL_SEC = 10 DATA_COUNT = 5 MIN_DATA_COUNT_REQUIRED = 3 OPERATION_NONE = -1 OPERATION_SELL = 0 OPERATION_BUY = 1 ANGLE_OFFSET = 0.1 def __init__(self, exmoApiModel): self.__exmoApiModel = exmoApiModel self.__timer = RepeatedTimer(self.REFRESH_INTERVAL_SEC, self.__step) self.__data = [] self.__lastOperation = self.OPERATION_NONE self.__math = SimpleMath() self.__currentRate = 0 self.__lastRate = 0 self.__printCurrentBalance() def __printCurrentBalance(self): print("Текущий баланс: {:.2f} {:s} и {:.2f} {:s}!".format( self.__exmoApiModel.getSrcAmount(), self.__exmoApiModel.getSrcCurrency(), self.__exmoApiModel.getDstAmount(), self.__exmoApiModel.getDstCurrency())) def __printCurrentRate(self): print("Текущий курс: {:.2f} {:s} за 1 {:s}.".format( self.__currentRate, self.__exmoApiModel.getSrcCurrency(), self.__exmoApiModel.getDstCurrency())) def __buy(self): result = self.__exmoApiModel.buy() if result: print("Совершена покупка по цене {:.2f} {:s}!".format( self.__currentRate, self.__exmoApiModel.getDstCurrency())) self.__printCurrentBalance() def __sell(self): result = self.__exmoApiModel.sell() if result: print("Совершена продажа по цене {:.2f} {:s}!".format( self.__currentRate, self.__exmoApiModel.getSrcCurrency())) self.__printCurrentBalance() def __step(self): try: self.__currentRate = self.__exmoApiModel.getCurrencySellPrice() self.__data.append(self.__currentRate) if (len(self.__data) > self.DATA_COUNT): del self.__data[0] if (len(self.__data) >= self.MIN_DATA_COUNT_REQUIRED): angle = self.__math.getInclinationAngle( self.__data, self.REFRESH_INTERVAL_SEC) if angle > self.ANGLE_OFFSET: if self.__lastOperation != self.OPERATION_BUY: self.__lastOperation = self.OPERATION_BUY self.__buy() elif angle < -self.ANGLE_OFFSET: if self.__lastOperation != self.OPERATION_SELL: self.__lastOperation = self.OPERATION_SELL self.__sell() if round(self.__currentRate, 2) != round(self.__lastRate, 2): self.__printCurrentRate() self.__lastRate = self.__currentRate except Exception as e: self.__timer.stop() print("Ошибка: " + str(e)) def start(self): self.__timer.start()