path_marker_1.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 """
00004 Copyright (c) 2014, Robotnik Automation
00005 All rights reserved.
00006 
00007 Redistribution and use in source and binary forms, with or without
00008 modification, are permitted provided that the following conditions are met:
00009 
00010     * Redistributions of source code must retain the above copyright
00011       notice, this list of conditions and the following disclaimer.
00012     * Redistributions in binary form must reproduce the above copyright
00013       notice, this list of conditions and the following disclaimer in the
00014       documentation and/or other materials provided with the distribution.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00020 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026 POSSIBILITY OF SUCH DAMAGE.
00027 """
00028 
00029 
00030 import roslib; roslib.load_manifest("interactive_markers")
00031 import rospy
00032 import copy
00033 
00034 from interactive_markers.interactive_marker_server import *
00035 from visualization_msgs.msg import InteractiveMarker
00036 from interactive_markers.menu_handler import *
00037 
00038 import actionlib
00039 from geometry_msgs.msg import Pose2D
00040 from purepursuit_planner.msg import goal, GoToGoal, GoToAction
00041 
00042 # Client based on ActionServer to send goals to the purepursuit node
00043 class PurepursuitClient():
00044         
00045         def __init__(self, planner_name):
00046                 self.planner_name = planner_name
00047                 # Creates the SimpleActionClient, passing the type of the action
00048                 # (GoTo) to the constructor.
00049                 self.client = actionlib.SimpleActionClient(planner_name, GoToAction)
00050 
00051         ## @brief Sends the goal to 
00052         ## @return 0 if OK, -1 if no server, -2 if it's tracking a goal at the moment
00053         def goTo(self, goal_list):
00054                 # Waits until the action server has started up and started
00055                 # listening for goals.
00056                 if self.client.wait_for_server(timeout = rospy.Duration(3.0) ):
00057                         #if self.getState() != GoalStatus.LOST:
00058                         #       rospy.loginfo('PurepursuitClient: planner is tracking a goal')
00059                         #       return -2
00060                                 
00061                         g = GoToGoal(target = goal_list)
00062                         rospy.loginfo('PurepursuitClient: Sendig %d waypoints'%(len(goal_list)))
00063                         self.client.send_goal(g)
00064                         return 0
00065                 else:
00066                         rospy.logerr('PurepursuitClient: Error waiting for server')
00067                         return -1
00068         
00069         ## @brief cancel the current goal
00070         def cancel(self):               
00071                 rospy.loginfo('PurepursuitClient: cancelling the goal')
00072                 self.client.cancel_goal()
00073         
00074         ## @brief Get the state information for this goal
00075     ##
00076     ## Possible States Are: PENDING, ACTIVE, RECALLED, REJECTED,
00077     ## PREEMPTED, ABORTED, SUCCEEDED, LOST.
00078     ##
00079     ## @return The goal's state. Returns LOST if this
00080     ## SimpleActionClient isn't tracking a goal.
00081         def getState(self):
00082                 return self.client.get_state()
00083         
00084         ## @brief Returns ret if OK, otherwise -1
00085         def getResult(self):
00086                 ret = self.client.get_result()
00087                 if not ret:
00088                         return -1
00089                 
00090                 else:
00091                         return ret
00092 
00093 ## @brief Class to manage  the creation of a Waypoint base on InteractiveMarker
00094 class PointPath(InteractiveMarker):
00095         
00096         def __init__(self, frame_id, name, description, is_manager = False):
00097                 InteractiveMarker.__init__(self)
00098                 
00099                 self.header.frame_id = frame_id
00100                 self.name = name
00101                 self.description = description
00102                 
00103                 self.marker = Marker()
00104                 self.marker.type = Marker.CYLINDER
00105                 self.marker.scale.x = 0.1
00106                 self.marker.scale.y = 0.1
00107                 self.marker.scale.z = 0.4
00108                 self.marker.pose.position.z = 0.20
00109                 if is_manager:
00110                         self.marker.color.r = 0.8
00111                         self.marker.color.g = 0.0
00112                         self.marker.color.b = 0.0
00113                         self.marker.color.a = 0.5
00114                 else:
00115                         self.marker.color.r = 0.0
00116                         self.marker.color.g = 0.8
00117                         self.marker.color.b = 0.0
00118                         self.marker.color.a = 0.5
00119                         
00120                 self.marker_control = InteractiveMarkerControl()
00121                 self.marker_control.always_visible = True
00122                 self.marker_control.orientation.w = 1
00123                 self.marker_control.orientation.x = 0
00124                 self.marker_control.orientation.y = 1
00125                 self.marker_control.orientation.z = 0
00126                 self.marker_control.markers.append( self.marker )
00127                 self.marker_control.interaction_mode = InteractiveMarkerControl.MOVE_PLANE
00128                 
00129                 self.controls.append( self.marker_control )
00130                 
00131         ## @brief method called every time that an interaction is received      
00132         def processFeedback(self, feedback):
00133                 #p = feedback.pose.position
00134                 self.pose = feedback.pose
00135                 #print feedback.marker_name + " is now at " + str(p.x) + ", " + str(p.y) + ", " + str(p.z)
00136                 
00137 
00138 ## @brief Manages the creation of waypoints and how to send them to Purepursuit
00139 class PointPathManager(InteractiveMarkerServer):
00140         
00141         def __init__(self, name, frame_id, planner):
00142                 InteractiveMarkerServer.__init__(self, name)
00143                 self.list_of_points = []
00144                 self.frame_id = frame_id
00145                 self.counter_points = 0
00146                 
00147                 # Menu handler to create a menu
00148                 self.menu_handler = MenuHandler()
00149                 h_first_entry = self.menu_handler.insert( "Waypoints" )
00150                 entry = self.menu_handler.insert( "Create New", parent=h_first_entry, callback=self.newPointCB)
00151                 entry = self.menu_handler.insert( "Delete last", parent=h_first_entry, callback=self.deletePointCB );
00152                 entry = self.menu_handler.insert( "Delete all", parent=h_first_entry, callback=self.deleteAllPointsCB );
00153                 h_second_entry = self.menu_handler.insert( "Path" )
00154                 entry = self.menu_handler.insert( "Go", parent=h_second_entry, callback=self.startRouteCB)      # Send the path from the first point to the last one
00155                 entry = self.menu_handler.insert( "Stop", parent=h_second_entry, callback=self.stopRouteCB)     # Stops the current path 
00156                 entry = self.menu_handler.insert( "Go back", parent=h_second_entry, callback=self.reverseRouteCB) # Sends the path from the last point to the first one
00157                 
00158                 # Creates the first point
00159                 #self.list_of_points.append(PointPath(frame_id, 'p1', 'p1'))
00160                 self.initial_point = PointPath(frame_id, 'PointManager', 'PointManager', True)
00161                 self.insert(self.initial_point, self.initial_point.processFeedback)
00162                 
00163                 self.menu_handler.apply( self, self.initial_point.name )
00164                 self.applyChanges()
00165                 
00166                 self.planner_client = PurepursuitClient(planner)
00167                 
00168                 #rospy.Timer(rospy.Duration(5), self.createNewPoint)
00169                 
00170         
00171         ## @brief Creates a new PointPath and save it a list
00172         def createNewPoint(self):
00173                                         
00174                 ##print 'Creating new point %d'%(self.counter_points)
00175                 new_point = PointPath(self.frame_id, 'p%d'%(self.counter_points), 'p%d'%(self.counter_points))
00176                 #new_point = PointPath(self.frame_id, '1', '1')
00177                 
00178                 if len(self.list_of_points) > 1:
00179                         new_point.pose.position.x = self.list_of_points[self.counter_points-1].pose.position.x
00180                         new_point.pose.position.y = self.list_of_points[self.counter_points-1].pose.position.y
00181                 elif len(self.list_of_points) == 1:
00182                         new_point.pose.position.x = self.list_of_points[0].pose.position.x
00183                         new_point.pose.position.y = self.list_of_points[0].pose.position.y
00184         
00185                 new_point.pose.position.x = new_point.pose.position.x  + 1.0
00186                         
00187                 
00188                 #print 'Creating new point at position %.2lf, %.2lf, %.2lf'%(new_point.pose.position.x, new_point.pose.position.y, new_point.pose.position.z)
00189                 
00190                 self.list_of_points.append(new_point)
00191                 self.insert(new_point, new_point.processFeedback)
00192                 self.menu_handler.apply( self, 'p%d'%(self.counter_points) )
00193                 self.applyChanges()
00194                 self.counter_points = self.counter_points + 1
00195                 
00196                 #for i in self.list_of_points:
00197                 #       print 'Point %s: %.2lf, %.2lf, %.2lf'%(i.name, i.pose.position.x, i.pose.position.y, i.pose.position.z)
00198                         
00199                 return
00200         
00201         ## @brief Callback called to create a new poing 
00202         def newPointCB(self, feedback):
00203                 #print 'newPointCB'
00204                 self.createNewPoint()
00205                 
00206         ## @brief Callback called to create a new poing 
00207         def deletePointCB(self, feedback):
00208                 if self.counter_points > 0:
00209                          p = self.list_of_points.pop()
00210                          self.counter_points = self.counter_points - 1
00211                          self.erase(p.name)
00212                          self.applyChanges()
00213                          
00214                  #print 'deletePointCB' 
00215         
00216         ## @brief Callback called to create a new poing 
00217         def deleteAllPointsCB(self, feedback):
00218                 for i in range(len(self.list_of_points)):
00219                         p = self.list_of_points.pop()
00220                         self.counter_points = self.counter_points - 1
00221                         self.erase(p.name)
00222                          
00223                 self.applyChanges()
00224                          
00225                 #print 'deleteAllPointsCB'      
00226         
00227         ## @brief Starts the route
00228         def startRouteCB(self, feedback):
00229                 goals = self.convertListOfPointPathIntoGoal()
00230                 print 'goals: %s'%(goals)
00231                 self.planner_client.goTo(goals)
00232                 return
00233         
00234         ## @brief Starts the route on the inverse direction
00235         def reverseRouteCB(self, feedback):
00236                 goals = self.convertListOfPointPathIntoGoal(inverse = True)
00237                 #print 'goals: %s'%(goals)
00238                 self.planner_client.goTo(goals)
00239                 return
00240                 
00241         ## @brief Stops the current route if it's started
00242         def stopRouteCB(self, feedback):
00243                 self.planner_client.cancel()
00244                 return
00245         
00246         ## @brief Starts the route (inverse order of waypoints)
00247         def convertListOfPointPathIntoGoal(self, inverse = False):
00248                 converted_list = []
00249                 if inverse:
00250                         for i in reversed(self.list_of_points):
00251                                 converted_list.append(goal(pose = Pose2D(i.pose.position.x, i.pose.position.y, 0.0), speed = 0.4)) # For now speed constant
00252                 else:
00253                         for i in self.list_of_points:
00254                                 #print 'convertListOfPointPathIntoGoal: %.2lf, %.2lf'%(i.pose.position.x, i.pose.position.y)
00255                                 converted_list.append(goal(pose = Pose2D(i.pose.position.x, i.pose.position.y, 0.0), speed = 0.4)) # For now speed constant
00256                 
00257                 return converted_list
00258                 
00259 if __name__=="__main__":
00260         rospy.init_node("agvs_path_maker")
00261         
00262         server = PointPathManager('agvs_path_maker', frame_id = '/map', planner = 'purepursuit_planner')
00263         
00264         rospy.spin()
00265 


purepursuit_planner
Author(s): Román Navarro
autogenerated on Thu Aug 27 2015 12:08:42