RobotData.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. import copy
  2. import enum
  3. import time
  4. from numpy import fabs
  5. import message_pb2 as message
  6. import grpc
  7. import message_pb2_grpc as msg_rpc
  8. from ManualOperationWidget import ManualOperationType
  9. from custom_define import RobotName, ActType
  10. from mqtt_async import MqttAsync
  11. import google.protobuf.json_format as jtf
  12. import json
  13. from dijkstra.Map import SpaceNode, StreetNode, MapManager, DijikstraMap
  14. import uuid
  15. import random
  16. import math
  17. import Count
  18. from sigmoid import sigmoid
  19. class TimeStatu:
  20. def __init__(self, statu=None, timeout=3):
  21. self.statu = statu
  22. self.time = time.time()
  23. self.timeout_s = timeout
  24. def timeout(self):
  25. tm = time.time()
  26. return tm - self.time > self.timeout_s or self.statu == None
  27. class Robot(MqttAsync):
  28. def __init__(self, rpc_ipport, name=""):
  29. MqttAsync.__init__(self)
  30. self.test_speed = 0
  31. self.timedRobotStatu_ = TimeStatu(message.RobotStatu, 0)
  32. self.timedNavStatu_ = TimeStatu(message.NavStatu, 0)
  33. self.dataTopic_ = {}
  34. self.rpc_ipport_ = rpc_ipport
  35. self.messageArrivedSignal = None
  36. self.currentNavData_ = None
  37. self.navCmdTopic_ = None
  38. if (name == RobotName.strAGVMain):
  39. self.speedCmdTopic = "monitor_child/speedcmd"
  40. else:
  41. self.speedCmdTopic = "monitor_child/speedcmd"
  42. self.currentNavPathNodes_ = None
  43. self.currentNavPath_ = None
  44. self.pathColor_ = [1, 1, 0]
  45. self.robotColor_ = [0.7, 0.2, 0.3] # agv当前颜色
  46. self.name_ = name
  47. self.begId_ = "------"
  48. self.targetId_ = "------"
  49. self.autoTest_ = False
  50. self.l_ = 0.8 # 轮长
  51. self.L_ = 1.3 # 轴距
  52. self.W_ = 2.5 # 宽
  53. self.heat_ = 0 # 心跳
  54. self.manual_status = ManualOperationType.eReady # 正在进行的手动操作
  55. self.manual_speed = [0.0, 0]
  56. def Color(self):
  57. if self.IsMainModeStatu():
  58. return [0, 0, 0]
  59. return self.robotColor_
  60. def IsMainAgv(self):
  61. if self.timedNavStatu_.timeout() == False:
  62. if self.timedNavStatu_.statu.main_agv == True:
  63. return True
  64. return False
  65. def IsMainModeStatu(self):
  66. if self.IsMainAgv():
  67. if self.timedNavStatu_.timeout() == False:
  68. if self.timedNavStatu_.statu.move_mode == 1:
  69. return True
  70. return False
  71. def SetSubDataTopic(self, match: dict, messageSignal=None):
  72. self.dataTopic_ = match
  73. self.messageArrivedSignal = messageSignal
  74. for item in match.items():
  75. [topic, _] = item
  76. self.subscribe(topic, self.on_message)
  77. def SetCmdTopic(self, topic):
  78. self.navCmdTopic_ = topic
  79. def SetColor(self, pathColor, robotColor):
  80. self.pathColor_ = pathColor
  81. self.robotColor_ = robotColor
  82. def ResetPose(self, agv: message.RobotStatu):
  83. self.timedRobotStatu_ = TimeStatu(agv, 2)
  84. def ResetNavStatu(self, statu: message.NavStatu):
  85. self.timedNavStatu_ = TimeStatu(statu, 2)
  86. def on_message(self, client, userdata, msg):
  87. topic = msg.topic
  88. if self.dataTopic_.get(topic) is not None:
  89. dtype = self.dataTopic_[topic]
  90. if dtype == message.RobotStatu.__name__:
  91. proto = message.RobotStatu()
  92. jtf.Parse(msg.payload.decode(), proto)
  93. self.ResetPose(proto)
  94. if dtype == message.NavStatu.__name__:
  95. self.last_running = self.IsNavigating()
  96. proto = message.NavStatu()
  97. jtf.Parse(msg.payload.decode(), proto)
  98. self.ResetNavStatu(proto)
  99. if self.last_running == True and self.IsNavigating() == False:
  100. self.currentNavPathNodes_ = None
  101. self.currentNavPath_ = None
  102. if self.messageArrivedSignal is not None:
  103. self.messageArrivedSignal()
  104. def MpcSelectTraj(self):
  105. traj = []
  106. if self.timedNavStatu_.timeout() == False:
  107. nav = self.timedNavStatu_.statu
  108. for pose2d in nav.selected_traj.poses:
  109. traj.append([pose2d.x, pose2d.y, pose2d.theta])
  110. return traj
  111. def MpcPredictTraj(self):
  112. traj = []
  113. if self.timedNavStatu_.timeout() == False:
  114. nav = self.timedNavStatu_.statu
  115. for pose2d in nav.predict_traj.poses:
  116. traj.append([pose2d.x, pose2d.y, pose2d.theta])
  117. return traj
  118. def Connected(self):
  119. return self.timedNavStatu_.timeout() == False and self.timedRobotStatu_.timeout() == False
  120. def IsNavigating(self):
  121. return not self.ActionType() == ActType.eReady
  122. '''if self.timedNavStatu_.timeout() == False:
  123. key = self.timedNavStatu_.statu.key
  124. if key == "" or key == None:
  125. return False
  126. return True'''
  127. def GeneratePath(self, begID, endID, task_type="None"):
  128. self.currentNavPathNodes_ = MapManager().GetShortestPath(begID, endID)
  129. # if task_type == "DoubleAGV":
  130. # print("AdjustPath------------------")
  131. # if self.IsMainModeStatu() is False:
  132. # print("原始路径:")
  133. # for node in self.currentNavPathNodes_:
  134. # print(node.id_, node.y_)
  135. # self.currentNavPathNodes_ = self.AdjustPath(self.currentNavPathNodes_)
  136. # print("修改路径:")
  137. # for node in self.currentNavPathNodes_:
  138. # print(node.id_, node.y_)
  139. self.currentNavPath_ = DijikstraMap().CreatePath(self.currentNavPathNodes_, 0.5)
  140. if self.currentNavPathNodes_ is not None and self.currentNavPath_ is not None:
  141. self.begId_ = begID
  142. self.targetId_ = endID
  143. return True
  144. return False
  145. def PositionId(self):
  146. if self.timedRobotStatu_.timeout():
  147. return None
  148. x = self.timedRobotStatu_.statu.x
  149. y = self.timedRobotStatu_.statu.y
  150. djks_map = MapManager()
  151. [label, pt] = djks_map.findNeastNode([x, y])
  152. return [label, pt]
  153. '''
  154. 阻塞直到导航完成
  155. '''
  156. def Navigatting(self, begId, targetId, autoDirect, wheelbase=0, task_type="None"):
  157. print("nav")
  158. # self.ExecPathNodes(autoDirect)
  159. self.ExecNavtask(autoDirect, wheelbase)
  160. if self.IsMainModeStatu():
  161. Count.TestCount().loadCountAdd()
  162. else:
  163. Count.TestCount().singleCountAdd()
  164. return True
  165. def AutoTestNavClamp(self, begId, targetId):
  166. beg = begId
  167. target = targetId
  168. while self.autoTest_:
  169. if self.TestNavClampOnce(beg, target) == False:
  170. print(" quit auto Test")
  171. break
  172. print("1111")
  173. posInfo = self.PositionId()
  174. if posInfo is not None:
  175. [label, pt] = posInfo
  176. beg = label
  177. print("beg", beg)
  178. node = MapManager().GetVertex(beg)
  179. if node is not None:
  180. if isinstance(node, (SpaceNode)):
  181. target = "O"
  182. if isinstance(node, (StreetNode)):
  183. end_nodes = ["E", "B", "C", "D"]
  184. id = random.randint(0, 1000) % 4
  185. target = end_nodes[id]
  186. print("3333", target)
  187. print(" Next nav clamp cmd,%s to %s" % (beg, target))
  188. def ActionType(self):
  189. if self.timedNavStatu_.timeout() == False:
  190. runningStatu = self.timedNavStatu_.statu
  191. if runningStatu.statu == 0:
  192. return ActType.eReady
  193. if runningStatu.statu == 1:
  194. return ActType.eRotation
  195. if runningStatu.statu == 2:
  196. return ActType.eHorizon
  197. if runningStatu.statu == 3:
  198. return ActType.eVertical
  199. if runningStatu.statu == 4:
  200. return ActType.eMPC
  201. if runningStatu.statu == 5:
  202. return ActType.eClampClose
  203. if runningStatu.statu == 6:
  204. return ActType.eClampOpen
  205. if runningStatu.statu == 7:
  206. return ActType.eLifterRise
  207. if runningStatu.statu == 8:
  208. return ActType.eLifterDown
  209. else:
  210. return ActType.eReady
  211. @staticmethod
  212. def generateProtoNode(node):
  213. protoNode = message.PathNode()
  214. protoNode.x = node.x_
  215. protoNode.y = node.y_
  216. protoNode.id = node.id_
  217. return protoNode
  218. def ExecNavtask(self, autoDirect, wheelbase=0):
  219. cmd = message.NavCmd()
  220. key = str(uuid.uuid4())
  221. cmd.key = key
  222. cmd.action = 0
  223. actions = self.SplitPath(self.currentNavPathNodes_)
  224. for action in actions:
  225. [type, nodes] = action
  226. if type == "input":
  227. [street, space] = nodes
  228. protoSpace = self.generateProtoNode(space)
  229. protoStreet = self.generateProtoNode(street)
  230. act = message.NewAction()
  231. act.type = 1
  232. act.wheelbase = wheelbase
  233. act.spaceNode.CopyFrom(protoSpace)
  234. act.streetNode.CopyFrom(protoStreet)
  235. cmd.newActions.add().CopyFrom(act)
  236. if type == "output":
  237. [space, street] = nodes
  238. protoSpace = self.generateProtoNode(space)
  239. protoStreet = self.generateProtoNode(street)
  240. act = message.NewAction()
  241. act.type = 2
  242. act.wheelbase = wheelbase
  243. act.spaceNode.CopyFrom(protoSpace)
  244. act.streetNode.CopyFrom(protoStreet)
  245. cmd.newActions.add().CopyFrom(act)
  246. if type == "nav":
  247. action = self.CreateNavPathNodesAction(nodes, autoDirect)
  248. if action is None:
  249. print("Nav cmd is None")
  250. return False
  251. else:
  252. cmd.newActions.add().CopyFrom(action)
  253. print(cmd)
  254. if cmd is None:
  255. print("Nav cmd is None")
  256. return False
  257. channel = grpc.insecure_channel(self.rpc_ipport_)
  258. stub = msg_rpc.NavExcutorStub(channel)
  259. response = stub.Start(cmd)
  260. print("client received: ", response)
  261. if not response.ret == 0:
  262. print("nav failed :%s" % (response.info))
  263. else:
  264. print("nav completed !!!")
  265. return True
  266. def CreateNavPathNodesAction(self, path, autoDirect):
  267. # if path is not None and self.timedRobotStatu_.timeout() == False:
  268. if 1:
  269. for node in path:
  270. if isinstance(node, (SpaceNode)):
  271. print(" nodes must all street node")
  272. return None
  273. statu = self.timedRobotStatu_.statu
  274. # if statu is not None:
  275. if 1:
  276. newAction = message.NewAction()
  277. size = len(path)
  278. for i in range(size):
  279. node = path[i]
  280. pathNode = message.PathNode()
  281. pathNode.x = node.x_
  282. pathNode.y = node.y_
  283. newAction.type = 4
  284. if autoDirect:
  285. newAction.type = 3
  286. newAction.pathNodes.add().CopyFrom(pathNode)
  287. return newAction
  288. else:
  289. print("statu is None")
  290. else:
  291. print("current path is none")
  292. return None
  293. def ExecPathNodes(self, autoDirect):
  294. if self.navCmdTopic_ == None:
  295. print("Robot has not set nav cmd topic")
  296. return False
  297. if not self.ActionType() == ActType.eReady:
  298. print(" robot is navigating ,key:%s" % (self.timedNavStatu_.statu.key))
  299. return False
  300. cmd = message.NavCmd()
  301. key = str(uuid.uuid4())
  302. cmd.key = key
  303. cmd.action = 0
  304. action = self.CreateNavPathNodesAction(self.currentNavPathNodes_, autoDirect)
  305. if action is None:
  306. print("Nav cmd is None")
  307. return False
  308. cmd.newActions.add().CopyFrom(action)
  309. print(cmd)
  310. channel = grpc.insecure_channel(self.rpc_ipport_)
  311. stub = msg_rpc.NavExcutorStub(channel)
  312. response = stub.Start(cmd)
  313. return True
  314. '''
  315. 根据AGV单车的起始位置调整路径
  316. '''
  317. def AdjustPath(self, path):
  318. adjusted_path = copy.deepcopy(path)
  319. y_offset = 1.2
  320. dy = 0
  321. # if self.IsMainAgv() or self.name_ == "AgvMain":
  322. if self.name_ == RobotName.strAGVMain:
  323. dy = 1
  324. # if not self.IsMainAgv() or self == "AGV2":
  325. if self.name_ == RobotName.strAGV2:
  326. dy = -1
  327. print("dy:", dy)
  328. for node in adjusted_path:
  329. if isinstance(node, StreetNode):
  330. if dy > 0:
  331. node.y_ += y_offset
  332. elif dy < 0:
  333. node.y_ -= y_offset
  334. else:
  335. pass
  336. return adjusted_path
  337. '''
  338. 拆分路径,生成动作集,input:入库动作,nav:导航动作,output:出库动作
  339. '''
  340. def SplitPath(self, path):
  341. space_count = 0
  342. for i in range(len(path)):
  343. if isinstance(path[i], (SpaceNode)):
  344. space_count += 1
  345. if i == 0 or i == len(path) - 1:
  346. pass
  347. else:
  348. print("Error: space node is not first/last of path")
  349. return None
  350. actions = []
  351. lastNode = None
  352. navIndex = -1
  353. for node in path:
  354. if lastNode == None:
  355. lastNode = node
  356. continue
  357. if isinstance(node, (SpaceNode)): # 当前点是车位点
  358. if isinstance(lastNode, (SpaceNode)): # 上一点为车位点
  359. print("Error: last node and current node is space node ")
  360. lastNode = None
  361. continue
  362. elif isinstance(lastNode, (StreetNode)): # 上一点为马路点,则动作为入库
  363. actions.append(["input", [lastNode, node]])
  364. lastNode = None
  365. continue
  366. if isinstance(node, (StreetNode)):
  367. if isinstance(lastNode, (SpaceNode)): # 上一点为车位点, 出库
  368. actions.append(["output", [lastNode, node]])
  369. elif isinstance(lastNode, (StreetNode)):
  370. if navIndex < 0:
  371. actions.append(["nav", [lastNode]])
  372. navIndex = len(actions) - 1
  373. actions[navIndex][1].append(node)
  374. lastNode = node
  375. return actions
  376. def SwitchMoveMode(self, mode, wheelbase):
  377. if self.IsMainAgv() == False:
  378. print(" this agv is single can not switch mode")
  379. return False
  380. cmd = message.NavCmd()
  381. key = str(uuid.uuid4())
  382. cmd.key = key
  383. cmd.action = 0
  384. action = message.NewAction()
  385. action.type = 8
  386. action.changedMode = mode
  387. if mode == 1:
  388. action.wheelbase = wheelbase
  389. cmd.newActions.add().CopyFrom(action)
  390. print(cmd)
  391. channel = grpc.insecure_channel(self.rpc_ipport_)
  392. stub = msg_rpc.NavExcutorStub(channel)
  393. response = stub.Start(cmd)
  394. return False
  395. def IsClampClosed(self):
  396. if self.timedRobotStatu_.timeout() == False:
  397. if self.IsMainModeStatu():
  398. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  399. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  400. return (clamp == 1 and clamp_other == 1)
  401. else:
  402. return self.timedRobotStatu_.statu.agvStatu.clamp == 1
  403. return False
  404. def IsClampRunning(self):
  405. if self.timedRobotStatu_.timeout() == False:
  406. if self.IsMainModeStatu():
  407. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  408. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  409. return (clamp == 0 or clamp_other == 0)
  410. else:
  411. return self.timedRobotStatu_.statu.agvStatu.clamp == 0
  412. return False
  413. def IsClampOpened(self):
  414. if self.timedRobotStatu_.timeout() == False:
  415. if self.IsMainModeStatu():
  416. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  417. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  418. return (clamp == 2 and clamp_other == 2)
  419. else:
  420. return self.timedRobotStatu_.statu.agvStatu.clamp == 2
  421. return False
  422. def ClampClose(self):
  423. if self.IsClampClosed() == True:
  424. print("clamp closed")
  425. return True
  426. cmd = message.NavCmd()
  427. cmd.action = 0
  428. key = str(uuid.uuid4())
  429. cmd.key = (key)
  430. act = message.NewAction()
  431. act.type = 6
  432. cmd.newActions.add().CopyFrom(act)
  433. channel = grpc.insecure_channel(self.rpc_ipport_)
  434. stub = msg_rpc.NavExcutorStub(channel)
  435. response = stub.Start(cmd)
  436. return True
  437. def ClampOpen(self):
  438. if self.IsClampOpened() == True:
  439. print("clamp opended")
  440. return True
  441. cmd = message.NavCmd()
  442. cmd.action = 0
  443. key = str(uuid.uuid4())
  444. cmd.key = (key)
  445. act = message.NewAction()
  446. act.type = 7
  447. cmd.newActions.add().CopyFrom(act)
  448. channel = grpc.insecure_channel(self.rpc_ipport_)
  449. stub = msg_rpc.NavExcutorStub(channel)
  450. response = stub.Start(cmd)
  451. return True
  452. def IsLiferDowned(self):
  453. if self.timedRobotStatu_.timeout() == False:
  454. if self.IsMainModeStatu():
  455. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  456. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  457. return (lifter == 2 and lifter_other == 2)
  458. else:
  459. return self.timedRobotStatu_.statu.agvStatu.lifter == 2
  460. return False
  461. def IsLiferRunning(self):
  462. if self.timedRobotStatu_.timeout() == False:
  463. if self.IsMainModeStatu():
  464. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  465. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  466. return (lifter == 0 and lifter_other == 0)
  467. else:
  468. return self.timedRobotStatu_.statu.agvStatu.lifter == 0
  469. return False
  470. def IsLiferRose(self):
  471. if self.timedRobotStatu_.timeout() == False:
  472. if self.IsMainModeStatu():
  473. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  474. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  475. return (lifter == 1 and lifter_other == 1)
  476. else:
  477. return self.timedRobotStatu_.statu.agvStatu.lifter == 1
  478. return False
  479. def LiferRise(self):
  480. if self.IsLiferRose() == True:
  481. print("lifter has rose")
  482. return True
  483. cmd = message.NavCmd()
  484. cmd.action = 0
  485. key = str(uuid.uuid4())
  486. cmd.key = (key)
  487. act = message.NewAction()
  488. act.type = 9
  489. cmd.newActions.add().CopyFrom(act)
  490. channel = grpc.insecure_channel(self.rpc_ipport_)
  491. stub = msg_rpc.NavExcutorStub(channel)
  492. response = stub.Start(cmd)
  493. return True
  494. def LiferDown(self):
  495. if self.IsLiferDowned() == True:
  496. print("lifter has downed")
  497. return True
  498. cmd = message.NavCmd()
  499. cmd.action = 0
  500. key = str(uuid.uuid4())
  501. cmd.key = (key)
  502. act = message.NewAction()
  503. act.type = 10
  504. cmd.newActions.add().CopyFrom(act)
  505. channel = grpc.insecure_channel(self.rpc_ipport_)
  506. stub = msg_rpc.NavExcutorStub(channel)
  507. response = stub.Start(cmd)
  508. return True
  509. def CancelNavTask(self):
  510. cmd = message.NavCmd()
  511. cmd.action = 3
  512. channel = grpc.insecure_channel(self.rpc_ipport_)
  513. stub = msg_rpc.NavExcutorStub(channel)
  514. response = stub.Cancel(cmd)
  515. print("client received: ", response)
  516. print(" Cancel task completed!!!")
  517. return True
  518. def IsManualTaskRunning(self):
  519. return self.manual_status != ManualOperationType.eReady
  520. def ManualTask(self, current_operation, step_acc=0, speed=0):
  521. if self.IsNavigating():
  522. print("AGV is navigating!!!")
  523. # return False
  524. # slowly stop
  525. if current_operation == ManualOperationType.eReady and \
  526. ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
  527. print("Manual_Unit_SlowlyStop")
  528. self.Manual_Unit_SlowlyStop(current_operation, speed)
  529. return True
  530. # if self.IsManualTaskRunning():
  531. # return print("ManualTask | ManualTask is running...")
  532. self.manual_status = current_operation
  533. if ManualOperationType.eReady < current_operation <= ManualOperationType.eRightMove:
  534. cmd = message.ToAgvCmd()
  535. self.heat_ += 1
  536. self.heat_ %= 255
  537. cmd.H1 = self.heat_
  538. if self.IsMainModeStatu():
  539. cmd.M1 = 1
  540. else:
  541. cmd.M1 = 0
  542. if current_operation == ManualOperationType.eCounterclockwiseRotate:
  543. cmd.T1 = 1
  544. cmd.V1 = 0
  545. cmd.W1 = speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
  546. if current_operation == ManualOperationType.eClockwiseRotate:
  547. cmd.T1 = 1
  548. cmd.V1 = 0
  549. cmd.W1 = -speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
  550. if current_operation == ManualOperationType.eForwardMove:
  551. cmd.T1 = 3
  552. cmd.V1= speed * sigmoid(step_acc, 0, 1)
  553. cmd.W1 = 0
  554. if current_operation == ManualOperationType.eBackwardMove:
  555. cmd.T1 = 3
  556. cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
  557. cmd.W1 = 0
  558. if current_operation == ManualOperationType.eLeftMove:
  559. cmd.T1 = 2
  560. cmd.V1 = speed * sigmoid(step_acc, 0, 1)
  561. cmd.W1 = 0
  562. if current_operation == ManualOperationType.eRightMove:
  563. cmd.T1 = 2
  564. cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
  565. cmd.W1 = 0
  566. cmd.V2 = cmd.V1
  567. cmd.V3 = cmd.V1
  568. cmd.W2 = cmd.W1
  569. cmd.W3 = cmd.W1
  570. cmd.L1 = self.L_
  571. cmd.P1 = 0
  572. cmd.D1 = 0.0
  573. cmd.end = 1
  574. self.manual_speed = [cmd.V1, cmd.W1]
  575. # 处理为json格式
  576. cmd_dict = {}
  577. for field in cmd.DESCRIPTOR.fields:
  578. cmd_dict[field.name] = field.default_value
  579. for field, value in cmd.ListFields():
  580. cmd_dict[field.name] = value
  581. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  582. self.publish(self.speedCmdTopic, cmd_json)
  583. print(cmd_json)
  584. # channel = grpc.insecure_channel(self.rpc_ipport_)
  585. # stub = msg_rpc.NavExcutorStub(channel)
  586. # response = stub.ManualOperation(cmd_0)
  587. # print("client received: ", response)
  588. # self.manual_status = ManualOperationType.eReady
  589. # print("ManualOperation {op_type} task completed!!!".format(op_type=hex(current_operation)))
  590. time.sleep(0.05)
  591. return True
  592. elif ManualOperationType.eClampClose <= current_operation <= ManualOperationType.eClampOpen:
  593. self.Manual_Unit_Clamp(current_operation)
  594. return True
  595. elif ManualOperationType.eLifterRise <= current_operation <= ManualOperationType.eLifterDown:
  596. self.Manual_Unit_Lifter(current_operation)
  597. return True
  598. return False
  599. def Manual_Unit_Lifter(self, current_operation: ManualOperationType):
  600. print(current_operation)
  601. cmd = message.ToAgvCmd()
  602. self.heat_ += 1
  603. self.heat_ %= 255
  604. cmd.H1 = self.heat_
  605. if self.IsMainModeStatu():
  606. cmd.M1 = 1
  607. else:
  608. cmd.M1 = 0
  609. cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
  610. # 处理为json格式 # jtf.MessageToJson(cmd)
  611. cmd_dict = {}
  612. for field in cmd.DESCRIPTOR.fields:
  613. cmd_dict[field.name] = field.default_value
  614. for field, value in cmd.ListFields():
  615. cmd_dict[field.name] = value
  616. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  617. self.publish(self.speedCmdTopic, cmd_json)
  618. print(cmd_json)
  619. # self.manual_status = ManualOperationType.eReady
  620. return True
  621. def Manual_Unit_Clamp(self, current_operation: ManualOperationType):
  622. print(current_operation)
  623. cmd = message.ToAgvCmd()
  624. self.heat_ += 1
  625. self.heat_ %= 255
  626. cmd.H1 = self.heat_
  627. if self.IsMainModeStatu():
  628. cmd.M1 = 1
  629. else:
  630. cmd.M1 = 0
  631. cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
  632. # 处理为json格式 # jtf.MessageToJson(cmd)
  633. cmd_dict = {}
  634. for field in cmd.DESCRIPTOR.fields:
  635. cmd_dict[field.name] = field.default_value
  636. for field, value in cmd.ListFields():
  637. cmd_dict[field.name] = value
  638. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  639. self.publish(self.speedCmdTopic, cmd_json)
  640. print(cmd_json)
  641. # self.manual_status = ManualOperationType.eReady
  642. return True
  643. def ManualOperationType2AgvCmdType(self, mo_type: ManualOperationType):
  644. if mo_type == ManualOperationType.eLifterRise:
  645. return ActType.eLifterRise
  646. if mo_type == ManualOperationType.eLifterDown:
  647. return ActType.eLifterDown
  648. if mo_type == ManualOperationType.eClampClose:
  649. return ActType.eClampClose
  650. if mo_type == ManualOperationType.eClampOpen:
  651. return ActType.eClampOpen
  652. def Manual_Unit_SlowlyStop(self, current_operation: ManualOperationType, speed):
  653. step_sum = 10
  654. step_acc = 1
  655. speed_v = max(fabs(self.manual_speed[0]), 0.01)
  656. speed_w = max(fabs(self.manual_speed[1]), 1)
  657. while step_acc <= step_sum:
  658. if ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
  659. cmd = message.ToAgvCmd()
  660. self.heat_ += 1
  661. self.heat_ %= 255
  662. cmd.H1 = self.heat_
  663. if self.IsMainModeStatu():
  664. cmd.M1 = 1
  665. else:
  666. cmd.M1 = 0
  667. if self.manual_status == ManualOperationType.eCounterclockwiseRotate:
  668. cmd.T1 = 1
  669. cmd.V1 = 0
  670. cmd.W1 = speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
  671. if self.manual_status == ManualOperationType.eClockwiseRotate:
  672. cmd.T1 = 1
  673. cmd.V1 = 0
  674. cmd.W1 = -speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
  675. if self.manual_status == ManualOperationType.eForwardMove:
  676. cmd.T1 = 3
  677. cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
  678. cmd.W1 = 0
  679. if self.manual_status == ManualOperationType.eBackwardMove:
  680. cmd.T1 = 3
  681. cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
  682. cmd.W1 = 0
  683. if self.manual_status == ManualOperationType.eLeftMove:
  684. cmd.T1 = 2
  685. cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
  686. cmd.W1 = 0
  687. if self.manual_status == ManualOperationType.eRightMove:
  688. cmd.T1 = 2
  689. cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
  690. cmd.W1 = 0
  691. cmd.V2 = cmd.V1
  692. cmd.V3 = cmd.V1
  693. cmd.W2 = cmd.W1
  694. cmd.W3 = cmd.W1
  695. cmd.L1 = self.L_
  696. cmd.end = 1
  697. # 处理为json格式
  698. cmd_dict = {}
  699. for field in cmd.DESCRIPTOR.fields:
  700. cmd_dict[field.name] = field.default_value
  701. for field, value in cmd.ListFields():
  702. cmd_dict[field.name] = value
  703. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  704. self.publish(self.speedCmdTopic, cmd_json)
  705. print(cmd_json)
  706. step_acc += 1
  707. time.sleep(0.1)
  708. self.manual_status = ManualOperationType.eReady
  709. self.manual_speed = [0, 0]
  710. print("Manual_Unit_SlowlyStop completed.")
  711. return True
  712. def GenerateActionMPC(self, beg_name, end_name, autoDirect, wheelbase=0, task_type="None"):
  713. self.GeneratePath(beg_name, end_name, task_type=task_type)
  714. actions = list()
  715. split_path = self.SplitPath(self.currentNavPathNodes_)
  716. for action in split_path:
  717. [type, nodes] = action
  718. if type == "input":
  719. [street, space] = nodes
  720. protoSpace = self.generateProtoNode(space)
  721. protoStreet = self.generateProtoNode(street)
  722. act = message.NewAction()
  723. act.type = 1
  724. act.wheelbase = wheelbase
  725. act.spaceNode.CopyFrom(protoSpace)
  726. act.streetNode.CopyFrom(protoStreet)
  727. actions.append(act)
  728. if type == "output":
  729. [space, street] = nodes
  730. protoSpace = self.generateProtoNode(space)
  731. protoStreet = self.generateProtoNode(street)
  732. act = message.NewAction()
  733. act.type = 2
  734. act.wheelbase = wheelbase
  735. act.spaceNode.CopyFrom(protoSpace)
  736. act.streetNode.CopyFrom(protoStreet)
  737. actions.append(act)
  738. if type == "nav":
  739. act = self.CreateNavPathNodesAction(nodes, autoDirect)
  740. if act is None:
  741. print("Nav cmd is None")
  742. return False
  743. else:
  744. actions.append(act)
  745. return actions