Scheduler_b1.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. """
  2. """
  3. # 圆心点坐标字典
  4. d1 = {
  5. 'LM.head': {'center': (11, 22)},
  6. 'JK.head': {'center': (11, 22)},
  7. 'HI.head': {'center': (11, 22)},
  8. 'FG.head': {'center': (11, 22)},
  9. 'DE.head': {'center': (11, 22)},
  10. 'BC.head': {'center': (11, 22)},
  11. 'A.head': {'center': (11, 22)},
  12. 'LM.tail': {'center': (11, 22)},
  13. 'JK.tail': {'center': (11, 22)},
  14. 'HI.tail': {'center': (11, 22)},
  15. 'FG.tail': {'center': (11, 22)},
  16. 'DE.tail': {'center': (11, 22)},
  17. 'BC.tail': {'center': (11, 22)},
  18. 'A.tail': {'center': (11, 22)},
  19. }
  20. # 倒渣口坐标字典
  21. d2 = {
  22. 'dump.MN': {'point': (11, 205.75)}, # 1号倒渣口
  23. 'dump.KL': {'point': (11, 177.75)}, # 2号倒渣口
  24. 'dump.IJ': {'point': (11, 149.75)}, # 3号倒渣口
  25. 'dump.GH': {'point': (11, 121.75)}, # 4号倒渣口
  26. 'dump.EF': {'point': (11, 93.75)}, # 5号倒渣口
  27. 'dump.CD': {'point': (11, 65.75)}, # 6号倒渣口
  28. 'dump.AB': {'point': (11, 37.75)}, # 7号倒渣口
  29. }
  30. # 接渣口坐标字典
  31. d3 = {
  32. 'load.1': {'point': (11, 22)},
  33. 'load.2': {'point': (11, 22)},
  34. 'load.3': {'point': (11, 22)},
  35. }
  36. # 停车区坐标字典
  37. d5 = {
  38. 'pack.1': {'x': 77, 'y': 44},
  39. 'pack.2': {'x': 77, 'y': 44},
  40. }
  41. # 渣罐坐标字典
  42. d4 = {
  43. 'M.31': {'pot': (22, 33), 'road_center': (44, 55)},
  44. 'M.30': {'pot': (22, 33), 'road_center': (44, 55)},
  45. 'M.29': {'pot': (22, 33), 'road_center': (44, 55)},
  46. 'M.28': {'pot': (22, 33), 'road_center': (44, 55)},
  47. 'M.27': {'pot': (22, 33), 'road_center': (44, 55)},
  48. 'M.26': {'pot': (22, 33), 'road_center': (44, 55)},
  49. 'M.25': {'pot': (22, 33), 'road_center': (44, 55)},
  50. 'M.24': {'pot': (22, 33), 'road_center': (44, 55)},
  51. 'M.23': {'pot': (22, 33), 'road_center': (44, 55)},
  52. 'M.22': {'pot': (22, 33), 'road_center': (44, 55)},
  53. 'M.21': {'pot': (22, 33), 'road_center': (44, 55)},
  54. 'M.20': {'pot': (22, 33), 'road_center': (44, 55)},
  55. 'M.19': {'pot': (22, 33), 'road_center': (44, 55)},
  56. 'M.18': {'pot': (22, 33), 'road_center': (44, 55)},
  57. 'M.17': {'pot': (22, 33), 'road_center': (44, 55)},
  58. 'M.16': {'pot': (22, 33), 'road_center': (44, 55)},
  59. 'M.15': {'pot': (22, 33), 'road_center': (44, 55)},
  60. 'M.14': {'pot': (22, 33), 'road_center': (44, 55)},
  61. 'M.13': {'pot': (22, 33), 'road_center': (44, 55)},
  62. 'M.12': {'pot': (22, 33), 'road_center': (44, 55)},
  63. 'M.11': {'pot': (22, 33), 'road_center': (44, 55)},
  64. 'M.10': {'pot': (22, 33), 'road_center': (44, 55)},
  65. 'M.9': {'pot': (22, 33), 'road_center': (44, 55)},
  66. 'M.8': {'pot': (22, 33), 'road_center': (44, 55)},
  67. 'M.7': {'pot': (22, 33), 'road_center': (44, 55)},
  68. 'M.6': {'pot': (22, 33), 'road_center': (44, 55)},
  69. 'M.5': {'pot': (22, 33), 'road_center': (44, 55)},
  70. 'M.4': {'pot': (22, 33), 'road_center': (44, 55)},
  71. 'M.3': {'pot': (22, 33), 'road_center': (44, 55)},
  72. 'M.2': {'pot': (22, 33), 'road_center': (44, 55)},
  73. 'M.1': {'pot': (22, 33), 'road_center': (44, 55)},
  74. 'F.31': {'pot': (22, 33), 'road_center': (44, 55)},
  75. 'F.30': {'pot': (22, 33), 'road_center': (44, 55)},
  76. 'F.29': {'pot': (22, 33), 'road_center': (44, 55)},
  77. 'F.28': {'pot': (22, 33), 'road_center': (44, 55)},
  78. 'F.27': {'pot': (22, 33), 'road_center': (44, 55)},
  79. 'F.26': {'pot': (22, 33), 'road_center': (44, 55)},
  80. 'F.25': {'pot': (22, 33), 'road_center': (44, 55)},
  81. 'F.24': {'pot': (22, 33), 'road_center': (44, 55)},
  82. 'F.23': {'pot': (22, 33), 'road_center': (44, 55)},
  83. 'F.22': {'pot': (22, 33), 'road_center': (44, 55)},
  84. 'F.21': {'pot': (22, 33), 'road_center': (44, 55)},
  85. 'F.20': {'pot': (22, 33), 'road_center': (44, 55)},
  86. 'F.19': {'pot': (22, 33), 'road_center': (44, 55)},
  87. 'F.18': {'pot': (22, 33), 'road_center': (44, 55)},
  88. 'F.17': {'pot': (22, 33), 'road_center': (44, 55)},
  89. 'F.16': {'pot': (22, 33), 'road_center': (44, 55)},
  90. 'F.15': {'pot': (22, 33), 'road_center': (44, 55)},
  91. 'F.14': {'pot': (22, 33), 'road_center': (44, 55)},
  92. 'F.13': {'pot': (22, 33), 'road_center': (44, 55)},
  93. 'F.12': {'pot': (22, 33), 'road_center': (44, 55)},
  94. 'F.11': {'pot': (22, 33), 'road_center': (44, 55)},
  95. 'F.10': {'pot': (22, 33), 'road_center': (44, 55)},
  96. 'F.9': {'pot': (22, 33), 'road_center': (44, 55)},
  97. 'F.8': {'pot': (22, 33), 'road_center': (44, 55)},
  98. 'F.7': {'pot': (22, 33), 'road_center': (44, 55)},
  99. 'F.6': {'pot': (22, 33), 'road_center': (44, 55)},
  100. 'F.5': {'pot': (22, 33), 'road_center': (44, 55)},
  101. 'F.4': {'pot': (22, 33), 'road_center': (44, 55)},
  102. 'F.3': {'pot': (22, 33), 'road_center': (44, 55)},
  103. 'F.2': {'pot': (22, 33), 'road_center': (44, 55)},
  104. 'F.1': {'pot': (22, 33), 'road_center': (44, 55)},
  105. }
  106. def get_nearest_point_name_from_pot_point(x, y):
  107. """
  108. 获取当前位置距离最忌的罐体位置名称
  109. """
  110. x = float(x)
  111. y = float(y)
  112. min_distance = float('inf') # 初始值无穷大
  113. for k, v in d4.items():
  114. center_x = float(v.get('pot')[0])
  115. center_y = float(v.get('pot')[1])
  116. distance = ((center_x - x) ** 2 + (center_y - y) ** 2) ** (1 / 2)
  117. if distance < min_distance:
  118. min_distance = distance
  119. nearest_pot_name = k
  120. return nearest_pot_name
  121. def get_nearest_point_from_road_center_point(x, y):
  122. """
  123. 获取当前所在位置最接近的坐标位置
  124. """
  125. x = float(x)
  126. y = float(y)
  127. min_distance = float('inf') # 初始值无穷大
  128. for k, v in d4.items():
  129. center_x = float(v.get('road_center')[0])
  130. center_y = float(v.get('road_center')[1])
  131. distance = ((center_x - x) ** 2 + (center_y - y) ** 2) ** (1 / 2)
  132. if distance < min_distance:
  133. min_distance = distance
  134. nearest_point = center_x, center_y
  135. return nearest_point
  136. def get_center_point_by_keyword(w1='N', w2='head'):
  137. """
  138. 获取圆心点坐标
  139. w1: 关键字
  140. w2: 关键字
  141. """
  142. for k, v in d1.items():
  143. k_s1, k_s2 = k.split('.')
  144. if w1 not in k_s1:
  145. continue
  146. if w2 not in k_s2:
  147. continue
  148. return dict(**v, **{'name': k})
  149. def get_path_name_by_pot_name(pot_name='M.25'):
  150. """根据渣罐名获取道路名"""
  151. s1, s2 = pot_name.split('.')
  152. path_name_list = [
  153. 'MN',
  154. 'KL',
  155. 'IJ',
  156. 'GH',
  157. 'EF',
  158. 'CD',
  159. 'AB',
  160. ]
  161. for s in path_name_list:
  162. if s1 in s:
  163. return s
  164. def get_path_name_by_dump_name(dump_name='dump.MN'):
  165. """根据渣罐名获取道路名"""
  166. _, s2 = dump_name.split('.')
  167. return s2
  168. import json
  169. def test(current_direction_type=3, start_x=11, start_y=22, target_point_name='M.1'):
  170. """
  171. current_direction_type: 起始方向 3 围栏方向 9 渣场方向 12 维修间方向 6 维修间正对方向 0 未知(默认值)
  172. s_name: 起始位置
  173. e_name: 目标位置
  174. """
  175. # --- update d4 ---
  176. # data = json.load(open('../data/渣罐坐标数据.json', 'r'))
  177. # data = json.load(open('/home/ubuntu/repositories/repositories/casperz.py-project/project-fastapi-hs/data/渣罐坐标数据.json', 'r'))
  178. data = json.load(
  179. open(r'E:\casper\repositories\repositories\casperz.py-project\project-fastapi-hs\data\渣罐坐标数据.json', 'rb'))
  180. for item in data.get('pot_name|pot_x|pot_y|road_center_x|road_center_y'):
  181. pot_name, pot_x, pot_y, road_center_x, road_center_y = item.split('|')
  182. d4[pot_name] = {
  183. 'pot': (pot_x, pot_y),
  184. 'road_center': (road_center_x, road_center_y),
  185. }
  186. # --- update d2 ---
  187. # data = json.load(open('../data/渣罐坐标数据.json', 'r'))
  188. # data = json.load(open('/home/ubuntu/repositories/repositories/casperz.py-project/project-fastapi-hs/data/倒渣口坐标数据.json', 'r'))
  189. data = json.load(
  190. open(r'E:\casper\repositories\repositories\casperz.py-project\project-fastapi-hs\data\倒渣口坐标数据.json',
  191. 'rb'))
  192. for item in data.get('name|x|y'):
  193. name, x, y = item.split('|')
  194. d2[name] = {
  195. 'point': (x, y),
  196. }
  197. # --- check ---
  198. if current_direction_type not in [3, 9]:
  199. return 1 # 暂不支持
  200. # --- check ---
  201. if not start_x or not start_y:
  202. return 2 # 参数缺失
  203. # --- define ---
  204. current_point_name = get_nearest_point_name_from_pot_point(start_x, start_y)
  205. # --- define ---
  206. if 'dump' in current_point_name:
  207. s_point_item = dict(**d2.get(current_point_name), **{'name': current_point_name})
  208. else:
  209. s_point_item = dict(**d4.get(current_point_name), **{'name': current_point_name})
  210. # --- define ---
  211. if 'dump' in target_point_name:
  212. e_point_item = dict(**d2.get(target_point_name), **{'name': target_point_name})
  213. else:
  214. e_point_item = dict(**d4.get(target_point_name), **{'name': target_point_name})
  215. # --- define ---
  216. radius = 14 # 转弯半径
  217. s_s1, s_s2 = current_point_name.split('.')
  218. e_s1, e_s2 = target_point_name.split('.')
  219. print(f"current_point_name: {current_point_name}")
  220. print(f"target_point_name: {target_point_name}")
  221. # --- check ---
  222. if 'dump' not in current_point_name and 'dump' not in target_point_name:
  223. if current_direction_type == 9 and s_s1 == e_s1 and int(s_s2) > int(e_s2):
  224. """
  225. 情况1:判断是否是在正前方的情况1
  226. """
  227. return [
  228. {
  229. 'type': 'forward',
  230. 'nav_coordinates': [
  231. {
  232. # 直行轨迹坐标参数
  233. 'start_point_x': start_x,
  234. 'start_point_y': start_y,
  235. 'end_point_x': e_point_item.get('road_center')[0],
  236. 'end_point_y': e_point_item.get('road_center')[1],
  237. },
  238. ],
  239. }
  240. ]
  241. elif current_direction_type == 3 and s_s1 == e_s1 and int(s_s2) < int(e_s2):
  242. """
  243. 情况2:判断是否是在正前方的情况2
  244. """
  245. return [
  246. {
  247. 'type': 'forward',
  248. 'nav_coordinates': [
  249. # 直线行驶
  250. {
  251. 'start_point_x': start_x,
  252. 'start_point_y': start_y,
  253. 'end_point_x': e_point_item.get('road_center')[0],
  254. 'end_point_y': e_point_item.get('road_center')[1],
  255. },
  256. ],
  257. }
  258. ]
  259. elif current_direction_type == 9 and s_s1 > e_s1:
  260. """
  261. 情况3:车头9方向,向6点行驶,并拐弯情况(共2个弯,1个是出弯,1个是入弯)
  262. """
  263. w1 = get_path_name_by_pot_name(current_point_name)[:1] # 首位
  264. center_1 = get_center_point_by_keyword(w1=w1, w2='head')
  265. w1 = get_path_name_by_pot_name(target_point_name)[-1:] # 末位
  266. center_2 = get_center_point_by_keyword(w1=w1, w2='head')
  267. return [
  268. {
  269. 'type': 'forward',
  270. 'nav_coordinates': [
  271. # 直线行驶
  272. {
  273. 'start_point_x': start_x, # 起始点坐标
  274. 'start_point_y': start_y, # 起始点坐标
  275. 'end_point_x': center_1.get('center')[0], # 入弯坐标
  276. 'end_point_y': center_1.get('center')[1] + radius, # 入弯坐标
  277. },
  278. # 转弯行驶
  279. {
  280. "start_point_x": center_1.get('center')[0], # 入弯坐标
  281. "start_point_y": center_1.get('center')[1] + radius, # 入弯坐标
  282. "center_point_x": center_1.get('center')[0], # 圆心坐标
  283. "center_point_y": center_1.get('center')[1], # 圆心坐标
  284. "end_point_x": center_1.get('center')[0] - radius, # 出弯坐标
  285. "end_point_y": center_1.get('center')[1], # 出弯坐标
  286. },
  287. # 直线行驶
  288. {
  289. 'start_point_x': center_1.get('center')[0] - radius, # 出弯坐标
  290. 'start_point_y': center_1.get('center')[1], # 出弯坐标
  291. 'end_point_x': center_2.get('center')[0] - radius, # 入弯坐标
  292. 'end_point_y': center_2.get('center')[1], # 入弯坐标
  293. },
  294. # 转弯行驶
  295. {
  296. "start_point_x": center_2.get('center')[0] - radius, # 入弯坐标
  297. "start_point_y": center_2.get('center')[1], # 入弯坐标
  298. "center_point_x": center_2.get('center')[0], # 圆心坐标
  299. "center_point_y": center_2.get('center')[1], # 圆心坐标
  300. "end_point_x": center_2.get('center')[0], # 出弯坐标
  301. "end_point_y": center_2.get('center')[1] - radius, # 出弯坐标
  302. },
  303. # 直线行驶
  304. {
  305. 'start_point_x': center_2.get('center')[0], # 出弯坐标
  306. 'start_point_y': center_2.get('center')[1] - radius, # 出弯坐标
  307. 'end_point_x': e_point_item.get('road_center')[0], # 目标点坐标
  308. 'end_point_y': e_point_item.get('road_center')[1], # 目标点坐标
  309. },
  310. ],
  311. }
  312. ]
  313. elif 'dump' not in current_point_name and 'dump' in target_point_name:
  314. if current_direction_type == 9:
  315. """
  316. 情况4:渣罐位,车头9点方向,6点拐弯,3点拐弯,倒车倒入指定倒渣口
  317. """
  318. path_name = get_path_name_by_pot_name(current_point_name)
  319. # print(f"path_name: {path_name}")
  320. corner_name = path_name[:1] # 拐弯点(9点到6点方向转弯)
  321. center_1 = get_center_point_by_keyword(w1=corner_name, w2='head')
  322. # print(f"center_1: {center_1}")
  323. path_name = get_path_name_by_dump_name(target_point_name)
  324. corner_name = path_name[-1:] # 拐弯点(6点到3点方向转弯)
  325. center_2 = get_center_point_by_keyword(w1=corner_name, w2='head')
  326. # print(f"center_2: {center_2}")
  327. return [
  328. {
  329. 'type': 'forward',
  330. 'nav_coordinates': [
  331. # 直线行驶
  332. {
  333. 'start_point_x': start_x, # 起始点坐标
  334. 'start_point_y': start_y, # 起始点坐标
  335. 'end_point_x': center_1.get('center')[0], # 入弯坐标
  336. 'end_point_y': center_1.get('center')[1] + radius, # 入弯坐标
  337. },
  338. # 转弯行驶
  339. {
  340. "start_point_x": center_1.get('center')[0], # 入弯坐标
  341. "start_point_y": center_1.get('center')[1] + radius, # 入弯坐标
  342. "center_point_x": center_1.get('center')[0], # 圆心坐标
  343. "center_point_y": center_1.get('center')[1], # 圆心坐标
  344. "end_point_x": center_1.get('center')[0] - radius, # 出弯坐标
  345. "end_point_y": center_1.get('center')[1], # 出弯坐标
  346. },
  347. # 直线行驶
  348. {
  349. 'start_point_x': center_1.get('center')[0] - radius, # 出弯坐标
  350. 'start_point_y': center_1.get('center')[1], # 出弯坐标
  351. 'end_point_x': center_2.get('center')[0] - radius, # 入弯坐标
  352. 'end_point_y': center_2.get('center')[1], # 入弯坐标
  353. },
  354. # 转弯行驶
  355. {
  356. "start_point_x": center_2.get('center')[0] - radius, # 入弯坐标
  357. "start_point_y": center_2.get('center')[1], # 入弯坐标
  358. "center_point_x": center_2.get('center')[0], # 圆心坐标
  359. "center_point_y": center_2.get('center')[1], # 圆心坐标
  360. "end_point_x": center_2.get('center')[0], # 出弯坐标
  361. "end_point_y": center_2.get('center')[1] - radius, # 出弯坐标
  362. },
  363. # 直线行驶
  364. {
  365. 'start_point_x': center_2.get('center')[0], # 出弯坐标
  366. 'start_point_y': center_2.get('center')[1] - radius, # 出弯坐标
  367. 'end_point_x': center_2.get('center')[0] + 10, # 3点方向移动10米,摆正车身,为倒车准备
  368. 'end_point_y': center_2.get('center')[1] - radius, # 3点方向移动10米,摆正车身,为倒车准备
  369. },
  370. ]
  371. },
  372. {
  373. 'type': 'backward',
  374. 'nav_coordinates': [
  375. # 直线行驶
  376. {
  377. 'start_point_x': center_2.get('center')[0] + 10, # 3点方向移动10米,摆正车身,为倒车准备
  378. 'start_point_y': center_2.get('center')[1] - radius, # 3点方向移动10米,摆正车身,为倒车准备
  379. 'end_point_x': e_point_item.get('point')[0], # 倒渣口坐标
  380. 'end_point_y': e_point_item.get('point')[1], # 倒渣口坐标
  381. },
  382. ]
  383. }
  384. ]
  385. if __name__ == '__main__':
  386. # --- test ---
  387. # 情况1:判断是否是在正前方的情况1 M.10 -> M.1
  388. # out = test(current_direction_type=9, start_x=74, start_y=205.75, target_point_name='M.1')
  389. # 情况2:判断是否是在正前方的情况2 M.12 -> M.20
  390. # out = test(current_direction_type=3, start_x=85, start_y=205.75, target_point_name='M.20')
  391. # 情况3:车头9方向,向6点行驶,并拐弯情况(共2个弯,1个是出弯,1个是入弯)
  392. # out = test(current_direction_type=9, start_x=85, start_y=205.75, target_point_name='F.20')
  393. # 情况4:渣罐位,车头9点方向,6点拐弯,3点拐弯,倒车倒入指定倒渣口
  394. out = test(current_direction_type=9, start_x=74, start_y=205.75, target_point_name='dump.CD')
  395. print(out)