RobotData.py 30 KB

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