|
@@ -1,145 +1,206 @@
|
|
|
-
|
|
|
import math
|
|
|
import random
|
|
|
import time
|
|
|
from PyGLWidget import PyGLWidget
|
|
|
from OpenGL.GL import *
|
|
|
-
|
|
|
+import RobotData as RD
|
|
|
import message_pb2 as message
|
|
|
-class TimeStatu:
|
|
|
- def __init__(self,statu=None,timeout=3):
|
|
|
- self.statu=statu
|
|
|
- self.time=time.time()
|
|
|
- self.timeout_ms=timeout
|
|
|
-
|
|
|
- def timeout(self):
|
|
|
- tm=time.time()
|
|
|
- return tm-self.time>self.timeout_ms or self.statu==None
|
|
|
+
|
|
|
+
|
|
|
class MapGLWidget(PyGLWidget):
|
|
|
|
|
|
- colors={"agv1":[1,0,0],
|
|
|
- "agv2":[0,1,0],
|
|
|
- "agv":[0,1,1]
|
|
|
- }
|
|
|
-
|
|
|
- nodes={}
|
|
|
- roads={}
|
|
|
- paths={}
|
|
|
- timedAgv1=TimeStatu(None,0.5)
|
|
|
- timedAgv2=TimeStatu(None,0.5)
|
|
|
- def ResetAgv1(self,statu):
|
|
|
- self.timedAgv1=TimeStatu(statu,0.5)
|
|
|
- self.update()
|
|
|
- def ResetAgv2(self,statu):
|
|
|
- self.timedAgv2=TimeStatu(statu,0.5)
|
|
|
- self.update()
|
|
|
- def AddNode(self,node):
|
|
|
- [id,type,point]=node
|
|
|
- self.nodes[id]=[type,point]
|
|
|
- def AddRoad(self,road):
|
|
|
- [key,value]=road
|
|
|
- self.roads[key]=value
|
|
|
-
|
|
|
- def AddTraj(self,name,path):
|
|
|
- self.paths[name]=path
|
|
|
-
|
|
|
-
|
|
|
- def drawPath(self,poses,width,color):
|
|
|
- glColor3f(color[0],color[1],color[2])
|
|
|
+ nodes = {}
|
|
|
+ roads = {}
|
|
|
+
|
|
|
+ robot1_ = None
|
|
|
+ robot2_ = None
|
|
|
+ robotMain_ = None
|
|
|
+ def SetRobot1Instance(self, robot):
|
|
|
+ self.robot1_ = robot
|
|
|
+ def SetRobot2Instance(self, robot):
|
|
|
+ self.robot2_ = robot
|
|
|
+
|
|
|
+ def SetRobotMainInstance(self, robot):
|
|
|
+ self.robotMain_ = robot
|
|
|
+
|
|
|
+ def AddNode(self, node):
|
|
|
+ [id, type, point] = node
|
|
|
+ self.nodes[id] = [type, point]
|
|
|
+
|
|
|
+ def AddRoad(self, road):
|
|
|
+ [key, value] = road
|
|
|
+ self.roads[key] = value
|
|
|
+
|
|
|
+ def drawTraj(self, poses, width, color):
|
|
|
+ glColor3f(color[0], color[1], color[2])
|
|
|
glLineWidth(2)
|
|
|
glBegin(GL_LINES)
|
|
|
for pose in poses:
|
|
|
- [x,y,yaw]=pose
|
|
|
- point1=[x,y]
|
|
|
+ [x, y, yaw] = pose
|
|
|
+ point1 = [x, y]
|
|
|
|
|
|
- [dx,dy]=self.RotatePoint([-width/2,-width/2],yaw)
|
|
|
- point2=[x+dx,y+dy]
|
|
|
+ [dx, dy] = self.RotatePoint([-width / 2, -width / 2], yaw)
|
|
|
+ point2 = [x + dx, y + dy]
|
|
|
|
|
|
- [dx,dy]=self.RotatePoint([-width/2,width/2],yaw)
|
|
|
- point3=[x+dx,y+dy]
|
|
|
+ [dx, dy] = self.RotatePoint([-width / 2, width / 2], yaw)
|
|
|
+ point3 = [x + dx, y + dy]
|
|
|
|
|
|
- glVertex2d(point1[0],point1[1])
|
|
|
- glVertex2d(point3[0],point3[1])
|
|
|
+ glVertex2d(point1[0], point1[1])
|
|
|
+ glVertex2d(point3[0], point3[1])
|
|
|
|
|
|
- glVertex2d(point1[0],point1[1])
|
|
|
- glVertex2d(point2[0],point2[1])
|
|
|
+ glVertex2d(point1[0], point1[1])
|
|
|
+ glVertex2d(point2[0], point2[1])
|
|
|
glEnd()
|
|
|
|
|
|
- def drawEdge(self,pt1,pt2,width,color):
|
|
|
+ def drawTrajWithPoint(self, poses, ptsize, color):
|
|
|
+ glPointSize(ptsize)
|
|
|
+ glDepthMask(GL_FALSE)
|
|
|
+ glBegin(GL_POINTS)
|
|
|
+ glColor3f(color[0], color[1], color[2])
|
|
|
+ for pt in poses:
|
|
|
+ [x, y, _] = pt
|
|
|
+ glVertex2d(x, y)
|
|
|
+ glEnd()
|
|
|
|
|
|
- glColor4f(color[0],color[1],color[2],0)
|
|
|
+ def drawEdge(self, pt1, pt2, width, color):
|
|
|
+
|
|
|
+ glColor4f(color[0], color[1], color[2], 0)
|
|
|
glLineWidth(width)
|
|
|
glBegin(GL_LINES)
|
|
|
- glVertex2d(pt1[0],pt1[1])
|
|
|
- glVertex2d(pt2[0],pt2[1])
|
|
|
+ glVertex2d(pt1[0], pt1[1])
|
|
|
+ glVertex2d(pt2[0], pt2[1])
|
|
|
glEnd()
|
|
|
|
|
|
@staticmethod
|
|
|
- def RotatePoint(point,yaw):
|
|
|
+ def RotatePoint(point, yaw):
|
|
|
+ [x, y] = point
|
|
|
+ nx = math.cos(yaw) * x - y * math.sin(yaw)
|
|
|
+ ny = x * math.sin(yaw) + y * math.cos(yaw)
|
|
|
+ return [nx, ny]
|
|
|
+ def Transform(self,point,yaw,dt):
|
|
|
[x,y]=point
|
|
|
- nx=math.cos(yaw)*x-y*math.sin(yaw)
|
|
|
- ny=x*math.sin(yaw)+y*math.cos(yaw)
|
|
|
- return [nx,ny]
|
|
|
- def drawAxis(self,pose,len,width):
|
|
|
- [x,y,yaw]=pose
|
|
|
- x_source=[x+len*math.cos(yaw),y+math.sin(yaw)*len]
|
|
|
- y_source=[x-math.sin(yaw)*len,y+len*math.cos(yaw)]
|
|
|
+ [dx,dy]=dt
|
|
|
+ nx = math.cos(yaw) * x - y * math.sin(yaw)+dx
|
|
|
+ ny = x * math.sin(yaw) + y * math.cos(yaw)+dy
|
|
|
+ return [nx, ny]
|
|
|
+
|
|
|
+ def drawAxis(self, pose, len, width):
|
|
|
+ [x, y, yaw] = pose
|
|
|
+ x_source = [x + len * math.cos(yaw), y + math.sin(yaw) * len]
|
|
|
+ y_source = [x - math.sin(yaw) * len, y + len * math.cos(yaw)]
|
|
|
|
|
|
glDepthMask(GL_FALSE)
|
|
|
- glColor3f(1,0,0)
|
|
|
+ glColor3f(1, 0, 0)
|
|
|
|
|
|
glLineWidth(width)
|
|
|
glBegin(GL_LINES)
|
|
|
- glVertex2d(x,y)
|
|
|
- glVertex2d(x_source[0],x_source[1])
|
|
|
+ glVertex2d(x, y)
|
|
|
+ glVertex2d(x_source[0], x_source[1])
|
|
|
glEnd()
|
|
|
|
|
|
- glColor3f(0,1,0)
|
|
|
+ glColor3f(0, 1, 0)
|
|
|
glBegin(GL_LINES)
|
|
|
- glVertex2d(x,y)
|
|
|
- glVertex2d(y_source[0],y_source[1])
|
|
|
+ glVertex2d(x, y)
|
|
|
+ glVertex2d(y_source[0], y_source[1])
|
|
|
glEnd()
|
|
|
- def drawNode(self,node,size,color):
|
|
|
- [x,y]=node
|
|
|
+ def DrawAGV(self,pose,rgb):
|
|
|
+ [x,y,yaw]=pose
|
|
|
+ l=0.8 #轮长
|
|
|
+ L=1.3 #轴距
|
|
|
+ W=2.5 #宽
|
|
|
+ pt1=self.Transform([-(L+l)/2,W/2],yaw,[x,y])
|
|
|
+ pt2=self.Transform([-(L-l)/2,W/2],yaw,[x,y])
|
|
|
+ pt3=self.Transform([(L-l)/2,W/2],yaw,[x,y])
|
|
|
+ pt4=self.Transform([(L+l)/2,W/2],yaw,[x,y])
|
|
|
+
|
|
|
+ pt5=self.Transform([-(L+l)/2,-W/2],yaw,[x,y])
|
|
|
+ pt6=self.Transform([-(L-l)/2,-W/2],yaw,[x,y])
|
|
|
+ pt7=self.Transform([(L-l)/2,-W/2],yaw,[x,y])
|
|
|
+ pt8=self.Transform([(L+l)/2,-W/2],yaw,[x,y])
|
|
|
+
|
|
|
+ glDepthMask(GL_FALSE)
|
|
|
+ glColor3f(rgb[0],rgb[1],rgb[2])
|
|
|
+
|
|
|
+ glLineWidth(20)
|
|
|
+ glBegin(GL_LINES)
|
|
|
+ glVertex2d(pt1[0],pt1[1])
|
|
|
+ glVertex2d(pt2[0],pt2[1])
|
|
|
+ glVertex2d(pt3[0],pt3[1])
|
|
|
+ glVertex2d(pt4[0],pt4[1])
|
|
|
+ glVertex2d(pt5[0],pt5[1])
|
|
|
+ glVertex2d(pt6[0],pt6[1])
|
|
|
+ glVertex2d(pt7[0],pt7[1])
|
|
|
+ glVertex2d(pt8[0],pt8[1])
|
|
|
+ glEnd()
|
|
|
+
|
|
|
+ glLineWidth(5)
|
|
|
+ glBegin(GL_LINES)
|
|
|
+ glVertex2d(pt2[0],pt2[1])
|
|
|
+ glVertex2d(pt6[0],pt6[1])
|
|
|
+ glVertex2d(pt3[0],pt3[1])
|
|
|
+ glVertex2d(pt7[0],pt7[1])
|
|
|
+
|
|
|
+ glVertex2d(pt2[0],pt2[1])
|
|
|
+ glVertex2d(pt3[0],pt3[1])
|
|
|
+ glVertex2d(pt6[0],pt6[1])
|
|
|
+ glVertex2d(pt7[0],pt7[1])
|
|
|
+ glEnd()
|
|
|
+ #绘制方向
|
|
|
+ self.drawAxis(pose,1,5)
|
|
|
+
|
|
|
+ def drawNode(self, node, size, color):
|
|
|
+ [x, y] = node
|
|
|
glPointSize(size)
|
|
|
glDepthMask(GL_FALSE)
|
|
|
glBegin(GL_POINTS)
|
|
|
- glColor4f(color[0],color[1],color[2],0.5)
|
|
|
- glVertex2d(x,y)
|
|
|
+ glColor4f(color[0], color[1], color[2], 0.5)
|
|
|
+ glVertex2d(x, y)
|
|
|
glEnd()
|
|
|
'''glColor3f(1,1,1);
|
|
|
#glBegin(GL_TEXTURE)
|
|
|
glText'''
|
|
|
-
|
|
|
+ def DrawRobotData(self,robot):
|
|
|
+ if robot is not None:
|
|
|
+ if robot.currentNavPath_ is not None:
|
|
|
+ for traj in robot.currentNavPath_:
|
|
|
+ self.drawTraj(traj, 0.5, robot.pathColor_)
|
|
|
+
|
|
|
+ # 绘制agv
|
|
|
+ if robot is not None:
|
|
|
+ if robot.timedPose_.timeout() == False:
|
|
|
+ agv_statu = robot.timedPose_.statu
|
|
|
+ x = agv_statu.x
|
|
|
+ y = agv_statu.y
|
|
|
+ theta = agv_statu.theta
|
|
|
+ self.DrawAGV([x, y, theta], robot.robotColor_)
|
|
|
+
|
|
|
+ if robot.timedNavStatu_.timeout() == False:
|
|
|
+ select_traj = robot.MpcSelectTraj()
|
|
|
+ predict_traj = robot.MpcPredictTraj()
|
|
|
+ self.drawTrajWithPoint(select_traj, 8, [1, 0, 1])
|
|
|
+ self.drawTrajWithPoint(predict_traj, 10, [0, 1, 1])
|
|
|
def paintGL(self):
|
|
|
PyGLWidget.paintGL(self)
|
|
|
+ self.drawAxis([0, 0, 0], 5, 5)
|
|
|
|
|
|
- self.drawAxis([0,0,0],5,5)
|
|
|
+ #绘制地图
|
|
|
for node in self.nodes.items():
|
|
|
- [_,[type,point]]=node
|
|
|
- if type=="street_node":
|
|
|
- self.drawNode(point,8,[0,0,1])
|
|
|
- if type=="space_node":
|
|
|
- self.drawNode(point,8,[1,1,0])
|
|
|
+ [_, [type, point]] = node
|
|
|
+ if type == "street_node":
|
|
|
+ self.drawNode(point, 8, [0, 0, 1])
|
|
|
+ if type == "space_node":
|
|
|
+ self.drawNode(point, 8, [1, 1, 0])
|
|
|
for road in self.roads.items():
|
|
|
- [_,value]=road
|
|
|
+ [_, value] = road
|
|
|
for nodeId in value:
|
|
|
for nextId in value:
|
|
|
- if not nodeId==nextId:
|
|
|
- [_,point1]=self.nodes[nodeId]
|
|
|
- [_,point2]=self.nodes[nextId]
|
|
|
- self.drawEdge(point1,point2,3.,[0,0.5,0.5])
|
|
|
-
|
|
|
- for [id,path] in self.paths.items():
|
|
|
-
|
|
|
- rgb=self.colors.get(id)
|
|
|
- if rgb is not None:
|
|
|
- for traj in path:
|
|
|
- self.drawPath(traj,0.5,rgb)
|
|
|
-
|
|
|
- #绘制agv
|
|
|
- if self.timedAgv1.timeout()==False:
|
|
|
- x=self.timedAgv1.statu.x
|
|
|
- y=self.timedAgv1.statu.y
|
|
|
- theta=self.timedAgv1.statu.theta
|
|
|
- self.drawAxis([x,y,theta],3,5)
|
|
|
+ if not nodeId == nextId:
|
|
|
+ [_, point1] = self.nodes[nodeId]
|
|
|
+ [_, point2] = self.nodes[nextId]
|
|
|
+ self.drawEdge(point1, point2, 3., [0, 0.5, 0.5])
|
|
|
+
|
|
|
+ #绘制agv相关数据,路径、轨迹、位姿
|
|
|
+ self.DrawRobotData(self.robot1_)
|
|
|
+ self.DrawRobotData(self.robot2_)
|
|
|
+ self.DrawRobotData(self.robotMain_)
|
|
|
+
|