6 import riptide_controllers.msg
7 from nav_msgs.msg
import Odometry
8 from geometry_msgs.msg
import Quaternion, Vector3, Twist
9 from dynamic_reconfigure.client
import Client
11 from tf.transformations
import euler_from_quaternion, quaternion_from_euler
20 _result = riptide_controllers.msg.CalibrateDragResult()
24 self.
position_pub = rospy.Publisher(
"position", Vector3, queue_size=5)
25 self.
lin_vel_pub = rospy.Publisher(
"linear_velocity", Vector3, queue_size=5)
26 self.
ang_vel_pub = rospy.Publisher(
"angular_velocity", Vector3, queue_size=5)
29 with open(rospy.get_param(
'~vehicle_config'),
'r')
as stream:
30 vehicle = yaml.safe_load(stream)
31 mass = vehicle[
'mass']
32 rotational_inertia = np.array(vehicle[
'inertia'])
33 self.
inertia = np.array([mass, mass, mass, rotational_inertia[0], rotational_inertia[1], rotational_inertia[2]])
37 self.
client = Client(
"controller", timeout=30)
42 quat = odom_msg.pose.pose.orientation
43 quat = [quat.x, quat.y, quat.z, quat.w]
44 return euler_from_quaternion(quat)
47 return ((angle + 180) % 360 ) - 180
54 quat = quaternion_from_euler(r, p, y)
71 lambda odom: odom.twist.twist.linear.x,
72 lambda odom: odom.twist.twist.linear.y,
73 lambda odom: odom.twist.twist.linear.z,
74 lambda odom: odom.twist.twist.angular.x,
75 lambda odom: odom.twist.twist.angular.y,
76 lambda odom: odom.twist.twist.angular.z
80 lambda twist: twist.linear.x,
81 lambda twist: twist.linear.y,
82 lambda twist: twist.linear.z,
83 lambda twist: twist.angular.x,
84 lambda twist: twist.angular.y,
85 lambda twist: twist.angular.z
89 publish_velocity[axis](velocity)
93 stable_measurements = 0
94 while stable_measurements < 10:
95 odom_msg = rospy.wait_for_message(
"odometry/filtered", Odometry)
96 cur_vel = get_twist[axis](odom_msg)
98 if abs((cur_vel - last_vel) / cur_vel) >= 0.1:
99 stable_measurements = 0
101 stable_measurements += 1
107 odom_msg = rospy.wait_for_message(
"odometry/filtered", Odometry)
108 velocities.append(get_twist[axis](odom_msg))
113 accel_msg = rospy.wait_for_message(
"controller/requested_accel", Twist)
114 forces.append(get_accel[axis](accel_msg) * self.
inertia[axis])
117 publish_velocity[axis](0)
120 return np.average(velocities), -np.average(forces)
125 X = np.array([velocities, np.abs(velocities) * np.array(velocities)])
127 return np.linalg.lstsq(X,y)[0]
131 self.
client.update_configuration({
141 "quadratic_rot_x": 0,
142 "quadratic_rot_y": 0,
147 odom_msg = rospy.wait_for_message(
"odometry/filtered", Odometry)
148 startYaw = self.
get_euler(odom_msg)[2] * 180 / pi
149 startPosition = odom_msg.pose.pose.position
150 rospy.loginfo(
"Starting drag calibration")
152 linear_params = np.zeros(6)
153 quadratic_params = np.zeros(6)
156 axes_test_orientations = [
166 [0.05, -0.05, .1, -.1, .2, -.2],
167 [0.05, -0.05, .1, -.1, .2, -.2],
168 [-0.05, 0.05, -.1, .1, -.2, .2],
169 [0.2, -0.2, 0.5, -0.5, 1.2, -1.2],
170 [0.2, -0.2, 0.5, -0.5, 1.2, -1.2],
171 [0.2, -0.2, 0.5, -0.5, 1.2, -1.2],
174 for axis
in range(6):
180 for requested_velocity
in axis_velocities[axis]:
181 velocity, force = self.
collect_data(axis, requested_velocity)
183 velocities.append(velocity)
186 rospy.loginfo(
"Linear: %f" % linear_params[axis])
187 rospy.loginfo(
"Quadratic: %f" % quadratic_params[axis])
191 rospy.loginfo(
"Drag calibration completed.")
193 self.
client.update_configuration({
194 "linear_x": linear_params[0],
195 "linear_y": linear_params[1],
196 "linear_z": linear_params[2],
197 "linear_rot_x": linear_params[3],
198 "linear_rot_y": linear_params[4],
199 "linear_rot_z": linear_params[5],
200 "quadratic_x": quadratic_params[0],
201 "quadratic_y": quadratic_params[1],
202 "quadratic_z": quadratic_params[2],
203 "quadratic_rot_x": quadratic_params[3],
204 "quadratic_rot_y": quadratic_params[4],
205 "quadratic_rot_z": quadratic_params[5]
208 self.
_result.linear_drag = linear_params
209 self.
_result.quadratic_drag = quadratic_params
213 if __name__ ==
'__main__':
214 rospy.init_node(
'calibrate_drag')