random_search_states.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 '''
4 Copyright (c) 2016, Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Hutmacher Robin, Karrenbauer Oliver, Marek Felix, Meissner Pascal, Trautmann Jeremias, Wittenbeck Valerij
5 
6 All rights reserved.
7 
8 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 
12 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 
14 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 
16 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.
17 '''
18 
19 import roslib
20 import rospy
21 import smach
22 import smach_ros
23 import random
24 import tf
25 import common.state_acquisition as state_acquisition
26 
27 from geometry_msgs.msg import Pose, Point, Quaternion
28 from nav_msgs.msg import OccupancyGrid
29 from asr_flir_ptu_driver.srv import Range
30 from asr_robot_model_services.srv import IsPositionAllowed
31 
32 from common.evaluation_decorators import *
33 
34 
35 class GenerateRandomPose(smach.State):
36 
37  class RobotState:
38 
39  def __init__(self):
40  self.pose = Pose()
41  self.tilt = 0.0
42 
43  def __repr__(self):
44  return str(self.pose) + "\ntilt: " + str(self.tilt)
45 
46 
47  def __init__(self):
48  smach.State.__init__(self, outcomes=['succeeded'],
49  output_keys=['goal_robot_pose', 'goal_ptu_position'])
51  self.isInitDone = 0
53  self.amountOfTime = 0
54  self.attempts = 0
55 
56  def initNode(self):
57  rospy.loginfo('Init GENERATE_RANDOM_POSE')
58  self.isInitDone = 1
59  self.isWaitForMap = 0
60  rospy.Subscriber("map", OccupancyGrid, self.mapCallback)
61 
62  #Increase recognizer frequency in random search ONLY to speed up search.
63  rospy.set_param("/nbv/speedFactorRecognizer", 0.5)
64 
65  self.initTiltRange()
66  self.AllowSameViewInRandomSearch = rospy.get_param("/scene_exploration_sm/AllowSameViewInRandomSearch", False)
67  rospy.loginfo("AllowSameViewInRandomSearch has value: " + str(self.AllowSameViewInRandomSearch))
68  self.initThresholds()
69 
70  r = rospy.Rate(20) # 20hz
71  rospy.loginfo('Wait for callback from map')
72  while (self.isWaitForMap == 0):
73  r.sleep()
74 
75  def mapCallback(self, data):
76  self.width = (data.info.width * data.info.resolution) / 2 + 0.5
77  self.height = (data.info.height * data.info.resolution) / 2 + 0.5
78  rospy.loginfo('Random poses are generated between width: ' + str(-self.width) + ' x ' + str(self.width)
79  + ' and height: ' + str(-self.height) + ' x ' + str(self.height))
80  self.isWaitForMap = 1
81 
82  def initTiltRange(self):
83  try:
84  rospy.wait_for_service('/asr_flir_ptu_driver/get_range')
85  ptuRange = rospy.ServiceProxy('/asr_flir_ptu_driver/get_range', Range)()
86  self.tiltMin = ptuRange.tilt_min_angle
87  self.tiltMax = ptuRange.tilt_max_angle
88  rospy.loginfo('Random tilts are generated between tiltMin: ' + str(self.tiltMin) + ' and tiltMax: ' + str(self.tiltMax))
89  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
90  rospy.logwarn(str(e))
91 
92  def initThresholds(self):
93  self.positionThreshold = rospy.get_param("/nbv/global_costmap/robot_radius")
94 
95  fovx = rospy.get_param("/nbv/fovx")
96  self.orientationThreshold = fovx / 2.0
97 
98  fovy = rospy.get_param("/nbv/fovy")
99  self.tiltThreshold = fovy / 2.0
100  rospy.loginfo("positionThreshold: " + str(self.positionThreshold) + "; orientationThreshold: " + str(self.orientationThreshold)
101  + "; tiltThreshold: " + str(self.tiltThreshold))
102 
103  @log
104  @key_press
105  @timed
106  def execute(self, userdata):
107  rospy.loginfo('Executing GENERATE_RANDOM_POSE')
108  beginn = rospy.get_time()
109  if (self.isInitDone == 0):
110  self.initNode()
111 
112  random_robot_state = self.RobotState()
113  while True:
114  random_robot_state.pose.position = Point(*[random.uniform(-self.width, self.width), random.uniform(-self.height, self.height), 0])
115  random_robot_state.pose.orientation = Quaternion(*tf.transformations.quaternion_from_euler(0, 0, random.uniform(0,359)))
116  random_robot_state.tilt = random.uniform(self.tiltMin, self.tiltMax)
117 
118  self.attempts += 1
119  if self.checkCalculatedStateAllowed(random_robot_state):
120  break;
121 
122  self.searched_robot_states.append(random_robot_state)
123 
124  userdata.goal_robot_pose = random_robot_state.pose
125  # pan is const, because it is redundant with orientation
126  random_ptu_config = [0, random_robot_state.tilt]
127  userdata.goal_ptu_position = random_ptu_config
128 
129  rospy.loginfo('Generated random\n' + str(random_robot_state.pose))
130  rospy.loginfo('Generated random PTU (tilt): ' + str(random_ptu_config))
131 
132  self.numberOfGeneratedPoses += 1
133  self.amountOfTime += (rospy.get_time() - beginn)
134  rospy.loginfo('Average number of attempts for isPosReachable: ' + str(self.attempts / float(self.numberOfGeneratedPoses)) + ' for all '
135  + str(self.numberOfGeneratedPoses) + ' generated poses to finish')
136  rospy.loginfo('GENERATE_RANDOM_POSE took ' + str(self.amountOfTime / float(self.numberOfGeneratedPoses)) + ' secs average to finish')
137  return 'succeeded'
138 
139  def checkCalculatedStateAllowed(self, robot_state_to_test):
140  if self.isRobotPositionAllowed(robot_state_to_test.pose.position) is False:
141  return False
142  if self.AllowSameViewInRandomSearch is True:
143  return True
144 
145  for oldRobotState in self.searched_robot_states:
146  if state_acquisition.approx_equal_robot_state(oldRobotState.pose, oldRobotState.tilt, robot_state_to_test.pose,
147  robot_state_to_test.tilt, self.positionThreshold, self.orientationThreshold, self.tiltThreshold):
148  return False
149  return True
150 
151  def isRobotPositionAllowed(self, robotPosition):
152  """
153  returns if robotPosition is allowed using the appropriate service call
154  """
155  rospy.wait_for_service('/asr_robot_model_services/IsPositionAllowed')
156  try:
157  isReachableHandler = rospy.ServiceProxy('/asr_robot_model_services/IsPositionAllowed', IsPositionAllowed)
158  ret = isReachableHandler(robotPosition)
159  return ret.isAllowed
160  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
161  rospy.logwarn(str(e))
162 


asr_state_machine
Author(s): Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Hutmacher Robin, Karrenbauer Oliver, Marek Felix, Meißner Pascal, Trautmann Jeremias, Wittenbeck Valerij
autogenerated on Mon Feb 28 2022 21:53:50