コード例 #1
0
    def __init__(self, world, name, role):
        RADIUS = 130 / 5  # The diameter of the telliskivi robot is 260mm. In pixels it makes a radius of 26
        self.WHEEL_RADIUS = 105 / 5
        self.FORWARD_EDGE_FRONT = 85 / 5
        self.FORWARD_EDGE_LEFT = 100 / 5  # 98.86mm
        CENTER = Point(12 + RADIUS, 12 +
                       RADIUS) if (role == "TOPLEFT") else Point(
                           world.width - 12 - RADIUS, world.height - 12 -
                           RADIUS)
        WorldObject.__init__(self, CENTER, RADIUS)
        self.world = world
        self.name = name
        self.wr = RADIUS
        self.hr = RADIUS
        self.beacon_point = Point(
            world.width +
            50, world.cy) if role == "TOPLEFT" else Point(-50, world.cy)
        self.beacon_point_en = Point(0,
                                     world.cy) if role == "TOPLEFT" else Point(
                                         world.width, world.cy)
        self.goal_center = Point(world.width,
                                 world.cy) if role == "TOPLEFT" else Point(
                                     0, world.cy)

        # "Forward" is the unit direction vector where the robot is facing
        # (0, 1) is the "default" (height along the Y axis)
        self.forward = Point(0, 1)
        self.left = Point(-self.forward.y, self.forward.x)
        if role == "TOPLEFT":
            self.rotate(3.1415 / 2)
        else:
            self.rotate(-3.1415 / 2)

        # Those are state parameters
        self.leftSpeed = 0
        self.rightSpeed = 0

        # Camera sensor parameters
        self.CAMERA_DEPTH = 1000  # Let's say the camera sees as far as the end of the field (~5 meters = 1000 px)
        self.CAMERA_SIDE = 340  # The camera's side angle is 20 degree, i.e. at 1000 pixels it stretches to 340px

        # Write concurrency lock (we assume reads are atomic, and even if not, just ignore read errors)
        self.data_lock = thread.allocate_lock()

        # Whether there's a ball in the grabber
        self.grabbed_ball = None
        self.grabbed_ball_lock = thread.allocate_lock()
コード例 #2
0
    def simulate(self):
        # This is a hack which only works at small simulation steps
        leftTurn = (self.leftSpeed - self.rightSpeed) / self.WHEEL_RADIUS / 2
        forwardMove = (self.leftSpeed + self.rightSpeed) / 2
        self.v = self.forward * forwardMove
        if (self.v != 0):
            self.center.add(self.v)
        if (leftTurn != 0):
            self.forward = self.forward + self.left * leftTurn
            self.forward.normalize()
            self.left = Point(-self.forward.y, self.forward.x)

        # If there is a grabbed ball, carry it around
        with self.grabbed_ball_lock:
            if self.grabbed_ball is not None:
                self.grabbed_ball.v = Point(0, 0)
                self.grabbed_ball.center = self.center + self.forward * self.grabbed_forward + self.left * self.grabbed_left

        # Precompute "edge walls", those will be useful in collision checks
        self.edge_walls = [Wall(e[1], e[0]) for e in self.edges()]
        all_x = [w.p1.x for w in self.edge_walls]
        all_y = [w.p1.y for w in self.edge_walls]
