def check_updates(): global current_version current_version = tuple(map(int, current_version.split('.'))) animate('Checking updates') releases_url = 'https://github.com/ankit1w/OCD/releases/latest' latest_version = session.head(releases_url, allow_redirects=True, timeout=10).url.split('/tag/v')[1] latest_version = tuple(map(int, latest_version.split('.'))) animate(end=1) if latest_version != current_version: print('Update available! Get the latest version from bit.ly/ocd-update') if latest_version[0] > current_version[0] or latest_version[1] > current_version[1]: print('Press any key to launch site.') getch() system('start https://github.com/ankit1w/OCD/releases') raise SystemExit(1) else: print("Press 'U' to launch update page, any other key to continue.", '\n') update_now = getch() in (b'U', b'u') if update_now: system('start https://github.com/ankit1w/OCD/releases') raise SystemExit(1)
def dropTile(self, uiTile, lowerHalf): """drop meld or uiTile into lower or upper half of our hand""" senderBoard = uiTile.board self.checkTiles() senderBoard.checkTiles() newMeld = senderBoard.chooseVariant(uiTile, lowerHalf) if not newMeld: self.checkTiles() senderBoard.checkTiles() return False uiMeld = senderBoard.assignUITiles(uiTile, newMeld) senderBoard.deselect(uiMeld) for uiTile, tile in zip(uiMeld, newMeld): uiTile.tile = tile self.uiMelds.append(uiMeld) self.player.addMeld(newMeld) self.sync() self.hasFocus = senderBoard == self or not senderBoard.uiTiles self.checkTiles() senderBoard.autoSelectTile() senderBoard.checkTiles() if senderBoard is not self and senderBoard.isHandBoard: Internal.scene.handSelectorChanged(senderBoard) Internal.scene.handSelectorChanged(self) animate() self.checkTiles() return True
def applySettings(self): """apply preferences""" # pylint: disable=R0912 # too many branches self.actionAngle.setEnabled(bool(self.game) and Preferences.showShadows) animate() # drain the queue afterCurrentAnimationDo(self.__applySettings2)
def applySettings(self): """apply preferences""" # pylint: disable=R0912 # too many branches self.actionAngle.setEnabled( bool(self.game) and Preferences.showShadows) animate() # drain the queue afterCurrentAnimationDo(self.__applySettings2)
def myAction(self, move): """ask myself what I want to do after picking or claiming a tile""" # only when all animations ended, our handboard gets focus. Otherwise # we would see a blue focusRect in the handboard even when a tile # ist still moving from the discardboard to the handboard. animate().addCallback(move.player.getsFocus) possibleAnswers = [Message.Discard, Message.Kong, Message.MahJongg] if not move.player.discarded: possibleAnswers.append(Message.OriginalCall) return self.ask(move, possibleAnswers)
def login(): animate('Attempting login') driver.execute_script("window.location.href='http://122.252.249.26:96/forms/frmlogin.aspx'") total_sum = driver.find_element_by_id('cntxt_tot_sum').get_attribute('value') driver.find_element_by_id('ctxt_user_id').send_keys('student') driver.find_element_by_id('ctxt_pass_word').send_keys('student') driver.find_element_by_id('cntxt_sum').send_keys(total_sum) driver.find_element_by_id('cmd_login').click() animate('Login successful!', end=1)
def dropHere(self, tile, meld, lowerHalf): """drop meld or tile into lower or upper half of our hand""" if meld: meld.state = CONCEALED if lowerHalf else EXPOSED result = self.receive(meld=meld) else: if lowerHalf and not tile.isBonus(): tile.element = tile.element.capitalize() result = self.receive(tile) animate() return result
def exec_move(self, move): """mirror the move of a player as told by the game server""" message = move.message if message.needsGame and not self.game: # server already disconnected, see # HumanClient.remote_ServerDisconnects return succeed(Message.OK) action = message.notifyAction if move.notifying else message.clientAction game = self.game if game: game.moves.append(move) answer = action(self, move) if not isinstance(answer, Deferred): answer = succeed(answer) if game: if not move.notifying and move.player and not move.player.scoreMatchesServer( move.score): game.close() # This is an example how to find games where specific situations arise. We prefer games where this # happens very early for easier reproduction. So set number of rounds to 1 in the ruleset before doing this. # This example looks for a situation where the single human player may call Chow but one of the # robot players calls Pung. See https://bugs.kde.org/show_bug.cgi?id=318981 # if game.nextPlayer() == game.myself: # I am next # if message == Message.Pung and move.notifying: # somebody claimed a pung # if move.player != game.myself: # it was not me # if game.handctr == 0 and len(game.moves) < 30: # early on in the game # game.myself.computeSayable(move, [Message.Chow]) # if game.myself.sayable[Message.Chow]: # I may say Chow # logDebug('FOUND EXAMPLE FOR %s IN %s' % (game.myself, # game.handId.prompt(withMoveCount=True))) if message == Message.Discard: # do not block here, we want to get the clientDialog # before the animated tile reaches its end position animate() return answer elif message == Message.AskForClaims: # no need to start an animation. If we did the below standard clause, this is what # could happen: # 1. user says Chow # 2. SelectChow dialog pops up # 3. previous animation ends, making animate() callback with current answer # 4. but this answer is Chow, without a selected Chow. This is # wrongly sent to server return answer else: # return answer only after animation ends. Put answer into # the Deferred returned by animate(). return animate().addCallback(lambda x: answer)
def dropMeld(self, uiMeld): """drop uiMeld into selector board""" senderHand = uiMeld[0].board if senderHand == self: return for myTile in uiMeld: self.__placeAvailable(myTile) myTile.focusable = True senderHand.deselect(uiMeld) (senderHand if senderHand.uiTiles else self).hasFocus = True self._noPen() animate()
def exec_move(self, move): """mirror the move of a player as told by the game server""" message = move.message if message.needsGame and not self.game: # server already disconnected, see # HumanClient.remote_ServerDisconnects return succeed(Message.OK) action = message.notifyAction if move.notifying else message.clientAction game = self.game if game: game.moves.append(move) answer = action(self, move) if not isinstance(answer, Deferred): answer = succeed(answer) if game: if not move.notifying and move.player and not move.player.scoreMatchesServer(move.score): game.close() # This is an example how to find games where specific situations arise. We prefer games where this # happens very early for easier reproduction. So set number of rounds to 1 in the ruleset before doing this. # This example looks for a situation where the single human player may call Chow but one of the # robot players calls Pung. See https://bugs.kde.org/show_bug.cgi?id=318981 # if game.nextPlayer() == game.myself: # I am next # if message == Message.Pung and move.notifying: # somebody claimed a pung # if move.player != game.myself: # it was not me # if game.handctr == 0 and len(game.moves) < 30: # early on in the game # game.myself.computeSayable(move, [Message.Chow]) # if game.myself.sayable[Message.Chow]: # I may say Chow # logDebug(u'FOUND EXAMPLE FOR %s IN %s' % (game.myself, # game.handId.prompt(withMoveCount=True))) if message == Message.Discard: # do not block here, we want to get the clientDialog # before the animated tile reaches its end position animate() return answer elif message == Message.AskForClaims: # no need to start an animation. If we did the below standard clause, this is what # could happen: # 1. user says Chow # 2. SelectChow dialog pops up # 3. previous animation ends, making animate() callback with current answer # 4. but this answer is Chow, without a selected Chow. This is # wrongly sent to server return answer else: # return answer only after animation ends. Put answer into # the Deferred returned by animate(). return animate().addCallback(lambda x: answer)
def start_phantomjs(): global driver animate('Starting page render engine') driver = webdriver.PhantomJS(service_args=['--load-images=no'], executable_path=fr'{phantomjs_path}\phantomjs.exe', service_log_path='nul') driver.implicitly_wait(20) driver.set_page_load_timeout(20) driver.set_script_timeout(20) animate('Page render engine online', end=1)
def dropTile(self, uiTile, lowerHalf=False): # pylint: disable=unused-argument """drop uiTile into selector board""" senderHand = uiTile.board if senderHand == self: return meld = uiTile.board.uiMeldWithTile(uiTile) self.lastReceived = uiTile for myTile in meld: self.__placeAvailable(myTile) myTile.focusable = True senderHand.deselect(meld) (senderHand if senderHand.uiTiles else self).hasFocus = True self._noPen() animate()
def initScores(scores): ui.addText(render.WIDTH_WINDOW/24, render.HEIGHT_WINDOW/20, text="Levels", textColor="white", textSize=32, textAnchor="nw") ui.addButton(render.WIDTH_WINDOW/4, 2*render.HEIGHT_WINDOW / 14, width=100, height=30, fill="white", stroke=5, polygonal=POLYGONS["up-arrow"], action=evenement.setGameEvent, arguments=["up"]) ui.addButton(render.WIDTH_WINDOW/4, 13*render.HEIGHT_WINDOW / 14, width=100, height=30, fill="white", stroke=5, polygonal=POLYGONS["down-arrow"], action=evenement.setGameEvent, arguments=["down"]) levels = [key for key in scores["s"]] for i in range(3): ui.addText(render.WIDTH_WINDOW/20, render.HEIGHT_WINDOW / 3.3 + (render.HEIGHT_WINDOW/7) * 1.30*i, ID="ltext"+str(i+1), text= levels[i] + " - "+ str(scores["s"][levels[i]][0]) + "\n\t"+scores["s"][levels[i]][1], textColor="white", textSize=18, textAnchor="sw") ui.addPolygon(render.WIDTH_WINDOW/4, render.HEIGHT_WINDOW / 2.9 + (render.HEIGHT_WINDOW/7) * 1.30*i, width=render.WIDTH_WINDOW/2.4, height=render.HEIGHT_WINDOW/80, points=POLYGONS["separator-horizontal"], fill="white", ID='levelSeparator'+str(i)) ui.addText(render.WIDTH_WINDOW/20, render.HEIGHT_WINDOW / 3.3 + (render.HEIGHT_WINDOW/7) * 1.30*3, ID="ltext"+str(3+1), text= levels[3%len(levels)] + " - "+ str(scores["s"][levels[3%len(levels)]][0]) + "\n\t"+scores["s"][levels[3%len(levels)]][1], textColor="white", textSize=18, textAnchor="sw") ui.addPolygon(render.WIDTH_WINDOW/2, render.HEIGHT_WINDOW/2, width=render.WIDTH_WINDOW/100, height=0, points=POLYGONS["separator-vertical"], fill="white", ID='separator') animation.animate("separator", [0.4], [{"height":render.HEIGHT_WINDOW/1.1}]) ui.addText(render.WIDTH_WINDOW/2 + render.WIDTH_WINDOW/24, render.HEIGHT_WINDOW/20, text="Unlimited Random", textColor="white", textSize=32, textAnchor="nw") for i in range(10): ui.addText(render.WIDTH_WINDOW/2 + render.WIDTH_WINDOW/24, render.HEIGHT_WINDOW/5.5+ (render.HEIGHT_WINDOW/16) * 1.3*i, ID="urtext"+str(i+1), text=str(i+1)+") "+scores["r"][i][0]+" - "+scores["r"][i][1], textColor="white", textSize=18, textAnchor="nw")
def load_handbook(): animate('Gathering subjects') driver.execute_script("LoadPage('frmSubjectList.aspx',0)") timeout = 0 while True: subject_list = driver.find_element_by_id('ul_subject_menu').find_elements_by_tag_name('input') if subject_list[0].get_attribute('onclick'): break if timeout == 10: raise NoSuchElementException system('timeout 1 > nul') timeout += 1 js_functions = tuple(map(lambda x: x.get_attribute('onclick').split(';')[0], subject_list)) if not len(js_functions): raise NoSuchElementException animate('Subjects loaded!', end=1) print() for index, command in enumerate(js_functions): sub_name = command.split(',')[1][1:-2].split(' - ', 1) sub_name = (sub_name[0] + ' ').ljust(20, '─') + ' ' + sub_name[1] print(f'{str(index + 1).rjust(15)}. {sub_name}', center=0, color=0) while True: print() try: cmd_no = int(input(f'Enter subject number [1-{len(js_functions)}] : '.rjust(60))) - 1 if cmd_no not in range(0, len(js_functions)): raise ValueError break except ValueError: print('Wrong input! Enter again.' + ' ' * 10, '\n') driver.execute_script(js_functions[cmd_no]) lecture_name = js_functions[cmd_no].split(',', 1)[1][1:-2] system('cls') system(f'title Online Courseware Downloader : Downloading ↓ {lecture_name}'.replace('&', '^&')) print('Online Courseware Downloader', 'github.com/ankit1w/OCD', '─' * 125, sep='\n', color=0) blink(f"Loading...{lecture_name}") print() return lecture_name
def dropMeld(self, uiMeld): """drop uiMeld into our hand""" senderBoard = uiMeld[0].board senderBoard.deselect(uiMeld) self.uiMelds.append(uiMeld) self.player.addMeld(uiMeld.meld) self.sync() self.hasFocus = senderBoard == self or not senderBoard.uiTiles self.checkTiles() senderBoard.autoSelectTile() senderBoard.checkTiles() if senderBoard is not self and senderBoard.isHandBoard: Internal.scene.handSelectorChanged(senderBoard) Internal.scene.handSelectorChanged(self) animate() self.checkTiles() return True
def __onMouseDown(self, Event): if Event.source==avg.TOUCH or Event.source==avg.MOUSE: if self.game.animalSounds[self.type] != None: self.game.animalSounds[self.type].sound.play() if self.__offset == None: if self.state == CAUGHT: collision.catchedControl(self, False) self.startCollision() self.startMove() self.bounceX=-1 if self.state != CAUGHT: if (self.game.player.getFrameTime() - self.__lastMouseDownFrameTime) < 500 and self.type == IGEL and self.cooldown <= self.game.player.getFrameTime(): animation.animate(self) self.__lastMouseDownFrameTime = self.game.player.getFrameTime() self.__offset = avg.Point2D(self.animal.getRelPos((Event.x, Event.y))) self.animal.setEventCapture(Event.cursorid) self.__cursorID = Event.cursorid
def divide(self): """divides a wall, building a living and and a dead end""" with Animated(False): Wall.divide(self) for tile in self.tiles: # update graphics because tiles having been # in kongbox in a previous game # might not be there anymore. This gets rid # of the cross on them. tile.graphics.update() # move last two tiles onto the dead end: return animate().addCallback(self.__placeLooseTiles2)
def __placeWallTiles(self, dummyResult=None): """place all wall tiles""" tileIter = iter(self.tiles) tilesPerSide = len(self.tiles) // 4 for side in (self.__sides[0], self.__sides[3], self.__sides[2], self.__sides[1]): upper = True # upper tile is played first for position in range(tilesPerSide-1, -1, -1): tile = tileIter.next() tile.setBoard(side, position//2, 0, level=int(upper)) upper = not upper self.__setDrawingOrder() return animate()
def __placeWallTiles(self, dummyResult=None): """place all wall tiles""" tileIter = iter(self.tiles) tilesPerSide = len(self.tiles) // 4 for side in (self.__sides[0], self.__sides[3], self.__sides[2], self.__sides[1]): upper = True # upper tile is played first for position in range(tilesPerSide - 1, -1, -1): uiTile = next(tileIter) uiTile.setBoard(side, position // 2, 0, level=int(upper)) upper = not upper self.__setDrawingOrder() return animate()
def course_scraper(): global step try: check_updates() step = 1 start_phantomjs() step = 2 login() step = 3 lecture_name = load_handbook() step = 4 lecture_links, new_type = get_lecture_res() return lecture_name, lecture_links, new_type except (NoSuchElementException, requests.exceptions.RequestException, WebDriverException): if driver: driver.quit() animate(end=1) print(f'An error occurred while {error_pos[step]} :(') print('Please check your internet connection speed and stability.') raise SystemExit
def refreshAll(): """recompute ourself. Always do this for all for sides together because if two names change place we want the to move simultaneously""" sides = SideText.sideTexts if all(not x.needsRefresh for x in sides): return rotating = False for side in sides: side.show() if not side.needsRefresh: continue side.needsRefresh = False rotating |= sceneRotation(side) != sceneRotation(side.board) alreadyMoved = any(x.x() for x in sides) with AnimationSpeed( speed=Speeds.windMarker if rotating and alreadyMoved else 99): # first round: just place the winds. Only animate moving them # for later rounds. for side in sides: side.setupAnimations() animate()
def build(self): """builds the wall without dividing""" # recycle used tiles for tile in self.tiles: tile.element = 'Xy' tile.dark = True # field = Internal.field # animateBuild = not field.game.isScoringGame() and not self.game.isFirstHand() animateBuild = False with Animated(animateBuild): self.__shuffleTiles() for tile in self.tiles: tile.focusable = False return animate().addCallback(self.__placeWallTiles)
def build(self, shuffleFirst=False): """builds the wall without dividing""" # recycle used tiles for uiTile in self.tiles: uiTile.tile = Tile.unknown uiTile.dark = True # scene = Internal.scene # animateBuild = not scene.game.isScoringGame() and not # self.game.isFirstHand() animateBuild = False with MoveImmediate(animateBuild): if shuffleFirst: self.__shuffleTiles() for uiTile in self.tiles: uiTile.focusable = False return animate().addCallback(self.__placeWallTiles)
def initMenuUI(): """ Initialise les éléments d'interface du menu principal du jeu. """ ui.setBackground("black") ui.addButton(render.WIDTH_WINDOW / 2, -render.HEIGHT_WINDOW/3, width=render.WIDTH_WINDOW / 3 / 1.4, height=int(render.HEIGHT_WINDOW / 3 / 1.4), polygonal=POLYGONS["octo"], text=language.get("playButton"), textSize=42, textColor="white", outlineColor="white", action=playButton, ID="playButton") ui.addButton(-render.WIDTH_WINDOW/4, render.HEIGHT_WINDOW *1.8/3, width=render.WIDTH_WINDOW / 4, height=int(render.HEIGHT_WINDOW / 4), polygonal=POLYGONS["octo"], text=language.get("scoreButton"), textSize=28, textColor="white", outlineColor="white", action=evenement.setGameEvent, arguments=["score"], ID="scoreButton") ui.addButton(render.WIDTH_WINDOW*5/4, render.HEIGHT_WINDOW *1.8/3, width=render.WIDTH_WINDOW / 4, height=int(render.HEIGHT_WINDOW / 4), polygonal=POLYGONS["octo"], text=language.get("editorButton"), textSize=28, textColor="white", outlineColor="white", action=evenement.setGameEvent, arguments=["editor"], ID="editorButton") ui.addButton(render.WIDTH_WINDOW / 2, render.HEIGHT_WINDOW*1.15, width=150, height=50, polygonal=POLYGONS["octo"], text=language.get("quitButton"), textSize=18, textColor="white", outlineColor="white", action=logic.quitter, ID="quitButton") # ui.addButton(render.WIDTH_WINDOW - 85, render.HEIGHT_WINDOW - 10, polygonal=POLYGONS["octo"], text=language.get("settingsButton"), textSize=18, textColor="white", outlineColor="white", anchor="sc") ui.addButton(render.WIDTH_WINDOW*0.05, render.HEIGHT_WINDOW*0.05, polygonal=POLYGONS["trapeze-up"], width=render.WIDTH_WINDOW*0.10 , text="FR", action=setLanguage, arguments=["fr", initMenuUI], outlineColor="white", textColor="white", ID="frButton") ui.addButton(render.WIDTH_WINDOW*0.05, render.HEIGHT_WINDOW*0.15, polygonal=POLYGONS["trapeze-down"], width=render.WIDTH_WINDOW*0.10 , text="EN", action=setLanguage, arguments=["en", initMenuUI], outlineColor="white", textColor="white", ID="enButton") ui.addTextField(render.WIDTH_WINDOW*0.90, render.HEIGHT_WINDOW/26, text=playerName, ID="tfPlayer",outlineColor="white", textColor="white" ) # ui.addButton(render.WIDTH_WINDOW*0.1, render.HEIGHT_WINDOW*0.15, text=language.get("englishButton"), action=ui.setBackground, arguments=["green"], outlineColor="white", textColor="white") animation.animate("playButton", [0.5, 0.3], [{"y":render.HEIGHT_WINDOW *0.8/3}, {"width":render.WIDTH_WINDOW / 3, "height":int(render.HEIGHT_WINDOW / 3)}]) animation.animate("scoreButton", [0.5], [{"x":render.WIDTH_WINDOW / 4}]) animation.animate("editorButton", [0.5], [{"x": 3*render.WIDTH_WINDOW / 4}]) animation.animate("quitButton", [0.5], [{"y": render.HEIGHT_WINDOW*0.85}])
def print_to_pdf(lecture_links, lecture_name, new_type): try: print('\n', 'Printing gathered pages to PDF...') print() common_args = '-L 0mm -R 0mm -T 0mm -B 0mm --image-quality 100 -n --load-media-error-handling abort ' if new_type: cli_args = common_args + ' '.join(lecture_links) print_error = system( fr'{work_dir}\wkhtmltopdf.exe {cli_args} "{temp_pdf}"') else: cli_args = common_args + '--page-width 350mm --page-height 10000mm -d 600 --zoom 2 ' + ' '.join( lecture_links) print_error = system( fr'{work_dir}\wkhtmltopdf.exe {cli_args} "{temp_pdf}_uncropped"' ) print() if path.exists(f'{temp_pdf}_uncropped'): animate('Adjusting margins') from pdfCropMargins_mod.main_pdfCropMargins import main_crop main_crop() remove(f'{temp_pdf}_uncropped') animate('Margins adjusted!', end=1) else: raise ConnectionError if path.exists(f'{temp_pdf}'): move_fail = system( f'move "{temp_pdf}" "{lecture_name}.pdf">nul 2>&1') if move_fail: raise MoveFailed else: raise ConnectionError return print_error except ConnectionError: animate(end=1) print('Connection Error :(') raise SystemExit except MoveFailed: print( '\n', 'Could not attain permissions to create PDF in the current location.' ) print( "Make sure an already existing PDF isn't open in a running program," " or administrative rights are not required.", '\n') raise SystemExit
def get_lecture_res(): animate('Counting lectures') lecture_links = list() module_navigators = driver.find_element_by_id('div_navigate_session').find_elements_by_tag_name('input') if not module_navigators: raise NoSuchElementException total_lectures = int(module_navigators[-1].get_attribute('value')) lecture_page = driver.find_element_by_id('IFRAME_ID_1').get_attribute('src').split('#')[0] driver.quit() if session.head(lecture_page, timeout=10).status_code != 200: animate(end=1) print('Lecture could not be found on server.') raise SystemExit new_type = "src='Imagepath/" in session.get(lecture_page, timeout=10).text if total_lectures == 1: animate('Lecture loaded!', end=1) lecture_links.append(lecture_page) else: module = 1 animate(f'{total_lectures} lectures have been found.', end=1) print() for i in range(1, total_lectures + 1): printProgressBar(i, total_lectures, prefix=' Discovering pages', suffix='Complete', length=50) lecture_page = lecture_page.replace(f'_L{i - 1}', f'_L{i}') if session.head(lecture_page, timeout=10).status_code == 404: lecture_page = lecture_page.replace(f'_M{module}', f'_M{module + 1}') module += 1 lecture_links.append(lecture_page) return lecture_links, new_type
print("Output name is", sys.argv[2]) ################################################## # plot simple animation of phases def myplot(frame, fig): ax = fig.add_subplot(111) plot.cells(frame, ax) plot.solidarea(frame, ax) plot.shape(frame, ax) plot.velocity(frame, ax) plot.pressure_force(frame, ax) plot.walls(frame, ax) ax.axes.set_aspect('equal', adjustable='box') ax.set_xlim([0, frame.parameters['Size'][0]-1]) ax.set_ylim([0, frame.parameters['Size'][1]-1]) ax.axis('off') if len(oname) == 0: animation.animate(ar, myplot, show=True) exit(0) else: an = animation.animate(ar, myplot, show=False) animation.save(an, oname+'.mp4', 5)
system(f'title Online Courseware Downloader : Downloaded ↓ {lecture_name}'.replace('&', '^&')) system('cls') print('\n', f'{lecture_name}.pdf saved to current directory.', '\n') if print_error: print('The file is possibly incomplete due to missing resources.') print(open(fr'{work_dir}\dino.txt').read()) print('\n', "Press any key to quit.") getch() except KeyboardInterrupt: animate(end=1) print('Received KeyboardInterrupt!') except SystemExit as e: if not str(e): print('\n', 'Press any key to quit.') getch() except: animate(end=1) print('Unknown error occurred :(') try: with open('ocd_error_log.txt', 'a') as error_log: error_log.write(traceback.format_exc() + '\n\n') print("Please share the log file 'ocd_error_log.txt' with the developer at [email protected]") except:
def dropHere(self, tile, meld, dummyLowerHalf=None): """drop tile or meld into selector board""" tile1 = tile or meld[0] if tile1.board != self: self.receive(tile, meld) animate()
def run_animation(self, delay=100): animate(self.lines_history, delay)
def animate(self, method, **kwargs): return animation.animate(self, method, **kwargs)
dt = 0.01 # time steps for simulation time_end = 5. # duration of simulation t = np.arange(0, time_end + dt, dt) n_points = int(time_end / dt) states = np.zeros((n_states, n_points)) # states over simulation time statesDes = np.zeros((n_states, n_points)) # desired state (default to 0) inputs = np.zeros((n_inputs, n_points)) # inputs over simulation time # Initialization state_0 = np.array([4, 1, 4, 1, 0, 0]) # initial state #state_0 = drone.randStart(xMax, yMax) # random initial state with xMax, yMax drone = Drone(mass, l_f, l_r, h, w, state_0) states[:, 0] = state_0 # Set desired states over time for i in range(n_points): statesDes[:, i] = np.array([2, 0, 2, 0, 0, 0]) # (go to x=10, y=10, and stay stationary) # Set gain matrix K = np.array([2, 2, 5, 5, 20, 20]) # y, ydot, x, xdot, theta, thetadot # Solve simulation for i in range(1, len(t) - 1): next_u = drone.feedbackLin(states[:, i - 1], statesDes[:, i - 1], K, dt) next_state = drone.update(states[:, i - 1], next_u, dt) states[:, i] = next_state # animation of path animate(states, drone, dt, time_end)