assigner.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 #--------Include modules---------------
00004 from copy import copy
00005 import rospy
00006 from visualization_msgs.msg import Marker
00007 from geometry_msgs.msg import Point
00008 from nav_msgs.msg import OccupancyGrid
00009 import tf
00010 from rrt_exploration.msg import PointArray
00011 from time import time
00012 from numpy import array
00013 from numpy import linalg as LA
00014 from numpy import all as All
00015 from numpy import inf
00016 from functions import robot,informationGain,discount
00017 from numpy.linalg import norm
00018 
00019 # Subscribers' callbacks------------------------------
00020 mapData=OccupancyGrid()
00021 frontiers=[]
00022 global1=OccupancyGrid()
00023 global2=OccupancyGrid()
00024 global3=OccupancyGrid()
00025 globalmaps=[]
00026 def callBack(data):
00027         global frontiers
00028         frontiers=[]
00029         for point in data.points:
00030                 frontiers.append(array([point.x,point.y]))
00031 
00032 def mapCallBack(data):
00033     global mapData
00034     mapData=data
00035 # Node----------------------------------------------
00036 
00037 def node():
00038         global frontiers,mapData,global1,global2,global3,globalmaps
00039         rospy.init_node('assigner', anonymous=False)
00040         
00041         # fetching all parameters
00042         map_topic= rospy.get_param('~map_topic','/map')
00043         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
00044         info_multiplier=rospy.get_param('~info_multiplier',3.0)         
00045         hysteresis_radius=rospy.get_param('~hysteresis_radius',3.0)                     #at least as much as the laser scanner range
00046         hysteresis_gain=rospy.get_param('~hysteresis_gain',2.0)                         #bigger than 1 (biase robot to continue exploring current region
00047         frontiers_topic= rospy.get_param('~frontiers_topic','/filtered_points') 
00048         n_robots = rospy.get_param('~n_robots',1)
00049         namespace = rospy.get_param('~namespace','')
00050         namespace_init_count = rospy.get_param('namespace_init_count',1)
00051         delay_after_assignement=rospy.get_param('~delay_after_assignement',0.5)
00052         rateHz = rospy.get_param('~rate',100)
00053         
00054         rate = rospy.Rate(rateHz)
00055 #-------------------------------------------
00056         rospy.Subscriber(map_topic, OccupancyGrid, mapCallBack)
00057         rospy.Subscriber(frontiers_topic, PointArray, callBack)
00058 #---------------------------------------------------------------------------------------------------------------
00059                 
00060 # wait if no frontier is received yet 
00061         while len(frontiers)<1:
00062                 pass
00063         centroids=copy(frontiers)       
00064 #wait if map is not received yet
00065         while (len(mapData.data)<1):
00066                 pass
00067 
00068         robots=[]
00069         if len(namespace)>0:
00070                 for i in range(0,n_robots):
00071                         robots.append(robot(namespace+str(i+namespace_init_count)))
00072         elif len(namespace)==0:
00073                         robots.append(robot(namespace))
00074         for i in range(0,n_robots):
00075                 robots[i].sendGoal(robots[i].getPosition())
00076 #-------------------------------------------------------------------------
00077 #---------------------     Main   Loop     -------------------------------
00078 #-------------------------------------------------------------------------
00079         while not rospy.is_shutdown():
00080                 centroids=copy(frontiers)               
00081 #-------------------------------------------------------------------------                      
00082 #Get information gain for each frontier point
00083                 infoGain=[]
00084                 for ip in range(0,len(centroids)):
00085                         infoGain.append(informationGain(mapData,[centroids[ip][0],centroids[ip][1]],info_radius))
00086 #-------------------------------------------------------------------------                      
00087 #get number of available/busy robots
00088                 na=[] #available robots
00089                 nb=[] #busy robots
00090                 for i in range(0,n_robots):
00091                         if (robots[i].getState()==1):
00092                                 nb.append(i)
00093                         else:
00094                                 na.append(i)    
00095                 rospy.loginfo("available robots: "+str(na))     
00096 #------------------------------------------------------------------------- 
00097 #get dicount and update informationGain
00098                 for i in nb+na:
00099                         infoGain=discount(mapData,robots[i].assigned_point,centroids,infoGain,info_radius)
00100 #-------------------------------------------------------------------------            
00101                 revenue_record=[]
00102                 centroid_record=[]
00103                 id_record=[]
00104                 
00105                 for ir in na:
00106                         for ip in range(0,len(centroids)):
00107                                 cost=norm(robots[ir].getPosition()-centroids[ip])               
00108                                 threshold=1
00109                                 information_gain=infoGain[ip]
00110                                 if (norm(robots[ir].getPosition()-centroids[ip])<=hysteresis_radius):
00111 
00112                                         information_gain*=hysteresis_gain
00113                                 revenue=information_gain*info_multiplier-cost
00114                                 revenue_record.append(revenue)
00115                                 centroid_record.append(centroids[ip])
00116                                 id_record.append(ir)
00117                 
00118                 if len(na)<1:
00119                         revenue_record=[]
00120                         centroid_record=[]
00121                         id_record=[]
00122                         for ir in nb:
00123                                 for ip in range(0,len(centroids)):
00124                                         cost=norm(robots[ir].getPosition()-centroids[ip])               
00125                                         threshold=1
00126                                         information_gain=infoGain[ip]
00127                                         if (norm(robots[ir].getPosition()-centroids[ip])<=hysteresis_radius):
00128                                                 information_gain*=hysteresis_gain
00129                                 
00130                                         if ((norm(centroids[ip]-robots[ir].assigned_point))<hysteresis_radius):
00131                                                 information_gain=informationGain(mapData,[centroids[ip][0],centroids[ip][1]],info_radius)*hysteresis_gain
00132 
00133                                         revenue=information_gain*info_multiplier-cost
00134                                         revenue_record.append(revenue)
00135                                         centroid_record.append(centroids[ip])
00136                                         id_record.append(ir)
00137                 
00138                 rospy.loginfo("revenue record: "+str(revenue_record))   
00139                 rospy.loginfo("centroid record: "+str(centroid_record)) 
00140                 rospy.loginfo("robot IDs record: "+str(id_record))      
00141                 
00142 #-------------------------------------------------------------------------      
00143                 if (len(id_record)>0):
00144                         winner_id=revenue_record.index(max(revenue_record))
00145                         robots[id_record[winner_id]].sendGoal(centroid_record[winner_id])
00146                         rospy.loginfo(namespace+str(namespace_init_count+id_record[winner_id])+"  assigned to  "+str(centroid_record[winner_id]))       
00147                         rospy.sleep(delay_after_assignement)
00148 #------------------------------------------------------------------------- 
00149                 rate.sleep()
00150 #-------------------------------------------------------------------------
00151 
00152 if __name__ == '__main__':
00153     try:
00154         node()
00155     except rospy.ROSInterruptException:
00156         pass
00157  
00158  
00159  
00160  


rrt_exploration
Author(s): Hassan Umari
autogenerated on Thu Jun 6 2019 20:54:03