コード例 #3
0
	def __init__(self, world, name, role):
		width  = 40 
		height = 40
		center 					= Point(int(12+height/2), int(12+width/2)) if role == "TOPLEFT" else Point(world.width-(12+height/2), world.height-(12+width/2))
		
		WorldObject.__init__(self, center, int(sqrt(width**2 + height**2)/2) )
		self.world = world
		self.name = name
		self.wr = width/2
		self.hr = height/2
		self.beacon_point 		= Point(world.width + 50, world.cy) if role == "TOPLEFT" else Point(-50, world.cy)
		self.beacon_point_en 	= Point(0, world.cy) 				if role == "TOPLEFT" else Point(world.width, world.cy)
		self.goal_center 		= Point(world.width, world.cy) 		if role == "TOPLEFT" else Point(0, world.cy)		
		
		
		# "Forward" is the unit direction vector where the robot is facing
		# (0, 1) is the "default" (height along the Y axis)
		self.forward = Point(0, 1)
		self.left = Point(-self.forward.y, self.forward.x)
		if role == "TOPLEFT":
			self.rotate(3.1415/2)
		else:
			self.rotate(-3.1415/2)

		# Those are state parameters
		self.leftSpeed = 0
		self.rightSpeed = 0
		
		# Camera sensor parameters
		self.CAMERA_DEPTH 	= 800 	# Kaugus kuhu naeme 
		self.CAMERA_SIDE 	= 500	# Laius kuhu naeme
		
		# Write concurrency lock (we assume reads are atomic, and even if not, just ignore read errors)
		self.data_lock = thread.allocate_lock()

		# Whether there's a ball in the grabber
		self.grabbed_ball = None
		self.grabbed_ball_lock = thread.allocate_lock()
コード例 #4
0
 def grab(self):
     "If at the moment this function is called there is a ball right at the front of the robot, the ball is 'grabbed'"
     if self.grabbed_ball is not None:
         return
     for b in self.world.objects:
         if isinstance(b, Ball):
             # First check distance to center
             v = b.center - self.center
             v_forward = self.forward.inner_product(v)
             if v_forward > 0 and v_forward < self.FORWARD_EDGE_FRONT + b.radius + 3:
                 # See whether the ball is within the front edge
                 v_left = self.left.inner_product(v)
                 if (abs(v_left) < self.FORWARD_EDGE_LEFT - 2):
                     # OK, grab
                     with self.grabbed_ball_lock:
                         self.grabbed_ball = b
                         b.v = Point(0, 0)
                         self.grabbed_forward = v_forward - 5
                         self.grabbed_left = v_left
                     return
コード例 #5
0
	def grab(self):
		"If at the moment this function is called there is a ball right at the front of the robot, the ball is 'grabbed'"
		if self.grabbed_ball is not None: #pall on juba haaratud, meil peaks olema, et votab koik pallid
			return
		for b in self.world.objects:
			if isinstance(b, Ball):
				# First check distance to center
				v = b.center - self.center
				v_forward = self.forward.inner_product(v)
				if v_forward > 0 and v_forward < self.hr + b.radius + 3:
					# See whether the ball is within the front edge
					v_left = self.left.inner_product(v)
					if (abs(v_left) < self.wr - 2):
						# OK, grab
						with self.grabbed_ball_lock:
							self.grabbed_ball = b
							b.v = Point(0, 0)
							self.grabbed_forward = v_forward - 5
							self.grabbed_left = v_left
						return
コード例 #6
0
	def collision_check(self, obj):
		# If it is not a ball, ignore it
		if not isinstance(obj, Ball): # objekt ei ole pall
			# Just check the "bounding circle"
			dir = obj.center - self.center
			dist = dir.norm()
			if (dist < obj.radius + self.radius):
				# Nudge either us or them, choose randomly to avoid some ugliness
				dir_normalized = dir * (1/dist)
				if (random.randint(0,1) == 0):
					# Them
					obj.center.add(dir_normalized*(obj.radius + self.radius - dist))
				else:
					# Us
					self.center.add(dir_normalized*(dist - (obj.radius + self.radius)))
		else: #objekt on pall
			# Find which wall is the ball touching
			for w in self.edge_walls:
				d = w.dist_to_point(obj.center) - obj.radius
				if (d > -0.3 and d < 0):
					# Is the ball within the range of the wall at all?
					wall_coord = (obj.center - w.p1).inner_product(w.v_normalized)
					if (wall_coord >= -obj.radius and wall_coord <= w.len+obj.radius):
						# Yes, it does, something must be done.
						# Nyyd kontrollime kas esimene ots?
						v = obj.center - self.center
						v_left = self.left.inner_product(v)
						v_forward = self.forward.inner_product(v)
						if (abs(v_left) < self.wr - 2):
							# OK, grab
							with self.grabbed_ball_lock:
								self.grabbed_ball = obj
								obj.v = Point(0, 0)
								self.grabbed_forward = v_forward - 5
								self.grabbed_left = v_left
							return
						else: #kui pole esimene ots	
							# First, nudge
							obj.center.add(w.normal * (-d))
							# Second, simulate a rebounce (this is a hack, but it's way easier than considering rotations and stuff)
							obj.v.add(w.normal * (-d*2))
