|
@@ -1,6 +1,9 @@
|
|
import copy
|
|
import copy
|
|
import enum
|
|
import enum
|
|
import time
|
|
import time
|
|
|
|
+
|
|
|
|
+from numpy import fabs
|
|
|
|
+
|
|
import message_pb2 as message
|
|
import message_pb2 as message
|
|
import grpc
|
|
import grpc
|
|
import message_pb2_grpc as msg_rpc
|
|
import message_pb2_grpc as msg_rpc
|
|
@@ -9,7 +12,7 @@ from custom_define import RobotName, ActType
|
|
from mqtt_async import MqttAsync
|
|
from mqtt_async import MqttAsync
|
|
import google.protobuf.json_format as jtf
|
|
import google.protobuf.json_format as jtf
|
|
import json
|
|
import json
|
|
-from dijkstra.Map import DijikstraMap, SpaceNode, StreetNode
|
|
|
|
|
|
+from dijkstra.Map import SpaceNode, StreetNode, MapManager, DijikstraMap
|
|
import uuid
|
|
import uuid
|
|
import random
|
|
import random
|
|
import math
|
|
import math
|
|
@@ -62,6 +65,7 @@ class Robot(MqttAsync):
|
|
self.heat_ = 0 # 心跳
|
|
self.heat_ = 0 # 心跳
|
|
|
|
|
|
self.manual_status = ManualOperationType.eReady # 正在进行的手动操作
|
|
self.manual_status = ManualOperationType.eReady # 正在进行的手动操作
|
|
|
|
+ self.manual_speed = [0.0, 0]
|
|
|
|
|
|
def Color(self):
|
|
def Color(self):
|
|
if self.IsMainModeStatu():
|
|
if self.IsMainModeStatu():
|
|
@@ -148,18 +152,18 @@ class Robot(MqttAsync):
|
|
return True'''
|
|
return True'''
|
|
|
|
|
|
def GeneratePath(self, begID, endID, task_type="None"):
|
|
def GeneratePath(self, begID, endID, task_type="None"):
|
|
- self.currentNavPathNodes_ = DijikstraMap().GetShortestPath(begID, endID)
|
|
|
|
-
|
|
|
|
- if task_type == "DoubleAGV":
|
|
|
|
- print("AdjustPath------------------")
|
|
|
|
- if self.IsMainModeStatu() is False:
|
|
|
|
- print("原始路径:")
|
|
|
|
- for node in self.currentNavPathNodes_:
|
|
|
|
- print(node.id_, node.y_)
|
|
|
|
- self.currentNavPathNodes_ = self.AdjustPath(self.currentNavPathNodes_)
|
|
|
|
- print("修改路径:")
|
|
|
|
- for node in self.currentNavPathNodes_:
|
|
|
|
- print(node.id_, node.y_)
|
|
|
|
|
|
+ self.currentNavPathNodes_ = MapManager().GetShortestPath(begID, endID)
|
|
|
|
+
|
|
|
|
+ # if task_type == "DoubleAGV":
|
|
|
|
+ # print("AdjustPath------------------")
|
|
|
|
+ # if self.IsMainModeStatu() is False:
|
|
|
|
+ # print("原始路径:")
|
|
|
|
+ # for node in self.currentNavPathNodes_:
|
|
|
|
+ # print(node.id_, node.y_)
|
|
|
|
+ # self.currentNavPathNodes_ = self.AdjustPath(self.currentNavPathNodes_)
|
|
|
|
+ # print("修改路径:")
|
|
|
|
+ # for node in self.currentNavPathNodes_:
|
|
|
|
+ # print(node.id_, node.y_)
|
|
|
|
|
|
self.currentNavPath_ = DijikstraMap().CreatePath(self.currentNavPathNodes_, 0.5)
|
|
self.currentNavPath_ = DijikstraMap().CreatePath(self.currentNavPathNodes_, 0.5)
|
|
if self.currentNavPathNodes_ is not None and self.currentNavPath_ is not None:
|
|
if self.currentNavPathNodes_ is not None and self.currentNavPath_ is not None:
|
|
@@ -173,7 +177,7 @@ class Robot(MqttAsync):
|
|
return None
|
|
return None
|
|
x = self.timedRobotStatu_.statu.x
|
|
x = self.timedRobotStatu_.statu.x
|
|
y = self.timedRobotStatu_.statu.y
|
|
y = self.timedRobotStatu_.statu.y
|
|
- djks_map = DijikstraMap()
|
|
|
|
|
|
+ djks_map = MapManager()
|
|
[label, pt] = djks_map.findNeastNode([x, y])
|
|
[label, pt] = djks_map.findNeastNode([x, y])
|
|
return [label, pt]
|
|
return [label, pt]
|
|
|
|
|
|
@@ -207,7 +211,7 @@ class Robot(MqttAsync):
|
|
[label, pt] = posInfo
|
|
[label, pt] = posInfo
|
|
beg = label
|
|
beg = label
|
|
print("beg", beg)
|
|
print("beg", beg)
|
|
- node = DijikstraMap().GetVertex(beg)
|
|
|
|
|
|
+ node = MapManager().GetVertex(beg)
|
|
|
|
|
|
if node is not None:
|
|
if node is not None:
|
|
if isinstance(node, (SpaceNode)):
|
|
if isinstance(node, (SpaceNode)):
|
|
@@ -302,7 +306,6 @@ class Robot(MqttAsync):
|
|
print("nav failed :%s" % (response.info))
|
|
print("nav failed :%s" % (response.info))
|
|
else:
|
|
else:
|
|
print("nav completed !!!")
|
|
print("nav completed !!!")
|
|
-
|
|
|
|
return True
|
|
return True
|
|
|
|
|
|
def CreateNavPathNodesAction(self, path, autoDirect):
|
|
def CreateNavPathNodesAction(self, path, autoDirect):
|
|
@@ -598,51 +601,66 @@ class Robot(MqttAsync):
|
|
return self.manual_status != ManualOperationType.eReady
|
|
return self.manual_status != ManualOperationType.eReady
|
|
|
|
|
|
def ManualTask(self, current_operation, step_acc=0, speed=0):
|
|
def ManualTask(self, current_operation, step_acc=0, speed=0):
|
|
- print("speed: ", speed)
|
|
|
|
if self.IsNavigating():
|
|
if self.IsNavigating():
|
|
print("AGV is navigating!!!")
|
|
print("AGV is navigating!!!")
|
|
return
|
|
return
|
|
- if self.IsManualTaskRunning():
|
|
|
|
- return print("ManualTask | ManualTask is running...")
|
|
|
|
|
|
+
|
|
|
|
+ # slowly stop
|
|
|
|
+ if current_operation == ManualOperationType.eReady and \
|
|
|
|
+ ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
|
|
|
|
+ print("Manual_Unit_SlowlyStop")
|
|
|
|
+ self.Manual_Unit_SlowlyStop(current_operation, speed)
|
|
|
|
+ return True
|
|
|
|
+
|
|
|
|
+ # if self.IsManualTaskRunning():
|
|
|
|
+ # return print("ManualTask | ManualTask is running...")
|
|
|
|
+
|
|
self.manual_status = current_operation
|
|
self.manual_status = current_operation
|
|
|
|
|
|
if ManualOperationType.eReady < current_operation <= ManualOperationType.eRightMove:
|
|
if ManualOperationType.eReady < current_operation <= ManualOperationType.eRightMove:
|
|
cmd = message.ToAgvCmd()
|
|
cmd = message.ToAgvCmd()
|
|
self.heat_ += 1
|
|
self.heat_ += 1
|
|
self.heat_ %= 255
|
|
self.heat_ %= 255
|
|
- cmd.H = self.heat_
|
|
|
|
|
|
+ cmd.H1 = self.heat_
|
|
if self.IsMainModeStatu():
|
|
if self.IsMainModeStatu():
|
|
- cmd.M = 1
|
|
|
|
|
|
+ cmd.M1 = 1
|
|
else:
|
|
else:
|
|
- cmd.M = 0
|
|
|
|
|
|
+ cmd.M1 = 0
|
|
|
|
|
|
if current_operation == ManualOperationType.eCounterclockwiseRotate:
|
|
if current_operation == ManualOperationType.eCounterclockwiseRotate:
|
|
- cmd.T = 1
|
|
|
|
- cmd.V = 0
|
|
|
|
- cmd.W = speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
|
|
|
|
|
|
+ cmd.T1 = 1
|
|
|
|
+ cmd.V1 = 0
|
|
|
|
+ cmd.W1 = speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
|
|
if current_operation == ManualOperationType.eClockwiseRotate:
|
|
if current_operation == ManualOperationType.eClockwiseRotate:
|
|
- cmd.T = 1
|
|
|
|
- cmd.V = 0
|
|
|
|
- cmd.W = -speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
|
|
|
|
|
|
+ cmd.T1 = 1
|
|
|
|
+ cmd.V1 = 0
|
|
|
|
+ cmd.W1 = -speed / 180 * math.pi * sigmoid(step_acc, 0, 1)
|
|
if current_operation == ManualOperationType.eForwardMove:
|
|
if current_operation == ManualOperationType.eForwardMove:
|
|
- cmd.T = 3
|
|
|
|
- cmd.V = speed * sigmoid(step_acc, 0, 1)
|
|
|
|
- cmd.W = 0
|
|
|
|
|
|
+ cmd.T1 = 3
|
|
|
|
+ cmd.V1= speed * sigmoid(step_acc, 0, 1)
|
|
|
|
+ cmd.W1 = 0
|
|
if current_operation == ManualOperationType.eBackwardMove:
|
|
if current_operation == ManualOperationType.eBackwardMove:
|
|
- cmd.T = 3
|
|
|
|
- cmd.V = -speed * sigmoid(step_acc, 0, 1)
|
|
|
|
- cmd.W = 0
|
|
|
|
|
|
+ cmd.T1 = 3
|
|
|
|
+ cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
|
|
|
|
+ cmd.W1 = 0
|
|
if current_operation == ManualOperationType.eLeftMove:
|
|
if current_operation == ManualOperationType.eLeftMove:
|
|
- cmd.T = 2
|
|
|
|
- cmd.V = speed * sigmoid(step_acc, 0, 1)
|
|
|
|
- cmd.W = 0
|
|
|
|
|
|
+ cmd.T1 = 2
|
|
|
|
+ cmd.V1 = speed * sigmoid(step_acc, 0, 1)
|
|
|
|
+ cmd.W1 = 0
|
|
if current_operation == ManualOperationType.eRightMove:
|
|
if current_operation == ManualOperationType.eRightMove:
|
|
- cmd.T = 2
|
|
|
|
- cmd.V = -speed * sigmoid(step_acc, 0, 1)
|
|
|
|
- cmd.W = 0
|
|
|
|
- cmd.L = self.L_
|
|
|
|
|
|
+ cmd.T1 = 2
|
|
|
|
+ cmd.V1 = -speed * sigmoid(step_acc, 0, 1)
|
|
|
|
+ cmd.W1 = 0
|
|
|
|
+ cmd.V2 = cmd.V1
|
|
|
|
+ cmd.V3 = cmd.V1
|
|
|
|
+ cmd.W2 = cmd.W1
|
|
|
|
+ cmd.W3 = cmd.W1
|
|
|
|
+
|
|
|
|
+ cmd.L1 = self.L_
|
|
|
|
+ cmd.P1 = 0
|
|
|
|
+ cmd.D1 = 0.0
|
|
cmd.end = 1
|
|
cmd.end = 1
|
|
-
|
|
|
|
|
|
+ self.manual_speed = [cmd.V1, cmd.W1]
|
|
# 处理为json格式
|
|
# 处理为json格式
|
|
cmd_dict = {}
|
|
cmd_dict = {}
|
|
for field in cmd.DESCRIPTOR.fields:
|
|
for field in cmd.DESCRIPTOR.fields:
|
|
@@ -658,8 +676,9 @@ class Robot(MqttAsync):
|
|
# stub = msg_rpc.NavExcutorStub(channel)
|
|
# stub = msg_rpc.NavExcutorStub(channel)
|
|
# response = stub.ManualOperation(cmd_0)
|
|
# response = stub.ManualOperation(cmd_0)
|
|
# print("client received: ", response)
|
|
# print("client received: ", response)
|
|
- self.manual_status = ManualOperationType.eReady
|
|
|
|
|
|
+ # self.manual_status = ManualOperationType.eReady
|
|
# print("ManualOperation {op_type} task completed!!!".format(op_type=hex(current_operation)))
|
|
# print("ManualOperation {op_type} task completed!!!".format(op_type=hex(current_operation)))
|
|
|
|
+ time.sleep(0.05)
|
|
return True
|
|
return True
|
|
|
|
|
|
elif ManualOperationType.eClampClose <= current_operation <= ManualOperationType.eClampOpen:
|
|
elif ManualOperationType.eClampClose <= current_operation <= ManualOperationType.eClampOpen:
|
|
@@ -669,6 +688,7 @@ class Robot(MqttAsync):
|
|
elif ManualOperationType.eLifterRise <= current_operation <= ManualOperationType.eLifterDown:
|
|
elif ManualOperationType.eLifterRise <= current_operation <= ManualOperationType.eLifterDown:
|
|
self.Manual_Unit_Lifter(current_operation)
|
|
self.Manual_Unit_Lifter(current_operation)
|
|
return True
|
|
return True
|
|
|
|
+
|
|
return False
|
|
return False
|
|
|
|
|
|
def Manual_Unit_Lifter(self, current_operation: ManualOperationType):
|
|
def Manual_Unit_Lifter(self, current_operation: ManualOperationType):
|
|
@@ -676,12 +696,12 @@ class Robot(MqttAsync):
|
|
cmd = message.ToAgvCmd()
|
|
cmd = message.ToAgvCmd()
|
|
self.heat_ += 1
|
|
self.heat_ += 1
|
|
self.heat_ %= 255
|
|
self.heat_ %= 255
|
|
- cmd.H = self.heat_
|
|
|
|
|
|
+ cmd.H1 = self.heat_
|
|
if self.IsMainModeStatu():
|
|
if self.IsMainModeStatu():
|
|
- cmd.M = 1
|
|
|
|
|
|
+ cmd.M1 = 1
|
|
else:
|
|
else:
|
|
- cmd.M = 0
|
|
|
|
- cmd.T = self.ManualOperationType2AgvCmdType(current_operation)
|
|
|
|
|
|
+ cmd.M1 = 0
|
|
|
|
+ cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
|
|
|
|
|
|
# 处理为json格式 # jtf.MessageToJson(cmd)
|
|
# 处理为json格式 # jtf.MessageToJson(cmd)
|
|
cmd_dict = {}
|
|
cmd_dict = {}
|
|
@@ -692,7 +712,7 @@ class Robot(MqttAsync):
|
|
cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
|
|
cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
|
|
self.publish(self.speedCmdTopic, cmd_json)
|
|
self.publish(self.speedCmdTopic, cmd_json)
|
|
print(cmd_json)
|
|
print(cmd_json)
|
|
- self.manual_status = ManualOperationType.eReady
|
|
|
|
|
|
+ # self.manual_status = ManualOperationType.eReady
|
|
return True
|
|
return True
|
|
|
|
|
|
def Manual_Unit_Clamp(self, current_operation: ManualOperationType):
|
|
def Manual_Unit_Clamp(self, current_operation: ManualOperationType):
|
|
@@ -700,12 +720,12 @@ class Robot(MqttAsync):
|
|
cmd = message.ToAgvCmd()
|
|
cmd = message.ToAgvCmd()
|
|
self.heat_ += 1
|
|
self.heat_ += 1
|
|
self.heat_ %= 255
|
|
self.heat_ %= 255
|
|
- cmd.H = self.heat_
|
|
|
|
|
|
+ cmd.H1 = self.heat_
|
|
if self.IsMainModeStatu():
|
|
if self.IsMainModeStatu():
|
|
- cmd.M = 1
|
|
|
|
|
|
+ cmd.M1 = 1
|
|
else:
|
|
else:
|
|
- cmd.M = 0
|
|
|
|
- cmd.T = self.ManualOperationType2AgvCmdType(current_operation)
|
|
|
|
|
|
+ cmd.M1 = 0
|
|
|
|
+ cmd.T1 = self.ManualOperationType2AgvCmdType(current_operation)
|
|
|
|
|
|
# 处理为json格式 # jtf.MessageToJson(cmd)
|
|
# 处理为json格式 # jtf.MessageToJson(cmd)
|
|
cmd_dict = {}
|
|
cmd_dict = {}
|
|
@@ -716,7 +736,7 @@ class Robot(MqttAsync):
|
|
cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
|
|
cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
|
|
self.publish(self.speedCmdTopic, cmd_json)
|
|
self.publish(self.speedCmdTopic, cmd_json)
|
|
print(cmd_json)
|
|
print(cmd_json)
|
|
- self.manual_status = ManualOperationType.eReady
|
|
|
|
|
|
+ # self.manual_status = ManualOperationType.eReady
|
|
return True
|
|
return True
|
|
|
|
|
|
def ManualOperationType2AgvCmdType(self, mo_type: ManualOperationType):
|
|
def ManualOperationType2AgvCmdType(self, mo_type: ManualOperationType):
|
|
@@ -728,3 +748,74 @@ class Robot(MqttAsync):
|
|
return ActType.eClampClose
|
|
return ActType.eClampClose
|
|
if mo_type == ManualOperationType.eClampOpen:
|
|
if mo_type == ManualOperationType.eClampOpen:
|
|
return ActType.eClampOpen
|
|
return ActType.eClampOpen
|
|
|
|
+
|
|
|
|
+ def Manual_Unit_SlowlyStop(self, current_operation: ManualOperationType, speed):
|
|
|
|
+ step_sum = 10
|
|
|
|
+ step_acc = 1
|
|
|
|
+ speed_v = max(fabs(self.manual_speed[0]), 0.01)
|
|
|
|
+ speed_w = max(fabs(self.manual_speed[1]), 1)
|
|
|
|
+ while step_acc <= step_sum:
|
|
|
|
+ if ManualOperationType.eReady < self.manual_status <= ManualOperationType.eRightMove:
|
|
|
|
+ cmd = message.ToAgvCmd()
|
|
|
|
+ self.heat_ += 1
|
|
|
|
+ self.heat_ %= 255
|
|
|
|
+ cmd.H1 = self.heat_
|
|
|
|
+ if self.IsMainModeStatu():
|
|
|
|
+ cmd.M1 = 1
|
|
|
|
+ else:
|
|
|
|
+ cmd.M1 = 0
|
|
|
|
+
|
|
|
|
+ if self.manual_status == ManualOperationType.eCounterclockwiseRotate:
|
|
|
|
+ cmd.T1 = 1
|
|
|
|
+ cmd.V1 = 0
|
|
|
|
+ cmd.W1 = speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
|
|
|
|
+ if self.manual_status == ManualOperationType.eClockwiseRotate:
|
|
|
|
+ cmd.T1 = 1
|
|
|
|
+ cmd.V1 = 0
|
|
|
|
+ cmd.W1 = -speed_w / 180 * math.pi * (step_sum-step_acc) / step_sum
|
|
|
|
+ if self.manual_status == ManualOperationType.eForwardMove:
|
|
|
|
+ cmd.T1 = 3
|
|
|
|
+ cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
|
|
|
|
+ cmd.W1 = 0
|
|
|
|
+ if self.manual_status == ManualOperationType.eBackwardMove:
|
|
|
|
+ cmd.T1 = 3
|
|
|
|
+ cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
|
|
|
|
+ cmd.W1 = 0
|
|
|
|
+ if self.manual_status == ManualOperationType.eLeftMove:
|
|
|
|
+ cmd.T1 = 2
|
|
|
|
+ cmd.V1 = speed_v * (step_sum-step_acc) / step_sum
|
|
|
|
+ cmd.W1 = 0
|
|
|
|
+ if self.manual_status == ManualOperationType.eRightMove:
|
|
|
|
+ cmd.T1 = 2
|
|
|
|
+ cmd.V1 = -speed_v * (step_sum-step_acc) / step_sum
|
|
|
|
+ cmd.W1 = 0
|
|
|
|
+ cmd.V2 = cmd.V1
|
|
|
|
+ cmd.V3 = cmd.V1
|
|
|
|
+ cmd.W2 = cmd.W1
|
|
|
|
+ cmd.W3 = cmd.W1
|
|
|
|
+ cmd.L1 = self.L_
|
|
|
|
+ cmd.end = 1
|
|
|
|
+
|
|
|
|
+ # 处理为json格式
|
|
|
|
+ cmd_dict = {}
|
|
|
|
+ for field in cmd.DESCRIPTOR.fields:
|
|
|
|
+ cmd_dict[field.name] = field.default_value
|
|
|
|
+ for field, value in cmd.ListFields():
|
|
|
|
+ cmd_dict[field.name] = value
|
|
|
|
+ cmd_json = json.dumps(cmd_dict, indent=None, separators=(',', ':'))
|
|
|
|
+ self.publish(self.speedCmdTopic, cmd_json)
|
|
|
|
+
|
|
|
|
+ print(cmd_json)
|
|
|
|
+ step_acc += 1
|
|
|
|
+ time.sleep(0.1)
|
|
|
|
+ self.manual_status = ManualOperationType.eReady
|
|
|
|
+ self.manual_speed = [0, 0]
|
|
|
|
+ print("Manual_Unit_SlowlyStop completed.")
|
|
|
|
+ return True
|
|
|
|
+
|
|
|
|
+ def GenerateActionMPC(self, beg_name, end_name, autoDirect, wheelbase=0, task_type="None"):
|
|
|
|
+ self.GeneratePath(beg_name, end_name, task_type=task_type)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|