assigner.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #--------Include modules---------------
4 from copy import copy
5 import rospy
6 from visualization_msgs.msg import Marker
7 from geometry_msgs.msg import Point
8 from nav_msgs.msg import OccupancyGrid
9 import tf
10 from rrt_exploration.msg import PointArray
11 from time import time
12 from numpy import array
13 from numpy import linalg as LA
14 from numpy import all as All
15 from numpy import inf
16 from functions import robot,informationGain,discount
17 from numpy.linalg import norm
18 
19 # Subscribers' callbacks------------------------------
20 mapData=OccupancyGrid()
21 frontiers=[]
22 global1=OccupancyGrid()
23 global2=OccupancyGrid()
24 global3=OccupancyGrid()
25 globalmaps=[]
26 def callBack(data):
27  global frontiers
28  frontiers=[]
29  for point in data.points:
30  frontiers.append(array([point.x,point.y]))
31 
32 def mapCallBack(data):
33  global mapData
34  mapData=data
35 # Node----------------------------------------------
36 
37 def node():
38  global frontiers,mapData,global1,global2,global3,globalmaps
39  rospy.init_node('assigner', anonymous=False)
40 
41  # fetching all parameters
42  map_topic= rospy.get_param('~map_topic','/map')
43  info_radius= rospy.get_param('~info_radius',1.0) #this can be smaller than the laser scanner range, >> smaller >>less computation time>> too small is not good, info gain won't be accurate
44  info_multiplier=rospy.get_param('~info_multiplier',3.0)
45  hysteresis_radius=rospy.get_param('~hysteresis_radius',3.0) #at least as much as the laser scanner range
46  hysteresis_gain=rospy.get_param('~hysteresis_gain',2.0) #bigger than 1 (biase robot to continue exploring current region
47  frontiers_topic= rospy.get_param('~frontiers_topic','/filtered_points')
48  n_robots = rospy.get_param('~n_robots',1)
49  namespace = rospy.get_param('~namespace','')
50  namespace_init_count = rospy.get_param('namespace_init_count',1)
51  delay_after_assignement=rospy.get_param('~delay_after_assignement',0.5)
52  rateHz = rospy.get_param('~rate',100)
53 
54  rate = rospy.Rate(rateHz)
55 #-------------------------------------------
56  rospy.Subscriber(map_topic, OccupancyGrid, mapCallBack)
57  rospy.Subscriber(frontiers_topic, PointArray, callBack)
58 #---------------------------------------------------------------------------------------------------------------
59 
60 # wait if no frontier is received yet
61  while len(frontiers)<1:
62  pass
63  centroids=copy(frontiers)
64 #wait if map is not received yet
65  while (len(mapData.data)<1):
66  pass
67 
68  robots=[]
69  if len(namespace)>0:
70  for i in range(0,n_robots):
71  robots.append(robot(namespace+str(i+namespace_init_count)))
72  elif len(namespace)==0:
73  robots.append(robot(namespace))
74  for i in range(0,n_robots):
75  robots[i].sendGoal(robots[i].getPosition())
76 #-------------------------------------------------------------------------
77 #--------------------- Main Loop -------------------------------
78 #-------------------------------------------------------------------------
79  while not rospy.is_shutdown():
80  centroids=copy(frontiers)
81 #-------------------------------------------------------------------------
82 #Get information gain for each frontier point
83  infoGain=[]
84  for ip in range(0,len(centroids)):
85  infoGain.append(informationGain(mapData,[centroids[ip][0],centroids[ip][1]],info_radius))
86 #-------------------------------------------------------------------------
87 #get number of available/busy robots
88  na=[] #available robots
89  nb=[] #busy robots
90  for i in range(0,n_robots):
91  if (robots[i].getState()==1):
92  nb.append(i)
93  else:
94  na.append(i)
95  rospy.loginfo("available robots: "+str(na))
96 #-------------------------------------------------------------------------
97 #get dicount and update informationGain
98  for i in nb+na:
99  infoGain=discount(mapData,robots[i].assigned_point,centroids,infoGain,info_radius)
100 #-------------------------------------------------------------------------
101  revenue_record=[]
102  centroid_record=[]
103  id_record=[]
104 
105  for ir in na:
106  for ip in range(0,len(centroids)):
107  cost=norm(robots[ir].getPosition()-centroids[ip])
108  threshold=1
109  information_gain=infoGain[ip]
110  if (norm(robots[ir].getPosition()-centroids[ip])<=hysteresis_radius):
111 
112  information_gain*=hysteresis_gain
113  revenue=information_gain*info_multiplier-cost
114  revenue_record.append(revenue)
115  centroid_record.append(centroids[ip])
116  id_record.append(ir)
117 
118  if len(na)<1:
119  revenue_record=[]
120  centroid_record=[]
121  id_record=[]
122  for ir in nb:
123  for ip in range(0,len(centroids)):
124  cost=norm(robots[ir].getPosition()-centroids[ip])
125  threshold=1
126  information_gain=infoGain[ip]
127  if (norm(robots[ir].getPosition()-centroids[ip])<=hysteresis_radius):
128  information_gain*=hysteresis_gain
129 
130  if ((norm(centroids[ip]-robots[ir].assigned_point))<hysteresis_radius):
131  information_gain=informationGain(mapData,[centroids[ip][0],centroids[ip][1]],info_radius)*hysteresis_gain
132 
133  revenue=information_gain*info_multiplier-cost
134  revenue_record.append(revenue)
135  centroid_record.append(centroids[ip])
136  id_record.append(ir)
137 
138  rospy.loginfo("revenue record: "+str(revenue_record))
139  rospy.loginfo("centroid record: "+str(centroid_record))
140  rospy.loginfo("robot IDs record: "+str(id_record))
141 
142 #-------------------------------------------------------------------------
143  if (len(id_record)>0):
144  winner_id=revenue_record.index(max(revenue_record))
145  robots[id_record[winner_id]].sendGoal(centroid_record[winner_id])
146  rospy.loginfo(namespace+str(namespace_init_count+id_record[winner_id])+" assigned to "+str(centroid_record[winner_id]))
147  rospy.sleep(delay_after_assignement)
148 #-------------------------------------------------------------------------
149  rate.sleep()
150 #-------------------------------------------------------------------------
151 
152 if __name__ == '__main__':
153  try:
154  node()
155  except rospy.ROSInterruptException:
156  pass
157 
158 
159 
160 
def node()
Definition: assigner.py:37
def mapCallBack(data)
Definition: assigner.py:32
def discount(mapData, assigned_pt, centroids, infoGain, r)
Definition: functions.py:109
def informationGain(mapData, point, r)
Definition: functions.py:93
def callBack(data)
Definition: assigner.py:26


rrt_exploration
Author(s): Hassan Umari
autogenerated on Mon Jun 10 2019 14:57:44