26 from gazebo_msgs.srv
import SpawnModel, SpawnModelRequest, DeleteModel, DeleteModelRequest, GetWorldProperties
27 from geometry_msgs.msg
import Pose
28 import tf.transformations
as tft
34 """expands all objects to a flat dictionary""" 36 for key, value
in objects.items():
39 if(parent_name!=
None):
41 if(
'parent_name' not in parents):
42 parents[key] = parent_name
44 compound_keys[parent_name] = parent_name
46 compound_keys[key] = compound_keys[parent_name] +
'_' + key
49 compound_keys[key] = key
51 if "children" in value:
53 tmp_value = copy.deepcopy(value)
54 to_process = tmp_value[
"children"]
57 for child_key, child_value
in tmp_value[
"children"].items():
58 yaw = objects[key][
"orientation"][2]
59 x = objects[key][
"position"][0] + math.cos(yaw) * child_value[
"position"][0] - math.sin(yaw) * child_value[
"position"][1]
60 y = objects[key][
"position"][1] + math.sin(yaw) * child_value[
"position"][0] + math.cos(yaw) * child_value[
"position"][1]
61 child_value[
"position"][0] = x
62 child_value[
"position"][1] = y
63 child_value[
"position"][2] = objects[key][
"position"][2] + child_value[
"position"][2]
64 child_value[
"orientation"][2] = yaw + child_value[
"orientation"][2]
65 del tmp_value[
"children"]
66 flat_objects.update({compound_keys[key]:tmp_value})
68 flat_objects.update(
get_flat_dict(to_process, compound_keys[key]))
72 flat_objects.update({compound_keys[key]:value})
76 if __name__ ==
"__main__":
78 print(
'[spawn_object.py] Please specify the names of the objects to be loaded')
81 rospy.init_node(
"object_spawner")
84 if not rospy.has_param(
"/objects"):
85 rospy.logerr(
"No objects uploaded to /objects")
87 objects = rospy.get_param(
"/objects")
91 if rospy.has_param(
"/object_groups"):
92 groups = rospy.get_param(
"/object_groups")
95 rospy.loginfo(
'No object-groups uploaded to /object_groups')
99 objects = flat_objects
100 elif not set(groups.keys()).isdisjoint(sys.argv):
102 found_groups = set(groups.keys()) & set(sys.argv)
104 object_names = [groups[k]
for k
in found_groups]
106 object_names = [item
for sublist
in object_names
for item
in sublist]
109 for object_name
in object_names:
110 if object_name
in list(flat_objects.keys()):
111 objects.update({object_name:flat_objects[object_name]})
112 elif sys.argv[1]
not in list(flat_objects.keys()):
113 rospy.logerr(
"Object %s not found", sys.argv[1])
116 objects = {sys.argv[1]:flat_objects[sys.argv[1]]}
118 rospy.loginfo(
"Trying to spawn %s", list(objects.keys()))
123 rospy.wait_for_service(
'/gazebo/get_world_properties', 30)
124 except rospy.exceptions.ROSException:
125 rospy.logerr(
"Service /gazebo/get_world_properties not available.")
128 srv_get_world_properties = rospy.ServiceProxy(
'/gazebo/get_world_properties', GetWorldProperties)
132 except rospy.ServiceException
as exc:
133 rospy.logerr(
"Service did not process request: " + str(exc))
135 if world_properties.success:
136 existing_models = world_properties.model_names
141 for key, value
in objects.items():
143 if not "model" in value:
144 rospy.logerr(
"No model for " + key +
" found.")
146 model_string = value[
"model"]
147 model_package = model_string.split(
"/")[0]
148 model_path = model_string.replace(model_package +
"/",
"")
149 model_type = model_string.split(
".").pop()
152 if not "position" in value:
153 rospy.logerr(
"No position for " + key +
" found.")
155 position = value[
"position"]
158 if not "orientation" in value:
159 rospy.logerr(
"No orientation for " + key +
" found.")
162 orientation = value[
"orientation"]
163 quaternion = tft.quaternion_from_euler(orientation[0], orientation[1], orientation[2])
167 object_pose.position.x = float(position[0])
168 object_pose.position.y = float(position[1])
169 object_pose.position.z = float(position[2])
170 object_pose.orientation.x = quaternion[0]
171 object_pose.orientation.y = quaternion[1]
172 object_pose.orientation.z = quaternion[2]
173 object_pose.orientation.w = quaternion[3]
177 file_location = roslib.packages.get_pkg_dir(model_package) +
"/" + model_path
178 except roslib.packages.InvalidROSPkgException:
179 rospy.logerr(
"No model package found for " + key +
": " + model_package +
" does not exist in ROS_PACKAGE_PATH")
183 if model_type ==
"xacro":
185 xacro_args =
'--inorder' if (os.environ[
'ROS_DISTRO'] <
'melodic')
else '' 186 f = os.popen(
"xacro "+ xacro_args +
" " + file_location)
188 rospy.logerr(
"No xacro file found for " + key +
" at " + file_location)
191 elif model_type
in [
'urdf',
'sdf',
'model']:
193 f = open(file_location)
195 rospy.logerr(
"No model file found for " + key +
" at " + file_location)
198 rospy.logerr(
'Model type not known. model_type = ' + model_type)
202 xml_string = f.read()
207 rospy.wait_for_service(
'/gazebo/spawn_'+model_type+
'_model',30)
208 except rospy.exceptions.ROSException:
209 rospy.logerr(
"Service /gazebo/spawn_"+model_type+
"_model not available.")
211 srv_spawn_model = rospy.ServiceProxy(
'/gazebo/spawn_'+model_type+
'_model', SpawnModel)
214 if key
in existing_models:
215 srv_delete_model = rospy.ServiceProxy(
'gazebo/delete_model', DeleteModel)
218 except rospy.ServiceException:
219 rospy.logdebug(
"Error while trying to call Service /gazebo/get_world_properties.")
220 rospy.loginfo(
"Model %s already exists in gazebo. Model will be deleted and added again.", key)
223 req = SpawnModelRequest()
225 req.model_xml = xml_string
226 req.initial_pose = object_pose
230 except rospy.service.ServiceException:
234 if res.success ==
True:
235 rospy.loginfo(res.status_message +
" " + key)
237 rospy.logerr(
"Error: model %s not spawn. error message = "% key + res.status_message)
def get_flat_dict(objects, parent_name)