linear.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 #  Copyright (c) 2011, UC Regents
00004 #  All rights reserved.
00005 #
00006 #  Redistribution and use in source and binary forms, with or without
00007 #  modification, are permitted provided that the following conditions
00008 #  are met:
00009 #
00010 #   * Redistributions of source code must retain the above copyright
00011 #     notice, this list of conditions and the following disclaimer.
00012 #   * Redistributions in binary form must reproduce the above
00013 #     copyright notice, this list of conditions and the following
00014 #     disclaimer in the documentation and/or other materials provided
00015 #     with the distribution.
00016 #   * Neither the name of the University of California nor the names of its
00017 #     contributors may be used to endorse or promote products derived
00018 #     from this software without specific prior written permission.
00019 #
00020 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 #  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 #  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 #  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 #  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 #  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 #  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 #  POSSIBILITY OF SUCH DAMAGE.
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     # Data from Anil's email "Re: Did some simulations", Wed, Feb 9, 2011 at 8:30 PM 
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 # [s]
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') # xyzw
00140         self.x[6:10] = np.concatenate([[ori_init[3]], ori_init[:3]]) # wxyz
00141         self.x[2] = -0.6
00142         #self.x[6] = 1.0 # identity quaternion
00143         #self.u = np.zeros(4)
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             #self.u = u[:4]
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         #rospy.loginfo(str(A.shape) + str(x_ypr.shape) + str(B.shape) + str(self.u.shape))
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         #u_ypra = self.u[:4]
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         #rospy.loginfo(str(A.shape) + str(x_ypr.shape) + str(B.shape) + str(self.u.shape))
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             # On the ground..
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') # xyzw
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         


simulated_quadrotor
Author(s): bouffard
autogenerated on Sun Jan 5 2014 11:38:50