RobotData.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  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. if wheelbase < 2.4 or wheelbase > 3.2:
  158. return print("wheelbase is out of range!\n")
  159. print("nav")
  160. # self.ExecPathNodes(autoDirect)
  161. self.ExecNavtask(autoDirect, wheelbase)
  162. if self.IsMainModeStatu():
  163. Count.TestCount().loadCountAdd()
  164. else:
  165. Count.TestCount().singleCountAdd()
  166. return True
  167. def AutoTestNavClamp(self, begId, targetId):
  168. beg = begId
  169. target = targetId
  170. while self.autoTest_:
  171. if self.TestNavClampOnce(beg, target) == False:
  172. print(" quit auto Test")
  173. break
  174. print("1111")
  175. posInfo = self.PositionId()
  176. if posInfo is not None:
  177. [label, pt] = posInfo
  178. beg = label
  179. print("beg", beg)
  180. node = MapManager().GetVertex(beg)
  181. if node is not None:
  182. if isinstance(node, (SpaceNode)):
  183. target = "O"
  184. if isinstance(node, (StreetNode)):
  185. end_nodes = ["E", "B", "C", "D"]
  186. id = random.randint(0, 1000) % 4
  187. target = end_nodes[id]
  188. print("3333", target)
  189. print(" Next nav clamp cmd,%s to %s" % (beg, target))
  190. def ActionType(self):
  191. if self.timedNavStatu_.timeout() == False:
  192. runningStatu = self.timedNavStatu_.statu
  193. if runningStatu.statu == 0:
  194. return ActType.eReady
  195. if runningStatu.statu == 1:
  196. return ActType.eRotation
  197. if runningStatu.statu == 2:
  198. return ActType.eHorizon
  199. if runningStatu.statu == 3:
  200. return ActType.eVertical
  201. if runningStatu.statu == 4:
  202. return ActType.eMPC
  203. if runningStatu.statu == 5:
  204. return ActType.eClampClose
  205. if runningStatu.statu == 6:
  206. return ActType.eClampOpen
  207. if runningStatu.statu == 7:
  208. return ActType.eLifterRise
  209. if runningStatu.statu == 8:
  210. return ActType.eLifterDown
  211. else:
  212. return ActType.eReady
  213. @staticmethod
  214. def generateProtoNode(node):
  215. protoNode = message.PathNode()
  216. protoNode.x = node.x_
  217. protoNode.y = node.y_
  218. protoNode.id = node.id_
  219. return protoNode
  220. def ExecNavtask(self, autoDirect, wheelbase=0):
  221. cmd = message.NavCmd()
  222. key = str(uuid.uuid4())
  223. cmd.key = key
  224. cmd.action = 0
  225. actions = self.SplitPath(self.currentNavPathNodes_)
  226. for action in actions:
  227. [type, nodes] = action
  228. if type == "input":
  229. [street, space] = nodes
  230. protoSpace = self.generateProtoNode(space)
  231. protoStreet = self.generateProtoNode(street)
  232. act = message.NewAction()
  233. act.type = 1
  234. act.wheelbase = wheelbase
  235. act.spaceNode.CopyFrom(protoSpace)
  236. act.streetNode.CopyFrom(protoStreet)
  237. cmd.newActions.add().CopyFrom(act)
  238. if type == "output":
  239. [space, street] = nodes
  240. protoSpace = self.generateProtoNode(space)
  241. protoStreet = self.generateProtoNode(street)
  242. act = message.NewAction()
  243. act.type = 2
  244. act.wheelbase = wheelbase
  245. act.spaceNode.CopyFrom(protoSpace)
  246. act.streetNode.CopyFrom(protoStreet)
  247. cmd.newActions.add().CopyFrom(act)
  248. if type == "nav":
  249. action = self.CreateNavPathNodesAction(nodes, autoDirect)
  250. if action is None:
  251. print("Nav cmd is None")
  252. return False
  253. else:
  254. cmd.newActions.add().CopyFrom(action)
  255. print(cmd)
  256. if cmd is None:
  257. print("Nav cmd is None")
  258. return False
  259. channel = grpc.insecure_channel(self.rpc_ipport_)
  260. stub = msg_rpc.NavExcutorStub(channel)
  261. response = stub.Start(cmd)
  262. print("client received: ", response)
  263. if not response.ret == 0:
  264. print("nav failed :%s" % (response.info))
  265. else:
  266. print("nav completed !!!")
  267. return True
  268. def CreateNavPathNodesAction(self, path, autoDirect):
  269. # if path is not None and self.timedRobotStatu_.timeout() == False:
  270. if 1:
  271. for node in path:
  272. if isinstance(node, (SpaceNode)):
  273. print(" nodes must all street node")
  274. return None
  275. statu = self.timedRobotStatu_.statu
  276. # if statu is not None:
  277. if 1:
  278. newAction = message.NewAction()
  279. size = len(path)
  280. for i in range(size):
  281. node = path[i]
  282. pathNode = message.PathNode()
  283. pathNode.x = node.x_
  284. pathNode.y = node.y_
  285. newAction.type = 4
  286. if autoDirect:
  287. newAction.type = 3
  288. newAction.pathNodes.add().CopyFrom(pathNode)
  289. return newAction
  290. else:
  291. print("statu is None")
  292. else:
  293. print("current path is none")
  294. return None
  295. def ExecPathNodes(self, autoDirect):
  296. if self.navCmdTopic_ == None:
  297. print("Robot has not set nav cmd topic")
  298. return False
  299. if not self.ActionType() == ActType.eReady:
  300. print(" robot is navigating ,key:%s" % (self.timedNavStatu_.statu.key))
  301. return False
  302. cmd = message.NavCmd()
  303. key = str(uuid.uuid4())
  304. cmd.key = key
  305. cmd.action = 0
  306. action = self.CreateNavPathNodesAction(self.currentNavPathNodes_, autoDirect)
  307. if action is None:
  308. print("Nav cmd is None")
  309. return False
  310. cmd.newActions.add().CopyFrom(action)
  311. print(cmd)
  312. channel = grpc.insecure_channel(self.rpc_ipport_)
  313. stub = msg_rpc.NavExcutorStub(channel)
  314. response = stub.Start(cmd)
  315. return True
  316. '''
  317. 根据AGV单车的起始位置调整路径
  318. '''
  319. def AdjustPath(self, path):
  320. adjusted_path = copy.deepcopy(path)
  321. y_offset = 1.2
  322. dy = 0
  323. # if self.IsMainAgv() or self.name_ == "AgvMain":
  324. if self.name_ == RobotName.strAGVMain:
  325. dy = 1
  326. # if not self.IsMainAgv() or self == "AGV2":
  327. if self.name_ == RobotName.strAGV2:
  328. dy = -1
  329. print("dy:", dy)
  330. for node in adjusted_path:
  331. if isinstance(node, StreetNode):
  332. if dy > 0:
  333. node.y_ += y_offset
  334. elif dy < 0:
  335. node.y_ -= y_offset
  336. else:
  337. pass
  338. return adjusted_path
  339. '''
  340. 拆分路径,生成动作集,input:入库动作,nav:导航动作,output:出库动作
  341. '''
  342. def SplitPath(self, path):
  343. space_count = 0
  344. for i in range(len(path)):
  345. if isinstance(path[i], (SpaceNode)):
  346. space_count += 1
  347. if i == 0 or i == len(path) - 1:
  348. pass
  349. else:
  350. print("Error: space node is not first/last of path")
  351. return None
  352. actions = []
  353. lastNode = None
  354. navIndex = -1
  355. for node in path:
  356. if lastNode == None:
  357. lastNode = node
  358. continue
  359. if isinstance(node, (SpaceNode)): # 当前点是车位点
  360. if isinstance(lastNode, (SpaceNode)): # 上一点为车位点
  361. print("Error: last node and current node is space node ")
  362. lastNode = None
  363. continue
  364. elif isinstance(lastNode, (StreetNode)): # 上一点为马路点,则动作为入库
  365. actions.append(["input", [lastNode, node]])
  366. lastNode = None
  367. continue
  368. if isinstance(node, (StreetNode)):
  369. if isinstance(lastNode, (SpaceNode)): # 上一点为车位点, 出库
  370. actions.append(["output", [lastNode, node]])
  371. elif isinstance(lastNode, (StreetNode)):
  372. if navIndex < 0:
  373. actions.append(["nav", [lastNode]])
  374. navIndex = len(actions) - 1
  375. actions[navIndex][1].append(node)
  376. lastNode = node
  377. return actions
  378. def SwitchMoveMode(self, mode, wheelbase):
  379. if self.IsMainAgv() == False:
  380. print(" this agv is single can not switch mode")
  381. return False
  382. cmd = message.NavCmd()
  383. key = str(uuid.uuid4())
  384. cmd.key = key
  385. cmd.action = 0
  386. action = message.NewAction()
  387. action.type = 8
  388. action.changedMode = mode
  389. if mode == 1:
  390. action.wheelbase = wheelbase
  391. cmd.newActions.add().CopyFrom(action)
  392. print(cmd)
  393. channel = grpc.insecure_channel(self.rpc_ipport_)
  394. stub = msg_rpc.NavExcutorStub(channel)
  395. response = stub.Start(cmd)
  396. return False
  397. def IsClampClosed(self):
  398. if self.timedRobotStatu_.timeout() == False:
  399. if self.IsMainModeStatu():
  400. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  401. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  402. return (clamp == 1 and clamp_other == 1)
  403. else:
  404. return self.timedRobotStatu_.statu.agvStatu.clamp == 1
  405. return False
  406. def IsClampRunning(self):
  407. if self.timedRobotStatu_.timeout() == False:
  408. if self.IsMainModeStatu():
  409. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  410. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  411. return (clamp == 0 or clamp_other == 0)
  412. else:
  413. return self.timedRobotStatu_.statu.agvStatu.clamp == 0
  414. return False
  415. def IsClampOpened(self):
  416. if self.timedRobotStatu_.timeout() == False:
  417. if self.IsMainModeStatu():
  418. clamp = self.timedRobotStatu_.statu.agvStatu.clamp
  419. clamp_other = self.timedRobotStatu_.statu.agvStatu.clamp_other
  420. return (clamp == 2 and clamp_other == 2)
  421. else:
  422. return self.timedRobotStatu_.statu.agvStatu.clamp == 2
  423. return False
  424. def ClampClose(self):
  425. if self.IsClampClosed() == True:
  426. print("clamp closed")
  427. return True
  428. cmd = message.NavCmd()
  429. cmd.action = 0
  430. key = str(uuid.uuid4())
  431. cmd.key = (key)
  432. act = message.NewAction()
  433. act.type = 6
  434. cmd.newActions.add().CopyFrom(act)
  435. channel = grpc.insecure_channel(self.rpc_ipport_)
  436. stub = msg_rpc.NavExcutorStub(channel)
  437. response = stub.Start(cmd)
  438. return True
  439. def ClampOpen(self):
  440. if self.IsClampOpened() == True:
  441. print("clamp opended")
  442. return True
  443. cmd = message.NavCmd()
  444. cmd.action = 0
  445. key = str(uuid.uuid4())
  446. cmd.key = (key)
  447. act = message.NewAction()
  448. act.type = 7
  449. cmd.newActions.add().CopyFrom(act)
  450. channel = grpc.insecure_channel(self.rpc_ipport_)
  451. stub = msg_rpc.NavExcutorStub(channel)
  452. response = stub.Start(cmd)
  453. return True
  454. def IsLiferDowned(self):
  455. if self.timedRobotStatu_.timeout() == False:
  456. if self.IsMainModeStatu():
  457. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  458. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  459. return (lifter == 2 and lifter_other == 2)
  460. else:
  461. return self.timedRobotStatu_.statu.agvStatu.lifter == 2
  462. return False
  463. def IsLiferRunning(self):
  464. if self.timedRobotStatu_.timeout() == False:
  465. if self.IsMainModeStatu():
  466. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  467. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  468. return (lifter == 0 and lifter_other == 0)
  469. else:
  470. return self.timedRobotStatu_.statu.agvStatu.lifter == 0
  471. return False
  472. def IsLiferRose(self):
  473. if self.timedRobotStatu_.timeout() == False:
  474. if self.IsMainModeStatu():
  475. lifter = self.timedRobotStatu_.statu.agvStatu.lifter
  476. lifter_other = self.timedRobotStatu_.statu.agvStatu.lifter_other
  477. return (lifter == 1 and lifter_other == 1)
  478. else:
  479. return self.timedRobotStatu_.statu.agvStatu.lifter == 1
  480. return False
  481. def LiferRise(self):
  482. if self.IsLiferRose() == True:
  483. print("lifter has rose")
  484. return True
  485. cmd = message.NavCmd()
  486. cmd.action = 0
  487. key = str(uuid.uuid4())
  488. cmd.key = (key)
  489. act = message.NewAction()
  490. act.type = 9
  491. cmd.newActions.add().CopyFrom(act)
  492. channel = grpc.insecure_channel(self.rpc_ipport_)
  493. stub = msg_rpc.NavExcutorStub(channel)
  494. response = stub.Start(cmd)
  495. return True
  496. def LiferDown(self):
  497. if self.IsLiferDowned() == True:
  498. print("lifter has downed")
  499. return True
  500. cmd = message.NavCmd()
  501. cmd.action = 0
  502. key = str(uuid.uuid4())
  503. cmd.key = (key)
  504. act = message.NewAction()
  505. act.type = 10
  506. cmd.newActions.add().CopyFrom(act)
  507. channel = grpc.insecure_channel(self.rpc_ipport_)
  508. stub = msg_rpc.NavExcutorStub(channel)
  509. response = stub.Start(cmd)
  510. return True
  511. def CancelNavTask(self):
  512. cmd = message.NavCmd()
  513. cmd.action = 3
  514. channel = grpc.insecure_channel(self.rpc_ipport_)
  515. stub = msg_rpc.NavExcutorStub(channel)
  516. response = stub.Cancel(cmd)
  517. print("client received: ", response)
  518. print(" Cancel task completed!!!")
  519. return True
  520. def IsManualTaskRunning(self):
  521. return self.manual_status != ManualOperationType.eReady
  522. def ManualTask(self, current_operation, step_acc=0, speed=0):
  523. if self.IsNavigating():
  524. print("AGV is navigating!!!")
  525. # return False
  526. # slowly stop
  527. if current_operation == ManualOperationType.eReady and \
  528. ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
  529. print("Manual_Unit_SlowlyStop")
  530. self.Manual_Unit_SlowlyStop(current_operation, speed)
  531. return True
  532. # if self.IsManualTaskRunning():
  533. # return print("ManualTask | ManualTask is running...")
  534. self.manual_status = current_operation
  535. if ManualOperationType.eReady < current_operation <= ManualOperationType.eRightMove:
  536. cmd = message.ToAgvCmd()
  537. self.heat_ += 1
  538. self.heat_ %= 255
  539. cmd.H1 = self.heat_
  540. if self.IsMainModeStatu():
  541. cmd.M1 = 1
  542. else:
  543. cmd.M1 = 0
  544. if current_operation == ManualOperationType.eCounterclockwiseRotate:
  545. cmd.T1 = 1
  546. cmd.V1 = 0
  547. cmd.W1 = speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
  548. if current_operation == ManualOperationType.eClockwiseRotate:
  549. cmd.T1 = 1
  550. cmd.V1 = 0
  551. cmd.W1 = -speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
  552. if current_operation == ManualOperationType.eForwardMove:
  553. cmd.T1 = 3
  554. cmd.V1= speed * sigmoid(step_acc, 0, 1)
  555. cmd.W1 = 0
  556. if current_operation == ManualOperationType.eBackwardMove:
  557. cmd.T1 = 3
  558. cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
  559. cmd.W1 = 0
  560. if current_operation == ManualOperationType.eLeftMove:
  561. cmd.T1 = 2
  562. cmd.V1 = speed * sigmoid(step_acc, 0, 1)
  563. cmd.W1 = 0
  564. if current_operation == ManualOperationType.eRightMove:
  565. cmd.T1 = 2
  566. cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
  567. cmd.W1 = 0
  568. cmd.V2 = cmd.V1
  569. cmd.V3 = cmd.V1
  570. cmd.W2 = cmd.W1
  571. cmd.W3 = cmd.W1
  572. cmd.L1 = self.L_
  573. cmd.P1 = 0
  574. cmd.D1 = 0.0
  575. cmd.end = 1
  576. self.manual_speed = [cmd.V1, cmd.W1]
  577. # 处理为json格式
  578. cmd_dict = {}
  579. for field in cmd.DESCRIPTOR.fields:
  580. cmd_dict[field.name] = field.default_value
  581. for field, value in cmd.ListFields():
  582. cmd_dict[field.name] = value
  583. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  584. self.publish(self.speedCmdTopic, cmd_json)
  585. print(cmd_json)
  586. # channel = grpc.insecure_channel(self.rpc_ipport_)
  587. # stub = msg_rpc.NavExcutorStub(channel)
  588. # response = stub.ManualOperation(cmd_0)
  589. # print("client received: ", response)
  590. # self.manual_status = ManualOperationType.eReady
  591. # print("ManualOperation {op_type} task completed!!!".format(op_type=hex(current_operation)))
  592. time.sleep(0.05)
  593. return True
  594. elif ManualOperationType.eClampClose <= current_operation <= ManualOperationType.eClampOpen:
  595. self.Manual_Unit_Clamp(current_operation)
  596. return True
  597. elif ManualOperationType.eLifterRise <= current_operation <= ManualOperationType.eLifterDown:
  598. self.Manual_Unit_Lifter(current_operation)
  599. return True
  600. return False
  601. def Manual_Unit_Lifter(self, current_operation: ManualOperationType):
  602. print(current_operation)
  603. cmd = message.ToAgvCmd()
  604. self.heat_ += 1
  605. self.heat_ %= 255
  606. cmd.H1 = self.heat_
  607. if self.IsMainModeStatu():
  608. cmd.M1 = 1
  609. else:
  610. cmd.M1 = 0
  611. cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
  612. # 处理为json格式 # jtf.MessageToJson(cmd)
  613. cmd_dict = {}
  614. for field in cmd.DESCRIPTOR.fields:
  615. cmd_dict[field.name] = field.default_value
  616. for field, value in cmd.ListFields():
  617. cmd_dict[field.name] = value
  618. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  619. self.publish(self.speedCmdTopic, cmd_json)
  620. print(cmd_json)
  621. # self.manual_status = ManualOperationType.eReady
  622. return True
  623. def Manual_Unit_Clamp(self, current_operation: ManualOperationType):
  624. print(current_operation)
  625. cmd = message.ToAgvCmd()
  626. self.heat_ += 1
  627. self.heat_ %= 255
  628. cmd.H1 = self.heat_
  629. if self.IsMainModeStatu():
  630. cmd.M1 = 1
  631. else:
  632. cmd.M1 = 0
  633. cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
  634. # 处理为json格式 # jtf.MessageToJson(cmd)
  635. cmd_dict = {}
  636. for field in cmd.DESCRIPTOR.fields:
  637. cmd_dict[field.name] = field.default_value
  638. for field, value in cmd.ListFields():
  639. cmd_dict[field.name] = value
  640. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  641. self.publish(self.speedCmdTopic, cmd_json)
  642. print(cmd_json)
  643. # self.manual_status = ManualOperationType.eReady
  644. return True
  645. def ManualOperationType2AgvCmdType(self, mo_type: ManualOperationType):
  646. if mo_type == ManualOperationType.eLifterRise:
  647. return ActType.eLifterRise
  648. if mo_type == ManualOperationType.eLifterDown:
  649. return ActType.eLifterDown
  650. if mo_type == ManualOperationType.eClampClose:
  651. return ActType.eClampClose
  652. if mo_type == ManualOperationType.eClampOpen:
  653. return ActType.eClampOpen
  654. def Manual_Unit_SlowlyStop(self, current_operation: ManualOperationType, speed):
  655. step_sum = 10
  656. step_acc = 1
  657. speed_v = max(fabs(self.manual_speed[0]), 0.01)
  658. speed_w = max(fabs(self.manual_speed[1]), 1)
  659. while step_acc <= step_sum:
  660. if ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
  661. cmd = message.ToAgvCmd()
  662. self.heat_ += 1
  663. self.heat_ %= 255
  664. cmd.H1 = self.heat_
  665. if self.IsMainModeStatu():
  666. cmd.M1 = 1
  667. else:
  668. cmd.M1 = 0
  669. if self.manual_status == ManualOperationType.eCounterclockwiseRotate:
  670. cmd.T1 = 1
  671. cmd.V1 = 0
  672. cmd.W1 = speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
  673. if self.manual_status == ManualOperationType.eClockwiseRotate:
  674. cmd.T1 = 1
  675. cmd.V1 = 0
  676. cmd.W1 = -speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
  677. if self.manual_status == ManualOperationType.eForwardMove:
  678. cmd.T1 = 3
  679. cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
  680. cmd.W1 = 0
  681. if self.manual_status == ManualOperationType.eBackwardMove:
  682. cmd.T1 = 3
  683. cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
  684. cmd.W1 = 0
  685. if self.manual_status == ManualOperationType.eLeftMove:
  686. cmd.T1 = 2
  687. cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
  688. cmd.W1 = 0
  689. if self.manual_status == ManualOperationType.eRightMove:
  690. cmd.T1 = 2
  691. cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
  692. cmd.W1 = 0
  693. cmd.V2 = cmd.V1
  694. cmd.V3 = cmd.V1
  695. cmd.W2 = cmd.W1
  696. cmd.W3 = cmd.W1
  697. cmd.L1 = self.L_
  698. cmd.end = 1
  699. # 处理为json格式
  700. cmd_dict = {}
  701. for field in cmd.DESCRIPTOR.fields:
  702. cmd_dict[field.name] = field.default_value
  703. for field, value in cmd.ListFields():
  704. cmd_dict[field.name] = value
  705. cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
  706. self.publish(self.speedCmdTopic, cmd_json)
  707. print(cmd_json)
  708. step_acc += 1
  709. time.sleep(0.1)
  710. self.manual_status = ManualOperationType.eReady
  711. self.manual_speed = [0, 0]
  712. print("Manual_Unit_SlowlyStop completed.")
  713. return True
  714. def GenerateActionMPC(self, beg_name, end_name, autoDirect, wheelbase=0, task_type="None"):
  715. self.GeneratePath(beg_name, end_name, task_type=task_type)
  716. actions = list()
  717. split_path = self.SplitPath(self.currentNavPathNodes_)
  718. for action in split_path:
  719. [type, nodes] = action
  720. if type == "input":
  721. [street, space] = nodes
  722. protoSpace = self.generateProtoNode(space)
  723. protoStreet = self.generateProtoNode(street)
  724. act = message.NewAction()
  725. act.type = 1
  726. act.wheelbase = wheelbase
  727. act.spaceNode.CopyFrom(protoSpace)
  728. act.streetNode.CopyFrom(protoStreet)
  729. actions.append(act)
  730. if type == "output":
  731. [space, street] = nodes
  732. protoSpace = self.generateProtoNode(space)
  733. protoStreet = self.generateProtoNode(street)
  734. act = message.NewAction()
  735. act.type = 2
  736. act.wheelbase = wheelbase
  737. act.spaceNode.CopyFrom(protoSpace)
  738. act.streetNode.CopyFrom(protoStreet)
  739. actions.append(act)
  740. if type == "nav":
  741. act = self.CreateNavPathNodesAction(nodes, autoDirect)
  742. if act is None:
  743. print("Nav cmd is None")
  744. return False
  745. else:
  746. actions.append(act)
  747. return actions