tag.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import socket
  2. import sys
  3. import threading
  4. import numpy as np
  5. from socket import error as SocketError
  6. class Robot():
  7. # frente
  8. # ---------
  9. # | |
  10. # | |
  11. # | LLL |
  12. # | LLL |
  13. # ---------
  14. # idd, id do robo
  15. # xsize, largura do robo
  16. # xsize, comprimento do robo
  17. # xtag, distancia horizontal do lado esquerdo ao cento do tag
  18. # ytag, distancia vertical do topo ao cento do tag
  19. # posx, posy, course, posicao do robo
  20. def __init__(self, idd, xsize, ysize, xtag, ytag, posx = 0, posy = 0, course = 0):
  21. self.idd = idd
  22. self.xsize = xsize
  23. self.ysize = ysize
  24. self.xtag = xtag
  25. self.ytag = ytag
  26. self.posx = posx
  27. self.posy = posy
  28. self.course = course
  29. def lines(self):
  30. p1 = np.array([-self.xtag, self.ytag])
  31. p2 = np.array([-self.xtag, -self.ysize+self.ytag])
  32. p3 = np.array([self.xsize-self.xtag, self.ytag])
  33. p4 = np.array([self.xsize-self.xtag, -self.ysize+self.ytag])
  34. pos = np.array([self.posx, self.posy])
  35. c, s = np.cos(self.course), np.sin(self.course)
  36. R = np.array(((c,-s), (s, c)))
  37. p1 = p1.dot(R)+pos
  38. p2 = p2.dot(R)+pos
  39. p3 = p3.dot(R)+pos
  40. p4 = p4.dot(R)+pos
  41. return np.array([[p1, p2], [p2, p4], [p4, p3], [p1, p3]])
  42. def ccw(self, A,B,C):
  43. return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])
  44. # Return true if line segments AB and CD intersect
  45. def line_intersect(self, A,B,C,D):
  46. return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)
  47. # get robot and see if this intersect te other
  48. def intersect(self, robot):
  49. thislines = self.lines()
  50. other = robot.lines()
  51. for i in thislines:
  52. for j in thislines:
  53. if line_intersect(i[0], i[1], j[0], j[1]):
  54. return True
  55. return False
  56. class TagServer(threading.Thread):
  57. def __init__(self, port, board_size):
  58. threading.Thread.__init__(self)
  59. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  60. server_address = ('0.0.0.0', port)
  61. print ('Starting up on %s port %s' % server_address)
  62. sock.bind(server_address)
  63. sock.listen(1)
  64. sock.settimeout(1)
  65. self.sock = sock
  66. self.clients_threads = []
  67. self.tag = None
  68. self.board_size = board_size
  69. self.runV = True
  70. self.start()
  71. def updatePosition (self, idd, posx, posy, course):
  72. for thread in self.clients_threads:
  73. if thread.robot is not None and thread.robot.idd == idd:
  74. msg = "P "
  75. msg = msg + str(posx)+","
  76. msg = msg + str(posy)+","
  77. msg = msg + str(course)+","
  78. msg = msg + str(thread.robot.idd)+","
  79. msg = msg + str(thread.robot.xsize)+","
  80. msg = msg + str(thread.robot.ysize)+","
  81. msg = msg + str(thread.robot.xtag)+","
  82. msg = msg + str(thread.robot.ytag)
  83. thread.robot.posx = posx
  84. thread.robot.posy = posy
  85. thread.robot.course = course
  86. self.brodcast(msg)
  87. # check for collision
  88. for i in self.robots():
  89. if i != self.tag:
  90. continue
  91. for j in self.robots():
  92. if i == j:
  93. continue
  94. if i.intersect(j):
  95. self.tag = j
  96. self.brodcast("RUN "+str(self.tag.id)+" 10")
  97. def startGame (self):
  98. self.brodcast("STOP")
  99. def startGame (self):
  100. self.brodcast("START")
  101. if self.tag is None:
  102. tag = np.random.choice(self.robots(), 1)
  103. if len(tag) == 1:
  104. self.tag = tag
  105. self.brodcast("RUN "+str(self.tag.id)+" 10")
  106. return True
  107. return False
  108. def brodcast(self, msg):
  109. for thread in self.clients_threads:
  110. if thread.robot is not None:
  111. thread.send(msg+"\n")
  112. def run(self):
  113. while self.runV:
  114. try:
  115. (clientsock, (ip, port)) = self.sock.accept()
  116. newthread = TagThread(ip, port, clientsock, self)
  117. self.clients_threads.append(newthread)
  118. except socket.timeout as err:
  119. pass
  120. self.sock.close()
  121. def robots(self):
  122. r = []
  123. for thread in self.clients_threads:
  124. if thread.robot is not None:
  125. r.append(thread.robot)
  126. return r
  127. def stop(self):
  128. for thread in self.clients_threads:
  129. thread.stop()
  130. self.runV = False
  131. class TagThread(threading.Thread):
  132. def __init__(self, ip, port, socket, server):
  133. threading.Thread.__init__(self)
  134. self.ip = ip
  135. self.port = port
  136. self.sock = socket
  137. self.points = 0
  138. self.robot = None
  139. self.bz = server.board_size
  140. self.server = server
  141. socket.settimeout(1)
  142. self.runV = True
  143. self.start()
  144. def run(self):
  145. while self.runV:
  146. try:
  147. data = self.sock.recv(64).decode('ascii')
  148. except socket.timeout as err:
  149. continue
  150. except SocketError as e:
  151. self.robot = None
  152. break
  153. data = data.split(" ")
  154. try:
  155. if data[0] == "SUB":
  156. idd, xsize, ysize, xtag, ytag = data[1].split(",")
  157. self.robot = Robot(int(idd), float(xsize), float(ysize), float(xtag), float(ytag))
  158. self.send("OK "+str(self.bz[0])+","+str(self.bz[1])+"\n")
  159. if data[0] == "P":
  160. posx, posy, curse = data[1].split(",")
  161. posx, posy, curse = float(posx), float(posy), float(curse)
  162. self.server.updatePosition(self.robot.idd, posx, posy, curse)
  163. except Exception as e:
  164. print(e)
  165. self.send("ERR\n")
  166. self.sock.close()
  167. def send(self, msg):
  168. self.sock.sendall(msg.encode('ascii'))
  169. def stop(self):
  170. self.runV = False
  171. class TagClient(threading.Thread):
  172. def __init__(sself, ip, port):
  173. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  174. server_address = (ip, port)
  175. sock.connect(server_address)
  176. self.sock = sock
  177. self.stop = None
  178. self.start = None
  179. self.tagger = None
  180. self.position = None
  181. def info (self, idd, xsize, ysize, xtag, ytag):
  182. message = "SUB "+idd+","+xsize+","+ysize+","+xtag+","+ytag+"\n"
  183. self.sock.sendall(message.encode('ascii'))
  184. self.start()
  185. def run(self):
  186. while True:
  187. try:
  188. data = self.sock.recv(64).decode('ascii')
  189. except SocketError as e:
  190. self.robot = None
  191. break
  192. data = data.split("\n")[0].split(" ")
  193. if data[0] == "OK":
  194. self.board_size = self.position(data[1].split(","))
  195. print("SUB OK")
  196. elif data[0] == "P" and self.position is not None:
  197. self.position(data[1].split(","))
  198. def stopCallback (self, function):
  199. self.stop = function
  200. def startCallback (self, function):
  201. self.start = function
  202. def taggerCallback (self, function):
  203. self.tagger = function
  204. def positionCallback (self, function):
  205. self.position = function
  206. def boardinfoCallback (self, function):
  207. self.boardinfo = function
  208. # Somente na simulacao
  209. def setPosition(px, py):
  210. message = "P "+px+","+py+"\n"
  211. self.sock.sendall(message.encode('ascii'))