00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 import roslib
00034 roslib.load_manifest('simulated_quadrotor')
00035 import rospy
00036
00037 import numpy as np
00038 from math import sin, cos, radians, degrees
00039
00040 import tf.transformations as tft
00041
00042 from model_base import ModelBase
00043
00044 model_select = 3
00045
00046 if model_select == 1:
00047
00048 A = np.array([
00049 [1.0000, 0, 0.0004, 0.0212, 0.0043, -0.0034, 0.0001, 0.0003, 0.0008, 0.0027, -0.0018, 0.0002],
00050 [ 0, 1.0000, -0.0006, 0.0001, 0.0207, 0.0008, -0.0000, 0.0005, -0.0003, 0.0006, -0.0038, -0.0003],
00051 [ 0, 0, 0.9960, 0.0001, -0.0006, 0.0184, 0.0000, -0.0000, -0.0001, -0.0005, 0.0005, -0.0003],
00052
00053 [ 0, 0, 0.0133, 0.9981, 0.0096, 0.0007, 0.0003, 0.0025, 0.0030, -0.0019, -0.0001, -0.0071],
00054 [ 0, 0, 0.0129, -0.0012, 0.9986, 0.0076, 0.0002, 0.0015, -0.0029, -0.0010, 0.0076, 0.0012],
00055 [ 0, 0, -0.0396, 0.0006, -0.0017, 0.9834, 0.0000, 0.0002, -0.0000, 0.0012, -0.0019, 0.0011],
00056
00057 [ 0, 0, -0.0202, 0.0075, -0.0473, -0.0555, 0.9909, -0.0032, -0.0029, -0.0907, 0.1183, -0.7797],
00058 [ 0, 0, -0.0995, -0.0098, -0.1662, -0.0309, -0.0068, 0.9669, 0.0014, 0.1366, -0.4267, 0.1508],
00059 [ 0, 0, 0.2266, -0.0289, 0.0505, 0.1060, 0.0029, 0.0050, 0.9712, 0.6622, -0.1306, 0.0434],
00060 [ 0, 0, -0.0167, 0.0133, -0.0011, -0.0023, 0.0000, -0.0003, -0.0121, 0.8542, -0.0141, 0.0248],
00061
00062 [ 0, 0, -0.0193, -0.0034, 0.0104, -0.0077, -0.0002, 0.0117, 0.0022, 0.0250, 0.8149, -0.0197],
00063 [ 0, 0, 0.0049, -0.0061, 0.0085, -0.0058, 0.0044, 0.0001, 0.0015, 0.0176, -0.0114, 0.8621]])
00064
00065
00066 B = np.array([[-0.0001, 0.0001, -0.0004, 0.0004],
00067 [ 0.0000, -0.0002, 0.0000, -0.0006],
00068 [-0.0000, -0.0000, 0.0001, -0.0040],
00069 [-0.0003, 0.0002, -0.0006, 0.0133],
00070 [-0.0002, 0.0004, 0.0001, 0.0129],
00071 [-0.0000, -0.0002, 0.0000, -0.0396],
00072 [ 0.0091, 0.0029, 0.0034, -0.0202],
00073 [ 0.0068, 0.0270, -0.0003, -0.0995],
00074 [-0.0029, -0.0047, 0.0244, 0.2266],
00075 [-0.0000, 0.0000, 0.0073, -0.0167],
00076 [ 0.0002, -0.0073, -0.0024, -0.0193],
00077 [-0.0044, -0.0003, -0.0013, 0.0049]])
00078 elif model_select == 2:
00079 A = np.array([
00080 [1.0000 , 0, -0.0002, 0.0096, 0.0031, -0.0052, 0.0007, 0.0037, 0.0034, -0.0210, 0.0063, 0.0271],
00081 [ 0 , 1.0000, -0.0009, -0.0045, 0.0179, 0.0019, 0.0017, 0.0041, -0.0008, 0.0019, 0.0087, 0.0116],
00082 [ 0 , 0, 0.9851, 0.0595, 0.0933, -0.0012, -0.0239, 0.0864, -0.0118, -0.0381, -0.0764, -0.0012],
00083 [ 0 , 0, -0.0010, 0.8633, -0.1564, -0.0008, 0.0901, -0.1560, 0.0218, 0.0734, 0.1417, 0.0454],
00084 [ 0 , 0, 0.0003, -0.1302, 0.8409, 0.0105, 0.0907, -0.1647, 0.0218, 0.0597, 0.0744, 0.2472],
00085 [ 0 , 0, -0.0363, 0.0254, 0.0600, 0.9726, -0.0173, 0.0455, -0.0021, -0.0432, -0.0116, -0.0326],
00086 [ 0 , 0, 0.0261, 0.0859, 0.1287, -0.0004, 0.9266, 0.1462, -0.0188, -0.0369, -0.0829, -0.2062],
00087 [ 0 , 0, 0.0394, -0.0154, -0.0937, 0.0399, -0.0189, 0.9719, -0.0023, 0.1016, -0.2105, 0.1236],
00088 [ 0 , 0, 0.0755, -0.0109, 0.0722, 0.0586, 0.0279, 0.0083, 0.9713, 0.2726, -0.0792, 0.0357],
00089 [ 0 , 0, 0.0031, -0.0248, -0.0478, 0.0753, 0.0259, -0.0087, -0.0174, 0.9000, -0.0333, -0.0138],
00090 [ 0 , 0, 0.0007, -0.0066, 0.0386, -0.0458, -0.0041, 0.0822, -0.0050, 0.0514, 0.8091, 0.0006],
00091 [ 0 , 0, -0.0015, -0.1527, -0.2472, 0.0071, 0.0999, -0.1885, 0.0210, 0.0921, 0.1135, 0.9362]])
00092
00093 B = np.array([ [-0.0007, -0.0006, -0.0027, -0.0002],
00094 [-0.0017, -0.0009, 0.0005, -0.0009],
00095 [ 0.0239, 0.0081, -0.0062, -0.0149],
00096 [-0.0901, -0.0263, 0.0144, -0.0010],
00097 [-0.0907, -0.0266, 0.0148, 0.0003],
00098 [ 0.0173, 0.0067, -0.0065, -0.0363],
00099 [ 0.0734, 0.0156, -0.0121, 0.0261],
00100 [ 0.0189, 0.0016, 0.0050, 0.0394],
00101 [-0.0279, -0.0071, 0.0190, 0.0755],
00102 [-0.0259, -0.0035, 0.0147, 0.0031],
00103 [ 0.0041, -0.0071, -0.0102, 0.0007],
00104 [-0.0999, -0.0265, 0.0192, -0.0015]])
00105 elif model_select == 3:
00106 A = np.array([[1.0000, 0, 0.0002, 0.0188, 0.0001, -0.0000, 0.0000, 0.0000, 0.0002, 0.0001, 0.0001, 0.0003],
00107 [0 , 1.0000, 0.0001, -0.0000, 0.0188, 0.0001, 0.0001, 0.0000, -0.0001, 0.0003, 0.0000, -0.0007],
00108 [0 , 0, 0.9960, 0.0000, -0.0000, 0.0176, 0.0000, -0.0000, 0.0000, 0.0000, 0.0002, -0.0002],
00109 [0 , 0, 0.0007, 0.9958, 0.0002, -0.0002, 0.0003, 0.0016, 0.0017, -0.0004, 0.0001, -0.0007],
00110 [0 , 0, 0.0005, -0.0003, 0.9964, 0.0007, 0.0005, 0.0016, -0.0018, 0.0006, 0.0005, -0.0012],
00111 [0 , 0, -0.0385, -0.0001, -0.0003, 0.9840, 0.0002, -0.0002, -0.0001, -0.0004, 0.0000, -0.0004],
00112 [0 , 0, 0.0315, -0.0059, -0.0079, -0.0025, 0.9974, -0.0009, -0.0024, -0.0269, 0.0327, -0.2031],
00113 [0 , 0, 0.0828, -0.0053, -0.0258, 0.0430, -0.0029, 0.9721, -0.0000, 0.0977, -0.1581, 0.1109],
00114 [0 , 0, 0.0491, -0.0065, 0.0327, 0.0372, 0.0021, 0.0006, 0.9728, 0.2388, -0.0849, 0.0715],
00115 [0 , 0, -0.0008, 0.0066, -0.0046, 0.0031, 0.0019, -0.0007, -0.0099, 0.8491, -0.0210, 0.0064],
00116 [0 , 0, -0.0232, -0.0046, -0.0041, -0.0016, 0.0021, 0.0089, 0.0001, 0.0240, 0.8275, -0.0050],
00117 [0 , 0, 0.0013, -0.0020, 0.0004, -0.0008, 0.0029, 0.0004, 0.0003, 0.0102, -0.0061, 0.8554]])
00118
00119 B = np.array([ [-0.0000, -0.0002, -0.0002, 0.0002],
00120 [-0.0001, -0.0004, 0.0004, 0.0001],
00121 [-0.0000, -0.0000, -0.0000, -0.0040],
00122 [-0.0003, -0.0010, -0.0011, 0.0007],
00123 [-0.0005, -0.0012, 0.0011, 0.0005],
00124 [-0.0002, -0.0004, -0.0002, -0.0385],
00125 [ 0.0026, 0.0006, 0.0006, 0.0315],
00126 [ 0.0029, 0.0244, -0.0001, 0.0828],
00127 [-0.0021, -0.0011, 0.0196, 0.0491],
00128 [-0.0019, -0.0004, 0.0052, -0.0008],
00129 [-0.0021, -0.0060, -0.0005, -0.0232],
00130 [-0.0029, -0.0006, -0.0004, 0.0013]])
00131
00132
00133
00134 DT_NOMINAL = 0.02
00135
00136 class LinearModel(ModelBase):
00137 def __init__(self):
00138 self.x = np.zeros(13)
00139 ori_init = tft.quaternion_from_euler(radians(-130), 0, 0, 'rzyx')
00140 self.x[6:10] = np.concatenate([[ori_init[3]], ori_init[:3]])
00141 self.x[2] = -0.6
00142
00143
00144 self.initial_input = np.concatenate([self.get_ypr_deg(), [-self.x[2]]])
00145 self.u = self.initial_input
00146 rospy.loginfo("initial conditions:")
00147 self.report()
00148 rospy.loginfo("end initial conditions")
00149
00150 def set_input(self, u, dt):
00151 self.u = u
00152 if not u[4]:
00153 self.u = self.initial_input
00154 else:
00155
00156 self.u = np.array([-130, 10, 0, 0.6])
00157
00158 def report(self):
00159 ypr = self.get_ypr_deg()
00160 x_ypr = np.concatenate([self.x[:6], ypr, self.x[10:13]])
00161 rospy.loginfo('x_ypr = ' + str(x_ypr))
00162
00163 rospy.loginfo('u = ' + str(self.u))
00164
00165
00166
00167 def update(self, dt):
00168 dt_rel_err = (dt - DT_NOMINAL)/DT_NOMINAL
00169 if abs(dt_rel_err) > 0.1:
00170 rospy.logwarn('dt = %f (relative error %f)' % (dt, dt_rel_err))
00171
00172 ypr = self.get_ypr_deg()
00173 x_ypr = np.concatenate([self.x[:6], ypr, self.x[10:13]])
00174 rospy.loginfo('x_ypr = ' + str(x_ypr))
00175
00176 rospy.loginfo('u = ' + str(self.u))
00177 x_ypr_next = np.dot(A, x_ypr) + np.dot(B, self.u)
00178 rospy.loginfo('x_ypr_next = ' + str(x_ypr_next))
00179 if x_ypr_next[2] >= 0.0 and x_ypr_next[5] > 0:
00180
00181 x_ypr_next[3:6] = np.zeros(3)
00182 x_ypr_next[6:9] = (ypr[0], 0, 0)
00183
00184 ori_quat = tft.quaternion_from_euler(*(np.radians(x_ypr_next[6:9])), axes='rzyx')
00185 self.x = np.concatenate([x_ypr_next[:6],
00186 [ori_quat[3]], ori_quat[:3],
00187 x_ypr_next[9:12]])
00188 rospy.loginfo('x = ' + str(self.x))
00189
00190 def get_position(self):
00191 return self.x[0:3]
00192
00193 def get_velocity(self):
00194 return self.x[3:6]
00195
00196 def get_orientation(self):
00197 """
00198 Return orientation quaternion in (x, y, z, w) convention
00199 """
00200 return tuple(self.x[7:10]) + (self.x[6],)
00201
00202 def get_ypr_deg(self):
00203 return np.degrees(tft.euler_from_quaternion(self.get_orientation(), 'rzyx'))
00204
00205 def get_angular_velocity(self):
00206 return self.x[10:13]
00207
00208
00209