RobotData.py 29 KB

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