direct_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 time
24 import types
25 import common.init
26 import common.state_acquisition as state_acquisition
27 import xml.etree.ElementTree as ET
28 
29 from actionlib import SimpleActionClient
30 from actionlib.msg import actionlib
31 from asr_direct_search_manager.msg import asr_direct_search_manager
32 from asr_next_best_view.srv import TriggerFrustumVisualization
33 from asr_world_model.srv import GetMissingObjectList, GetAllObjectsList
34 from asr_msgs.msg import AsrTypeAndId
35 
36 from common.evaluation_decorators import *
37 
38 """
39 This file defines useful states for usage with the MILD infrastructure. Keep in
40 mind that most of them need some sort of userdata that must be provided during
41 runtime in order to behave properly.
42 """
43 
44 
45 class CheckSearchFinished(smach.State):
46  def __init__(self):
47  smach.State.__init__(self, outcomes=['search_finished', 'search_not_finished', 'aborted'],
48  output_keys=['searched_object_types_and_ids'])
49 
50  @log
51  @key_press
52  @timed
53  def execute(self, userdata):
54  rospy.loginfo('Executing CHECK_SEARCH_FINISHED')
55 
56  searched_object_types_and_ids = get_search_object_types_and_ids()
57  if (searched_object_types_and_ids == 'aborted'):
58  return 'aborted'
59  userdata.searched_object_types_and_ids = searched_object_types_and_ids
60 
61  if rospy.get_param("/scene_exploration_sm/StopAtfirst"):
62  return 'search_finished'
63  elif (not rospy.get_param("/scene_exploration_sm/SearchAllobject")
64  and len(searched_object_types_and_ids) is 0):
65  return 'search_finished'
66  else:
67  return 'search_not_finished'
68 
69 
70 class DirectSearchInit(smach.State):
71 
72  def __init__(self):
73  smach.State.__init__(self, outcomes=['aborted', 'object_poses_from_demonstrations_given',
74  'no_object_poses_from_demonstrations'],
75  output_keys=['searched_object_types_and_ids'])
76 
77  @log
78  @key_press
79  @timed
80  def execute(self, userdata):
81  rospy.loginfo('Executing DIRECT_SEARCH_INIT')
82 
83  mode = rospy.get_param('/scene_exploration_sm/mode')
84  if mode != 3:
85  common.init.clear_costmap()
86  common.init.clear_world_model()
87  common.init.reset_ism()
88  result = execute_direct_search_action("Reset")
89  if (result == 'aborted'):
90  return 'aborted'
91 
92  searched_object_types_and_ids = get_search_object_types_and_ids()
93  if (searched_object_types_and_ids == 'aborted'):
94  return 'aborted'
95  userdata.searched_object_types_and_ids = searched_object_types_and_ids
96 
97  result = execute_direct_search_action("BackToInitial", searched_object_types_and_ids)
98  if (result == 'aborted'):
99  return 'aborted'
100 
101  if result.arePosesFromDemonstrationLeft:
102  return 'object_poses_from_demonstrations_given'
103  else:
104  return 'no_object_poses_from_demonstrations'
105 
106 
107 class GetGoalCameraPose(smach.State):
108  def __init__(self):
109  smach.State.__init__(self, outcomes=['MoveRobot', 'MovePTUOnly', 'nowhere_left_to_search', 'aborted'],
110  output_keys=['goal_camera_pose', 'goal_robot_pose', 'goal_ptu_position', 'filtered_searched_object_types'],
111  input_keys=['filtered_searched_object_types', 'searched_object_types_and_ids'])
114 
115 
116  @log
117  @key_press
118  @timed
119  def execute(self, userdata):
120  rospy.loginfo('Executing GET_GOAL_CAMERA_POSE')
121 
123  return 'nowhere_left_to_search'
124 
125  result = execute_direct_search_action("GetGoalCameraPose", userdata.searched_object_types_and_ids)
126  if (result == 'aborted'):
127  return 'aborted'
128 
129  if result.arePosesFromDemonstrationLeft:
131 
132  self.arePosesFromDemonstrationLeft = result.arePosesFromDemonstrationLeft
133 
134  if result.isNoPoseLeft:
135  return 'nowhere_left_to_search'
136 
137  #Trigger old frustum viz for current_camera_pose
138  current_camera_pose = state_acquisition.get_camera_pose_cpp()
139  trigger_old_frustum_viz(current_camera_pose)
140  trigger_frustum_viz(result.goalCameraPose)
141  userdata.goal_camera_pose = result.goalCameraPose
142  userdata.goal_ptu_position = [result.pan, result.tilt]
143 
144  userdata.filtered_searched_object_types = []
145  for object_type_and_id in result.filteredSearchedObjectTypesAndIds:
146  userdata.filtered_searched_object_types.append(object_type_and_id.type)
147 
148  rospy.loginfo("Searched object types and ids:\n" + str(userdata.searched_object_types_and_ids))
149  rospy.loginfo("Filtered searched object types and ids:\n" + str(result.filteredSearchedObjectTypesAndIds))
150 
151  if result.isSameRobotPoseAsBefore:
152  return 'MovePTUOnly'
153  else:
154  userdata.goal_robot_pose = result.goalRobotPose
155  return 'MoveRobot'
156 
157 
158 class FrustumViz(smach.State):
159  def __init__(self):
160  smach.State.__init__(self, outcomes=['succeeded'])
161 
162  @log
163  @key_press
164  @timed
165  def execute(self, userdata):
166  rospy.loginfo('Executing FRUSTUM_VIZ')
167 
168  # Sometimes the PTU has not moved yet
169  rospy.sleep(0.2)
170  camera_pose = state_acquisition.get_camera_pose_cpp()
171  trigger_frustum_viz(camera_pose)
172  return 'succeeded'
173 
174 
175 def execute_direct_search_action(action_command, searched_object_types_and_ids=None):
176  rospy.loginfo("Direct search manager service call for: " + str(action_command))
177  client = actionlib.SimpleActionClient('asr_direct_search_manager', asr_direct_search_manager.msg.directSearchAction)
178  client.wait_for_server()
179  goal = asr_direct_search_manager.msg.directSearchGoal(command=str(action_command), searchedObjectTypesAndIds=searched_object_types_and_ids)
180  client.send_goal(goal)
181  client.wait_for_result()
182  if client.get_state() != 3:
183  rospy.logerr("Direct search manager service call for: " + str(client.get_state()) + " was not successful!")
184  return 'aborted'
185  return client.get_result()
186 
187 
188 def trigger_old_frustum_viz(current_camera_pose):
189  try:
190  rospy.wait_for_service('/nbv/trigger_old_frustum_visualization', timeout=5)
191  trigger_old_frustum_v = rospy.ServiceProxy(
192  '/nbv/trigger_old_frustum_visualization', TriggerFrustumVisualization)
193  trigger_old_frustum_v(current_camera_pose)
194  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
195  rospy.logwarn(str(e))
196 
197 def trigger_frustum_viz(camera_pose):
198  try:
199  rospy.wait_for_service('/nbv/trigger_frustum_visualization', timeout=5)
200  get_frustum = rospy.ServiceProxy(
201  '/nbv/trigger_frustum_visualization', TriggerFrustumVisualization)
202  get_frustum(camera_pose)
203  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
204  rospy.logwarn(str(e))
205 
206 
208  try:
209  rospy.loginfo("wait_for_service /env/asr_world_model/get_all_objects_list")
210  rospy.wait_for_service('/env/asr_world_model/get_all_objects_list', timeout=5)
211  get_all_objects_list = rospy.ServiceProxy(
212  '/env/asr_world_model/get_all_objects_list', GetAllObjectsList)
213  return get_all_objects_list().allObjects
214  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
215  rospy.logwarn(str(e))
216  return 'aborted'
217 
219  dbfilename = rospy.get_param('/rp_ism_node/dbfilename');
220  pathSplit = dbfilename.split("/")
221  dbName = pathSplit[-1]
222 
223  path = rospy.get_param('/scene_exploration_sm/IOPath')
224  path = path.replace("XXX", dbName);
225  rospy.loginfo("Parsed IntermediateObject path: " + str(path))
226 
227  tree = ET.parse(path)
228  root = tree.getroot()
229  object_types_and_ids = []
230  for child in root:
231  typeAndId = AsrTypeAndId()
232  typeAndId.type = child.attrib["type"]
233  typeAndId.identifier = child.attrib["identifier"]
234  object_types_and_ids.append(typeAndId)
235  return object_types_and_ids
236 
238  try:
239  rospy.loginfo("wait_for_service /env/asr_world_model/get_missing_object_list")
240  rospy.wait_for_service('/env/asr_world_model/get_missing_object_list', timeout=5)
241  get_missing_objects = rospy.ServiceProxy(
242  '/env/asr_world_model/get_missing_object_list', GetMissingObjectList)
243  return get_missing_objects().missingObjects
244  except (rospy.ServiceException, rospy.exceptions.ROSException), e:
245  rospy.logwarn(str(e))
246  return 'aborted'
247 
248 
250  searched_object_types_and_ids = []
251  if rospy.get_param("scene_exploration_sm/SearchAllobject"):
252  all_object_types = get_all_object_types_and_ids()
253  if (all_object_types == 'aborted'):
254  return 'aborted'
255  searched_object_types_and_ids = all_object_types
256  else:
257  searched_object_types_and_ids = get_object_types_and_ids_from_file()
258  rospy.loginfo("Unfiltered object types and ids:\n" + str(searched_object_types_and_ids))
259 
260  missing_object_types_and_ids = get_missing_object_types_and_ids()
261  if missing_object_types_and_ids == 'aborted':
262  return 'aborted'
263  filtered_object_types_and_ids = []
264  for object_type_and_id in searched_object_types_and_ids:
265  for missing_object_type_and_id in missing_object_types_and_ids:
266  if object_type_and_id.type == missing_object_type_and_id.type and object_type_and_id.identifier == missing_object_type_and_id.identifier:
267  missing_object_types_and_ids.remove(missing_object_type_and_id)
268  filtered_object_types_and_ids.append(missing_object_type_and_id)
269  rospy.loginfo("Searched object types and ids (filtered now):\n" + str(filtered_object_types_and_ids))
270  return filtered_object_types_and_ids
271 
def trigger_old_frustum_viz(current_camera_pose)
def execute_direct_search_action(action_command, searched_object_types_and_ids=None)


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