class DatDashSampler: def __init__(self, app, interval): self._app = app self._timer = RepeatedTimer(interval, self._sample) def stop(self): self._timer.stop() 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["updateAt"] = \ 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 DashieSampler(object): def __init__(self, app, interval): self._app = app self._timer = RepeatedTimer(interval, self._sample) def stop(self): self._timer.stop() 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['updateAt'] = 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 MultiTouchInput: current_state = 0 current_state_counter = [0] * 12 touch_timer = None def __init__(self, ipcon, key_queue): if not config.UID_MULTI_TOUCH_BRICKLET: print("Not Configured: Multi Touch") return self.key_queue = key_queue self.ipcon = ipcon self.mt = MultiTouch(config.UID_MULTI_TOUCH_BRICKLET, self.ipcon) try: self.mt.get_electrode_sensitivity() print("Found: Multi Touch ({0})").format( config.UID_MULTI_TOUCH_BRICKLET) except: print("Not Found: Multi Touch ({0})").format( config.UID_MULTI_TOUCH_BRICKLET) return self.mt.set_electrode_sensitivity(100) self.mt.register_callback(self.mt.CALLBACK_TOUCH_STATE, self.cb_touch_state) self.touch_timer = RepeatedTimer(0.1, self.touch_tick) def stop(self): if self.touch_timer is not None: self.touch_timer.stop() def state_to_queue(self, state): for item in config.KEYMAP_MULTI_TOUCH.items(): if state & (1 << item[0]): self.key_queue.put(item[1]) def touch_tick(self): state = 0 for i in range(12): if self.current_state & (1 << i): self.current_state_counter[i] += 1 else: self.current_state_counter[i] = 0 if self.current_state_counter[i] > 5: state |= (1 << i) if state != 0: self.state_to_queue(state) def cb_touch_state(self, state): changed_state = self.current_state ^ state self.current_state = state self.state_to_queue(changed_state & self.current_state)
class MultiTouchInput: current_state = 0 current_state_counter = [0]*12 touch_timer = None def __init__(self, ipcon, key_queue): if not config.UID_MULTI_TOUCH_BRICKLET: print("Not Configured: Multi Touch") return self.key_queue = key_queue self.ipcon = ipcon self.mt = MultiTouch(config.UID_MULTI_TOUCH_BRICKLET, self.ipcon) try: self.mt.get_electrode_sensitivity() print("Found: Multi Touch ({0})").format(config.UID_MULTI_TOUCH_BRICKLET) except: print("Not Found: Multi Touch ({0})").format(config.UID_MULTI_TOUCH_BRICKLET) return self.mt.set_electrode_sensitivity(100) self.mt.register_callback(self.mt.CALLBACK_TOUCH_STATE, self.cb_touch_state) self.touch_timer = RepeatedTimer(0.1, self.touch_tick) def stop(self): if self.touch_timer is not None: self.touch_timer.stop() def state_to_queue(self, state): for item in config.KEYMAP_MULTI_TOUCH.items(): if state & (1 << item[0]): self.key_queue.put(item[1]) def touch_tick(self): state = 0 for i in range(12): if self.current_state & (1 << i): self.current_state_counter[i] += 1 else: self.current_state_counter[i] = 0 if self.current_state_counter[i] > 5: state |= (1 << i) if state != 0: self.state_to_queue(state) def cb_touch_state(self, state): changed_state = self.current_state ^ state self.current_state = state self.state_to_queue(changed_state & self.current_state)
def updateNPMDependencies(): npm = NPM() try : npm.getCurrentNPMVersion(True) except Exception as e: print("Error: "+traceback.format_exc()) return animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Updating npm dependencies ") interval_animation = RepeatedTimer(animation_loader.sec, animation_loader.animate) try : npm.update_all(False) except Exception as e: pass animation_loader.on_complete() interval_animation.stop()
def updateNPMDependencies(): npm = NPM() try : npm.getCurrentNPMVersion(True) except Exception as e: if node_variables.NODE_JS_OS == "win" : sublime.active_window().status_message("Can't use \"npm\"! To use features that requires \"npm\", you must install it! Download it from https://nodejs.org site") print("Error: "+traceback.format_exc()) return animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Updating npm dependencies ") interval_animation = RepeatedTimer(animation_loader.sec, animation_loader.animate) try : npm.update_all(False) except Exception as e: pass animation_loader.on_complete() interval_animation.stop()
def updateNPMDependencies(): npm = NPM() try: npm.getCurrentNPMVersion(True) except Exception as e: print("Error: " + traceback.format_exc()) return animation_loader = AnimationLoader([ "[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]" ], 0.067, "Updating npm dependencies ") interval_animation = RepeatedTimer(animation_loader.sec, animation_loader.animate) try: npm.update_all(False) except Exception as e: pass animation_loader.on_complete() interval_animation.stop()
def updateNPMDependencies(): npm = NPM() try: npm.getCurrentNPMVersion(True) except Exception as e: if node_variables.NODE_JS_OS == "win": sublime.active_window().status_message( "Can't use \"npm\"! To use features that requires \"npm\", you must install it! Download it from https://nodejs.org site" ) print("Error: " + traceback.format_exc()) return animation_loader = AnimationLoader([ "[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]" ], 0.067, "Updating npm dependencies ") interval_animation = RepeatedTimer(animation_loader.sec, animation_loader.animate) try: npm.update_all(False) except Exception as e: pass animation_loader.on_complete() interval_animation.stop()
class DownloadNodeJS(object): def __init__(self, node_version): self.NODE_JS_VERSION = node_version self.NODE_JS_TAR_EXTENSION = ".zip" if node_variables.NODE_JS_OS == "win" else ".tar.gz" self.NODE_JS_BINARY_URL = "https://nodejs.org/dist/"+self.NODE_JS_VERSION+"/node-"+self.NODE_JS_VERSION+"-"+node_variables.NODE_JS_OS+"-"+node_variables.NODE_JS_ARCHITECTURE+self.NODE_JS_TAR_EXTENSION self.NODE_JS_BINARY_TARFILE_NAME = self.NODE_JS_BINARY_URL.split('/')[-1] self.NODE_JS_BINARY_TARFILE_FULL_PATH = os.path.join(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM, self.NODE_JS_BINARY_TARFILE_NAME) self.animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Downloading: "+self.NODE_JS_BINARY_URL+" ") self.interval_animation = None self.thread = None def download(self): try : if os.path.exists(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM): shutil.rmtree(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else : os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) if os.path.exists(node_variables.NODE_MODULES_PATH): shutil.rmtree(node_variables.NODE_MODULES_PATH) request = urllib.request.Request(self.NODE_JS_BINARY_URL) request.add_header('User-agent', r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1') with urllib.request.urlopen(request) as response : with open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, 'wb') as out_file : shutil.copyfileobj(response, out_file) except Exception as err : traceback.print_exc() self.on_error(err) return self.extract() self.on_complete() def start(self): self.thread = create_and_start_thread(self.download, "DownloadNodeJS") if self.animation_loader : self.interval_animation = RepeatedTimer(self.animation_loader.sec, self.animation_loader.animate) def extract(self): sep = os.sep if self.NODE_JS_TAR_EXTENSION != ".zip" : with tarfile.open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r:gz") as tar : for member in tar.getmembers() : member.name = sep.join(member.name.split(sep)[1:]) tar.extract(member, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else : with zipfile.ZipFile(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r") as zip_file : for member in zip_file.namelist() : if member.endswith("/node.exe") : with zip_file.open(member) as node_file: with open(os.path.join(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM, "node.exe"), "wb") as target : shutil.copyfileobj(node_file, target) break def on_error(self, err): self.animation_loader.on_complete() self.interval_animation.stop() sublime.active_window().status_message("Can't install Node.js! Check your internet connection!") def on_complete(self): self.animation_loader.on_complete() self.interval_animation.stop() if os.path.isfile(self.NODE_JS_BINARY_TARFILE_FULL_PATH) : os.remove(self.NODE_JS_BINARY_TARFILE_FULL_PATH) node_js = NodeJS() npm = NPM() self.animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Installing npm dependencies ") self.interval_animation = RepeatedTimer(self.animation_loader.sec, self.animation_loader.animate) try : npm.getCurrentNPMVersion(True) except Exception as e: if node_variables.NODE_JS_OS == "win" : sublime.error_message("Can't use \"npm\"! To use features that requires \"npm\", you must install it! Download it from https://nodejs.org site") print("Error: "+traceback.format_exc()) try : npm.install_all() except Exception as e : #print("Error: "+traceback.format_exc()) pass self.animation_loader.on_complete() self.interval_animation.stop() if node_js.getCurrentNodeJSVersion(True) == self.NODE_JS_VERSION : sublime.active_window().status_message("Node.js "+self.NODE_JS_VERSION+" installed correctly! NPM version: "+npm.getCurrentNPMVersion(True)) else : sublime.active_window().status_message("Can't install Node.js! Something went wrong during installation.")
class Pong: PADDLE_SIZE = 3 # Antialased ball? # PONG_COLOR_INDEX_BALL_TOP = 8 # PONG_COLOR_INDEX_BALL_LEFT = 9 # PONG_COLOR_INDEX_BALL_RIGHT = 10 # PONG_COLOR_INDEX_BALL_BOTTOM = 11 COLORS = [ ( 0, 0, 0), # off # ( 10, 10, 10), # grey (255, 0, 0), # red (255, 80, 0), # orange (255, 255, 0), # yellow ( 0, 255, 0), # green ( 0, 0, 255), # blue (255, 0, 150), # violet (255, 0, 40), # purple ( 0, 0, 0), # ball top ( 0, 0, 0), # ball left ( 0, 0, 0), # ball right ( 0, 0, 0) # ball bottom ] SCORE_FONT = { 0: ["222", "202", "202", "202", "222"], 1: ["020", "020", "020", "020", "020"], 2: ["222", "002", "222", "200", "222"], 3: ["222", "002", "222", "002", "222"], 4: ["202", "202", "222", "002", "002"], 5: ["222", "200", "222", "002", "222"], 6: ["222", "200", "222", "202", "222"], 7: ["222", "002", "002", "002", "002"], 8: ["222", "202", "222", "202", "222"], 9: ["222", "202", "222", "002", "002"], } playfield = [x[:] for x in [[0]*config.LED_COLS]*config.LED_ROWS] score = [0, 0] paddle_position_x = [4, 15] paddle_position_y = [3, 3] ball_position = [10, 5] ball_direction = [0.1, 0.2] timer = None loop = True def __init__(self, ipcon): self.okay = False self.ipcon = ipcon if not config.UID_LED_STRIP_BRICKLET: print("Not Configured: LED Strip or LED Strip V2 (required)") return if not config.IS_LED_STRIP_V2: self.led_strip = LEDStrip(config.UID_LED_STRIP_BRICKLET, self.ipcon) else: self.led_strip = LEDStripV2(config.UID_LED_STRIP_BRICKLET, self.ipcon) try: self.led_strip.get_frame_duration() if not config.IS_LED_STRIP_V2: print("Found: LED Strip ({0})".format(config.UID_LED_STRIP_BRICKLET)) else: print("Found: LED Strip V2 ({0})".format(config.UID_LED_STRIP_BRICKLET)) except: if not config.IS_LED_STRIP_V2: print("Not Found: LED Strip ({0})".format(config.UID_LED_STRIP_BRICKLET)) else: print("Not Found: LED Strip V2({0})".format(config.UID_LED_STRIP_BRICKLET)) return self.kp = KeyPress(self.ipcon) self.speaker = PongSpeaker(self.ipcon) self.okay = True self.led_strip.set_frame_duration(40) if not config.IS_LED_STRIP_V2: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_RENDERED, self.frame_rendered) else: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_STARTED, self.frame_rendered) self.led_strip.set_channel_mapping(config.CHANNEL_MAPPING) self.init_game() def init_game(self): self.new_ball() self.paddle_position_y = [3, 3] self.score = [0, 0] def frame_rendered(self, length): self.write_playfield() def write_playfield(self): if not self.okay: return field = copy.deepcopy(self.playfield) self.add_score_to_playfield(field) self.add_paddles_to_playfield(field) self.add_ball_to_playfield(field) # Reorder LED data into R, G and B channel r = [] g = [] b = [] frame = [] for row in range(config.LED_ROWS): col_range = range(config.LED_COLS) if row % 2 == 0: col_range = reversed(col_range) for col in col_range: r.append(self.COLORS[field[row][col]][0]) g.append(self.COLORS[field[row][col]][1]) b.append(self.COLORS[field[row][col]][2]) frame.append(self.COLORS[field[row][col]][0]) frame.append(self.COLORS[field[row][col]][1]) frame.append(self.COLORS[field[row][col]][2]) if not config.IS_LED_STRIP_V2: # Make chunks of size 16 r_chunk = [r[i:i+16] for i in range(0, len(r), 16)] g_chunk = [g[i:i+16] for i in range(0, len(g), 16)] b_chunk = [b[i:i+16] for i in range(0, len(b), 16)] for i in range(len(r_chunk)): length = len(r_chunk[i]) # Fill up chunks with zeros r_chunk[i].extend([0]*(16-len(r_chunk[i]))) g_chunk[i].extend([0]*(16-len(g_chunk[i]))) b_chunk[i].extend([0]*(16-len(b_chunk[i]))) try: self.led_strip.set_rgb_values(i*16, length, r_chunk[i], g_chunk[i], b_chunk[i]) except: break else: try: self.led_strip.set_led_values(0, frame) except: return def add_score_to_playfield(self, field): for row in range(3): for col in range(5): field[row][col+1] = int(self.SCORE_FONT[self.score[0]][col][row]) field[row+17][col+1] = int(self.SCORE_FONT[self.score[1]][col][row]) def add_ball_to_playfield(self, field): x = max(0, min(19, int(self.ball_position[0]))) y = max(0, min(9, int(self.ball_position[1]))) field[x][y] = config.PONG_COLOR_INDEX_BALL # Antialased ball? # x = max(0, min(19, self.ball_position[0])) # y = max(0, min(9, self.ball_position[1])) # ix = int(x) # iy = int(y) # field[ix][iy] = config.PONG_COLOR_INDEX_BALL # if ix + 1 < config.LED_ROWS: # field[ix+1][iy] = PONG_COLOR_INDEX_BALL_RIGHT # if ix - 1 > 0: # field[ix-1][iy] = PONG_COLOR_INDEX_BALL_LEFT # if iy + 1 < config.LED_COLS: # field[ix][iy+1] = PONG_COLOR_INDEX_BALL_TOP # if iy - 1 > 0: # field[ix][iy-1] = PONG_COLOR_INDEX_BALL_BOTTOM # # dx = x - int(x) # dy = x - int(x) # self.COLORS[PONG_COLOR_INDEX_BALL_RIGHT] = (0, 255*dx/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_LEFT] = (0, 255*(1-dx)/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_TOP] = (0, 255*dy/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_BOTTOM] = (0, 255*(1-dy)/64, 0) def add_paddles_to_playfield(self, field): for player in range(2): for i in range(self.PADDLE_SIZE): field[self.paddle_position_x[player]][self.paddle_position_y[player]+i] = config.PONG_COLOR_INDEX_PLAYER[player] def move_paddle(self, player, change): new_pos = self.paddle_position_y[player] + change if new_pos >= 0 and new_pos <= config.LED_COLS - self.PADDLE_SIZE: self.paddle_position_y[player] = new_pos def new_ball(self): self.ball_position = [(config.LED_ROWS - 1.0) / 2.0, (config.LED_COLS - 1.0) / 2.0] self.ball_direction = [random.choice([-0.2, 0.2]), random.choice([random.randrange(1, 9)/10.0, random.randrange(-9, -1)/10.0])] def tick(self): # Move ball for i in range(2): self.ball_position[i] += self.ball_direction[i] # Wall collision top/bottom if self.ball_position[1] < 0 or self.ball_position[1] >= config.LED_COLS: self.ball_direction[1] = -self.ball_direction[1] # Wall collision left/right def hit_left_right(player): self.speaker.beep_sirene() self.new_ball() self.score[player] += 1 if self.score[player] > 9: self.score[player] = 0 if self.ball_position[0] < 0: hit_left_right(1) if self.ball_position[0] >= config.LED_ROWS: hit_left_right(0) # Paddle collision def hit_paddle(skew): self.speaker.beep_paddle_hit() self.ball_direction[0] = -self.ball_direction[0] self.ball_direction[1] -= skew for i in range(2): self.ball_direction[i] *= 1.1 # Increase speed if self.ball_direction[0] < 0: if self.paddle_position_x[0] + 0.5 <= self.ball_position[0] <= self.paddle_position_x[0] + 1.5: if self.paddle_position_y[0] - 0.5 <= self.ball_position[1] <= self.paddle_position_y[0] + self.PADDLE_SIZE + 0.5: paddle_skew = (self.paddle_position_y[0] + self.PADDLE_SIZE/2.0 - self.ball_position[1])/10.0 hit_paddle(paddle_skew) if self.ball_direction[0] > 0: if self.paddle_position_x[1] - 0.5 <= self.ball_position[0] <= self.paddle_position_x[1] + 0.5: if self.paddle_position_y[1] - 0.5 <= self.ball_position[1] <= self.paddle_position_y[1] + self.PADDLE_SIZE + 0.5: paddle_skew = (self.paddle_position_y[1] + self.PADDLE_SIZE/2.0 - self.ball_position[1])/10.0 hit_paddle(paddle_skew) def run_game_loop(self): self.frame_rendered(0) self.timer = RepeatedTimer(0.1, self.tick) while self.loop: key = self.kp.read_single_keypress().lower() if key == 'a': self.move_paddle(0, -1) elif key == 's': self.move_paddle(0, 1) elif key == 'k': self.move_paddle(1, -1) elif key == 'l': self.move_paddle(1, 1) elif key == 'r': self.init_game() elif not config.HAS_GUI and key == 'q': break if not config.IS_LED_STRIP_V2: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_RENDERED, None) else: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_STARTED, None) self.timer.stop() self.kp.stop()
class DownloadNodeJS(object): def __init__(self, node_version): self.NODE_JS_VERSION = node_version self.NODE_JS_TAR_EXTENSION = ".zip" if node_variables.NODE_JS_OS == "win" else ".tar.gz" self.NODE_JS_BINARY_URL = "https://nodejs.org/dist/" + self.NODE_JS_VERSION + "/node-" + self.NODE_JS_VERSION + "-" + node_variables.NODE_JS_OS + "-" + node_variables.NODE_JS_ARCHITECTURE + self.NODE_JS_TAR_EXTENSION self.NODE_JS_BINARY_TARFILE_NAME = self.NODE_JS_BINARY_URL.split( '/')[-1] self.NODE_JS_BINARY_TARFILE_FULL_PATH = os.path.join( node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM, self.NODE_JS_BINARY_TARFILE_NAME) self.animation_loader = AnimationLoader([ "[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]" ], 0.067, "Downloading: " + self.NODE_JS_BINARY_URL + " ") self.interval_animation = None self.thread = None def download(self): try: if os.path.exists(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM): self.rmtree(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else: os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) if os.path.exists(node_variables.NODE_MODULES_PATH): self.rmtree(node_variables.NODE_MODULES_PATH) request = urllib.request.Request(self.NODE_JS_BINARY_URL) request.add_header( 'User-agent', r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1' ) with urllib.request.urlopen(request) as response: with open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, 'wb') as out_file: shutil.copyfileobj(response, out_file) except Exception as err: traceback.print_exc() self.on_error(err) return self.extract() self.on_complete() def start(self): self.thread = create_and_start_thread(self.download, "DownloadNodeJS") if self.animation_loader: self.interval_animation = RepeatedTimer( self.animation_loader.sec, self.animation_loader.animate) def extract(self): sep = os.sep if self.NODE_JS_TAR_EXTENSION != ".zip": with tarfile.open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r:gz") as tar: for member in tar.getmembers(): member.name = sep.join(member.name.split(sep)[1:]) tar.extract( member, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else: if node_variables.NODE_JS_OS == "win": import string from ctypes import windll, c_int, c_wchar_p UNUSUED_DRIVE_LETTER = "" for letter in string.ascii_uppercase: if not os.path.exists(letter + ":"): UNUSUED_DRIVE_LETTER = letter + ":" break if not UNUSUED_DRIVE_LETTER: sublime.message_dialog( "Can't install node.js and npm! UNUSUED_DRIVE_LETTER not found." ) return DefineDosDevice = windll.kernel32.DefineDosDeviceW DefineDosDevice.argtypes = [c_int, c_wchar_p, c_wchar_p] DefineDosDevice( 0, UNUSUED_DRIVE_LETTER, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) try: with zipfile.ZipFile(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r") as zip_file: for member in zip_file.namelist(): if not member.endswith("/"): with zip_file.open(member) as node_file: with open( UNUSUED_DRIVE_LETTER + "\\" + member.replace( "node-" + self.NODE_JS_VERSION + "-" + node_variables.NODE_JS_OS + "-" + node_variables. NODE_JS_ARCHITECTURE + "/", ""), "wb+") as target: shutil.copyfileobj(node_file, target) elif not member.endswith( "node-" + self.NODE_JS_VERSION + "-" + node_variables.NODE_JS_OS + "-" + node_variables.NODE_JS_ARCHITECTURE + "/"): os.mkdir( UNUSUED_DRIVE_LETTER + "\\" + member.replace( "node-" + self.NODE_JS_VERSION + "-" + node_variables.NODE_JS_OS + "-" + node_variables.NODE_JS_ARCHITECTURE + "/", "")) except Exception as e: print("Error: " + traceback.format_exc()) finally: DefineDosDevice( 2, UNUSUED_DRIVE_LETTER, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) def rmtree(self, path): if node_variables.NODE_JS_OS == "win": import string from ctypes import windll, c_int, c_wchar_p UNUSUED_DRIVE_LETTER = "" for letter in string.ascii_uppercase: if not os.path.exists(letter + ":"): UNUSUED_DRIVE_LETTER = letter + ":" break if not UNUSUED_DRIVE_LETTER: sublime.message_dialog( "Can't remove node.js! UNUSUED_DRIVE_LETTER not found.") return DefineDosDevice = windll.kernel32.DefineDosDeviceW DefineDosDevice.argtypes = [c_int, c_wchar_p, c_wchar_p] DefineDosDevice(0, UNUSUED_DRIVE_LETTER, path) try: shutil.rmtree(UNUSUED_DRIVE_LETTER) except Exception as e: print("Error: " + traceback.format_exc()) finally: DefineDosDevice(2, UNUSUED_DRIVE_LETTER, path) else: shutil.rmtree(path) def on_error(self, err): self.animation_loader.on_complete() self.interval_animation.stop() sublime.active_window().status_message( "Can't install Node.js! Check your internet connection!") def on_complete(self): self.animation_loader.on_complete() self.interval_animation.stop() if os.path.isfile(self.NODE_JS_BINARY_TARFILE_FULL_PATH): os.remove(self.NODE_JS_BINARY_TARFILE_FULL_PATH) node_js = NodeJS() npm = NPM() self.animation_loader = AnimationLoader([ "[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]" ], 0.067, "Installing npm dependencies ") self.interval_animation = RepeatedTimer(self.animation_loader.sec, self.animation_loader.animate) try: npm.getCurrentNPMVersion(True) except Exception as e: print("Error: " + traceback.format_exc()) try: npm.install_all() except Exception as e: #print("Error: "+traceback.format_exc()) pass self.animation_loader.on_complete() self.interval_animation.stop() if node_js.getCurrentNodeJSVersion(True) == self.NODE_JS_VERSION: sublime.active_window().status_message( "Node.js " + self.NODE_JS_VERSION + " installed correctly! NPM version: " + npm.getCurrentNPMVersion(True)) else: sublime.active_window().status_message( "Can't install Node.js! Something went wrong during installation." )
for i, x in enumerate(stars_x): pygame.draw.ellipse(screen, (255, 255, 255), [x, stars_y[i], 3, 3]) if death is False: for i, l in enumerate(lasers): if l.end_of_life(): del lasers[i] else: l.draw(screen) for i, a in enumerate(asteroids): if a.laser_collision(l): a.damage() if a.size == 0: del asteroids[i] else: death_text.draw(screen) for a in asteroids: a.tick() a.draw(screen) if player.collision(a): death = True player.tick() pygame.display.flip() clock.tick(60) pygame.quit() asteroid_timer.stop()
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')
class Pong: PADDLE_SIZE = 3 # Antialased ball? # PONG_COLOR_INDEX_BALL_TOP = 8 # PONG_COLOR_INDEX_BALL_LEFT = 9 # PONG_COLOR_INDEX_BALL_RIGHT = 10 # PONG_COLOR_INDEX_BALL_BOTTOM = 11 COLORS = [ (0, 0, 0), # off # ( 10, 10, 10), # grey (255, 0, 0), # red (255, 80, 0), # orange (255, 255, 0), # yellow (0, 255, 0), # green (0, 0, 255), # blue (255, 0, 150), # violet (255, 0, 40), # purple (0, 0, 0), # ball top (0, 0, 0), # ball left (0, 0, 0), # ball right (0, 0, 0) # ball bottom ] SCORE_FONT = { 0: ["222", "202", "202", "202", "222"], 1: ["020", "020", "020", "020", "020"], 2: ["222", "002", "222", "200", "222"], 3: ["222", "002", "222", "002", "222"], 4: ["202", "202", "222", "002", "002"], 5: ["222", "200", "222", "002", "222"], 6: ["222", "200", "222", "202", "222"], 7: ["222", "002", "002", "002", "002"], 8: ["222", "202", "222", "202", "222"], 9: ["222", "202", "222", "002", "002"], } playfield = [x[:] for x in [[0] * config.LED_COLS] * config.LED_ROWS] score = [0, 0] paddle_position_x = [4, 15] paddle_position_y = [3, 3] ball_position = [10, 5] ball_direction = [0.1, 0.2] timer = None loop = True def __init__(self, ipcon): self.okay = False self.ipcon = ipcon if not config.UID_LED_STRIP_BRICKLET: print("Not Configured: LED Strip (required)") return self.led_strip = LEDStrip(config.UID_LED_STRIP_BRICKLET, self.ipcon) try: self.led_strip.get_frame_duration() print("Found: LED Strip ({0})".format( config.UID_LED_STRIP_BRICKLET)) except: print("Not Found: LED Strip ({0})".format( config.UID_LED_STRIP_BRICKLET)) return self.kp = KeyPress(self.ipcon) self.speaker = PongSpeaker(self.ipcon) self.okay = True self.led_strip.set_frame_duration(40) self.led_strip.register_callback( self.led_strip.CALLBACK_FRAME_RENDERED, self.frame_rendered) self.init_game() def init_game(self): self.new_ball() self.paddle_position_y = [3, 3] self.score = [0, 0] def frame_rendered(self, length): self.write_playfield() def write_playfield(self): if not self.okay: return field = copy.deepcopy(self.playfield) self.add_score_to_playfield(field) self.add_paddles_to_playfield(field) self.add_ball_to_playfield(field) # Reorder LED data into R, G and B channel r = [] g = [] b = [] for row in range(config.LED_ROWS): col_range = range(config.LED_COLS) if row % 2 == 0: col_range = reversed(col_range) for col in col_range: r.append(self.COLORS[field[row][col]][config.R_INDEX]) g.append(self.COLORS[field[row][col]][config.G_INDEX]) b.append(self.COLORS[field[row][col]][config.B_INDEX]) # Make chunks of size 16 r_chunk = [r[i:i + 16] for i in range(0, len(r), 16)] g_chunk = [g[i:i + 16] for i in range(0, len(g), 16)] b_chunk = [b[i:i + 16] for i in range(0, len(b), 16)] for i in range(len(r_chunk)): length = len(r_chunk[i]) # Fill up chunks with zeros r_chunk[i].extend([0] * (16 - len(r_chunk[i]))) g_chunk[i].extend([0] * (16 - len(g_chunk[i]))) b_chunk[i].extend([0] * (16 - len(b_chunk[i]))) try: self.led_strip.set_rgb_values(i * 16, length, r_chunk[i], g_chunk[i], b_chunk[i]) except: break def add_score_to_playfield(self, field): for row in range(3): for col in range(5): field[row][col + 1] = int( self.SCORE_FONT[self.score[0]][col][row]) field[row + 17][col + 1] = int( self.SCORE_FONT[self.score[1]][col][row]) def add_ball_to_playfield(self, field): x = max(0, min(19, int(self.ball_position[0]))) y = max(0, min(9, int(self.ball_position[1]))) field[x][y] = config.PONG_COLOR_INDEX_BALL # Antialased ball? # x = max(0, min(19, self.ball_position[0])) # y = max(0, min(9, self.ball_position[1])) # ix = int(x) # iy = int(y) # field[ix][iy] = config.PONG_COLOR_INDEX_BALL # if ix + 1 < config.LED_ROWS: # field[ix+1][iy] = PONG_COLOR_INDEX_BALL_RIGHT # if ix - 1 > 0: # field[ix-1][iy] = PONG_COLOR_INDEX_BALL_LEFT # if iy + 1 < config.LED_COLS: # field[ix][iy+1] = PONG_COLOR_INDEX_BALL_TOP # if iy - 1 > 0: # field[ix][iy-1] = PONG_COLOR_INDEX_BALL_BOTTOM # # dx = x - int(x) # dy = x - int(x) # self.COLORS[PONG_COLOR_INDEX_BALL_RIGHT] = (0, 255*dx/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_LEFT] = (0, 255*(1-dx)/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_TOP] = (0, 255*dy/64, 0) # self.COLORS[PONG_COLOR_INDEX_BALL_BOTTOM] = (0, 255*(1-dy)/64, 0) def add_paddles_to_playfield(self, field): for player in range(2): for i in range(self.PADDLE_SIZE): field[self.paddle_position_x[player]][ self.paddle_position_y[player] + i] = config.PONG_COLOR_INDEX_PLAYER[player] def move_paddle(self, player, change): new_pos = self.paddle_position_y[player] + change if new_pos >= 0 and new_pos <= config.LED_COLS - self.PADDLE_SIZE: self.paddle_position_y[player] = new_pos def new_ball(self): self.ball_position = [(config.LED_ROWS - 1.0) / 2.0, (config.LED_COLS - 1.0) / 2.0] self.ball_direction = [ random.choice([-0.2, 0.2]), random.choice([ random.randrange(1, 9) / 10.0, random.randrange(-9, -1) / 10.0 ]) ] def tick(self): # Move ball for i in range(2): self.ball_position[i] += self.ball_direction[i] # Wall collision top/bottom if self.ball_position[1] < 0 or self.ball_position[ 1] >= config.LED_COLS: self.ball_direction[1] = -self.ball_direction[1] # Wall collision left/right def hit_left_right(player): self.speaker.beep_sirene() self.new_ball() self.score[player] += 1 if self.score[player] > 9: self.score[player] = 0 if self.ball_position[0] < 0: hit_left_right(1) if self.ball_position[0] >= config.LED_ROWS: hit_left_right(0) # Paddle collision def hit_paddle(skew): self.speaker.beep_paddle_hit() self.ball_direction[0] = -self.ball_direction[0] self.ball_direction[1] -= skew for i in range(2): self.ball_direction[i] *= 1.1 # Increase speed if self.ball_direction[0] < 0: if self.paddle_position_x[0] + 0.5 <= self.ball_position[ 0] <= self.paddle_position_x[0] + 1.5: if self.paddle_position_y[0] - 0.5 <= self.ball_position[ 1] <= self.paddle_position_y[ 0] + self.PADDLE_SIZE + 0.5: paddle_skew = (self.paddle_position_y[0] + self.PADDLE_SIZE / 2.0 - self.ball_position[1]) / 10.0 hit_paddle(paddle_skew) if self.ball_direction[0] > 0: if self.paddle_position_x[1] - 0.5 <= self.ball_position[ 0] <= self.paddle_position_x[1] + 0.5: if self.paddle_position_y[1] - 0.5 <= self.ball_position[ 1] <= self.paddle_position_y[ 1] + self.PADDLE_SIZE + 0.5: paddle_skew = (self.paddle_position_y[1] + self.PADDLE_SIZE / 2.0 - self.ball_position[1]) / 10.0 hit_paddle(paddle_skew) def run_game_loop(self): self.frame_rendered(0) self.timer = RepeatedTimer(0.1, self.tick) while self.loop: key = self.kp.read_single_keypress().lower() if key == 'a': self.move_paddle(0, -1) elif key == 's': self.move_paddle(0, 1) elif key == 'k': self.move_paddle(1, -1) elif key == 'l': self.move_paddle(1, 1) elif key == 'r': self.init_game() elif not config.HAS_GUI and key == 'q': break self.led_strip.register_callback( self.led_strip.CALLBACK_FRAME_RENDERED, None) self.timer.stop() self.kp.stop()
player.tick() bottom_barrier.draw(screen) #draw cyan barrier at bottom top_barrier.draw(screen) left_barrier.draw(screen) right_barrier.draw(screen) for i, l in enumerate(lasers): if l.end_of_life(): del lasers[i] l.tick() l.draw(screen) if player.collision(l): death = True if player.victory(): victory = True if victory: victory_text.draw(screen) elif death: death_text.draw(screen) else: player.draw(screen) #draw player pygame.display.flip() clock.tick(60) pygame.display.quit() laser_timer.stop() sys.exit()
class Master: def msg_callback(self, ch, method, properties, body): callback_set = {'SUCCESS': self.success, 'FAIL': self.fail, 'AWAKE': self.update_slave_response_time, 'STOP': self.stop, 'ADD_SLAVE': self.add_slave, 'KILL_SLAVE': self.kill_slave, 'RESTART_SLAVE': self.restart_slave, 'STAT': self.stat, 'START': self.start, 'RECONFIGURE': self.configure, 'REFRESH': self.refresh } try: command = body[:body.find(' ')] info = body[body.find(' ')+1:] if command in callback_set: callback_set[command](ujson.loads(info)) else: logging.debug(" [x] Unknown command %r" % (str(body),)) except KeyError as e: if str(e) == "'Queue.DeclareOk'": logging.debug("Queue.DelcareOk at %r" % (str(body),)) else: logging.error("Unknown KeyError at %r:" % (str(body),)) except RuntimeError as e: if 'recursion' in str(e): logging.error('MAXIMUM RECURSION ERROR') def __init__(self, conf_file): self.config = ConfigParser.ConfigParser(allow_no_value=True) self.clean_time_gap = None self.wait_time_for_slave = None self.master_queue_name = None self.task_queue_name = None self.task_queue_size_limit = None self.task_file_name = None self.task_counter_file = None self.ssh_key = None self.s3_bucket = None self.s3_folder = None self.slave_num_every_packup = None self.slave_max_sec_each_task = None self.slave_python_version = None self.master_ip = None self.slaves_ip = None self.slave_awake_frequency = None self.configure(conf_file) self.last_wake_time = None self.repeated_timer = None self.is_started = False self.pop_forever_handler = None logging.info('Starting task manager...') self.task_manager = TaskManager(self.task_file_name, self.task_counter_file) logging.info('Starting slave manager...') self.slave_manager = SlaveManager(master_ip=self.master_ip, slaves_ip=self.slaves_ip, ssh_key=self.ssh_key, s3_bucket=self.s3_bucket, s3_folder=self.s3_folder, slave_num_every_packup=self.slave_num_every_packup, slave_max_sec_each_task=self.slave_max_sec_each_task, slave_python_version=self.slave_python_version, slave_awake_frequency=self.slave_awake_frequency, slave_buffer_size=1) logging.info('Starting connection manager...') self.message_connection = ConnectionManager(queue_name=self.master_queue_name, durable=False, callback=self.msg_callback, no_ack=True) def run(self): logging.info(' [*] Waiting for messages. To exit press CTRL+C') try: self.message_connection.start_accepting_message() except KeyboardInterrupt: logging.info('Stopping master...') master.stop(None) except EOFError: logging.info('Download finishes. Shutting down master.') master.stop(None) # except Exception as e: # logging.info(str(e)) # logging.info('Stopping master...') # TODO: write all configuration in one file def configure(self, conf_file): self.config.read(conf_file) self.clean_time_gap = self.config.getint('main', 'clean_time_gap') self.wait_time_for_slave = self.config.getint('main', 'wait_time_for_slave') self.slave_awake_frequency = self.config.get('main', 'slave_awake_frequency') self.master_ip = self.config.get('main', 'master_private_ip') self.slaves_ip = self.config.get('main', 'slaves_private_ip') self.master_queue_name = self.config.get('main', 'master_queue_name') self.task_queue_name = self.config.get('main', 'task_queue_name') self.task_file_name = self.config.get('main', 'task_file') self.task_queue_size_limit = int(self.config.get('main', 'task_queue_size_limit')) self.task_counter_file = self.config.get('main', 'task_counter_file') self.ssh_key = self.config.get('main', 'ssh_key') self.s3_bucket = self.config.get('main', 's3_bucket') self.s3_folder = self.config.get('main', 's3_folder') self.slave_num_every_packup = self.config.get('main', 'slave_num_every_packup') self.slave_max_sec_each_task = self.config.get('main', 'slave_max_sec_each_task') self.slave_python_version = self.config.get('main', 'slave_python_version') def add_slave(self, slave_info): if self.slave_manager.exist_slave(slave_info): logging.info('Slave ' + slave_info['host'] + ' already exists.') return logging.info('master: add slave' + str(slave_info)) new_slave_info = self.slave_manager.add_slave(slave_info) self.slave_manager.run_slave(new_slave_info) # TODO: def kill_slave(self, slave_info): if not self.slave_manager.exist_slave(slave_info): return logging.info('kill slave ' + str(slave_info)) self.slave_manager.kill_slave(slave_info) def restart_slave(self, slave_info): logging.info(slave_info['host']) logging.info('restart_slave' + str(slave_info)) self.kill_slave(slave_info) self.add_slave(slave_info) def start(self, info): logging.info('Master Starts') self.last_wake_time = datetime.datetime.utcnow() self.is_started = True self.pop_forever_handler = threading.Thread(target=self.start_popping_tasks) self.pop_forever_handler.start() self.repeated_timer = RepeatedTimer(self.clean_time_gap, self.notice_refresh, None) def pop_forever(self): self.start_popping_tasks() def get_task_queue_size(self): pass # TODO: There is a bottle neck here def start_popping_tasks(self): task_connection = ConnectionManager(queue_name=self.task_queue_name, durable=True, no_ack=False) eof_reached = False while self.is_started and not eof_reached: current_task_queue_size = task_connection.get_task_queue_size() while self.is_started and current_task_queue_size < self.task_queue_size_limit: task = self.task_manager.pop_task() if task is None: # TODO: Don't use Error. Just break and handle the case later in this function logging.info('EOF Reached') eof_reached = True break message = 'WORK ' + ujson.dumps(task) task_connection.publish(message) current_task_queue_size += 1 task_connection.stop() def fail(self, slave_task_info): self.task_manager.add_task(slave_task_info['task']) self.slave_manager.update_last_response(slave_task_info) def success(self, slave_task_info): slave_info = self.slave_manager.update_last_response(slave_task_info) def update_slave_response_time(self, slave_task_info): slave_info = self.slave_manager.update_last_response(slave_task_info) def stop(self, info): self.is_started = False self.notice_slaves_stop() if self.pop_forever_handler is not None: self.pop_forever_handler.join() if self.repeated_timer is not None: self.repeated_timer.stop() self.slave_manager.stop() self.task_manager.stop() self.message_connection.stop() def notice_slaves_stop(self): task_connection = ConnectionManager(queue_name=self.task_queue_name, durable=True, no_ack=False) screen_list = [key for key in self.slave_manager.slave_dict.keys()] for screen in screen_list: task_connection.publish('STOP {}') # task_connection.broadcast_task('STOP {}') task_connection.stop() def refresh(self, info): cur_progress, total_task = self.task_manager.get_progress() logging.info('downloading {}/{} files'.format(cur_progress, total_task)) if not self.is_started: return # if time interval met, check failed slave if self.last_wake_time is None: self.last_wake_time = datetime.datetime.utcnow() if self.last_wake_time + datetime.timedelta( seconds=self.clean_time_gap) > datetime.datetime.utcnow(): return failed_slaves = self.slave_manager.get_failed_slaves(self.wait_time_for_slave) if len(failed_slaves) != 0: logging.info('Finding failed slaves... ' + str(failed_slaves)) for slave in failed_slaves: self.restart_slave(slave) self.last_wake_time = datetime.datetime.utcnow() def notice_refresh(self, info): try: self.message_connection.publish('REFRESH {}') except IndexError: logging.critical('INDEX_ERROR') def stat(self, info): logging.info('=====================================') logging.info('Num of slave: ', self.slave_manager.get_num_slaves()) logging.info('=====================================') if len(info) > 0: for slave in self.slave_manager.slave_list: if slave['last_response'] is None: delta = 'new slave' else: delta = datetime.datetime.utcnow() - slave['last_response'] logging.info(slave['host'], '|', slave['queue'], '|', delta) logging.info('====================================')
class Robot: def __init__(self, clientID, robotId, robotHandle): self._name = '' self._clientID = clientID self._id = robotId self._robotHandle = robotHandle self._jointNames = GB_CROBOT_JOINT_NAMES self._handJointNames = GB_CROBOT_HAND_JOINT_NAMES self._x = 1 print(self._jointNames) self._jointHandles = [ vrep.simxGetObjectHandle(clientID, jointName, vrep.simx_opmode_blocking)[1] for jointName in self._jointNames ] self._handJointHandles = [ vrep.simxGetObjectHandle(clientID, handJointName, vrep.simx_opmode_blocking)[1] for handJointName in self._handJointNames ] # --------------------------------------------------------------------------------------------------- # Initialize EigenGrasps Info (after initializing the hand specifics) if(self._id == RC.CJACO_ARM_HAND or self._id == RC.CKUKA_ARM_BARRETT_HAND \ or self._id == RC.CUR5_ARM_BARRETT_HAND): self.eigen_grasp_initialize() # --------------------------------------------------------------------------------------------------- # Initialize Timer Task #self.initializeTimerTask() #def __del__(self): #self.finalizeTimerTask() # ######################################################################################################## # INIT TIMER TASK # def initializeTimerTask(self): # 1 - Timer essential properties self._timerInterval = 1 # 2 - Start Timer self._rt = RepeatedTimer( self._timerInterval, self.doTimerTask) # it auto-starts, no need of rt.start() def finalizeTimerTask(self): self._rt.stop() # ######################################################################################################## # INIT EIGEN GRASPS # def eigen_grasp_initialize(self): # Eigen Graps List # global gb_hand_eigengrasps gb_hand_eigengrasps = [ EigenGrasp(self.getDofsCount(), 0.0) for i in range(GB_CEIGENGRASP_NO) ] for i in range(len(gb_hand_eigengrasps)): gb_hand_eigengrasps[i].setVals(GB_HAND_EIGENGRASP_VALUES[i]) # Eigen Graps Interface # global gb_hand_eigengrasp_interface gb_hand_eigengrasp_interface = EigenGraspInterface( self, gb_hand_eigengrasps, GB_HAND_EIGENGRASP_ORI) def accumulateMove(self, dofs): handJointPoses = self.getCurrentHandJointPoses() for dof in dofs: for i in range(self.getHandJointsCount()): handJointPoses[i] = dof * BARRETT_HAND_JOINT_DOF_RATIOS[ self._handJointNames[i]] return handJointPoses def id(self): return self._id def getRobotWorldPosition(self): res, robotPos = vrep.simxGetObjectPosition(self._clientID, self._robotHandle, -1, vrep.simx_opmode_oneshot) return robotPos def getEndTipWorldPosition(self): return RC.getObjectWorldPosition(GB_CEND_TIP_NAME) def getEndTipOrientation(self): return RC.getObjectOrientation(GB_CEND_TIP_NAME) def getEndTipVelocity(self): return RC.getObjectVelocity(GB_CEND_TIP_NAME) def getDOFRange(self, i): return -3.14, 3.14 # This name is immutable, required by eigen_grasp def getDofsCount(self): return len(GB_BARRETT_HAND_EIGENGRASP_VALUES[0]) def getJointsCount(self): return len(self._jointHandles) def getHandJointsCount(self): return len(self._handJointHandles) def getCurrentHandJointPoses(self): handJointPoses = [] for i in range(len(self._handJointNames)): res, handJointHandle = vrep.simxGetObjectHandle( self._clientID, self._handJointNames[i], vrep.simx_opmode_oneshot_wait) pos = RC.getJointPosition(handJointHandle) handJointPoses.append(pos) return handJointPoses def getJointCurrentPos(self, jointName): res, jointHandle = vrep.simxGetObjectHandle( self._clientID, jointName, vrep.simx_opmode_oneshot_wait) return RC.getJointPosition(jointHandle) # This name is immutable, required by eigen_grasp def getCurrentDofs(self): dofs = [1] * self.getDofsCount() handJointPoses = self.getCurrentHandJointPoses() for i in range(len(dofs)): for j in range(len(handJointPoses)): dofs[i] = handJointPoses[j] / BARRETT_HAND_JOINT_DOF_RATIOS[ self._handJointNames[j]] return dofs # !NOTE: useSignalToJoint means that the joint Control Loop is enabled & in Custom Control Mode (Signal to Joint Control Callback Script) def setJointVelocity(self, jointIndex, vel, isHandJoint=False, useSignalToJoint=0): if (isHandJoint): jointSignalPrefixes = GB_CROBOT_HAND_JOINT_SIGNAL_NAME_PREFIXES else: jointSignalPrefixes = GB_CROBOT_JOINT_SIGNAL_NAME_PREFIXES # http://www.coppeliarobotics.com/helpFiles/en/jointDescription.htm # Signal to the joint control callback script if (useSignalToJoint): jointSignalName = jointSignalPrefixes[jointIndex] + "TargetVel" res = vrep.simxSetFloatSignal( self._clientID, jointSignalName, vel, vrep.simx_opmode_oneshot_wait ) # set the signal value: !!simx_opmode_oneshot_wait else: res = vrep.simxSetJointTargetVelocity( self._clientID, self._jointHandles[jointIndex], vel, # target velocity vrep.simx_opmode_blocking) if (res != 0): print('Set Joint Velocity Error', res) return res # !NOTE: useSignalToJoint means that the joint Control Loop is enabled & in Custom Control Mode (Signal to Joint Control Callback Script) def setJointForce(self, jointIndex, force, isHandJoint=False, useSignalToJoint=0): if (isHandJoint): jointSignalPrefixes = GB_CROBOT_HAND_JOINT_SIGNAL_NAME_PREFIXES else: jointSignalPrefixes = GB_CROBOT_JOINT_SIGNAL_NAME_PREFIXES # Signal to the joint control callback script jointSignalName = jointSignalPrefixes[jointIndex] + "Force" if (useSignalToJoint): res = vrep.simxSetFloatSignal( self._clientID, jointSignalName, force, vrep.simx_opmode_oneshot_wait ) # set the signal value: !!simx_opmode_oneshot_wait else: res = vrep.simxSetJointForce( self._clientID, self._jointHandles[jointIndex], force, # force to apply vrep.simx_opmode_blocking) if (res != 0): print('Set Joint Force Error', res) return res def getCurrentJointForces(self): forces = [] for i in range(len(self._jointHandles)): forces.append(RC.getJointForce(self._jointHandles[i])) return forces # action containing eigen graps ams of KUKA_ARM_JOINT_NAMES respectively # !NOTE: Current condition: Target is velocity command to the joint # Oct 14: Since working with custom control is not yet cleared yet, set force/torque and velocity does not work! # -> Tentative solution is disabling Control loop for joints targeted, then set the target velocity directly using # simSetJointTargetVelocity, as specified in this link: http://www.coppeliarobotics.com/helpFiles/en/jointDescription.htm # # When the joint motor is enabled and the control loop is disabled, then the joint will try to reach the desired # target velocity given the maximum torque/force it is capable to deliver. When that maximum torque/force is very high, # the target velocity is instantaneously reached and the joint operates in velocity control, otherwise it operates at # the specified torque/force until the desired target velocity is reached (torque/force control). # def applyAction(self, action, requestRemoteServer=True): # if (requestRemoteServer): if (self._id == RC.CYOUBOT): remoteObjectName = 'youBot' else: remoteObjectName = RC.CSERVER_REMOTE_API_OBJECT_NAME scale = 1 if (self._id == RC.CKUKA_ARM_BARRETT_HAND): scale = 1 elif (self._id == RC.CJACO_ARM_HAND): hand_eigengrasp_amps = action dofs = gb_hand_eigengrasp_interface.toDOF(hand_eigengrasp_amps) action = self.accumulateMove(dofs) # dofs -> jointPoses action = [action[i] * scale for i in range(len(action))] # ----------------------------------------------------------------------- # inputInts = [] inputFloats = action inputStrings = [] inputBuffer = bytearray() print('ApplyAction:', action) res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, remoteObjectName, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_ROBOT_ACT, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) # =================================================================================================================================== # # move simulation ahead one time step vrep.simxSynchronousTrigger(self._clientID) return 1 def getSuctionPadTipInfo(self): inputInts = [self._robotHandle] #[objHandles[16]] inputFloats = [1] inputStrings = [] inputBuffer = bytearray() res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, RC.CSERVER_REMOTE_API_OBJECT_NAME, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_GET_SUCTION_PAD_TIP_INFO, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) return retFloats # ======================================================================================================================================== # JOIN CONTROL --------------------------------------------------------------------------------------------------------------------------- # # # http://www.forum.coppeliarobotics.com/viewtopic.php?f=9&t=497 # The way joints operate in V-REP is directly linked to the ODE or Bullet physics engines. # # VELOCITY CONTROL: # !NOTE: THIS REQUIRES CONTROL LOOP BE DISABLED (OF COURSE, MOTOR ENABLED) # # When in velocity control (i.e. motor is enabled, position control is disabled (Uncheck it in joint's dynamic properties dialog): # # You specify a target velocity # You specify a max. torque # If current velocity is below the target velocity, the max. torque is applied # If current velocity is above the target velocity, a negative torque is applied # # http://www.coppeliarobotics.com/helpFiles/en/jointDescription.htm # When the joint motor is enabled and the control loop is disabled, then the joint will try # to reach the desired target velocity given the maximum torque/force it is capable to deliver. # # When that maximum torque/force is very high, the target velocity is instantaneously reached # and the joint operates in velocity control, # FORCE/TORQUE CONTROL: # Otherwise it operates at the specified torque/force until the desired target velocity is reached (torque/force control). # # This means that if you want to control your joint in force/torque, # just specify a target velocity very high (e.g. that will never be reached). # To modulate the torque/force, use the simSetJointForce function. # # 1) the engine will apply the specified torque/force to the joint # 2) if the load on the joint is very small, the maximum velocity will be reached in one # simulation step. And the joint will stay at that maximum velocity # 3) if the load on the joint is high, the joint will accelerate, until the maximum velocity is reached # SIDE NOTES by Coppelia: # http://www.forum.coppeliarobotics.com/viewtopic.php?f=9&t=497 # Well, # # when you measure the force/torque that is applied to a joint, it always depends what is acting upon the joint and how. # Let's take an example with a revolute joint: # # 1) the motor of the joint is disabled # 2) the joint has no free movement because its lower limit is 0, and its higher limit is 0 too # 3) the rotation axis of the joint lies in the x/y plane # # If a mass is attached to the joint on one side, you will measure a torque of T=D*M*G (Distance*Mass*Gravity). # If the mass is attached to the joint on the other side, you will measure a torque of -T (the opposite). # # In case your joint exerts a torque/force, you will also be able to measure a positive or negative torque/force, depending on the situation. # ======================================================================================================================================== # JOINT FORCE CONTROL -------------------------------------------------------------------------------------------------------------------- # def doJointForceControl(self, jointIndex, inputForce, handJoint=False): # get the current joint force if (handJoint): jointHandle = self._handJointHandles[jointIndex] else: jointHandle = self._jointHandles[jointIndex] res, curForce = vrep.simxGetJointForce(self._clientID, jointHandle, vrep.simx_opmode_blocking) if res != 0: raise Exception() curVel = RC.getJointVelocity(jointHandle) # To make the joint balance around the position # if force has changed signs, # we need to change the target velocity sign joint_target_vel = 10000 if (np.sign(curForce) < 0): joint_target_vel *= (-1) #print('SWITCH FORCE', jointIndex, curForce, curVel) res = self.setJointVelocity(jointIndex, joint_target_vel, handJoint) if res != 0: raise Exception() # and now modulate the force res = self.setJointForce(jointIndex, inputForce, handJoint) # force to apply if res != 0: raise Exception() return res def applyAllJointActionForces(self, actionForces, handJoint=False): # joint target velocities discussed below # !Note: len(self._jointNames) == len(self._jointHandles) jointCount = len(self._handJointNames) if handJoint else len( self._jointNames) for i in range(jointCount): self.applyJointSingleActionForce(i, actionForces[i], handJoint) # move simulation ahead one time step vrep.simxSynchronousTrigger(self._clientID) return 1 def applyJointSpecificActionForces(self, actionForces, jointIds, handJoint=False): for i in range(len(jointIds)): self.doJointForceControl(jointIds[i], actionForces[i], handJoint) # move simulation ahead one time step vrep.simxSynchronousTrigger(self._clientID) return 1 # ======================================================================================================================================== # JOINT VEL CONTROL ---------------------------------------------------------------------------------------------------------------------- # # !NOTE: THIS REQUIRES CONTROL LOOP BE DISABLED (OF COURSE, MOTOR ENABLED) def doJointVelocityControl(self, jointIndex, inputVel, handJoint=False): # get the current joint force if (handJoint): jointHandle = self._handJointHandles[jointIndex] else: jointHandle = self._jointHandles[jointIndex] # if force has changed signs, # we need to change the target velocity sign joint_max_torque = 10000 res = self.setJointForce(jointIndex, joint_max_torque, handJoint) if res != 0: raise Exception() # and now modulate the force res, curForce = vrep.simxGetJointForce(self._clientID, jointHandle, vrep.simx_opmode_blocking) if res != 0: raise Exception() if (np.sign(curForce) < 0): inputVel *= (-1) res = self.setJointVelocity(jointIndex, inputVel, handJoint) if res != 0: raise Exception() return res def applyAllJointActionVels(self, actionVels, handJoint=False): # !Note: len(self._jointNames) == len(self._jointHandles) jointCount = len(self._handJointNames) if handJoint else len( self._jointNames) for i in range(jointCount): self.doJointVelocityControl(i, actionVels[i], handJoint) # move simulation ahead one time step vrep.simxSynchronousTrigger(self._clientID) return 1 def applyJointSpecificActionVels(self, actionVels, jointIds, handJoint=False): for i in range(len(jointIds)): self.doJointVelocityControl(jointIds[i], actionVels[i], handJoint) # move simulation ahead one time step vrep.simxSynchronousTrigger(self._clientID) return 1 # ======================================================================================================================================== # JOINT VEL CONTROL ---------------------------------------------------------------------------------------------------------------------- # def commandJointVibration(self, isStart): res = vrep.simxSetFloatSignal( self._clientID, "commandVibration", isStart, vrep.simx_opmode_oneshot_wait ) # set the signal value: !!simx_opmode_oneshot_wait # For working with robotBot only def actRobot(self, actionId): inputInts = [actionId] #[objHandles[16]] inputFloats = [] inputStrings = [] inputBuffer = bytearray() if (self._id == RC.CYOUBOT): remoteObjectName = 'youBot' else: remoteObjectName = RC.CSERVER_REMOTE_API_OBJECT_NAME res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, remoteObjectName, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_ROBOT_ACT, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) def getOperationState(self): inputInts = [] #[objHandles[16]] inputFloats = [] inputStrings = [] inputBuffer = bytearray() if (self._id == RC.CYOUBOT): remoteObjectName = 'youBot' else: remoteObjectName = RC.CSERVER_REMOTE_API_OBJECT_NAME res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, remoteObjectName, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_GET_OPERATION_STATE, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) return retInts[0] def getObservation(self): observation = [] #endTipPos = self.getEndTipWorldPosition() isTaskObjHandBalance = RC.isTaskObjHandBalance() isTaskObjSuctionBalance = RC.isTaskObjSuctionBalance() isTaskObjHexapodBalance = RC.isTaskObjHexapodBalance() isTaskObjHold = RC.isTaskObjHold() isTaskObjCatch = RC.isTaskObjCatch() isTaskObjTimelyPick = RC.isTaskObjTimelyPick() isTaskObjTimelyCatch = RC.isTaskObjTimelyCatch() if (False): #isTaskObjTimelyPick inputInts = [self._robotHandle] #[objHandles[16]] inputFloats = [] inputStrings = '' inputBuffer = bytearray() ##inputBuffer.append(78) ##inputBuffer.append(42) res, retInts, randomInitJointPose, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, RC.CUR5_ARM_NAME, \ vrep.sim_scripttype_childscript, \ 'gbGetRandomInitJointPoseFromClient', \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) observation.append( np.array(randomInitJointPose[0], dtype=np.float32)) #self._jointHandles #for i in range(len(randomInitJointPose)): #observation.append(np.array(randomInitJointPose[i], dtype=np.float32)) for i in range(len(self._jointHandles)): if (isTaskObjHexapodBalance): pos = RC.getJointPosition(self._jointHandles[i]) # Pos # observation.append(np.array(pos, dtype=np.float32)) else: if (i == 0 or i == 3 or i == 4 or i == 5): pos = RC.getJointPosition(self._jointHandles[i]) #vel = RC.getJointVelocity(self._jointHandles[i]) # if (isTaskObjHandBalance or isTaskObjSuctionBalance): observation.append(np.array(pos, dtype=np.float32)) # Pos #observation.append(np.array(vel, dtype=np.float32)) # Vel elif (isTaskObjHold): force = RC.getJointForce(self._jointHandles[i]) observation.append(np.array(force, dtype=np.float32)) # Force if (isTaskObjHandBalance): # HAND INFO (!Hand is also one factor that makes up the object condition (pos & orient), therefore should # also be added into the environment) # # Hand Joint Pos handJointPoses = self.getCurrentHandJointPoses() observation.append(np.array(handJointPoses[2], dtype=np.float32)) observation.append(np.array(handJointPoses[7], dtype=np.float32)) elif (isTaskObjHold): # HAND INFO (!Hand is also one factor that makes up the object condition (pos & orient), therefore should # also be added into the environment) # # Hand Joint Pos handJointPoses = self.getCurrentHandJointPoses() observation.append(np.array(handJointPoses[2], dtype=np.float32)) observation.append(np.array(handJointPoses[7], dtype=np.float32)) handJointForces = [ RC.getJointForce(self._handJointHandles[0]), RC.getJointForce(self._handJointHandles[1]) ] observation.append(np.array(handJointForces[0], dtype=np.float32)) observation.append(np.array(handJointForces[1], dtype=np.float32)) elif (isTaskObjCatch): pos0 = RC.getJointPosition(self._jointHandles[0]) vel0 = RC.getJointVelocity(self._jointHandles[0]) observation.append(np.array(pos0, dtype=np.float32)) observation.append(np.array(vel0, dtype=np.float32)) return observation def getCurrentBaseJointPos(self): res, jointHandle = vrep.simxGetObjectHandle( self._clientID, GB_CBASE_JOINT_NAME, vrep.simx_opmode_oneshot_wait) res, pos = vrep.simxGetJointPosition(self._clientID, jointHandle, vrep.simx_opmode_streaming) # Wait until the first data has arrived (just any blocking funtion): vrep.simxGetPingTime(self._clientID) # Now you can read the data that is being continuously streamed: res, pos = vrep.simxGetJointPosition(self._clientID, jointHandle, vrep.simx_opmode_buffer) return pos def resetRobot(self): # !NOTE: V-REP NOT ALLOW ALL-VOID PARAMETERS, SO WE HAVE TO ADD A DUMMY VALUE INTO inputFloats[] inputInts = [] inputFloats = [1] inputStrings = [] inputBuffer = bytearray() if (self._id == RC.CYOUBOT): remoteObjectName = 'youBot' else: remoteObjectName = RC.CSERVER_REMOTE_API_OBJECT_NAME res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, remoteObjectName, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_RESET_ROBOT, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) # Wait here until the robot finish the reset #time.sleep(3) # =================================================================================================================================== # # move simulation ahead one time step (only meaningful in V-Rep server synchronous mode! vrep.simxSynchronousTrigger(self._clientID) def detectCollisionWith(self, objectName): #res, objectCollisionHandle = vrep.simxGetCollisionHandle(self._clientID, objectName, vrep.simx_opmode_oneshot_wait) inputInts = [self._robotHandle] #[objHandles[16]] inputFloats = [53.21, 17.39] inputStrings = [objectName] inputBuffer = bytearray() res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, RC.CSERVER_REMOTE_API_OBJECT_NAME, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_DETECT_COLLISION, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) if (retInts[0]): print('COLLIDED WITH: ', objectName) return retInts[0] def checkObjectCaught(self): inputInts = [self._robotHandle] #[objHandles[16]] inputFloats = [1] inputStrings = [] inputBuffer = bytearray() res, retInts, retFloats, retStrings, retBuffer = vrep.simxCallScriptFunction(self._clientID, RC.CSERVER_REMOTE_API_OBJECT_NAME, \ vrep.sim_scripttype_childscript, \ CSERVER_REMOTE_FUNC_ROBOT_CAUGHT_OBJ, \ inputInts, inputFloats, inputStrings, inputBuffer, \ vrep.simx_opmode_oneshot_wait) if (retInts[0]): print('SOME OBJECT CAUGHT: ') return retInts[0] def distanceFromEndTipToPos(self, pos): result = 0 endTipPos = self.getEndTipWorldPosition() #print('POS:', pos, endTipPos) #distPosLine = norm(np.cross(p2-p1, p1-endTipPos))/norm(p2-p1) distToPos = math.sqrt((pos[0] - endTipPos[0])**2 + (pos[1] - endTipPos[1])**2 + (pos[2] - endTipPos[2])**2) #print('DIST', distToPos) result += distToPos return result def getHandWorldPosition(self): return RC.getObjectWorldPosition(RC.CBARRETT_HAND_NAME) def getHandOrientation(self): eulerAngles = RC.getObjectOrientation(RC.CBARRETT_HAND_NAME) return eulerAngles def getHandVelocity(self): vel = RC.getObjectVelocity(RC.CBARRETT_HAND_NAME) return vel def doInverseKinematicsCalculation(self): count = 0 target_index = 0 change_target_time = dt * 1000 vmax = 0.5 kp = 200.0 kv = np.sqrt(kp) # define variables to share with nengo q = np.zeros(len(joint_handles)) dq = np.zeros(len(joint_handles)) # NOTE: main loop starts here ----------------------------------------- target_xyz = RC.getObjectWorldPosition("obstacle") track_target.append(np.copy(target_xyz)) # store for plotting target_xyz = np.asarray(target_xyz) for ii, joint_handle in enumerate(joint_handles): old_q = np.copy(q) # get the joint angles _, q[ii] = vrep.simxGetJointPosition(clientID, joint_handle, vrep.simx_opmode_blocking) if _ != 0: raise Exception() # get the joint velocity _, dq[ii] = vrep.simxGetObjectFloatParameter( clientID, joint_handle, 2012, # parameter ID for angular velocity of the joint vrep.simx_opmode_blocking) if _ != 0: raise Exception() # calculate position of the end-effector # derived in the ur5 calc_TnJ class xyz = robot_config.Tx('EE', q) # calculate the Jacobian for the end effector JEE = robot_config.J('EE', q) # calculate the inertia matrix in joint space Mq = robot_config.Mq(q) # calculate the effect of gravity in joint space Mq_g = robot_config.Mq_g(q) # convert the mass compensation into end effector space Mx_inv = np.dot(JEE, np.dot(np.linalg.inv(Mq), JEE.T)) svd_u, svd_s, svd_v = np.linalg.svd(Mx_inv) # cut off any singular values that could cause control problems singularity_thresh = .00025 for i in range(len(svd_s)): svd_s[i] = 0 if svd_s[i] < singularity_thresh else \ 1./float(svd_s[i]) # numpy returns U,S,V.T, so have to transpose both here Mx = np.dot(svd_v.T, np.dot(np.diag(svd_s), svd_u.T)) # calculate desired force in (x,y,z) space dx = np.dot(JEE, dq) # implement velocity limiting lamb = kp / kv x_tilde = xyz - target_xyz sat = vmax / (lamb * np.abs(x_tilde)) scale = np.ones(3) if np.any(sat < 1): index = np.argmin(sat) unclipped = kp * x_tilde[index] clipped = kv * vmax * np.sign(x_tilde[index]) scale = np.ones(3) * clipped / unclipped scale[index] = 1 u_xyz = -kv * (dx - np.clip(sat / scale, 0, 1) * -lamb * scale * x_tilde) u_xyz = np.dot(Mx, u_xyz) # transform into joint space, add vel and gravity compensation u = np.dot(JEE.T, u_xyz) - Mq_g # calculate the null space filter Jdyn_inv = np.dot(Mx, np.dot(JEE, np.linalg.inv(Mq))) null_filter = (np.eye(robot_config.num_joints) - np.dot(JEE.T, Jdyn_inv)) # calculate our secondary control signal q_des = np.zeros(robot_config.num_joints) dq_des = np.zeros(robot_config.num_joints) # calculated desired joint angle acceleration using rest angles for ii in range(1, robot_config.num_joints): if robot_config.rest_angles[ii] is not None: q_des[ii] = (((robot_config.rest_angles[ii] - q[ii]) + np.pi) % (np.pi * 2) - np.pi) dq_des[ii] = dq[ii] # only compensate for velocity for joints with a control signal nkp = kp * .1 nkv = np.sqrt(nkp) u_null = np.dot(Mq, (nkp * q_des - nkv * dq_des)) u += np.dot(null_filter, u_null) # get the (x,y,z) position of the center of the obstacle v = RC.getObjectWorldPosition('obstacle') v = np.asarray(v) # find the closest point of each link to the obstacle for ii in range(robot_config.num_joints): # get the start and end-points of the arm segment p1 = robot_config.Tx('joint%i' % ii, q=q) if ii == robot_config.num_joints - 1: p2 = robot_config.Tx('EE', q=q) else: p2 = robot_config.Tx('joint%i' % (ii + 1), q=q) # calculate minimum distance from arm segment to obstacle # the vector of our line vec_line = p2 - p1 # the vector from the obstacle to the first line point vec_ob_line = v - p1 # calculate the projection normalized by length of arm segment projection = np.dot(vec_ob_line, vec_line) / np.sum((vec_line)**2) if projection < 0: # then closest point is the start of the segment closest = p1 elif projection > 1: # then closest point is the end of the segment closest = p2 else: closest = p1 + projection * vec_line # calculate distance from obstacle vertex to the closest point dist = np.sqrt(np.sum((v - closest)**2)) # account for size of obstacle rho = dist - obstacle_radius if rho < threshold: eta = .02 # feel like i saw 4 somewhere in the paper drhodx = (v - closest) / rho Fpsp = (eta * (1.0 / rho - 1.0 / threshold) * 1.0 / rho**2 * drhodx) # get offset of closest point from link's reference frame T_inv = robot_config.T_inv('link%i' % ii, q=q) m = np.dot(T_inv, np.hstack([closest, [1]]))[:-1] # calculate the Jacobian for this point Jpsp = robot_config.J('link%i' % ii, x=m, q=q)[:3] # calculate the inertia matrix for the # point subjected to the potential space Mxpsp_inv = np.dot(Jpsp, np.dot(np.linalg.pinv(Mq), Jpsp.T)) svd_u, svd_s, svd_v = np.linalg.svd(Mxpsp_inv) # cut off singular values that could cause problems singularity_thresh = .00025 for ii in range(len(svd_s)): svd_s[ii] = 0 if svd_s[ii] < singularity_thresh else \ 1./float(svd_s[ii]) # numpy returns U,S,V.T, so have to transpose both here Mxpsp = np.dot(svd_v.T, np.dot(np.diag(svd_s), svd_u.T)) u_psp = -np.dot(Jpsp.T, np.dot(Mxpsp, Fpsp)) if rho < .01: u = u_psp else: u += u_psp # multiply by -1 because torque is opposite of expected u *= -1 print('u: ', u) for ii, joint_handle in enumerate(joint_handles): # the way we're going to do force control is by setting # the target velocities of each joint super high and then # controlling the max torque allowed (yeah, i know) # get the current joint torque _, torque = \ vrep.simxGetJointForce( clientID, joint_handle, vrep.simx_opmode_blocking) if _ != 0: raise Exception() # if force has changed signs, # we need to change the target velocity sign if np.sign(torque) * np.sign(u[ii]) <= 0: joint_target_velocities[ii] = \ joint_target_velocities[ii] * -1 _ = self.setJointVelocity( ii, joint_target_velocities[ii]) # target velocity if _ != 0: raise Exception() # and now modulate the force _ = self.setJointForce(ii, abs(u[ii])) # force to apply if _ != 0: raise Exception()
class DownloadNodeJS(object): def __init__(self, node_version): self.NODE_JS_VERSION = node_version self.NODE_JS_TAR_EXTENSION = ".zip" if node_variables.NODE_JS_OS == "win" else ".tar.gz" self.NODE_JS_BINARY_URL = "https://nodejs.org/dist/"+self.NODE_JS_VERSION+"/node-"+self.NODE_JS_VERSION+"-"+node_variables.NODE_JS_OS+"-"+node_variables.NODE_JS_ARCHITECTURE+self.NODE_JS_TAR_EXTENSION self.NODE_JS_BINARY_TARFILE_NAME = self.NODE_JS_BINARY_URL.split('/')[-1] self.NODE_JS_BINARY_TARFILE_FULL_PATH = os.path.join(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM, self.NODE_JS_BINARY_TARFILE_NAME) self.animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Downloading: "+self.NODE_JS_BINARY_URL+" ") self.interval_animation = None self.thread = None def download(self): try : if os.path.exists(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM): self.rmtree(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else : os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) if os.path.exists(node_variables.NODE_MODULES_PATH): self.rmtree(node_variables.NODE_MODULES_PATH) request = urllib.request.Request(self.NODE_JS_BINARY_URL) request.add_header('User-agent', r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1') with urllib.request.urlopen(request) as response : with open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, 'wb') as out_file : shutil.copyfileobj(response, out_file) except Exception as err : traceback.print_exc() self.on_error(err) return self.extract() self.on_complete() def start(self): self.thread = create_and_start_thread(self.download, "DownloadNodeJS") if self.animation_loader : self.interval_animation = RepeatedTimer(self.animation_loader.sec, self.animation_loader.animate) def extract(self): sep = os.sep if self.NODE_JS_TAR_EXTENSION != ".zip" : with tarfile.open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r:gz") as tar : for member in tar.getmembers() : member.name = sep.join(member.name.split(sep)[1:]) tar.extract(member, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) else : if node_variables.NODE_JS_OS == "win" : import string from ctypes import windll, c_int, c_wchar_p UNUSUED_DRIVE_LETTER = "" for letter in string.ascii_uppercase: if not os.path.exists(letter+":") : UNUSUED_DRIVE_LETTER = letter+":" break if not UNUSUED_DRIVE_LETTER : sublime.message_dialog("Can't install node.js and npm! UNUSUED_DRIVE_LETTER not found.") return DefineDosDevice = windll.kernel32.DefineDosDeviceW DefineDosDevice.argtypes = [ c_int, c_wchar_p, c_wchar_p ] DefineDosDevice(0, UNUSUED_DRIVE_LETTER, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) try: with zipfile.ZipFile(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r") as zip_file : for member in zip_file.namelist() : if not member.endswith("/") : with zip_file.open(member) as node_file: with open(UNUSUED_DRIVE_LETTER + "\\"+ member.replace("node-"+self.NODE_JS_VERSION+"-"+node_variables.NODE_JS_OS+"-"+node_variables.NODE_JS_ARCHITECTURE+"/", ""), "wb+") as target : shutil.copyfileobj(node_file, target) elif not member.endswith("node-"+self.NODE_JS_VERSION+"-"+node_variables.NODE_JS_OS+"-"+node_variables.NODE_JS_ARCHITECTURE+"/"): os.mkdir(UNUSUED_DRIVE_LETTER + "\\"+ member.replace("node-"+self.NODE_JS_VERSION+"-"+node_variables.NODE_JS_OS+"-"+node_variables.NODE_JS_ARCHITECTURE+"/", "")) except Exception as e: print("Error: "+traceback.format_exc()) finally: DefineDosDevice(2, UNUSUED_DRIVE_LETTER, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) def rmtree(self, path) : if node_variables.NODE_JS_OS == "win" : import string from ctypes import windll, c_int, c_wchar_p UNUSUED_DRIVE_LETTER = "" for letter in string.ascii_uppercase: if not os.path.exists(letter+":") : UNUSUED_DRIVE_LETTER = letter+":" break if not UNUSUED_DRIVE_LETTER : sublime.message_dialog("Can't remove node.js! UNUSUED_DRIVE_LETTER not found.") return DefineDosDevice = windll.kernel32.DefineDosDeviceW DefineDosDevice.argtypes = [ c_int, c_wchar_p, c_wchar_p ] DefineDosDevice(0, UNUSUED_DRIVE_LETTER, path) try: shutil.rmtree(UNUSUED_DRIVE_LETTER) except Exception as e: print("Error: "+traceback.format_exc()) finally: DefineDosDevice(2, UNUSUED_DRIVE_LETTER, path) else : shutil.rmtree(path) def on_error(self, err): self.animation_loader.on_complete() self.interval_animation.stop() sublime.active_window().status_message("Can't install Node.js! Check your internet connection!") def on_complete(self): self.animation_loader.on_complete() self.interval_animation.stop() if os.path.isfile(self.NODE_JS_BINARY_TARFILE_FULL_PATH) : os.remove(self.NODE_JS_BINARY_TARFILE_FULL_PATH) node_js = NodeJS() npm = NPM() self.animation_loader = AnimationLoader(["[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]"], 0.067, "Installing npm dependencies ") self.interval_animation = RepeatedTimer(self.animation_loader.sec, self.animation_loader.animate) try : npm.getCurrentNPMVersion(True) except Exception as e: print("Error: "+traceback.format_exc()) try : npm.install_all() except Exception as e : #print("Error: "+traceback.format_exc()) pass self.animation_loader.on_complete() self.interval_animation.stop() if node_js.getCurrentNodeJSVersion(True) == self.NODE_JS_VERSION : sublime.active_window().status_message("Node.js "+self.NODE_JS_VERSION+" installed correctly! NPM version: "+npm.getCurrentNPMVersion(True)) else : sublime.active_window().status_message("Can't install Node.js! Something went wrong during installation.")
class MpmeRadioPage(tk.Frame): """ Class for the Radio page """ def __init__(self, parent, controller): """ Initialize the page. """ tk.Frame.__init__(self, parent) self.MINIMUM_FREQ = 87.5 self.MAXIMUM_FREQ = 108.0 self.controller = controller self.radio_freq_value = self.controller.settings_object.get_radio_freq( ) self.radio_volume = self.controller.settings_object.get_radio_volume() # When the user clicks on this button, call the # show_frame method to make the main screen appear. button_start = tk.Button( self, text='Start', command=lambda: self.controller.show_frame(MpmeStartPage)) # This control displays the frequency. self.frequency_display = tk.Label(self, text=self.radio_freq_value, font=('', 16)) # This control is for the radio volume. radio_volume_slider = VolumeSlider(self, from_=0, to=100, orient=tk.HORIZONTAL, label="VOLUME", length=290) radio_volume_slider.set( self.controller.settings_object.get_radio_volume()) # This slide control can control the radio frequency. self.radio_freq_slider = RadioFreqSlider( self, from_=self.MINIMUM_FREQ, to=self.MAXIMUM_FREQ, resolution=0.1, length=290, orient=tk.HORIZONTAL, label='FREQUENCY', variable=self.radio_freq_value) self.radio_freq_slider.set(float(self.radio_freq_value)) # These buttons can also change the radio frequency. scan_back = tk.Button(self, text='<< Scan', command=lambda: self.scan(-.1)) adjust_back = tk.Button(self, text='<', command=lambda: self.adjust_freq(-.1)) adjust_forward = tk.Button(self, text='>', command=lambda: self.adjust_freq(.1)) scan_forward = tk.Button(self, text='Scan >>', command=lambda: self.scan(.1)) # The preset buttons preset_1 = tk.Button( self, text=self.controller.settings_object.get_preset(1), command=lambda: self.preset(1)) preset_2 = tk.Button( self, text=self.controller.settings_object.get_preset(2), command=lambda: self.preset(2)) preset_3 = tk.Button( self, text=self.controller.settings_object.get_preset(3), command=lambda: self.preset(3)) preset_4 = tk.Button( self, text=self.controller.settings_object.get_preset(4), command=lambda: self.preset(4)) preset_5 = tk.Button( self, text=self.controller.settings_object.get_preset(5), command=lambda: self.preset(5)) preset_6 = tk.Button( self, text=self.controller.settings_object.get_preset(6), command=lambda: self.preset(6)) preset_7 = tk.Button( self, text=self.controller.settings_object.get_preset(7), command=lambda: self.preset(7)) preset_8 = tk.Button( self, text=self.controller.settings_object.get_preset(8), command=lambda: self.preset(8)) self.presets = [ preset_1, preset_2, preset_3, preset_4, preset_5, preset_6, preset_7, preset_8 ] # The controls to delete all presets delete_button = tk.Button(self, text='Delete all presets', command=lambda: self.confirm_delete()) self.confirmation_label = tk.Label(self, text='Are you sure?') self.button_yes = tk.Button(self, text='Yes', command=lambda: self.delete_all_presets()) self.button_no = tk.Button(self, text='No', command=lambda: self.hide_confirmation()) # Specify the geometry to place the widgets. button_start.grid(row=1, column=1) self.frequency_display.grid(row=1, column=2) radio_volume_slider.grid(row=2, column=1, columnspan=4) self.radio_freq_slider.grid(row=3, column=1, columnspan=4) scan_back.grid(row=4, column=1) adjust_back.grid(row=4, column=2) adjust_forward.grid(row=4, column=3) scan_forward.grid(row=4, column=4) preset_1.grid(row=5, column=1) preset_2.grid(row=5, column=2) preset_3.grid(row=5, column=3) preset_4.grid(row=5, column=4) preset_5.grid(row=6, column=1) preset_6.grid(row=6, column=2) preset_7.grid(row=6, column=3) preset_8.grid(row=6, column=4) delete_button.grid(row=7, column=1, columnspan=4) # Start the simulated radio reception. self.radio_receiver = RadioReceiver(self.radio_freq_value, self.radio_volume) def start_reception(self): self.timer = RepeatedTimer(1, self.receive_signal) def receive_signal(self): """ Receive the simulated "radio signal". """ # Do this by checking the file of stations that are "broadcasting". if self.radio_receiver.receiving_signal(self.radio_freq_value): # Indicate we're getting the signal with an * after the frequency. self.frequency_display.config(text=self.radio_freq_value + '*') else: self.frequency_display.config(text=self.radio_freq_value) # I need to look into this! This method can't be right! def stop_reception(self): """ Turn off the simulated "radio reception". """ if hasattr(self, 'timer'): self.timer.stop() def change_radio_freq(self, freq): """ Change the radio frequency. """ self.radio_freq_value = str(freq) self.frequency_display.config(text=self.radio_freq_value) self.receive_signal() self.controller.settings_object.save_radio_freq(self.radio_freq_value) def preset(self, preset): """ When the user hits a preset button do one of two things. If the button has no station assigned to it then assign it the current frequency. If it has one then change the station. """ text = self.controller.settings_object.get_preset(preset) try: text = round(float(text), 1) preset_is_set = True except: preset_is_set = False if preset_is_set: self.change_radio_freq(text) self.radio_freq_slider.set(text) else: # Extract the preset number (from 1 to 8) from the button text. preset_number = preset # Write the frequency on the button. self.presets[preset_number - 1].config(text=self.radio_freq_value) # Also, write that preset to the settings file. self.controller.settings_object.save_preset( preset_number, self.radio_freq_value) def scan(self, increment): """ Scan the radio (by -.1 or +.1) until it gets a signal. """ getting_signal = False original_radio_freq_value = self.radio_freq_value while True: self.adjust_freq(increment) getting_signal = self.radio_receiver.receiving_signal( self.radio_freq_value) if getting_signal or \ self.radio_freq_value == original_radio_freq_value: return def adjust_freq(self, increment): """ Adjust the radio frequency by "increment" (-.1 or +.1). """ freq = round(float(self.radio_freq_value) + increment, 1) if freq > self.MAXIMUM_FREQ: freq = self.MINIMUM_FREQ elif freq < self.MINIMUM_FREQ: freq = self.MAXIMUM_FREQ self.change_radio_freq(freq) self.radio_freq_slider.set(freq) def change_volume(self, volume): """ Change the radio's audio volume. """ self.radio_receiver.change_volume(volume) self.controller.settings_object.save_radio_volume(volume) def confirm_delete(self): """ Ask the user to confirm that (s)he wants to delete all the presets. """ self.confirmation_label.grid(row=8, column=1, columnspan=2) self.button_yes.grid(row=8, column=3) self.button_no.grid(row=8, column=4) def hide_confirmation(self): """ Hide the confirmation question and the answer buttons. """ self.confirmation_label.grid_forget() self.button_yes.grid_forget() self.button_no.grid_forget() def delete_all_presets(self): """ Wipe out all the radio station presets, leaving just Pre 1, Pre 2, etc """ for i in range(len(self.presets)): self.presets[i].config(text='Pre ' + str(i + 1)) self.controller.settings_object.save_preset( i + 1, 'Pre ' + str(i + 1)) self.hide_confirmation()
class DualButtonInput: current_state = 0 current_state_counter = [0]*4 press_timer = None def __init__(self, ipcon, key_queue): if not config.UID_DUAL_BUTTON_BRICKLET[0]: print("Not Configured: Dual Button 1") if not config.UID_DUAL_BUTTON_BRICKLET[1]: print("Not Configured: Dual Button 2") self.key_queue = key_queue self.ipcon = ipcon if config.UID_DUAL_BUTTON_BRICKLET[0]: self.db1 = DualButton(config.UID_DUAL_BUTTON_BRICKLET[0], self.ipcon) else: self.db1 = None if config.UID_DUAL_BUTTON_BRICKLET[1]: self.db2 = DualButton(config.UID_DUAL_BUTTON_BRICKLET[1], self.ipcon) else: self.db2 = None if self.db1: try: self.db1.get_button_state() print("Found: Dual Button 1 ({0})").format(config.UID_DUAL_BUTTON_BRICKLET[0]) except: self.db1 = None print("Not Found: Dual Button 1 ({0})").format(config.UID_DUAL_BUTTON_BRICKLET[0]) if self.db2: try: self.db2.get_button_state() print("Found: Dual Button 2 ({0})").format(config.UID_DUAL_BUTTON_BRICKLET[1]) except: self.db2 = None print("Not Found: Dual Button 2 ({0})").format(config.UID_DUAL_BUTTON_BRICKLET[1]) if self.db1: self.db1.register_callback(self.db1.CALLBACK_STATE_CHANGED, self.cb_state_changed1) if self.db2: self.db2.register_callback(self.db2.CALLBACK_STATE_CHANGED, self.cb_state_changed2) self.press_timer = RepeatedTimer(0.1, self.press_tick) def stop(self): if self.press_timer is not None: self.press_timer.stop() def cb_state_changed1(self, button_l, button_r, led_l, led_r): l = button_l == DualButton.BUTTON_STATE_PRESSED r = button_r == DualButton.BUTTON_STATE_PRESSED state = (l << 0) | (r << 1) changed_state = (self.current_state ^ state) & 0b0011 self.current_state = state self.state_to_queue(changed_state & self.current_state) def cb_state_changed2(self, button_l, button_r, led_l, led_r): l = button_l == DualButton.BUTTON_STATE_PRESSED r = button_r == DualButton.BUTTON_STATE_PRESSED state = (l << 2) | (r << 3) changed_state = (self.current_state ^ state) & 0b1100 self.current_state = state self.state_to_queue(changed_state & self.current_state) def state_to_queue(self, state): for item in config.KEYMAP_DUAL_BUTTON.items(): if state & (1 << item[0]): self.key_queue.put(item[1]) def press_tick(self): state = 0 for i in range(4): if self.current_state & (1 << i): self.current_state_counter[i] += 1 else: self.current_state_counter[i] = 0 if self.current_state_counter[i] > 1: state |= (1 << i) self.state_to_queue(state)
class Referee(object): """docstring for Referee""" def __init__(self, ui, timer_secs, use_timer, sim_mode, competition_mode): super(Referee, self).__init__() # Setup my UI self.ui = RefereeUI(ui, sim_mode, use_timer, competition_mode) # Connect to ROS things ball_topic = '/ball/truth' if sim_mode else 'vision/ball' rospy.Subscriber(ball_topic, Pose2D, self._handle_vision_ball) self.pub_game_state = rospy.Publisher('game_state', GameState, queue_size=10, latch=True) self.sim_mode = sim_mode self.game_started = False # Create a GameState msg that will be continually updated and published self.game_state = GameState() self.ballIsStillInGoal = False # Set up a 100ms timer event loop self.timer = RepeatedTimer(0.1, self._timer_handler) self.ui.reset_timer(timer_secs) # Populate team names into comboboxes. If sim_mode, these will come from # the catkin_ws packages. If not, these need to come from .. a YAML? self.ui.populate_team_names(sim_mode) # Connect Qt Buttons self.ui.btn_play.clicked.connect(self._btn_play) self.ui.btn_reset_field.clicked.connect(self._btn_reset_field) self.ui.btn_next_half.clicked.connect(self._btn_next_half) self.ui.btn_reset_clock.clicked.connect(self._btn_reset_clock) self.ui.btn_start_game.clicked.connect(self._btn_start_game) # Penalty buttons self.ui.btn_home_penalty.clicked.connect( lambda: self._handle_penalty(home=True)) self.ui.btn_away_penalty.clicked.connect( lambda: self._handle_penalty(home=False)) # Score +/- buttons self.ui.btn_home_inc_score.clicked.connect( lambda: self._handle_score(home=True, inc=True)) self.ui.btn_home_dec_score.clicked.connect( lambda: self._handle_score(home=True, inc=False)) self.ui.btn_away_inc_score.clicked.connect( lambda: self._handle_score(home=False, inc=True)) self.ui.btn_away_dec_score.clicked.connect( lambda: self._handle_score(home=False, inc=False)) # ========================================================================= # Public methods # ========================================================================= def close(self): self.timer.stop() # Don't leave any loose threads! if self.game_started and self.sim_mode: # Send a kill signal to all the process groups os.killpg(os.getpgid(self.process.pid), signal.SIGTERM) # ========================================================================= # Timer Event handler # ========================================================================= def _timer_handler(self): if self.ui.is_timer_done(): if self.game_state.play: self._btn_play() self.ui.stop_timer() if self.ui.is_timer_running(): self.ui.decrement_timer_by_tenth() # Add time info to GameState self.game_state.remaining_seconds = self.ui.get_timer_seconds() # send a GameState message self.pub_game_state.publish(self.game_state) # ========================================================================= # ROS Event Callbacks (subscribers, event loop) # ========================================================================= def _handle_vision_ball(self, msg): # If the ball is past the goal_threshold on either side, and if # the ball wasn't there before, then it was a goal goal = ((msg.x > goal_threshold) or (msg.x < -goal_threshold)) and not self.ballIsStillInGoal # Which goal did it go into? home_side = (msg.x < 0) # home goal is on the left (negative) away_side = (msg.x > 0) # away goal is on the right (positive) if goal: self.ballIsStillInGoal = True # Now lets decide who gets the point, based off home/away and which half we are on home = away_side ^ self.game_state.second_half inc = True self._handle_score(home=home, inc=inc) # If last we knew, the ball was in the goal but now it's not, update that if self.ballIsStillInGoal and abs(msg.x) < out_of_goal_threshold: self.ballIsStillInGoal = False # ========================================================================= # Qt Event Callbacks (buttons, etc) # ========================================================================= def _btn_play(self): if self.game_state.play: # Pause the game and stop the timer self.game_state.play = False self.ui.stop_timer() # Update the UI self.ui.btn_play.setText('Play') else: # Play the game and start the timer self.game_state.play = True self.ui.start_timer() # We don't need to reset the field anymore self.game_state.reset_field = False # we can also clear any penalties self.game_state.home_penalty = False self.game_state.away_penalty = False # Update the UI self.ui.btn_play.setText('Pause') def _btn_reset_field(self): # if necessary, press _btn_play to pause game # stop timer if self.game_state.play: self._btn_play() self.game_state.reset_field = True def _btn_next_half(self): # press _btn_reset_field # clear score # stop and reset timer self._btn_reset_field() self._btn_reset_clock() if self.game_state.second_half: self.game_state.second_half = False self.ui.lbl_half.setText('first half') else: self.game_state.second_half = True self.ui.lbl_half.setText('second half') def _btn_reset_clock(self): # Pause the game if it's being played if self.game_state.play: self._btn_play() self.ui.reset_timer() def _btn_start_game(self): if not self.game_started: self.game_started = True # Set game state settings self.game_state.home_bot_count = self.ui.spin_bots_home.value() self.game_state.away_bot_count = self.ui.spin_bots_away.value() # Get selected team names home_team = str(self.ui.cmb_teams_home.currentText()) away_team = str(self.ui.cmb_teams_away.currentText()) """ Only launch team roslaunch files if in sim mode. """ if self.sim_mode: # Call subprocess using http://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true cmd = 'roslaunch soccersim sim.launch home_team:=' + home_team + ' away_team:=' + away_team self.process = subprocess.Popen(cmd, shell=True, preexec_fn=os.setsid) # Go back to first half if necessary if self.game_state.second_half: self._btn_next_half() # Reset clock self._btn_reset_clock() # Clear GameState self.game_state = GameState() # Update UI self.ui.enable_team_settings(False) self.ui.btn_start_game.setText('Stop Game') self.ui.reset_team_scoreboards(home_team, away_team) self.ui.enable_game_play_buttons(True) elif self.game_started: self.game_started = False if self.sim_mode: # Send a kill signal to all the process groups os.killpg(os.getpgid(self.process.pid), signal.SIGTERM) # stop play self.game_state.play = False # reset clock self.ui.stop_timer() # Update UI self.ui.enable_team_settings(True) self.ui.btn_start_game.setText('Start Game') self.ui.enable_game_play_buttons(False) def _handle_score(self, home=True, inc=True): # reset the field self._btn_reset_field() # update the global state if home: self.game_state.home_score += 1 if inc else -1 else: self.game_state.away_score += 1 if inc else -1 # update the score UI self.ui.update_scores(self.game_state.home_score, self.game_state.away_score) def _handle_penalty(self, home=True): # reset the field self._btn_reset_field() # let the team know they need to reset in penalty mode self.game_state.home_penalty = home self.game_state.away_penalty = not home
class Tetris: FIELD_ROWS = config.LED_ROWS+4 # 22 rows in playfield, with only 20 columns visible and 2 coloms border FIELD_COLS = config.LED_COLS+2 # 10 columns in playfield, 2 column border FIELD_ROW_START = 2 FIELD_COL_START = 4 COLORS = [ ( 10, 10, 10), # grey (255, 0, 0), # red (255, 80, 0), # orange (255, 255, 0), # yellow ( 0, 255, 0), # green ( 0, 0, 255), # blue (255, 0, 150), # violet (255, 0, 40), # purple ] TETROMINOS = { None: [[[0], [0], [0], [0]]], 'I': [[[0,0,0,0], [0,0,2,0], [0,0,0,0], [0,2,0,0]], [[2,2,2,2], [0,0,2,0], [0,0,0,0], [0,2,0,0]], [[0,0,0,0], [0,0,2,0], [2,2,2,2], [0,2,0,0]], [[0,0,0,0], [0,0,2,0], [0,0,0,0], [0,2,0,0]]], 'J': [[[6,0,0], [0,6,6], [0,0,0], [0,6,0]], [[6,6,6], [0,6,0], [6,6,6], [0,6,0]], [[0,0,0], [0,6,0], [0,0,6], [6,6,0]]], 'L': [[[0,0,5], [0,5,0], [0,0,0], [5,5,0]], [[5,5,5], [0,5,0], [5,5,5], [0,5,0]], [[0,0,0], [0,5,5], [5,0,0], [0,5,0]]], 'O': [[[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]], [[0,1,1,0], [0,1,1,0], [0,1,1,0], [0,1,1,0]], [[0,1,1,0], [0,1,1,0], [0,1,1,0], [0,1,1,0]]], 'S': [[[0,3,3], [0,3,0], [0,0,0], [3,0,0]], [[3,3,0], [0,3,3], [0,3,3], [3,3,0]], [[0,0,0], [0,0,3], [3,3,0], [0,3,0]]], 'T': [[[0,7,0], [0,7,0], [0,0,0], [0,7,0]], [[7,7,7], [0,7,7], [7,7,7], [7,7,0]], [[0,0,0], [0,7,0], [0,7,0], [0,7,0]]], 'Z': [[[4,4,0], [0,0,4], [0,0,0], [0,4,0]], [[0,4,4], [0,4,4], [4,4,0], [4,4,0]], [[0,0,0], [0,4,0], [0,4,4], [4,0,0]]] } GAME_OVER_TEXT = [ "GameOverGameOverGameOverGameOverGameOverGameOverGameOve", " ", " GGGG OO ", " G GG O O ", " G aaa mmm mm ee O O v v ee rr ", " G GG a m m m e e O O v v e e r r ", " G G aaaa m m m eeee O O v v eeee r ", " G G a a m m m e O O v v e r ", " GGGG aaaa m m m eee OO v eee r ", " ", " ", "GameOverGameOverGameOverGameOverGameOverGameOverGameOve" ] GAME_OVER_COLORS = { ' ': 0, 'G': 1, 'a': 2, 'm': 3, 'e': 4, 'O': 5, 'v': 6, 'r': 7 } drop_timer = None tetromino_current = 'O' tetromino_form = 0 tetromino_pos_row = FIELD_ROW_START tetromino_pos_col = FIELD_COL_START playfield = [x[:] for x in [[0]*FIELD_COLS]*FIELD_ROWS] random_bag = ['O', 'I', 'S', 'Z', 'L', 'J', 'T'] random_bag_index = len(random_bag)-1 game_over_position = 0 is_game_over = False loop = True def __init__(self, ipcon): self.okay = False self.ipcon = ipcon if not config.UID_LED_STRIP_BRICKLET: print("Not Configured: LED Strip or LED Strip V2 (required)") return if not config.IS_LED_STRIP_V2: self.led_strip = LEDStrip(config.UID_LED_STRIP_BRICKLET, self.ipcon) else: self.led_strip = LEDStripV2(config.UID_LED_STRIP_BRICKLET, self.ipcon) try: self.led_strip.get_frame_duration() if not config.IS_LED_STRIP_V2: print("Found: LED Strip ({0})".format(config.UID_LED_STRIP_BRICKLET)) else: print("Found: LED Strip V2 ({0})".format(config.UID_LED_STRIP_BRICKLET)) except: if not config.IS_LED_STRIP_V2: print("Not Found: LED Strip ({0})".format(config.UID_LED_STRIP_BRICKLET)) else: print("Not Found: LED Strip V2({0})".format(config.UID_LED_STRIP_BRICKLET)) return self.kp = KeyPress(self.ipcon) self.display = TetrisSegmentDisplay(self.ipcon) self.speaker = TetrisSpeaker(self.ipcon) self.okay = True self.led_strip.set_frame_duration(40) if not config.IS_LED_STRIP_V2: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_RENDERED, self.frame_rendered) else: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_STARTED, self.frame_rendered) self.led_strip.set_channel_mapping(config.CHANNEL_MAPPING) self.init_game() def init_game(self): self.tetromino_current = 'O' self.tetromino_form = 0 self.tetromino_pos_row = self.FIELD_ROW_START self.tetromino_pos_col = self.FIELD_COL_START # Add border to playfield self.playfield = [x[:] for x in [[0]*self.FIELD_COLS]*self.FIELD_ROWS] self.playfield[0] = [255]*self.FIELD_COLS self.playfield[-1] = [255]*self.FIELD_COLS for col in self.playfield[1:-1]: col[0] = 255 col[-1] = 255 # initialize current tetronimo randomly self.tetromino_current = self.get_random_tetromino() self.is_game_over = False if self.drop_timer: self.drop_timer.interval = 1 def frame_rendered(self, length): self.write_playfield() # See http://tetris.wikia.com/wiki/Random_Generator for # details of random bag implementation according to tetris specification def get_random_tetromino(self): self.random_bag_index += 1 if self.random_bag_index >= len(self.random_bag): self.random_bag_index = 0 random.shuffle(self.random_bag) return self.random_bag[self.random_bag_index] def add_tetromino_to_field(self, field, pos_row, pos_col, tetromino, form): for index_col, col in enumerate(self.TETROMINOS[tetromino]): for index_row, color in enumerate(col[form]): if color != 0: row = pos_row + index_row col = pos_col + index_col if row >= 0 and row < self.FIELD_ROWS and col >= 0 and col < self.FIELD_COLS: field[row][col] = color def tetromino_fits(self, field, pos_row, pos_col, tetromino, form): for index_col, col in enumerate(self.TETROMINOS[tetromino]): for index_row, color in enumerate(col[form]): if color != 0: row = pos_row + index_row col = pos_col + index_col if row >= 0 and row < self.FIELD_ROWS and col >= 0 and col < self.FIELD_COLS: if field[row][col] != 0: return False return True def write_playfield(self): if not self.okay: return field = copy.deepcopy(self.playfield) if not self.is_game_over: self.add_tetromino_to_field(field, self.tetromino_pos_row, self.tetromino_pos_col, self.tetromino_current, self.tetromino_form) # Reorder LED data into R, G and B channel r = [] g = [] b = [] frame = [] for row in reversed(range(3, self.FIELD_ROWS-1)): col_range = range(1, self.FIELD_COLS-1) if row % 2 == 0: col_range = reversed(col_range) for col in col_range: r.append(self.COLORS[field[row][col]][0]) g.append(self.COLORS[field[row][col]][1]) b.append(self.COLORS[field[row][col]][2]) frame.append(self.COLORS[field[row][col]][0]) frame.append(self.COLORS[field[row][col]][1]) frame.append(self.COLORS[field[row][col]][2]) if not config.IS_LED_STRIP_V2: # Make chunks of size 16 r_chunk = [r[i:i+16] for i in range(0, len(r), 16)] g_chunk = [g[i:i+16] for i in range(0, len(g), 16)] b_chunk = [b[i:i+16] for i in range(0, len(b), 16)] for i in range(len(r_chunk)): length = len(r_chunk[i]) # Fill up chunks with zeros r_chunk[i].extend([0]*(16-len(r_chunk[i]))) g_chunk[i].extend([0]*(16-len(g_chunk[i]))) b_chunk[i].extend([0]*(16-len(b_chunk[i]))) try: self.led_strip.set_rgb_values(i*16, length, r_chunk[i], g_chunk[i], b_chunk[i]) except: break else: try: self.led_strip.set_led_values(0, frame) except: return def clear_lines(self, rows_to_clear): if not self.okay: return self.drop_timer.stop() rows_save = {} for to_clear in rows_to_clear: rows_save[to_clear] = self.playfield[to_clear] self.display.increase_line_count(len(rows_to_clear)) self.speaker.beep_delete_line(len(rows_to_clear)) for i in range(6): if i % 2 == 0: for to_clear in rows_to_clear: self.playfield[to_clear] = [255] + [0]*(self.FIELD_COLS-2) + [255] else: for to_clear in rows_to_clear: self.playfield[to_clear] = rows_save[to_clear] time.sleep(0.1) for to_clear in rows_to_clear: for row in reversed(range(1, to_clear+1)): self.playfield[row] = self.playfield[row-1] self.playfield[1] = [255] + [0]*(self.FIELD_COLS-2) + [255] self.drop_timer.start() def check_for_lines_to_clear(self): rows_to_clear = [] for row_index, col in enumerate(self.playfield[1:-1]): to_clear = True for color in col[1:-1]: if color == 0: to_clear = False break if to_clear: rows_to_clear.append(row_index+1) if len(rows_to_clear) > 0: self.clear_lines(rows_to_clear) def new_tetromino(self): self.add_tetromino_to_field(self.playfield, self.tetromino_pos_row, self.tetromino_pos_col, self.tetromino_current, self.tetromino_form) self.tetromino_current = None self.check_for_lines_to_clear() self.tetromino_current = self.get_random_tetromino() self.tetromino_pos_row = self.FIELD_ROW_START self.tetromino_pos_col = self.FIELD_COL_START self.tetromino_form = 0 if not self.tetromino_fits(self.playfield, self.tetromino_pos_row, self.tetromino_pos_col, self.tetromino_current, self.tetromino_form): self.is_game_over = True self.game_over_position = 0 self.drop_timer.interval = 0.15 def next_game_over_step(self): for row in range(len(self.GAME_OVER_TEXT)): for col in range(config.LED_COLS): k = (self.game_over_position+col) % len(self.GAME_OVER_TEXT[0]) self.playfield[7+row][1+col] = self.GAME_OVER_COLORS[self.GAME_OVER_TEXT[row][k]] self.game_over_position += 1 def drop_tetromino(self): if self.is_game_over: self.next_game_over_step() return if self.tetromino_fits(self.playfield, self.tetromino_pos_row+1, self.tetromino_pos_col, self.tetromino_current, self.tetromino_form): self.tetromino_pos_row += 1 else: self.new_tetromino() def move_tetromino(self, row, col, form): if self.is_game_over: return if self.tetromino_fits(self.playfield, self.tetromino_pos_row+row, self.tetromino_pos_col+col, self.tetromino_current, form): self.tetromino_pos_row += row self.tetromino_pos_col += col self.tetromino_form = form if row > 0: # restart drop timer, so we don't drop two tetrominos in a row self.drop_timer.stop() self.drop_timer.start() elif row == 1: # user is at bottom and hits button to go down again self.new_tetromino() def run_game_loop(self): self.frame_rendered(0) self.drop_timer = RepeatedTimer(1.0, self.drop_tetromino) while self.loop: key = self.kp.read_single_keypress() if key == 'a': self.speaker.beep_input() self.move_tetromino(0, -1, self.tetromino_form) elif key == 'd': self.speaker.beep_input() self.move_tetromino(0, 1, self.tetromino_form) elif key == 's': self.speaker.beep_input() self.move_tetromino(1, 0, self.tetromino_form) elif key == 'k': self.speaker.beep_input() self.move_tetromino(0, 0, (self.tetromino_form-1) % 4) elif key == 'l': self.speaker.beep_input() self.move_tetromino(0, 0, (self.tetromino_form+1) % 4) elif key == 'r': self.init_game() elif not config.HAS_GUI and key == 'q': break if not config.IS_LED_STRIP_V2: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_RENDERED, None) else: self.led_strip.register_callback(self.led_strip.CALLBACK_FRAME_STARTED, None) self.drop_timer.stop() self.kp.stop()
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()
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 DownloadNodeJS(object): def __init__(self, node_version): self.NODE_JS_VERSION = node_version self.NODE_JS_TAR_EXTENSION = ".zip" if node_variables.NODE_JS_OS == "win" else ".tar.gz" self.NODE_JS_BINARY_URL = "https://nodejs.org/dist/" + self.NODE_JS_VERSION + "/node-" + self.NODE_JS_VERSION + "-" + node_variables.NODE_JS_OS + "-" + node_variables.NODE_JS_ARCHITECTURE + self.NODE_JS_TAR_EXTENSION self.NODE_JS_BINARY_TARFILE_NAME = self.NODE_JS_BINARY_URL.split( '/')[-1] self.NODE_JS_BINARY_TARFILE_FULL_PATH = os.path.join( node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM, self.NODE_JS_BINARY_TARFILE_NAME) self.animation_loader = AnimationLoader([ "[= ]", "[ = ]", "[ = ]", "[ = ]", "[ =]", "[ = ]", "[ = ]", "[ = ]" ], 0.067, "Downloading: " + self.NODE_JS_BINARY_URL + " ") self.interval_animation = None self.thread = None if not os.path.exists(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM): os.makedirs(node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) def download(self): try: request = urllib.request.Request(self.NODE_JS_BINARY_URL) request.add_header( 'User-agent', r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1' ) with urllib.request.urlopen(request) as response: with open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, 'wb') as out_file: shutil.copyfileobj(response, out_file) except Exception as err: traceback.print_exc() self.on_error(err) return self.extract() self.on_complete() def start(self): self.thread = threading.Thread(target=self.download, name="DownloadNodeJS") self.thread.setDaemon(True) self.thread.start() if self.animation_loader: self.interval_animation = RepeatedTimer( self.animation_loader.sec, self.animation_loader.animate) def extract(self): if self.NODE_JS_TAR_EXTENSION != ".zip": with tarfile.open(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r:gz") as tar: for member in tar.getmembers(): if member.name.endswith("/bin/node"): member.name = node_variables.NODE_JS_PATH_EXECUTABLE tar.extract( member, node_variables.NODE_JS_BINARIES_FOLDER_PLATFORM) break else: with zipfile.ZipFile(self.NODE_JS_BINARY_TARFILE_FULL_PATH, "r") as zip_file: for member in zip_file.namelist(): if member.endswith("/node.exe"): with zip_file.open(member) as node_file: with open( os.path.join( node_variables. NODE_JS_BINARIES_FOLDER_PLATFORM, "node.exe"), "wb") as target: shutil.copyfileobj(node_file, target) break def on_error(self, err): self.animation_loader.on_complete() self.interval_animation.stop() sublime.active_window().status_message( "Can't install Node.js! Check your internet connection!") def on_complete(self): self.animation_loader.on_complete() self.interval_animation.stop() if os.path.isfile(self.NODE_JS_BINARY_TARFILE_FULL_PATH): os.remove(self.NODE_JS_BINARY_TARFILE_FULL_PATH) node_js = NodeJS() if node_js.getCurrentNodeJSVersion() == self.NODE_JS_VERSION: sublime.active_window().status_message("Node.js " + self.NODE_JS_VERSION + " installed correctly!") else: sublime.active_window().status_message( "Can't install Node.js! Something during installation went wrong." )
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 MpmeFolderPage(tk.Frame): """ Class for the Folder page for accessing all the folders and files """ def __init__(self, parent, controller): """ Initialize the page and create its objects. """ tk.Frame.__init__(self, parent) self.paused = False # Whether or not a song is paused self.controller = controller # When the user clicks on this button, call the # show_frame method to make the main screen appear. button_start = tk.Button(self, text='Start', command=lambda: self.save_and_start()) self.button_pause = tk.Button(self, text='Pause', command=lambda: self.pause()) self.button_pause["state"] = "disable" #button_stop = tk.Button(self, text='■', # command=lambda : self.stop()) # We're getting rid of the Stop button; we don't need it. # Specify the geometry to place the buttons. button_start.grid(row=1, column=1) self.button_pause.grid(row=1, column=2) # Create the file lister object. self.file_display = FileLister(self, 2, 1, 1, 4) # Create the Volume slide control. volume_slider = VolumeSlider(self, from_=0, to=100, orient=tk.HORIZONTAL, label="VOLUME", length=290) volume_slider.set(self.controller.settings_object.get_volume()) # Specify the geometry to place the Volume slide control. volume_slider.grid(row=3, column=1, columnspan=4) # Create the Position slide control. self.position_slider = PositionSlider(self, from_=0, to=100, orient=tk.HORIZONTAL, label="POSITION", length=290) # Specify the geometry to place the Position slide control. self.position_slider.grid(row=4, column=1, columnspan=4) # Create the time display. self.current_time = TimeDisplay(self, 1) # Specify the geometry to place the time display. self.current_time.grid(row=5, column=1) # Create the display for the song's total length. self.total_time = TimeDisplay(self, 0) # Specify the geometry to place the "total" time display. self.total_time.grid(row=5, column=2) # Create the display for the amount of time left. self.time_left = TimeDisplay(self, -1) # Specify the geometry to place the time-left display. self.time_left.grid(row=5, column=3) # The following variable is to indicate if, while the song is # paused, the user jumped to a different point in the song. self.jump_pending = False def save_and_start(self): """ Save the order and THEN return to the Start page. """ self.file_display.write_order() self.controller.show_frame(MpmeStartPage) def play(self, sound_file): """ Play a file and configure the rest of the window accordingly. """ # (But first check if there's a timer # currently running and if so, stop it.) if hasattr(self, 'timer'): self.timer.stop() self.position_slider.set(0) self.controller.sound_object.play(sound_file) self.current_time.move_timer(0) self.total_time.move_timer(self.controller.sound_object.get_length()) self.time_left.move_timer(self.controller.sound_object.get_length()) self.timer = RepeatedTimer(1, self.increment_timers) self.button_pause["state"] = "normal" self.button_pause.config(relief=tk.RAISED) self.paused = False self.song_now_playing = sound_file self.path_now_playing = self.file_display.get_current_path() def pause(self): """ Toggle between a "paused" and "non-paused" state. """ if self.paused: self.button_pause.config(relief=tk.RAISED) # Theoretically, if the user pauses and unpauses # many times during the same song, the timers # could get thrown off. So adjust the timers. if not self.jump_pending: self.current_time.move_timer( self.controller.sound_object.get_position()) self.time_left.move_timer( self.controller.sound_object.get_length() - self.controller.sound_object.get_position()) self.position_slider.set( self.current_time.timer_seconds / self.controller.sound_object.get_length() * 100) self.jump_pending = False self.controller.sound_object.unpause() self.timer = RepeatedTimer(1, self.increment_timers) else: self.button_pause.config(relief=tk.SUNKEN) self.controller.sound_object.pause() self.timer.stop() self.paused = not self.paused def stop(self): """ Stop the song and the timer. """ self.controller.sound_object.stop() self.button_pause.config(relief=tk.RAISED) self.paused = False self.button_pause["state"] = "disable" self.jump_pending = False if hasattr(self, 'timer'): self.timer.stop() def increment_timers(self): """ Add a seoond to the time, subtract a second from the time left, and push the position slider forward in proportion. """ # (But first check if the song is over, # in which case play the next song.) if self.controller.sound_object.song_is_over(): # Stop the song, find the next song, and play it. self.play( self.file_display.next_file(self.path_now_playing, self.song_now_playing)) # Scroll to the song so that it's visible. self.file_display.playlist.see( self.file_display.playlist.curselection()) else: self.current_time.increment() self.time_left.increment() self.position_slider.set( self.current_time.timer_seconds / self.controller.sound_object.get_length() * 100) def change_volume(self, volume): """ Change the song's audio volume. """ self.controller.sound_object.set_volume(volume / 100) self.controller.settings_object.save_volume(volume) def jump(self, position_percentage): """ Jump to a specified position. For instance, if position_percentage is 37 then jump to a point 37% of the way into the song. """ position_in_seconds = position_percentage * \ self.controller.sound_object.get_length() // 100 self.controller.sound_object.set_position(position_in_seconds) self.current_time.move_timer(position_in_seconds) self.time_left.move_timer(self.controller.sound_object.get_length() - position_in_seconds) if self.paused: self.jump_pending = True
class CommandRunner: UPDATE_INTERVAL = 5 def __init__(self, msg_func, master): self.msg_func = msg_func self.master = master self.child_process = None self.output_queue = queue.Queue() self.output_read_thread = None self.output_mutex = threading.RLock() self.update_timer = RepeatedTimer(self.on_update_timer) self._exitcode = None def _read_output(self): while True: # NOTE: don't use iterator interface since it uses an # internal buffer and we don't see output in a timely fashion line = self.child_process.stdout.readline() if not line: break self.output_queue.put(line) def is_alive(self): if self.child_process is None: return False return self.child_process.poll() is None def run_command(self, *args): if self.is_alive(): raise ValueError("already running a command") cmd = [sys.executable, "-u", "-m", "openslides"] cmd.extend(args) creationflags = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0) self._exitcode = None self.child_process = subprocess.Popen( cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=creationflags) self.child_process.stdin.close() self.output_read_thread = threading.Thread(target=self._read_output) self.output_read_thread.start() self.update_timer.run(self.UPDATE_INTERVAL) self.master.event_generate("<<EVT_CMD_START>>", when="tail") def cancel_command(self): if not self.is_alive(): return self.msg_func("Stopping server...\n") # hard-kill the spawned process tree # TODO: offer the server the chance for a clean shutdown proc = psutil.Process(self.child_process.pid) kill_procs = [proc] kill_procs.extend(proc.children(recursive=True)) for p in kill_procs: p.kill() def on_update_timer(self): is_alive = self.is_alive() if not is_alive: # join thread to make sure everything was read self.output_read_thread.join(5) if self.output_read_thread.is_alive(): self.msg_func("Internal error: failed to join output reader thread") self.output_read_thread = None for line_no in itertools.count(): try: data = self.output_queue.get(block=False) except queue.Empty: break else: # XXX: check whether django uses utf-8 or locale for # it's cli output text = data.decode("utf-8", errors="replace") with self.output_mutex: self.msg_func(text) # avoid waiting too long here if child is still alive if is_alive and line_no > 10: break if not is_alive: self._exitcode = self.child_process.returncode self.update_timer.stop() self.child_process = None self.master.event_generate("<<EVT_CMD_STOP>>", when="tail") def append_message(self, text, newline="\n"): with self.output_mutex: self.msg_func(text + newline) @property def exitcode(self): return self._exitcode
class DualButtonInput: current_state = 0 current_state_counter = [0] * 4 press_timer = None def __init__(self, ipcon, key_queue): if not config.UID_DUAL_BUTTON_BRICKLET[0]: print("Not Configured: Dual Button 1") if not config.UID_DUAL_BUTTON_BRICKLET[1]: print("Not Configured: Dual Button 2") self.key_queue = key_queue self.ipcon = ipcon if config.UID_DUAL_BUTTON_BRICKLET[0]: self.db1 = DualButton(config.UID_DUAL_BUTTON_BRICKLET[0], self.ipcon) else: self.db1 = None if config.UID_DUAL_BUTTON_BRICKLET[1]: self.db2 = DualButton(config.UID_DUAL_BUTTON_BRICKLET[1], self.ipcon) else: self.db2 = None if self.db1: try: self.db1.get_button_state() print("Found: Dual Button 1 ({0})").format( config.UID_DUAL_BUTTON_BRICKLET[0]) except: self.db1 = None print("Not Found: Dual Button 1 ({0})").format( config.UID_DUAL_BUTTON_BRICKLET[0]) if self.db2: try: self.db2.get_button_state() print("Found: Dual Button 2 ({0})").format( config.UID_DUAL_BUTTON_BRICKLET[1]) except: self.db2 = None print("Not Found: Dual Button 2 ({0})").format( config.UID_DUAL_BUTTON_BRICKLET[1]) if self.db1: self.db1.register_callback(self.db1.CALLBACK_STATE_CHANGED, self.cb_state_changed1) if self.db2: self.db2.register_callback(self.db2.CALLBACK_STATE_CHANGED, self.cb_state_changed2) self.press_timer = RepeatedTimer(0.1, self.press_tick) def stop(self): if self.press_timer is not None: self.press_timer.stop() def cb_state_changed1(self, button_l, button_r, led_l, led_r): l = button_l == DualButton.BUTTON_STATE_PRESSED r = button_r == DualButton.BUTTON_STATE_PRESSED state = (l << 0) | (r << 1) changed_state = (self.current_state ^ state) & 0b0011 self.current_state = state self.state_to_queue(changed_state & self.current_state) def cb_state_changed2(self, button_l, button_r, led_l, led_r): l = button_l == DualButton.BUTTON_STATE_PRESSED r = button_r == DualButton.BUTTON_STATE_PRESSED state = (l << 2) | (r << 3) changed_state = (self.current_state ^ state) & 0b1100 self.current_state = state self.state_to_queue(changed_state & self.current_state) def state_to_queue(self, state): for item in config.KEYMAP_DUAL_BUTTON.items(): if state & (1 << item[0]): self.key_queue.put(item[1]) def press_tick(self): state = 0 for i in range(4): if self.current_state & (1 << i): self.current_state_counter[i] += 1 else: self.current_state_counter[i] = 0 if self.current_state_counter[i] > 1: state |= (1 << i) self.state_to_queue(state)
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 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()