filter.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 from geometry_msgs.msg import PointStamped 
00010 import tf
00011 from numpy import array,vstack,delete
00012 from functions import gridValue,informationGain
00013 from sklearn.cluster import MeanShift
00014 from rrt_exploration.msg import PointArray
00015 
00016 # Subscribers' callbacks------------------------------
00017 mapData=OccupancyGrid()
00018 frontiers=[]
00019 globalmaps=[]
00020 def callBack(data,args):
00021         global frontiers,min_distance
00022         transformedPoint=args[0].transformPoint(args[1],data)
00023         x=[array([transformedPoint.point.x,transformedPoint.point.y])]
00024         if len(frontiers)>0:
00025                 frontiers=vstack((frontiers,x))
00026         else:
00027                 frontiers=x
00028     
00029 
00030 def mapCallBack(data):
00031     global mapData
00032     mapData=data
00033 
00034 def globalMap(data):
00035         global global1,globalmaps,litraIndx,namespace_init_count,n_robots
00036         global1=data
00037         if n_robots>1:
00038                 indx=int(data._connection_header['topic'][litraIndx])-namespace_init_count
00039         elif n_robots==1:
00040                 indx=0
00041         globalmaps[indx]=data
00042 
00043 # Node----------------------------------------------
00044 def node():
00045         global frontiers,mapData,global1,global2,global3,globalmaps,litraIndx,n_robots,namespace_init_count
00046         rospy.init_node('filter', anonymous=False)
00047         
00048         # fetching all parameters
00049         map_topic= rospy.get_param('~map_topic','/map')
00050         threshold= rospy.get_param('~costmap_clearing_threshold',70)
00051         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
00052         goals_topic= rospy.get_param('~goals_topic','/detected_points') 
00053         n_robots = rospy.get_param('~n_robots',1)
00054         namespace = rospy.get_param('~namespace','')
00055         namespace_init_count = rospy.get_param('namespace_init_count',1)
00056         rateHz = rospy.get_param('~rate',100)
00057         litraIndx=len(namespace)
00058         rate = rospy.Rate(rateHz)
00059 #-------------------------------------------
00060         rospy.Subscriber(map_topic, OccupancyGrid, mapCallBack)
00061         
00062 
00063 #---------------------------------------------------------------------------------------------------------------
00064         
00065 
00066         for i in range(0,n_robots):
00067                  globalmaps.append(OccupancyGrid()) 
00068         
00069         if len(namespace) > 0:   
00070                 for i in range(0,n_robots):
00071                         rospy.Subscriber(namespace+str(i+namespace_init_count)+'/move_base_node/global_costmap/costmap', OccupancyGrid, globalMap) 
00072         elif len(namespace)==0:
00073                         rospy.Subscriber('/move_base_node/global_costmap/costmap', OccupancyGrid, globalMap)    
00074 #wait if map is not received yet
00075         while (len(mapData.data)<1):
00076                 pass
00077 #wait if any of robots' global costmap map is not received yet
00078         for i in range(0,n_robots):
00079                  while (len(globalmaps[i].data)<1):
00080                         pass
00081         
00082         global_frame="/"+mapData.header.frame_id
00083 
00084 
00085         tfLisn=tf.TransformListener()
00086         if len(namespace) > 0:
00087                 for i in range(0,n_robots):
00088                         tfLisn.waitForTransform(global_frame[1:], namespace+str(i+namespace_init_count)+'/base_link', rospy.Time(0),rospy.Duration(10.0))
00089         elif len(namespace)==0:
00090                         tfLisn.waitForTransform(global_frame[1:], '/base_link', rospy.Time(0),rospy.Duration(10.0))
00091         
00092         rospy.Subscriber(goals_topic, PointStamped, callback=callBack,callback_args=[tfLisn,global_frame[1:]])
00093         pub = rospy.Publisher('frontiers', Marker, queue_size=10)
00094         pub2 = rospy.Publisher('centroids', Marker, queue_size=10)
00095         filterpub = rospy.Publisher('filtered_points', PointArray, queue_size=10)
00096 
00097         rospy.loginfo("the map and global costmaps are received")
00098         
00099         
00100         # wait if no frontier is received yet 
00101         while len(frontiers)<1:
00102                 pass
00103         
00104         
00105         points=Marker()
00106         points_clust=Marker()
00107 #Set the frame ID and timestamp.  See the TF tutorials for information on these.
00108         points.header.frame_id= mapData.header.frame_id
00109         points.header.stamp= rospy.Time.now()
00110 
00111         points.ns= "markers2"
00112         points.id = 0
00113         
00114         points.type = Marker.POINTS
00115         
00116 #Set the marker action for latched frontiers.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
00117         points.action = Marker.ADD;
00118 
00119         points.pose.orientation.w = 1.0
00120 
00121         points.scale.x=0.2
00122         points.scale.y=0.2 
00123 
00124         points.color.r = 255.0/255.0
00125         points.color.g = 255.0/255.0
00126         points.color.b = 0.0/255.0
00127 
00128         points.color.a=1;
00129         points.lifetime = rospy.Duration();
00130 
00131         p=Point()
00132 
00133         p.z = 0;
00134 
00135         pp=[]
00136         pl=[]
00137         
00138         points_clust.header.frame_id= mapData.header.frame_id
00139         points_clust.header.stamp= rospy.Time.now()
00140 
00141         points_clust.ns= "markers3"
00142         points_clust.id = 4
00143 
00144         points_clust.type = Marker.POINTS
00145 
00146 #Set the marker action for centroids.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
00147         points_clust.action = Marker.ADD;
00148 
00149         points_clust.pose.orientation.w = 1.0;
00150 
00151         points_clust.scale.x=0.2;
00152         points_clust.scale.y=0.2; 
00153         points_clust.color.r = 0.0/255.0
00154         points_clust.color.g = 255.0/255.0
00155         points_clust.color.b = 0.0/255.0
00156 
00157         points_clust.color.a=1;
00158         points_clust.lifetime = rospy.Duration();
00159 
00160                 
00161         temppoint=PointStamped()
00162         temppoint.header.frame_id= mapData.header.frame_id
00163         temppoint.header.stamp=rospy.Time(0)
00164         temppoint.point.z=0.0
00165         
00166         arraypoints=PointArray()
00167         tempPoint=Point()
00168         tempPoint.z=0.0
00169 #-------------------------------------------------------------------------
00170 #---------------------     Main   Loop     -------------------------------
00171 #-------------------------------------------------------------------------
00172         while not rospy.is_shutdown():
00173 #-------------------------------------------------------------------------      
00174 #Clustering frontier points
00175                 centroids=[]
00176                 front=copy(frontiers)
00177                 if len(front)>1:
00178                         ms = MeanShift(bandwidth=0.3)   
00179                         ms.fit(front)
00180                         centroids= ms.cluster_centers_   #centroids array is the centers of each cluster                
00181 
00182                 #if there is only one frontier no need for clustering, i.e. centroids=frontiers
00183                 if len(front)==1:
00184                         centroids=front
00185                 frontiers=copy(centroids)
00186 #-------------------------------------------------------------------------      
00187 #clearing old frontiers  
00188       
00189                 z=0
00190                 while z<len(centroids):
00191                         cond=False
00192                         temppoint.point.x=centroids[z][0]
00193                         temppoint.point.y=centroids[z][1]
00194                                                 
00195                         for i in range(0,n_robots):
00196                                 
00197                                 
00198                                 transformedPoint=tfLisn.transformPoint(globalmaps[i].header.frame_id,temppoint)
00199                                 x=array([transformedPoint.point.x,transformedPoint.point.y])
00200                                 cond=(gridValue(globalmaps[i],x)>threshold) or cond
00201                         if (cond or (informationGain(mapData,[centroids[z][0],centroids[z][1]],info_radius*0.5))<0.2):
00202                                 centroids=delete(centroids, (z), axis=0)
00203                                 z=z-1
00204                         z+=1
00205 #-------------------------------------------------------------------------
00206 #publishing
00207                 arraypoints.points=[]
00208                 for i in centroids:
00209                         tempPoint.x=i[0]
00210                         tempPoint.y=i[1]
00211                         arraypoints.points.append(copy(tempPoint))
00212                 filterpub.publish(arraypoints)
00213                 pp=[]   
00214                 for q in range(0,len(frontiers)):
00215                         p.x=frontiers[q][0]
00216                         p.y=frontiers[q][1]
00217                         pp.append(copy(p))
00218                 points.points=pp
00219                 pp=[]   
00220                 for q in range(0,len(centroids)):
00221                         p.x=centroids[q][0]
00222                         p.y=centroids[q][1]
00223                         pp.append(copy(p))
00224                 points_clust.points=pp
00225                 pub.publish(points)
00226                 pub2.publish(points_clust) 
00227                 rate.sleep()
00228 #-------------------------------------------------------------------------
00229 
00230 if __name__ == '__main__':
00231     try:
00232         node()
00233     except rospy.ROSInterruptException:
00234         pass
00235  
00236  
00237  
00238  


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