22 from gazebo_msgs.srv
import ApplyBodyWrench
23 from uuv_gazebo_ros_plugins_msgs.srv
import SetThrusterState, SetThrusterEfficiency
24 from geometry_msgs.msg
import Point, WrenchStamped, Vector3
30 self.
_logger = logging.getLogger(
'dp_local_planner')
31 out_hdlr = logging.StreamHandler(sys.stdout)
32 out_hdlr.setFormatter(logging.Formatter(
'%(asctime)s | %(levelname)s | %(module)s | %(message)s'))
33 out_hdlr.setLevel(logging.INFO)
34 self._logger.addHandler(out_hdlr)
35 self._logger.setLevel(logging.INFO)
38 specs = dict(current=[
'starting_time',
'velocity',
'horizontal_angle',
40 wrench=[
'starting_time',
'duration',
'force',
'torque'],
41 thruster_state=[
'starting_time',
'thruster_id',
'is_on',
43 propeller_efficiency=[
'starting_time',
'thruster_id',
'duration',
45 thrust_efficiency=[
'starting_time',
'thruster_id',
'duration',
50 if rospy.has_param(
'~disturbances'):
54 raise rospy.ROSException(
'Current specifications must be ' 55 'given as a list of dict')
58 if type(item) != dict:
59 raise rospy.ROSException(
'Disturbance description must be' 61 if 'type' not in item:
62 raise rospy.ROSException(
'Type of disturbance not ' 64 if item[
'type']
not in specs:
65 raise rospy.ROSException(
66 'Invalid type of disturbance, value=%s' % item[
'type'])
68 for spec
in specs[item[
'type']]:
70 raise rospy.ROSException(
71 'Invalid current model specification, ' 72 'missing tag=%s' % spec)
74 if item[
'type'] ==
'thruster_state':
75 thruster_ids.append(item[
'thruster_id'])
81 raise rospy.ROSException(
'No disturbance specifications given')
85 self._logger.info(
'Disturbance #%d: %s' % (i, self.
_disturbances[i]))
93 'wrench_perturbation', WrenchStamped, queue_size=1)
95 vehicle_name = rospy.get_namespace().replace(
'/',
'')
99 services = [
'/hydrodynamics/set_current_velocity',
100 '/gazebo/apply_body_wrench']
102 if item[
'type'] ==
'thruster_state':
103 services.append(
'/%s/thrusters/%d/set_thruster_state' % (vehicle_name, item[
'thruster_id']))
104 elif item[
'type'] ==
'propeller_efficiency':
105 services.append(
'/%s/thrusters/%d/set_dynamic_state_efficiency' % (vehicle_name, item[
'thruster_id']))
106 elif item[
'type'] ==
'thrust_efficiency':
107 services.append(
'/%s/thrusters/%d/set_thrust_force_efficiency' % (vehicle_name, item[
'thruster_id']))
109 rospy.wait_for_service(s, timeout=10)
110 except Exception
as e:
111 self._logger.error(
'Some services are not available! message=' + str(e))
112 self._logger.error(
'Closing node...')
118 self.
_service_cb[
'current_velocity'] = rospy.ServiceProxy(
119 '/hydrodynamics/set_current_velocity', SetCurrentVelocity)
121 '/gazebo/apply_body_wrench', ApplyBodyWrench)
124 if item[
'type'] ==
'thruster_state':
127 self.
_service_cb[
'thrusters'][
'state'][item[
'thruster_id']] = rospy.ServiceProxy(
128 '/%s/thrusters/%d/set_thruster_state' % (vehicle_name, item[
'thruster_id']),
130 elif item[
'type'] ==
'propeller_efficiency':
131 if 'propeller_efficiency' not in self.
_service_cb[
'thrusters']:
132 self.
_service_cb[
'thrusters'][
'propeller_efficiency'] = dict()
133 self.
_service_cb[
'thrusters'][
'propeller_efficiency'][item[
'thruster_id']] = rospy.ServiceProxy(
134 '/%s/thrusters/%d/set_dynamic_state_efficiency' % (vehicle_name, item[
'thruster_id']),
135 SetThrusterEfficiency)
136 elif item[
'type'] ==
'thrust_efficiency':
137 if 'thrust_efficiency' not in self.
_service_cb[
'thrusters']:
138 self.
_service_cb[
'thrusters'][
'thrust_efficiency'] = dict()
139 self.
_service_cb[
'thrusters'][
'thrust_efficiency'][item[
'thruster_id']] = rospy.ServiceProxy(
140 '/%s/thrusters/%d/set_thrust_force_efficiency' % (vehicle_name, item[
'thruster_id']),
141 SetThrusterEfficiency)
142 except rospy.ServiceException
as e:
143 self._logger.info(
'Service call failed, error=%s' % str(e))
149 rate = rospy.Rate(100)
150 while not rospy.is_shutdown():
154 if t > d[
'starting_time']
and not d[
'is_applied']:
156 if d[
'type'] ==
'current':
157 self.
set_current(d[
'velocity'], d[
'horizontal_angle'],
160 elif d[
'type'] ==
'wrench':
166 elif d[
'type'] ==
'thruster_state':
169 elif d[
'type'] ==
'propeller_efficiency':
172 elif d[
'type'] ==
'thrust_efficiency':
178 if d[
'duration'] == -1:
182 elif d[
'is_applied']
and 'duration' in d
and not d[
'ended']:
183 if d[
'duration'] > 0:
184 if rospy.get_time() > d[
'starting_time'] + d[
'duration']:
186 if d[
'type'] ==
'current':
191 elif d[
'type'] ==
'wrench':
194 [-1 * d[
'torque'][n]
for n
in range(3)],
198 elif d[
'type'] ==
'thruster_state':
201 elif d[
'type'] ==
'propeller_efficiency':
204 elif d[
'type'] ==
'thrust_efficiency':
211 msg = WrenchStamped()
212 msg.header.stamp = rospy.Time().now()
213 msg.header.frame_id =
'world' 217 self._wrench_topic.publish(msg)
220 def set_current(self, velocity, horizontal_angle, vertical_angle):
221 self._logger.info(
'Appying current velocity model...')
222 if self.
_service_cb[
'current_velocity'](velocity, horizontal_angle, vertical_angle):
223 self._logger.info(
'Current velocity changed successfully at %f s! vel= %f m/s' % (rospy.get_time(), velocity))
225 self._logger.error(
'Failed to change current velocity')
228 ns = rospy.get_namespace().replace(
'/',
'')
229 body_name =
'%s/base_link' % ns
235 self._body_wrench_msg.header.stamp = rospy.Time().now()
236 self._body_wrench_msg.header.frame_id =
'world' 237 self._body_wrench_msg.wrench.force = Vector3(*self.
_body_force)
238 self._body_wrench_msg.wrench.torque = Vector3(*self.
_body_torque)
243 self._body_wrench_msg.wrench,
244 rospy.Time(secs=starting_time),
245 rospy.Duration(duration))
248 self._logger.info(
'Body wrench perturbation applied!, body_name=%s, t=%.2f s' % (body_name, rospy.get_time()))
250 self._logger.error(
'Failed to apply body wrench!, body_name=%s, t=%.2f s' % (body_name, rospy.get_time()))
253 if self.
_service_cb[
'thrusters'][
'state'][thruster_id](is_on):
254 self._logger.info(
'Setting state of thruster #%d, state=%s, t=%.2f s' % (thruster_id,
'ON' if is_on
else 'OFF', rospy.get_time()))
256 self._logger.error(
'Setting state of thruster #%d failed! t=%.2f s' % (thruster_id, rospy.get_time()))
259 if self.
_service_cb[
'thrusters'][
'propeller_efficiency'][thruster_id](eff):
260 self._logger.info(
'Setting propeller efficiency of thruster #%d, eff=%s, t=%.2f s' % (thruster_id, eff, rospy.get_time()))
262 self._logger.error(
'Setting propeller efficiency of thruster #%d failed! t=%.2f s' % (thruster_id, rospy.get_time()))
265 if self.
_service_cb[
'thrusters'][
'thrust_efficiency'][thruster_id](eff):
266 self._logger.info(
'Setting thrust efficiency of thruster #%d, eff=%s, t=%.2f s' % (thruster_id, eff, rospy.get_time()))
268 self._logger.error(
'Setting thrust efficiency of thruster #%d failed! t=%.2f s' % (thruster_id, rospy.get_time()))
270 if __name__ ==
'__main__':
271 print(
'Starting disturbance manager')
272 rospy.init_node(
'disturbance_manager')
277 except rospy.ROSInterruptException:
278 print(
'caught exception')
def set_thruster_state(self, thruster_id, is_on)
def _publish_wrench_disturbance(self, event)
def set_thrust_efficiency(self, thruster_id, eff)
def set_body_wrench(self, force, torque, duration, starting_time)
def set_current(self, velocity, horizontal_angle, vertical_angle)
def set_propeller_efficiency(self, thruster_id, eff)