test_tcp.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. from multiprocessing import Process
  2. # from event_storage import EventStorage
  3. from hard_disk_storage import HardDiskStorage
  4. from memory_storage import MemoryStorage
  5. from sonar_socket2 import Receiver
  6. from sonar_temp_tcp import ClientTemp
  7. from temp_sonar import Receiver1
  8. from sonar_udp import sender
  9. from sonar_command_tcp_once import Client
  10. import socket
  11. import struct
  12. import time
  13. import construct as c
  14. import redis
  15. servo_angle = 'servo1_angle'
  16. MIN_ANGLE = 7
  17. MAX_ANGLE = 347
  18. SYSTEM_MODE = 'once' # once,multiple
  19. hard_disk_db = HardDiskStorage()
  20. servo_data = c.Struct(
  21. header=c.Int16ul, # 固定不便,可能用于区分不同设备
  22. none_1=c.Int8ub, # 固定不便,可能用于区分不同设备
  23. servo1_flag=c.Int8ub,
  24. none_2=c.Int8ub, # 固定不便,可能用于区分不同设备
  25. servo2_flag=c.Int8ub,
  26. depth=c.Bytes(4),
  27. temp=c.Bytes(4),
  28. yaw=c.Bytes(4), # 航向
  29. roll=c.Bytes(4), # 横滚
  30. pitch=c.Bytes(4), # 俯仰
  31. servo1_angle=c.Bytes(4),
  32. servo2_angle=c.Bytes(4),
  33. )
  34. def get_program_status():
  35. sql = "SELECT time_end FROM measurement_data ORDER BY id desc limit 1"
  36. res = hard_disk_db.execute_sql(sql, None)
  37. if res:
  38. if res[0]['time_end']:
  39. return "off"
  40. else:
  41. return "on"
  42. else:
  43. return "off"
  44. class MyProcess(Process): # 继承Process类
  45. def __init__(self, name, config):
  46. super(MyProcess, self).__init__()
  47. self.name = name
  48. self.__sock = None
  49. self.__ip = config['ip']
  50. self.__port = config['port']
  51. self.__save_run_time = 0
  52. # self.__converter = converter
  53. # self.__storager = MemoryStorage({'ip':'127.0.0.1','port':4001})
  54. # self.__save_frequency = config['save_frequency']
  55. self.__save_frequency = 300 # 最小值120
  56. self.redis_db = None
  57. self.__connected = False
  58. self.run_count = 0
  59. self.servo_status = None
  60. self.proc_status = get_program_status()
  61. def run(self):
  62. self.__connect()
  63. self.__connected = True
  64. self.redis_db = MemoryStorage()
  65. while True:
  66. speed = 30
  67. acceleration = 2000
  68. status = self.get_sonar_status() # 发查询指令,当作心跳包。
  69. info_dict = {'depth': status['depth'], 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'], 'pitch': status['pitch'], 'servo_angle': status[servo_angle]}
  70. self.redis_db.set_value(info_dict)
  71. now_time = time.time()
  72. switch = get_program_status()
  73. print(self.proc_status, "-->", switch)
  74. if self.proc_status == 'on' and switch == 'off':
  75. dict1 = {'sonar_open': 'open', 'range': 'big', 'flag': '0'}
  76. self.redis_db.set_value_permanent(dict1)
  77. time.sleep(3)
  78. self.proc_status = switch
  79. continue
  80. elif self.proc_status == 'off' and switch == 'off':
  81. dict1 = {'sonar_open': 'open', 'range': 'big', 'flag': '0'}
  82. self.redis_db.set_value_permanent(dict1)
  83. time.sleep(3)
  84. continue
  85. elif self.proc_status == 'off' and switch == 'on':
  86. self.__save_run_time = 0
  87. self.proc_status = switch
  88. else:
  89. pass
  90. if now_time - self.__save_run_time >= self.__save_frequency - 10: # 提前开启声纳
  91. print('sonar_begin---------------------------', time.time())
  92. if SYSTEM_MODE == 'once':
  93. dict = {'sonar_open': 'open', 'range': 'small', 'flag': '0'}
  94. elif SYSTEM_MODE == 'multiple':
  95. dict = {'sonar_open': 'open', 'range': 'big', 'flag': '0'}
  96. self.redis_db.set_value(dict)
  97. self.rotate_zero(speed, acceleration)
  98. if now_time - self.__save_run_time >= self.__save_frequency and self.redis_db.get_value(['sonar_status'])['sonar_status'] == 'open':
  99. print('zz', self.redis_db.get_value(['sonar_status'])['sonar_status'])
  100. self.__save_run_time = time.time()
  101. if SYSTEM_MODE == 'once':
  102. print('duoji_runing---------------------------', time.time())
  103. self.rotate_once_small(speed, acceleration, self.redis_db, MAX_ANGLE, self.__save_run_time)
  104. self.redis_db.set_value({'range': 'big'})
  105. time.sleep(3)
  106. self.rotate_once_big(speed, acceleration, self.redis_db, MIN_ANGLE, self.__save_run_time)
  107. self.run_count = self.run_count + 1
  108. # print('run_count',self.run_count)
  109. elif SYSTEM_MODE == 'multiple':
  110. speed = 50
  111. angle = 20
  112. self.rotate_multiple_small(angle, speed, acceleration, self.__save_run_time, 'b')
  113. self.redis_db.set_value({'range': 'small'})
  114. time.sleep(3)
  115. self.rotate_multiple_big(angle, speed, acceleration, self.__save_run_time, 's')
  116. # 关闭声纳
  117. dict = {'sonar_open': 'close'}
  118. self.redis_db.set_value(dict)
  119. time.sleep(1)
  120. # data_dict = get_sonar_status(self.__sock)
  121. # self.__conn.set_value(data_dict)
  122. # find_data = b'\xF0\x0F\xFF\xFF\xFF\xFF\x03'
  123. # self.__sock.send(find_data)
  124. #
  125. # # 接收服务器返回的数据
  126. # response = self.__sock.recv(1024)
  127. # print(response)
  128. # #res = servo_data.parse(response)
  129. # while True:
  130. # if isinstance(self.__command, list):
  131. # for i in self.__command:
  132. # command_list = json.loads(i['command'])
  133. # self.command_polling(command_list=command_list)
  134. # time.sleep(1)
  135. # else:
  136. # self.command_polling()
  137. # time.sleep(1)
  138. #
  139. # if self.__stopped:
  140. # break
  141. # 建立socket连接
  142. def __connect(self):
  143. if self.__sock:
  144. self.__sock.close()
  145. self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  146. self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 允许重用本地地址和端口
  147. self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳维护
  148. self.__sock.settimeout(10) # 设置超时时间3mins
  149. try:
  150. self.__sock.connect((self.__ip, self.__port))
  151. # logger.info(f'Connect to [{self.name}]:[{self.__ip}]:[{self.__port}] success !')
  152. self.__connected = True
  153. except Exception as e:
  154. # logger.info(f'Connect to [{self.name}]:[{self.__ip}]:[{self.__port}] failed:{e} !!!')
  155. self.__connected = False
  156. self.__reconnect()
  157. def __reconnect(self):
  158. while True:
  159. try:
  160. if self.__sock:
  161. self.__sock.close()
  162. self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  163. self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  164. self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳维护
  165. self.__sock.settimeout(10) # 设置超时时间,单位:秒
  166. self.__sock.connect((self.__ip, self.__port))
  167. self.__connected = True
  168. # logger.info(f'Reconnect to [{self.name}]:[{self.__ip}]:[{self.__port}] success !')
  169. break
  170. except Exception as e:
  171. # logger.info(f'Reconnect to [{self.name}]:[{self.__ip}]:[{self.__port}] failed:{e} !!! Continue reconnect in 5s..')
  172. self.__connected = False
  173. time.sleep(5)
  174. def __send_command(self, command):
  175. if self.__connected:
  176. try:
  177. # send_data = bytes.fromhex(command)
  178. self.__sock.send(command)
  179. response = self.__sock.recv(1024)
  180. return response
  181. except Exception as e:
  182. time.sleep(5)
  183. self.__reconnect()
  184. print('send', e)
  185. return None
  186. # logger.info(f'Send command to [{self.name}]:[{self.__ip}]:[{self.__port}] error:{e}')
  187. else:
  188. self.__reconnect()
  189. return None
  190. def calculate_checksum(self, data):
  191. checksum = 0
  192. for byte in data:
  193. checksum += byte
  194. checksum = (~checksum) & 0xFF
  195. byte_data = bytes([checksum])
  196. hex_string = byte_data.hex()
  197. return hex_string
  198. def data_converter(self, hex_data):
  199. servo_data = c.Struct(
  200. header=c.Int16ul, # 固定不便,可能用于区分不同设备
  201. none_1=c.Int8ub, # 固定不便,可能用于区分不同设备
  202. servo1_flag=c.Int8ub,
  203. none_2=c.Int8ub, # 固定不便,可能用于区分不同设备
  204. servo2_flag=c.Int8ub,
  205. depth=c.Bytes(4),
  206. temp=c.Bytes(4),
  207. yaw=c.Bytes(4), # 航向
  208. roll=c.Bytes(4), # 横滚
  209. pitch=c.Bytes(4), # 俯仰
  210. servo1_angle=c.Bytes(4),
  211. servo2_angle=c.Bytes(4),
  212. )
  213. res = servo_data.parse(hex_data)
  214. return res
  215. def get_sonar_status(self):
  216. find_data = b'\xF0\x0F\xFF\xFF\xFF\xFF\x03'
  217. response = self.__send_command(find_data)
  218. result = {'depth': None, 'temp': None, 'yaw': None, 'roll': None, 'pitch': None, 'servo1_angle': None, 'servo2_angle': None}
  219. if response != None:
  220. if len(response) == 35:
  221. res = servo_data.parse(response)
  222. result['depth'] = struct.unpack('>f', res.depth)[0]
  223. result['temp'] = struct.unpack('>f', res.temp)[0]
  224. result['yaw'] = struct.unpack('>f', res.yaw)[0]
  225. result['roll'] = struct.unpack('>f', res.roll)[0]
  226. result['pitch'] = struct.unpack('>f', res.pitch)[0]
  227. result['servo1_angle'] = int(struct.unpack('>f', res.servo1_angle)[0])
  228. result['servo2_angle'] = int(struct.unpack('>f', res.servo2_angle)[0])
  229. return result
  230. def send_command(self, location, speed, acceleration):
  231. header = 'f00f'
  232. servo1_location = struct.pack('>f', location).hex()
  233. servo2_location = struct.pack('>f', location).hex()
  234. servo1_speed = struct.pack('>f', speed).hex()
  235. servo2_speed = struct.pack('>f', speed).hex()
  236. servo1_acceleration = struct.pack('>f', acceleration).hex()
  237. servo2_acceleration = struct.pack('>f', acceleration).hex()
  238. data = servo1_location + servo2_location + servo1_speed + servo2_speed + servo1_acceleration + servo2_acceleration
  239. data_hex = bytes.fromhex(data)
  240. checksum = self.calculate_checksum(data_hex)
  241. send_data = header + data + checksum
  242. send_data = bytes.fromhex(send_data)
  243. # print(send_data) # 输出校验和的十六进制表示
  244. response = self.__send_command(send_data)
  245. def rotate_zero(self, speed, acceleration):
  246. while True:
  247. status = self.get_sonar_status()
  248. if status[servo_angle] != None:
  249. if status[servo_angle] > MIN_ANGLE + 5:
  250. print('rotate_zero', status[servo_angle])
  251. self.send_command(location=MIN_ANGLE, speed=speed, acceleration=acceleration)
  252. else:
  253. break
  254. def rotate_once_small(self, speed, acceleration, save_data, location, time_start):
  255. count = 0
  256. num = 0 # 图像编号
  257. angel = None
  258. save_flag = 0
  259. send_data = True
  260. while True:
  261. status = self.get_sonar_status()
  262. print(status[servo_angle])
  263. if status[servo_angle] != None:
  264. if send_data == True:
  265. # time_start = time.time() # 记录开始时间
  266. save_flag = 1
  267. self.send_command(location=location, speed=speed, acceleration=acceleration)
  268. send_data = False
  269. if save_flag == 1:
  270. info_dict = {'flag': '1', 'timestamp': time_start, 'num': num, 'depth': status['depth'],
  271. 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  272. 'pitch': status['pitch'], 'img_type': 's',
  273. 'servo_angle': status[servo_angle]}
  274. save_data.set_value(info_dict)
  275. num += 1
  276. if angel != status[servo_angle]:
  277. angel = status[servo_angle]
  278. count = 0
  279. else:
  280. count = count + 1
  281. if status[servo_angle] >= MAX_ANGLE - 1 or count > 3:
  282. save_data.set_value({'flag': '0'})
  283. break
  284. def rotate_once_big(self, speed, acceleration, save_data, location, time_start):
  285. count = 0
  286. num = 0 # 图像编号
  287. angel = None
  288. save_flag = 0
  289. send_data = True
  290. while True:
  291. status = self.get_sonar_status()
  292. print(status[servo_angle])
  293. if status[servo_angle] != None:
  294. if send_data == True:
  295. # time_start = time.time() # 记录开始时间
  296. save_flag = 1
  297. self.send_command(location=location, speed=speed, acceleration=acceleration)
  298. send_data = False
  299. if save_flag == 1:
  300. info_dict = {'flag': '1', 'timestamp': time_start, 'num': num, 'depth': status['depth'],
  301. 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  302. 'pitch': status['pitch'], 'img_type': 'b',
  303. 'servo_angle': status[servo_angle]}
  304. save_data.set_value(info_dict)
  305. num += 1
  306. if angel != status[servo_angle]:
  307. angel = status[servo_angle]
  308. count = 0
  309. else:
  310. count = count + 1
  311. if status[servo_angle] <= MIN_ANGLE + 0.5 or count > 3:
  312. save_data.set_value({'flag': '0'})
  313. break
  314. def rotate_once_little(self, speed, acceleration, save_data, location, time_start, mode):
  315. count = 0
  316. angel = None
  317. while True:
  318. status = self.get_sonar_status()
  319. if status[servo_angle] != None:
  320. if location >= MIN_ANGLE and location <= MAX_ANGLE:
  321. self.send_command(location=location, speed=speed, acceleration=acceleration)
  322. if angel != status[servo_angle]:
  323. angel = status[servo_angle]
  324. count = 0
  325. else:
  326. count = count + 1
  327. if status[servo_angle] == location or count > 3:
  328. info_dict = {'flag': '1', 'timestamp': time_start, 'num': status[servo_angle], 'depth': status['depth'],
  329. 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  330. 'pitch': status['pitch'], 'img_type': mode,
  331. 'servo_angle': status[servo_angle]}
  332. save_data.set_value(info_dict)
  333. break
  334. # def rotate_once(self,speed, acceleration,save_data):
  335. # status = self.get_sonar_status()
  336. # if status[servo_angle] != None:
  337. # if status[servo_angle] > 0.5:
  338. # self.send_command(location=0, speed=speed, acceleration=acceleration)
  339. # else:
  340. # count = 0
  341. # num = 0 # 图像编号
  342. # angel = None
  343. # save_image_flag = 0
  344. # while count < 5:
  345. # status = self.get_sonar_status()
  346. # if status[servo_angle] != None and save_image_flag == 0:
  347. # if status[servo_angle] < 0.5:
  348. # time_start = time.time() # 记录开始时间
  349. # save_image_flag = 1
  350. # self.send_command(location=359, speed=speed, acceleration=acceleration)
  351. # #print(angel,status[servo_angle])
  352. # if angel != status[servo_angle]:
  353. # angel = status[servo_angle]
  354. # count = 0
  355. # else:
  356. # count = count + 1
  357. # if save_image_flag == 2:
  358. # count = count + 2
  359. # if status[servo_angle] != None:
  360. # if count > 2 or status[servo_angle] >= 358:
  361. # save_image_flag = 0
  362. # save_data.set_value({'range':'big'})
  363. # if status[servo_angle] != None:
  364. # if count > 2 or status[servo_angle] >= 358:
  365. # save_image_flag = 2
  366. # time.sleep(5)
  367. # self.send_command(location=0, speed=speed, acceleration=acceleration)
  368. # time_now = time.time()
  369. # if save_image_flag == 1:
  370. # info_dict = {'flag': '1', 'timestamp': time_start, 'num': num, 'depth': status['depth'],
  371. # 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  372. # 'pitch': status['pitch'],
  373. # 'servo_angle': status[servo_angle]}
  374. # save_data.set_value(info_dict)
  375. # num += 1
  376. # print('asdasd',111111111111111111111)
  377. # elif save_image_flag == 2:
  378. # info_dict = {'flag': '1', 'timestamp': time_start, 'num': num, 'depth': status['depth'],
  379. # 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  380. # 'pitch': status['pitch'],
  381. # 'servo_angle': status[servo_angle]}
  382. # save_data.set_value(info_dict)
  383. # num += 1
  384. # print('asdasd', 22222222222222222222222222222222)
  385. # else:
  386. # info_dict = {'flag': '0', 'timestamp': time_start, 'num': num, 'depth': status['depth'],
  387. # 'temp': status['temp'], 'yaw': status['yaw'], 'roll': status['roll'],
  388. # 'pitch': status['pitch'],
  389. # 'servo_angle': status[servo_angle]}
  390. # save_data.set_value(info_dict)
  391. # # time_sum = time_end - time_start # 计算的时间差为程序的执行时间,单位为秒/s
  392. # # print(time_sum)
  393. def rotate_multiple_small(self, angel, speed, acceleration, time_start, mode):
  394. t = 0
  395. while True:
  396. save_status = self.redis_db.get_value(['flag'])['flag']
  397. if save_status == '0':
  398. location_angel = MIN_ANGLE + angel * t
  399. if location_angel > MAX_ANGLE:
  400. break
  401. else:
  402. self.rotate_once_little(speed, acceleration, self.redis_db, location_angel, time_start, mode)
  403. t = t + 1
  404. def rotate_multiple_big(self, angel, speed, acceleration, time_start, mode):
  405. t = 0
  406. while True:
  407. save_status = self.redis_db.get_value(['flag'])['flag']
  408. if save_status == '0':
  409. location_angel = MAX_ANGLE - angel * t - 10
  410. if location_angel < MIN_ANGLE:
  411. break
  412. else:
  413. self.rotate_once_little(speed, acceleration, self.redis_db, location_angel, time_start, mode)
  414. t = t + 1
  415. def rotate_multiple(self, client_socket, angel, speed, acceleration):
  416. # 模式二,指定间隔,达到,停顿,继续,完成,停止
  417. status = self.get_sonar_status()
  418. if status[servo_angle] != None:
  419. if status[servo_angle] > 0.5:
  420. self.send_command(location=0, speed=speed, acceleration=acceleration)
  421. else:
  422. i = int(360 / angel)
  423. t = 0
  424. time_start = time.time() # 记录开始时间
  425. while t < i + 1:
  426. count = 0
  427. speed = 300
  428. acceleration = 2000
  429. last_angel = None
  430. while count < 4:
  431. status = self.get_sonar_status()
  432. location_angel = min(angel * t, 359)
  433. self.send_command(location=location_angel, speed=speed, acceleration=acceleration)
  434. if last_angel != status[servo_angle]:
  435. last_angel = status[servo_angle]
  436. count = 0
  437. else:
  438. print(t, last_angel)
  439. count = count + 1
  440. if count > 3:
  441. t = t + 1
  442. self.send_command(location=0, speed=speed, acceleration=acceleration)
  443. if __name__ == '__main__':
  444. servo_config = {'ip': '192.168.1.61', 'port': 4001, 'save_frequency': 0}
  445. awaken_gls10 = Process(target=sender, name='awaken_gls10', daemon=True)
  446. command_p = Client()
  447. temp = ClientTemp()
  448. save_image = Process(target=Receiver, name='save_image', daemon=True)
  449. save_temp = Process(target=Receiver1, name='save_temp', daemon=True)
  450. p = MyProcess(name='servo', config=servo_config) # 实例化进程对象
  451. awaken_gls10.start()
  452. command_p.daemon = True
  453. command_p.start()
  454. temp.daemon = True
  455. temp.start()
  456. save_image.start()
  457. save_temp.start()
  458. p.daemon = True
  459. p.start()
  460. while True:
  461. time.sleep(1)
  462. print('main..............................', time.time())