15 from .fin_model
import FinModel
19 from tf_quaternion.transformations
import quaternion_matrix
20 from uuv_thrusters.models
import Thruster
21 from uuv_auv_control_allocator.msg
import AUVCommand
22 from uuv_gazebo_ros_plugins_msgs.msg
import FloatStamped
23 from geometry_msgs.msg
import Wrench, WrenchStamped
34 self.
namespace = rospy.get_namespace().replace(
'/',
'')
35 rospy.loginfo(
'Initialize control allocator for vehicle <%s>' % self.
namespace)
39 tf_trans_ned_to_enu =
None 43 target =
'{}/base_link'.format(self.
namespace)
44 source =
'{}/base_link_ned'.format(self.
namespace)
47 source =
'base_link_ned' 48 rospy.loginfo(
'Lookup transfrom from %s to %s' % (source, target))
49 tf_trans_ned_to_enu = self.tf_buffer.lookup_transform(
50 target, source, rospy.Time(), rospy.Duration(1))
51 except Exception
as e:
52 rospy.logwarn(
'No transform found between base_link and base_link_ned' 53 ' for vehicle {}, message={}'.format(self.
namespace, e))
56 if tf_trans_ned_to_enu
is not None:
58 (tf_trans_ned_to_enu.transform.rotation.x,
59 tf_trans_ned_to_enu.transform.rotation.y,
60 tf_trans_ned_to_enu.transform.rotation.z,
61 tf_trans_ned_to_enu.transform.rotation.w))[0:3, 0:3]
63 rospy.logwarn(
'base_link transform NED to ENU=\n{}'.format(
66 self.
base_link = rospy.get_param(
'~base_link',
'base_link')
69 if not rospy.has_param(
'~thruster_config'):
70 raise rospy.ROSException(
'Thruster configuration not available')
76 thruster_params = [
'conversion_fcn_params',
'conversion_fcn',
77 'topic_prefix',
'topic_suffix',
'frame_base',
'max_thrust']
78 for p
in thruster_params:
80 raise rospy.ROSException(
81 'Parameter <%s> for thruster conversion function is missing' % p)
90 if not rospy.has_param(
'~fin_config'):
91 raise rospy.ROSException(
'Fin configuration is not available')
97 fin_params = [
'fluid_density',
'lift_coefficient',
'fin_area',
98 'topic_prefix',
'topic_suffix',
'frame_base']
102 raise rospy.ROSException(
103 'Parameter <%s> for fin configuration is missing' % p)
114 raise rospy.ROSException(
'Fin angle limits are invalid')
121 raise rospy.ROSException(
'No thruster and/or fins found')
124 """Calculate the control allocation matrix, if one is not given.""" 127 rospy.loginfo(
'ControlAllocator: updating thruster poses')
133 rospy.loginfo(
'Lookup: Thruster transform found %s -> %s' % (base, frame))
134 trans = self.tf_buffer.lookup_transform(base, frame, rospy.Time(), rospy.Duration(1))
135 pos = np.array([trans.transform.translation.x,
136 trans.transform.translation.y,
137 trans.transform.translation.z])
138 quat = np.array([trans.transform.rotation.x,
139 trans.transform.rotation.y,
140 trans.transform.rotation.z,
141 trans.transform.rotation.w])
142 rospy.loginfo(
'Thruster transform found %s -> %s' % (base, frame))
143 rospy.loginfo(
'pos=' + str(pos))
144 rospy.loginfo(
'rot=' + str(quat))
147 self.
thruster = Thruster.create_thruster(
156 rospy.loginfo(
'Lookup: Fin transform found %s -> %s' % (base, frame))
157 trans = self.tf_buffer.lookup_transform(base, frame, rospy.Time(), rospy.Duration(1))
158 pos = np.array([trans.transform.translation.x,
159 trans.transform.translation.y,
160 trans.transform.translation.z])
161 quat = np.array([trans.transform.rotation.x,
162 trans.transform.rotation.y,
163 trans.transform.rotation.z,
164 trans.transform.rotation.w])
165 rospy.loginfo(
'Fin transform found %s -> %s' % (base, frame))
166 rospy.loginfo(
'pos=' + str(pos))
167 rospy.loginfo(
'quat=' + str(quat))
169 fin_topic =
'/%s/%s/%d/%s' % (self.
namespace,
172 self.
fins[i] = FinModel(
178 except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException):
179 rospy.loginfo(
'Could not get transform from %s to %s ' % (base, frame))
182 self.
n_fins = len(self.fins.keys())
183 rospy.loginfo(
'# fins found: %d' % len(self.fins.keys()))
185 for i
in range(self.
n_fins):
187 rospy.loginfo(self.
fins[i].pos)
188 rospy.loginfo(self.
fins[i].rot)
194 actuator_model = self.thruster.tam_column.reshape((6, 1)) * thrust
196 f_lift = (0.5 * self.
fin_config[
'fluid_density'] *
201 tau[0:3] = f_lift * self.
fins[i].lift_vector
202 tau[3::] = np.cross(self.
fins[i].pos, f_lift)
204 actuator_model += tau
205 return actuator_model
208 self.thruster.publish_command(command[0])
210 for i
in range(self.
n_fins):
211 self.
fins[i].publish_command(command[i + 1])
def compute_control_force(self, thrust, delta, u)
def publish_commands(self, command)