コード例 #7
0
def main():
	# Read two parameters identifying modules for the first and the second robots.
	if (len(sys.argv) < 3):
		print "Usage: python main.py <first_robot> <second_robot> [random seed]"
		print ""
		print "The <first_robot> and <second_robot> should identify modules containing classes Robot and RobotServer"
		print "E.g if you invoke "
		print "  python main.py telliskivi ekrs"
		print "The simulator will import telliskivi.Robot, telliskivi.RobotServer, ekrs.Robot, ekrs.RobotServer"
		sys.exit(1)
	
	# Try to import modules
	r1module = __import__(sys.argv[1])
	r2module = __import__(sys.argv[2])
	(a,b,c,d) = (r1module.Robot, r1module.RobotServer, r2module.Robot, r2module.RobotServer) # Testing
	random_seed = int(sys.argv[3]) if len(sys.argv) > 3 else None
	# random seeds 1,2,3,4 are already interesting use cases
	
	# Init graphics
	pygame.init()
	window = pygame.display.set_mode((1060, 760)) # This is the size of the field + contestant area. (5300 x 3800)
	pygame.display.set_caption('Robotex 2011 Simulator') 
	screen = pygame.display.get_surface() 

	# Init world. 
	world = World(screen)

	# Add 11 balls (coordinates are world-coords)
	# Make sure the balls are added symmetrically. That means the first ball goes in the center
	world.add_object(Ball(Point(world.width/2, world.height/2)))	
	for i in range(5):
		while True:
			xpos = random.uniform(10,world.width-10)
			ypos = random.uniform(10,world.height-10)
			# Make sure the positions do not get in the robot's starting corners ( 0..60px, i.e. 0..60px )
			if not ((xpos < 60 and ypos < 60) or (xpos > world.width - 60 and ypos > world.height - 60)):
				break
		world.add_object(Ball(Point(xpos, ypos)))
		world.add_object(Ball(Point(world.width-xpos, world.height-ypos)))
	
	# Create two robots
	robot1 = r1module.Robot(world, "Robot A", "TOPLEFT")
	robot2 = r2module.Robot(world, "Robot B", "BOTTOMRIGHT")
	world.add_object(robot1)
	world.add_object(robot2)
	
	# Start robot command servers
	r1module.RobotServer(robot1, 5000).serve()
	r2module.RobotServer(robot2, 5001).serve()
	
	# Do the simulation/drawing/event cycle
	last_sim = -1000
	last_draw = -1000
	while True:
		t = get_ticks()
		if (t - last_sim) > 1:
			# Simulate world (~1 iteration once every millisecond or so)
			# NB: This is kinda hard-coded into the logic currently,
			# i.e. World.simulate() and Ball.simulate() and anyone else is 
			# free to assume that a simulation step is 1ms. In particular,
			# the ball computes it's friction coefficient like that.
			world.simulate()
			last_sim = t
		
		if (t - last_draw) > 40:
			# Draw a frame once every 40 milliseconds or so (~25 fps)
			BACKGROUND_BLUE = (120,119,253)
			screen.fill(BACKGROUND_BLUE)
			world.draw(screen)
			pygame.display.flip()
			last_draw = t
		
		# Process input
		input(pygame.event.get())