def predictedPosition(self, t): """Calculate the position of the object in t ticks if it continues accelerating at its current rate Args: t (int): the number of ticks into the future you're predicting the object's position. Note that the large t gets, the less accurate the prediction will be. Returns: Point of the predicted position of the object """ try: displacement = self.currentSpeed * t + 0.5 * self.acceleration * ( t**2) xDisplacement = round(sin(self.direction) * displacement, 2) yDisplacement = round(cos(self.direction) * displacement, 2) return Point(self.currentPoint.x + xDisplacement, self.currentPoint.y + yDisplacement) except TypeError: if isinstance(t, int): return self.currentPoint else: raise TypeError("Float expected, " + t.__class__.__name__ + " found")
def move(self): if self.currentSpeed == 0 & self.acceleration == 0: return self.currentSpeed = self.currentSpeed + self.acceleration * tickTimeLeft distanceTravelled = self.currentSpeed * tickTimeLeft angle = self.currentRotation xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) newX = self.currentPoint.x + xDisplacement newY = self.currentPoint.y + yDisplacement topWall = xDisplacement == PITCH_WIDTH leftWall = xDisplacement == 0 rightWall = yDisplacement == PITCH_LENGTH bottomWall = yDisplacement == 0 if topWall | leftWall | rightWall | bottomWall: self.bounce(topWall, leftWall, rightWall, bottomWall) self.currentPoint = Point(newX, newY) if self.currentSpeed < 0: self.currentSpeed = 0 self.acceleration = 0
def move(self): if self.currentSpeed ==0 & self.acceleration ==0: return self.currentSpeed = self.currentSpeed + self.acceleration*tickTimeLeft distanceTravelled = self.currentSpeed* tickTimeLeft angle = self.currentRotation xDisplacement = round(cos(angle)*distanceTravelled, 2) yDisplacement = -round(sin(angle)*distanceTravelled, 2) newX = self.currentPoint.x+xDisplacement newY = self.currentPoint.y+yDisplacement topWall = xDisplacement == PITCH_WIDTH leftWall = xDisplacement ==0 rightWall = yDisplacement == PITCH_LENGTH bottomWall = yDisplacement ==0 if topWall | leftWall | rightWall | bottomWall: self.bounce(topWall, leftWall, rightWall, bottomWall) self.currentPoint = Point(newX, newY ) if self.currentSpeed < 0: self.currentSpeed = 0 self.acceleration = 0
def predictedPosition(self, t): """Calculate the position of the object in t ticks if it continues accelerating at its current rate Args: t (int): the number of ticks into the future you're predicting the object's position. Note that the large t gets, the less accurate the prediction will be. Returns: Point of the predicted position of the object """ try: displacement = self.currentSpeed*t + 0.5*self.acceleration*(t**2) xDisplacement = round(sin(self.direction)*displacement, 2) yDisplacement = round(cos(self.direction)*displacement, 2) return Point(self.currentPoint.x+xDisplacement, self.currentPoint.y+yDisplacement) except TypeError: if isinstance(t,int): return self.currentPoint else: raise TypeError("Float expected, " + t.__class__.__name__ + " found")
def tick(self, tickTimeLeft=TICK_TIME): '''Update the status of our robot and the ball based on our recent actions tickTimeLeft: the time remaining before the next tick, TICK_TIME by default or slightly less than this if an action finishes halfway through a tick and this gets called again on the remaining time''' try: currentAction = self.currentActionQueue[0] except IndexError: # if it's not currently carrying out an action, it'll stay the same return if currentAction['action'] == SimulatorActions.moveHolo: if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME distanceTravelled = MAX_SPEED * TICK_TIME * 0.9 angle = simulatedMe.currentRotation + currentAction['action'][0] xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) simulatedMe.currentPoint = Point( simulatedMe.currentPoint.x + xDisplacement, simulatedMe.currentPoint.y + yDisplacement) else: tickTimeLeft = TICK_TIME - currentAction['timeLeft'] distanceTravelled = MAX_SPEED * currentAction['timeLeft'] * 0.9 angle = simulatedMe.currentRotation + currentAction['action'][0] xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) simulatedMe.currentPoint = Point( simulatedMe.currentPoint.x + xDisplacement, simulatedMe.currentPoint.y + yDisplacement) # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently moving forwards if currentAction['action'] == SimulatorActions.moveForwards: # if it'll keep going for this whole tick, move the simulated robot forwards the appropriate amount if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME distanceTravelled = MAX_SPEED * TICK_TIME angle = simulatedMe.currentRotation xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) simulatedMe.currentPoint = Point( simulatedMe.currentPoint.x + xDisplacement, simulatedMe.currentPoint.y + yDisplacement) # if not, move the simulated robot forwards the lesser amount, then start the next action in the queue with the remaining time else: tickTimeLeft = TICK_TIME - currentAction['timeLeft'] distanceTravelled = MAX_SPEED * currentAction['timeLeft'] angle = simulatedMe.currentRotation xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) simulatedMe.currentPoint = Point( simulatedMe.currentPoint.x + xDisplacement, simulatedMe.currentPoint.y + yDisplacement) # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently rotating elif currentAction['action'] == SimulatorActions.rotate: # if it'll keep going for this whole tick, turn the simulated robot forwards the appropriate amount if TICK_TIME < currentAction['timeLeft']: # calculate how far to turn currentAction['timeLeft'] -= TICK_TIME degreesTurned = MAX_ROT_SPEED * TICK_TIME # turn the right direction if currentAction['amount'] < 0: simulatedMe.currentRotation -= degreesTurned else: simulatedMe.currentRotation += degreesTurned # keep the value in [-180, 180] if simulatedMe.currentRotation < -180: simulatedMe.currentRotation += 360 elif simulatedMe.currentRotation > 180: simulatedMe.currentRotation -= 360 # if not, move the simulated robot forwards the lesser amount, then start the next action in the queue with the remaining time else: # calculate how far to turn tickTimeLeft = TICK_TIME - currentAction['timeLeft'] degreesTurned = MAX_ROT_SPEED * currentAction['timeLeft'] # turn the right direction if currentAction['amount'] < 0: simulatedMe.currentRotation -= degreesTurned else: simulatedMe.currentRotation += degreesTurned # keep the value in [-180, 180] if simulatedMe.currentRotation < -180: simulatedMe.currentRotation += 360 elif simulatedMe.currentRotation > 180: simulatedMe.currentRotation -= 360 # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently kicking elif currentAction['action'] == SimulatorActions.kick: # if it'll keep kicking for this whole tick, the only potential change is that the ball starts moving if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME #simulatedBall.get_kicked() # if not, start the next action in the queue with the remaining time else: tickTimeLeft = TICK_TIME - currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently grabbing elif currentAction['action'] == SimulatorActions.grab: # if it'll keep grabbing for this whole tick, the only potential change is that the ball stops moving if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME # if the ball is close enough stop the ball and toggle 'holding ball' state #simulatedBall.get_grabbed(simulatedMe) # if not, start the next action in the queue with the remaining time TODO else: self.grabbed = True tickTimeLeft = TICK_TIME - currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently ungrabbing elif currentAction['action'] == SimulatorActions.ungrab: # if it'll keep grabbing for this whole tick, nothing changes if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME # if not, start the next action in the queue with the remaining time else: self.grabbed = False tickTimeLeft = TICK_TIME - currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft)
def tick(self, tickTimeLeft=TICK_TIME): '''Update the status of our robot and the ball based on our recent actions tickTimeLeft: the time remaining before the next tick, TICK_TIME by default or slightly less than this if an action finishes halfway through a tick and this gets called again on the remaining time''' try: currentAction = self.currentActionQueue[0] except IndexError: # if it's not currently carrying out an action, it'll stay the same return if currentAction['action'] == SimulatorActions.moveHolo: if TICK_TIME < currentAction['timeLeft']: currentAction['timeLeft'] -= TICK_TIME distanceTravelled = MAX_SPEED * TICK_TIME * 0.9 angle = simulatedMe.currentRotation + currentAction['action'][0] xDisplacement = round(cos(angle) * distanceTravelled, 2) yDisplacement = -round(sin(angle) * distanceTravelled, 2) simulatedMe.currentPoint = Point(simulatedMe.currentPoint.x + xDisplacement, simulatedMe.currentPoint.y + yDisplacement) else: tickTimeLeft = TICK_TIME-currentAction['timeLeft'] distanceTravelled = MAX_SPEED*currentAction['timeLeft'] * 0.9 angle = simulatedMe.currentRotation + currentAction['action'][0] xDisplacement = round(cos(angle)*distanceTravelled, 2) yDisplacement = -round(sin(angle)*distanceTravelled, 2) simulatedMe.currentPoint = Point(simulatedMe.currentPoint.x+xDisplacement, simulatedMe.currentPoint.y+yDisplacement) # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished += 1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently moving forwards if currentAction['action']==SimulatorActions.moveForwards: # if it'll keep going for this whole tick, move the simulated robot forwards the appropriate amount if TICK_TIME<currentAction['timeLeft']: currentAction['timeLeft']-=TICK_TIME distanceTravelled = MAX_SPEED*TICK_TIME angle = simulatedMe.currentRotation xDisplacement = round(cos(angle)*distanceTravelled, 2) yDisplacement = -round(sin(angle)*distanceTravelled, 2) simulatedMe.currentPoint = Point(simulatedMe.currentPoint.x+xDisplacement, simulatedMe.currentPoint.y+yDisplacement) # if not, move the simulated robot forwards the lesser amount, then start the next action in the queue with the remaining time else: tickTimeLeft = TICK_TIME-currentAction['timeLeft'] distanceTravelled = MAX_SPEED*currentAction['timeLeft'] angle = simulatedMe.currentRotation xDisplacement = round(cos(angle)*distanceTravelled, 2) yDisplacement = -round(sin(angle)*distanceTravelled, 2) simulatedMe.currentPoint = Point(simulatedMe.currentPoint.x+xDisplacement, simulatedMe.currentPoint.y+yDisplacement) # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished +=1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently rotating elif currentAction['action']==SimulatorActions.rotate: # if it'll keep going for this whole tick, turn the simulated robot forwards the appropriate amount if TICK_TIME<currentAction['timeLeft']: # calculate how far to turn currentAction['timeLeft']-=TICK_TIME degreesTurned = MAX_ROT_SPEED*TICK_TIME # turn the right direction if currentAction['amount']<0: simulatedMe.currentRotation -= degreesTurned else: simulatedMe.currentRotation += degreesTurned # keep the value in [-180, 180] if simulatedMe.currentRotation<-180: simulatedMe.currentRotation+=360 elif simulatedMe.currentRotation>180: simulatedMe.currentRotation-=360 # if not, move the simulated robot forwards the lesser amount, then start the next action in the queue with the remaining time else: # calculate how far to turn tickTimeLeft = TICK_TIME-currentAction['timeLeft'] degreesTurned = MAX_ROT_SPEED*currentAction['timeLeft'] # turn the right direction if currentAction['amount']<0: simulatedMe.currentRotation -= degreesTurned else: simulatedMe.currentRotation += degreesTurned # keep the value in [-180, 180] if simulatedMe.currentRotation<-180: simulatedMe.currentRotation+=360 elif simulatedMe.currentRotation>180: simulatedMe.currentRotation-=360 # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished +=1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently kicking elif currentAction['action']==SimulatorActions.kick: # if it'll keep kicking for this whole tick, the only potential change is that the ball starts moving if TICK_TIME<currentAction['timeLeft']: currentAction['timeLeft']-=TICK_TIME #simulatedBall.get_kicked() # if not, start the next action in the queue with the remaining time else: tickTimeLeft = TICK_TIME-currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished +=1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently grabbing elif currentAction['action']==SimulatorActions.grab: # if it'll keep grabbing for this whole tick, the only potential change is that the ball stops moving if TICK_TIME<currentAction['timeLeft']: currentAction['timeLeft']-=TICK_TIME # if the ball is close enough stop the ball and toggle 'holding ball' state #simulatedBall.get_grabbed(simulatedMe) # if not, start the next action in the queue with the remaining time TODO else: self.grabbed=True tickTimeLeft = TICK_TIME-currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished +=1 # start the next action if it's queued self.tick(tickTimeLeft) # if currently ungrabbing elif currentAction['action']==SimulatorActions.ungrab: # if it'll keep grabbing for this whole tick, nothing changes if TICK_TIME<currentAction['timeLeft']: currentAction['timeLeft']-=TICK_TIME # if not, start the next action in the queue with the remaining time else: self.grabbed=False tickTimeLeft = TICK_TIME-currentAction['timeLeft'] # report that we've finished executing this command self.currentActionQueue.pop(0) self.lastCommandFinished +=1 # start the next action if it's queued self.tick(tickTimeLeft)