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