4 Copyright (c) 2016, Borella Jocelyn, Karrenbauer Oliver, Meissner Pascal 7 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 import subprocess, os, signal
21 import xml.etree.cElementTree
as ET
27 from asr_robot_model_services.srv
import GetDistance, IsPositionAllowed
28 from geometry_msgs.msg
import Point
29 from std_msgs.msg
import ColorRGBA
30 from visualization_msgs.msg
import Marker, MarkerArray
36 rospy.init_node(
'grid_creator', anonymous=
True)
37 self.
Xmax = rospy.get_param(
"width")
38 self.
Ymax = rospy.get_param(
"height")
40 ExitPath = rospy.get_param(
"ExitXML")
42 StepSizeMin = rospy.get_param(
"StepSizeMin")
43 StepSizeMax = rospy.get_param(
"StepSizeMax")
44 StepSizeStep = rospy.get_param(
"StepSizeStep")
46 HtransMin = rospy.get_param(
"HtransMin")
47 HtransMax = rospy.get_param(
"HtransMax")
48 HtransStep = rospy.get_param(
"HtransStep")
50 VtransMin = rospy.get_param(
"VtransMin")
51 VtransMax = rospy.get_param(
"VtransMax")
52 VtransStep = rospy.get_param(
"VtransStep")
54 OffsetMin = rospy.get_param(
"OffsetMin")
55 OffsetMax = rospy.get_param(
"OffsetMax")
56 OffsetStep = rospy.get_param(
"OffsetStep")
60 bestMarkerArray = MarkerArray()
68 rospy.loginfo(
"begin of grid creations")
69 for currentStepSize
in self.
frange(StepSizeMin, StepSizeMax, StepSizeStep):
71 for currentHtrans
in self.
frange(HtransMin, HtransMax, HtransStep):
73 for currentVtrans
in self.
frange(VtransMin, VtransMax, VtransStep):
75 for currentOffset
in self.
frange(OffsetMin, OffsetMax, OffsetStep):
83 if len(self.
PoseListe) >= len(bestPoseListe):
93 rospy.loginfo(
"end of grid creations with number of best poses: " + str(len(bestPoseListe)))
95 rospy.loginfo(
"bestStepSize: " + str(bestStepSize))
96 rospy.loginfo(
"bestHtrans: " + str(bestHtrans))
97 rospy.loginfo(
"bestVtrans: " + str(bestVtrans))
98 rospy.loginfo(
"bestOffset: " + str(bestOffset))
109 if rospy.get_param(
"HamiltonCycle") ==
True:
116 root = ET.Element(
"Posen")
117 for elem
in orderedPoseListe:
118 ET.SubElement(root,
"Pose", X=str(elem.x), Y=str(elem.y), Z=
"0", QX=
"0", QY=
"0", QZ=
"0", QW=
"0")
119 tree = ET.ElementTree(root)
121 rospy.loginfo(
"config.xml created")
125 for child
in orderedPoseListe:
126 cpoints.append(Point(*[float(child.x),float(child.y),0]))
129 for point
in cpoints:
130 marker = self.
getMarker(point,bestK,
'GridPoints',0,0.7,1)
131 bestMarkerArray.markers.append(marker)
134 marker2 = self.
getMarker(point,bestK,
'NumPoints',1,0,0)
136 marker2.scale.z = 0.5
137 marker2.text = str(text)
138 bestMarkerArray.markers.append(marker2)
144 for j
in range(len(cpoints)-1):
146 points.append(Point(*[float(cpoints[j].x),float(cpoints[j].y),0]))
147 points.append(Point(*[float(cpoints[j+1].x),float(cpoints[j+1].y),0]))
149 bestMarkerArray.markers.append(marker)
153 pub = rospy.Publisher(
'direct_search/grid_visualization', MarkerArray, queue_size=100)
154 rate = rospy.Rate(10)
156 while not rospy.is_shutdown():
157 pub.publish(bestMarkerArray)
172 self.PoseListe.append(TempPose)
175 marker = self.
getMarker(TempPose,self.
k,
'UnreachablePoints',1,0.5,0)
176 self.markerArray.markers.append(marker)
181 marker = self.
drawQuad(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"QuadDrawReach")
183 markerColor = self.
colorQuad(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"ColorQuadReach")
184 self.markerArray.markers.append(markerColor)
186 marker = self.
drawQuad(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"QuadDrawUnreach")
189 markerColor = self.
colorQuad(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"ColorQuadUnreach")
190 self.markerArray.markers.append(markerColor)
192 self.markerArray.markers.append(marker)
208 self.PoseListe.append(TempPose)
211 marker = self.
getMarker(TempPose,self.
k,
'UnreachablePoints',1,0.5,0)
212 self.markerArray.markers.append(marker)
217 marker = self.
drawHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"HexDrawReach")
219 markerColor = self.
colorHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"ColorHexReach")
220 self.markerArray.markers.append(markerColor)
222 marker = self.
drawHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"HexDrawUnreach")
225 markerColor = self.
colorHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"ColorHexUnreach")
226 self.markerArray.markers.append(markerColor)
227 self.markerArray.markers.append(marker)
240 self.PoseListe.append(TempPose)
243 marker = self.
getMarker(TempPose,self.
k,
'UnreachablePoints',1,0.5,0)
244 self.markerArray.markers.append(marker)
249 marker = self.
drawHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"HexDrawReach")
251 markerColor = self.
colorHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,0,0,1,self.
k,
"ColorHexReach")
252 self.markerArray.markers.append(markerColor)
254 marker = self.
drawHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"HexDrawUnreach")
257 markerColor = self.
colorHexagon(i,j,self.
Offset,self.
Htrans,self.
Vtrans,self.
StepSize,1,0,0,self.
k,
"ColorHexUnreach")
258 self.markerArray.markers.append(markerColor)
259 self.markerArray.markers.append(marker)
275 returns if robotPosition is allowed using the appropriate service call 277 rospy.wait_for_service(
'/asr_robot_model_services/IsPositionAllowed')
279 isReachableHandler = rospy.ServiceProxy(
'/asr_robot_model_services/IsPositionAllowed', IsPositionAllowed)
280 ret = isReachableHandler(robotPosition)
282 except rospy.ServiceException, e:
283 print "Service call failed: %s"%e
288 returns the distance between two points using the appropriate service call 290 rospy.wait_for_service(
'/asr_robot_model_services/GetDistance')
292 GetDistanceHandler = rospy.ServiceProxy(
'/asr_robot_model_services/GetDistance', GetDistance)
293 ret = GetDistanceHandler(x, y)
295 except rospy.ServiceException, e:
296 print "Service call failed: %s"%e
300 returns a sphere marker 302 color = ColorRGBA(*[r,g,b,1])
304 marker.header.frame_id =
"map" 305 marker.header.stamp = rospy.get_rostime()
310 marker.pose.position = pose
319 returns a line marker 322 color = ColorRGBA(*[r,g,b,1])
323 marker.header.frame_id =
"map" 324 marker.header.stamp = rospy.get_rostime()
329 marker.points = points
330 marker.pose.position = Point(*[0,0,0])
331 marker.pose.orientation.w = 1.0
332 marker.scale.x = 0.05
338 returns an arrow marker 341 color = ColorRGBA(*[r,g,b,1])
342 marker.header.frame_id =
"map" 343 marker.header.stamp = rospy.get_rostime()
349 marker.pose.orientation.w = 1.0
350 marker.scale.x = 0.05
358 returns a transformed point using Offset rotation and (Htrans,Vtrans) translation 361 ret.x = float(point.x)*math.cos(Offset) - math.sin(Offset)*float(point.y) + Htrans
362 ret.y = float(point.x)*math.sin(Offset) + math.cos(Offset)*float(point.y) + Vtrans
366 def drawHexagon(self, i,j,Offset,Htrans,Vtrans,StepSize,r,g,b,k,ns):
368 returns a list of line marker to draw the Hexagonal grid 371 xplus = float(i)+StepSize*math.sqrt(3.0)/2
372 xminus = float(i)-StepSize*math.sqrt(3.0)/2
373 yplus = float(j)+float((StepSize/2.0))
374 yminus = float(j)-float((StepSize/2.0))
375 ypp = float(j)+float(StepSize)
376 ymm = float(j)-float(StepSize)
377 points.append(self.
transformPoint(Point(*[i,ypp,0]),Offset,Htrans,Vtrans))
378 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
379 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
380 points.append(self.
transformPoint(Point(*[i,ymm,0]),Offset,Htrans,Vtrans))
381 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
382 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
383 points.append(self.
transformPoint(Point(*[i,ypp,0]),Offset,Htrans,Vtrans))
386 def colorHexagon(self, i,j,Offset,Htrans,Vtrans,StepSize,r,g,b,k,ns):
388 returns a list of triangle marker to color the Hexagonal grid 391 xplus = float(i)+StepSize*math.sqrt(3.0)/2
392 xminus = float(i)-StepSize*math.sqrt(3.0)/2
393 yplus = float(j)+float((StepSize/2.0))
394 yminus = float(j)-float((StepSize/2.0))
395 ypp = float(j)+float(StepSize)
396 ymm = float(j)-float(StepSize)
400 points.append(self.
transformPoint(Point(*[i,ypp,0]),Offset,Htrans,Vtrans))
401 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
402 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
404 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
405 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
406 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
408 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
409 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
410 points.append(self.
transformPoint(Point(*[i,ymm,0]),Offset,Htrans,Vtrans))
412 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
413 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
414 points.append(self.
transformPoint(Point(*[i,ymm,0]),Offset,Htrans,Vtrans))
416 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
417 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
418 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
420 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
421 points.append(self.
transformPoint(Point(*[i,ypp,0]),Offset,Htrans,Vtrans))
422 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
425 color = ColorRGBA(*[r,g,b,1])
426 colorM = ColorRGBA(*[r,g,b,0.5])
427 marker.header.frame_id =
"map" 428 marker.header.stamp = rospy.get_rostime()
434 marker.pose.orientation.w = 1.0
440 marker.colors.append(colorM)
443 def drawQuad(self, i,j,Offset,Htrans,Vtrans,StepSize,r,g,b,k,ns):
445 returns a list of line marker to draw the quad grid 448 xplus = float(i)+float((StepSize/2.0))
449 xminus = float(i)-float((StepSize/2.0))
450 yplus = float(j)+float((StepSize/2.0))
451 yminus = float(j)-float((StepSize/2.0))
452 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
453 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
454 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
455 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
456 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
459 def colorQuad(self, i,j,Offset,Htrans,Vtrans,StepSize,r,g,b,k,ns):
461 returns a list of triangle marker to color the quad grid 464 xplus = float(i)+float((StepSize/2.0))
465 xminus = float(i)-float((StepSize/2.0))
466 yplus = float(j)+float((StepSize/2.0))
467 yminus = float(j)-float((StepSize/2.0))
471 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
472 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
473 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
475 points.append(self.
transformPoint(Point(*[xplus,yplus,0]),Offset,Htrans,Vtrans))
476 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
477 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
479 points.append(self.
transformPoint(Point(*[xplus,yminus,0]),Offset,Htrans,Vtrans))
480 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
481 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
483 points.append(self.
transformPoint(Point(*[xminus,yminus,0]),Offset,Htrans,Vtrans))
484 points.append(self.
transformPoint(Point(*[xminus,yplus,0]),Offset,Htrans,Vtrans))
485 points.append(self.
transformPoint(Point(*[i,j,0]),Offset,Htrans,Vtrans))
488 color = ColorRGBA(*[r,g,b,0.5])
489 colorM = ColorRGBA(*[r,g,b,0.5])
490 marker.header.frame_id =
"map" 491 marker.header.stamp = rospy.get_rostime()
497 marker.pose.orientation.w = 1.0
503 marker.colors.append(colorM)
508 returns an optimised list from an orderedpose using the 2-opt algo with creating a Hamilton cycle 511 while improve ==
True:
513 for i
in range(len(orderedPoseListe)):
514 for j
in range(i+2,len(orderedPoseListe)):
515 if i==len(orderedPoseListe)-1:
516 if self.
calcDist(orderedPoseListe[i],orderedPoseListe[0])+self.
calcDist(orderedPoseListe[j],orderedPoseListe[j+1]) > self.
calcDist(orderedPoseListe[i],orderedPoseListe[j])+self.
calcDist(orderedPoseListe[0],orderedPoseListe[j+1]):
517 orderedPoseListe[0], orderedPoseListe[j] = orderedPoseListe[j] , orderedPoseListe[0]
519 elif j==len(orderedPoseListe)-1:
520 if self.
calcDist(orderedPoseListe[i],orderedPoseListe[i+1])+self.
calcDist(orderedPoseListe[j],orderedPoseListe[0]) > self.
calcDist(orderedPoseListe[i],orderedPoseListe[j])+self.
calcDist(orderedPoseListe[i+1],orderedPoseListe[0]):
521 orderedPoseListe[i+1], orderedPoseListe[j] = orderedPoseListe[j] , orderedPoseListe[i+1]
524 if self.
calcDist(orderedPoseListe[i],orderedPoseListe[i+1])+self.
calcDist(orderedPoseListe[j],orderedPoseListe[j+1]) > self.
calcDist(orderedPoseListe[i],orderedPoseListe[j])+self.
calcDist(orderedPoseListe[i+1],orderedPoseListe[j+1]):
525 orderedPoseListe[i+1], orderedPoseListe[j] = orderedPoseListe[j] , orderedPoseListe[i+1]
527 return orderedPoseListe
531 returns an optimised list from an orderedpose using the 2-opt algo without creating a Hamilton cycle 534 while improve ==
True:
536 for i
in range(len(orderedPoseListe)-1):
537 for j
in range(i+2,len(orderedPoseListe)-1):
538 if self.
calcDist(orderedPoseListe[i],orderedPoseListe[i+1])+self.
calcDist(orderedPoseListe[j],orderedPoseListe[j+1]) > self.
calcDist(orderedPoseListe[i],orderedPoseListe[j])+self.
calcDist(orderedPoseListe[i+1],orderedPoseListe[j+1]):
539 orderedPoseListe[i+1], orderedPoseListe[j] = orderedPoseListe[j] , orderedPoseListe[i+1]
541 return orderedPoseListe
545 returns an ordered list from pose using the nearest neighbout algo 547 orderedPoseListe = []
549 startX = rospy.get_param(
"startX")
550 startY = rospy.get_param(
"startY")
551 for pose
in PoseListe:
552 if(math.sqrt(math.pow((startX-pose.x),2)+math.pow((startY-pose.y),2)) < distance):
553 distance = math.sqrt(math.pow((startX-pose.x),2)+math.pow((startY-pose.y),2))
554 if len(orderedPoseListe)>0:
555 del orderedPoseListe[0]
556 orderedPoseListe.append(pose)
557 for idx,pose
in enumerate(PoseListe):
558 if pose == orderedPoseListe[0]:
561 while len(PoseListe)>0:
562 distance = float(10000.0)
564 for index
in range(len(PoseListe)):
565 dist = self.
calcDist(orderedPoseListe[-1],PoseListe[index])
569 orderedPoseListe.append(PoseListe[ref])
571 return orderedPoseListe
574 if __name__ ==
"__main__":
def two_opt_with_cycle(self, orderedPoseListe)
def two_opt_without_cycle(self, orderedPoseListe)
def drawQuad(self, i, j, Offset, Htrans, Vtrans, StepSize, r, g, b, k, ns)
def transformPoint(self, point, Offset, Htrans, Vtrans)
def colorQuad(self, i, j, Offset, Htrans, Vtrans, StepSize, r, g, b, k, ns)
def nearest_neighbour(self, PoseListe)
def drawHexagon(self, i, j, Offset, Htrans, Vtrans, StepSize, r, g, b, k, ns)
def getMarker(self, pose, k, n_s, r, g, b)
def getMarkerLine(self, points, k, n_s, r, g, b)
def getMarkerArrow(self, points, k, n_s, r, g, b)
def frange(self, start, stop, step)
def isRobotPositionAllowed(self, robotPosition)
def colorHexagon(self, i, j, Offset, Htrans, Vtrans, StepSize, r, g, b, k, ns)