thruster_allocator.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (c) 2016-2019 The UUV Simulator Authors.
3 # All rights reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 from __future__ import print_function
17 import numpy
18 import rospy
19 import tf
20 import tf.transformations as trans
21 from os.path import isdir, join
22 from copy import deepcopy
23 import yaml
24 import tf2_ros
25 from uuv_thrusters import ThrusterManager
26 from geometry_msgs.msg import Wrench, WrenchStamped
27 from uuv_thruster_manager.srv import *
28 
29 
30 class ThrusterAllocatorNode(ThrusterManager):
31  """The thruster allocator node allows a client node
32  to command the thrusters.
33  """
34 
35  def __init__(self):
36  """Class constructor."""
37  ThrusterManager.__init__(self)
38 
39  self.last_update = rospy.Time.now()
40 
41  # Subscriber to the wrench to be applied on the UUV
42  self.input_sub = rospy.Subscriber('thruster_manager/input',
43  Wrench, self.input_callback)
44 
45  # To deliver the wrench input with an option to use another body frame
46  # (options: base_link and base_link_ned), use the wrench stamped
47  # message
48  self.input_stamped_sub = rospy.Subscriber(
49  'thruster_manager/input_stamped', WrenchStamped,
51  self.thruster_info_service = rospy.Service(
52  'thruster_manager/get_thrusters_info', ThrusterManagerInfo,
53  self.get_thruster_info)
54  self.curve_calc_service = rospy.Service(
55  'thruster_manager/get_thruster_curve', GetThrusterCurve,
56  self.get_thruster_curve)
58  'thruster_manager/set_config', SetThrusterManagerConfig,
59  self.set_config)
61  'thruster_manager/get_config', GetThrusterManagerConfig,
62  self.get_config)
63 
64  rate = rospy.Rate(self.config['update_rate'])
65  while not rospy.is_shutdown():
66  if self.config['timeout'] > 0:
67  # If a timeout is set, zero the outputs to the thrusters if
68  # there is no command signal for the length of timeout
69  if rospy.Time.now() - self.last_update > self.config['timeout']:
70  print('Turning thrusters off - inactive for too long')
71  if self.thrust is not None:
72  self.thrust.fill(0)
73  self.command_thrusters()
74  rate.sleep()
75 
76  def get_thruster_info(self, request):
77  """Return service callback with thruster information."""
78  return ThrusterManagerInfoResponse(
79  self.n_thrusters,
80  self.configuration_matrix.flatten().tolist(),
81  self.namespace + self.config['base_link'])
82 
83  def get_thruster_curve(self, request):
84  """Return service callback for computation of thruster curve."""
85  if self.n_thrusters == 0:
86  return GetThrusterCurveResponse([], [])
87  # TODO Get thruster index, for the case the vehicle has different
88  # models
89  input_values, thrust_values = self.thrusters[0].get_curve(
90  request.min, request.max, request.n_points)
91  return GetThrusterCurveResponse(input_values, thrust_values)
92 
93  def set_config(self, request):
94  old_config = deepcopy(self.config)
95  self.ready = False
96  self.config['base_link'] = request.base_link
97  self.config['thruster_frame_base'] = request.thruster_frame_base
98  self.config['thruster_topic_prefix'] = request.thruster_topic_prefix
99  self.config['thruster_topic_suffix'] = request.thruster_topic_suffix
100  self.config['timeout'] = request.timeout
101  print('New configuration:\n')
102  for key in self.config:
103  print(key, '=', self.config[key])
104  if not self.update_tam(recalculate=True):
105  print('Configuration parameters are invalid, going back to old configuration...')
106  self.config = old_config
107  self.update_tam(recalculate=True)
108  return SetThrusterManagerConfigResponse(True)
109 
110  def get_config(self, request):
111  return GetThrusterManagerConfigResponse(
112  self.namespace,
113  self.config['base_link'],
114  self.config['thruster_frame_base'],
115  self.config['thruster_topic_prefix'],
116  self.config['thruster_topic_suffix'],
117  self.config['timeout'],
118  self.config['max_thrust'],
119  self.n_thrusters,
120  self.configuration_matrix.flatten().tolist())
121 
122  def input_callback(self, msg):
123  """
124  Callback to the subscriber that receiver the wrench to be applied on
125  UUV's BODY frame.
126  @param msg Wrench message
127  """
128  if not self.ready:
129  return
130 
131  force = numpy.array((msg.force.x, msg.force.y, msg.force.z))
132  torque = numpy.array((msg.torque.x, msg.torque.y, msg.torque.z))
133 
134  # This mode assumes that the wrench is given wrt thruster manager
135  # configured base_link reference
136  self.publish_thrust_forces(force, torque)
137 
138  self.last_update = rospy.Time.now()
139 
140  def input_stamped_callback(self, msg):
141  """
142  Callback to the subscriber that receiver the stamped wrench to be
143  applied on UUV's BODY frame.
144  @param msg Stamped wrench message
145  """
146  if not self.ready:
147  return
148 
149  force = numpy.array(
150  (msg.wrench.force.x, msg.wrench.force.y, msg.wrench.force.z))
151  torque = numpy.array(
152  (msg.wrench.torque.x, msg.wrench.torque.y, msg.wrench.torque.z))
153 
154  # Send the frame ID for the requested wrench
155  self.publish_thrust_forces(force, torque, msg.header.frame_id.split('/')[-1])
156  self.last_update = rospy.Time.now()
157 
158 
159 if __name__ == '__main__':
160  rospy.init_node('thruster_allocator')
161 
162  try:
164  rospy.spin()
165  except rospy.ROSInterruptException:
166  print('ThrusterAllocatorNode::Exception')
167  print('Leaving ThrusterAllocatorNode')


uuv_thruster_manager
Author(s): Musa Morena Marcusso Manhaes , Sebastian Scherer , Luiz Ricardo Douat
autogenerated on Thu Jun 18 2020 03:28:39