[docs]defmpprint(expr,**settings):r"""Function for pretty printing of expressions generated in mechanics. Mainly used for expressions not inside a vector; the output of running scripts and generating equations of motion. Takes the same options as SymPy's pretty_print(); see that function for more information. Parameters ========== expr : valid sympy object SymPy expression to pretty print settings : args Same as pretty print Examples ======== Use in the same way as pprint """mp=MechanicsPrettyPrinter(settings)print(mp.doprint(expr))

[docs]defkinematic_equations(speeds,coords,rot_type,rot_order=''):"""Gives equations relating the qdot's to u's for a rotation type. Supply rotation type and order as in orient. Speeds are assumed to be body-fixed; if we are defining the orientation of B in A using by rot_type, the angular velocity of B in A is assumed to be in the form: speed[0]*B.x + speed[1]*B.y + speed[2]*B.z Parameters ========== speeds : list of length 3 The body fixed angular velocity measure numbers. coords : list of length 3 or 4 The coordinates used to define the orientation of the two frames. rot_type : str The type of rotation used to create the equations. Body, Space, or Quaternion only rot_order : str If applicable, the order of a series of rotations. Examples ======== >>> from sympy.physics.mechanics import dynamicsymbols >>> from sympy.physics.mechanics import kinematic_equations, mprint >>> u1, u2, u3 = dynamicsymbols('u1 u2 u3') >>> q1, q2, q3 = dynamicsymbols('q1 q2 q3') >>> mprint(kinematic_equations([u1,u2,u3], [q1,q2,q3], 'body', '313'), ... order=None) [-(u1*sin(q3) + u2*cos(q3))/sin(q2) + q1', -u1*cos(q3) + u2*sin(q3) + q2', (u1*sin(q3) + u2*cos(q3))*cos(q2)/sin(q2) - u3 + q3'] """# Code below is checking and sanitizing inputapproved_orders=('123','231','312','132','213','321','121','131','212','232','313','323','1','2','3','')rot_order=str(rot_order).upper()# Now we need to make sure XYZ = 123rot_type=rot_type.upper()rot_order=[i.replace('X','1')foriinrot_order]rot_order=[i.replace('Y','2')foriinrot_order]rot_order=[i.replace('Z','3')foriinrot_order]rot_order=''.join(rot_order)ifnotisinstance(speeds,(list,tuple)):raiseTypeError('Need to supply speeds in a list')iflen(speeds)!=3:raiseTypeError('Need to supply 3 body-fixed speeds')ifnotisinstance(coords,(list,tuple)):raiseTypeError('Need to supply coordinates in a list')ifrot_type.lower()in['body','space']:ifrot_ordernotinapproved_orders:raiseValueError('Not an acceptable rotation order')iflen(coords)!=3:raiseValueError('Need 3 coordinates for body or space')# Actual hard-coded kinematic differential equationsq1,q2,q3=coordsq1d,q2d,q3d=[diff(i,dynamicsymbols._t)foriincoords]w1,w2,w3=speedss1,s2,s3=[sin(q1),sin(q2),sin(q3)]c1,c2,c3=[cos(q1),cos(q2),cos(q3)]ifrot_type.lower()=='body':ifrot_order=='123':return[q1d-(w1*c3-w2*s3)/c2,q2d-w1*s3-w2*c3,q3d-(-w1*c3+w2*s3)*s2/c2-w3]ifrot_order=='231':return[q1d-(w2*c3-w3*s3)/c2,q2d-w2*s3-w3*c3,q3d-w1-(-w2*c3+w3*s3)*s2/c2]ifrot_order=='312':return[q1d-(-w1*s3+w3*c3)/c2,q2d-w1*c3-w3*s3,q3d-(w1*s3-w3*c3)*s2/c2-w2]ifrot_order=='132':return[q1d-(w1*c3+w3*s3)/c2,q2d+w1*s3-w3*c3,q3d-(w1*c3+w3*s3)*s2/c2-w2]ifrot_order=='213':return[q1d-(w1*s3+w2*c3)/c2,q2d-w1*c3+w2*s3,q3d-(w1*s3+w2*c3)*s2/c2-w3]ifrot_order=='321':return[q1d-(w2*s3+w3*c3)/c2,q2d-w2*c3+w3*s3,q3d-w1-(w2*s3+w3*c3)*s2/c2]ifrot_order=='121':return[q1d-(w2*s3+w3*c3)/s2,q2d-w2*c3+w3*s3,q3d-w1+(w2*s3+w3*c3)*c2/s2]ifrot_order=='131':return[q1d-(-w2*c3+w3*s3)/s2,q2d-w2*s3-w3*c3,q3d-w1-(w2*c3-w3*s3)*c2/s2]ifrot_order=='212':return[q1d-(w1*s3-w3*c3)/s2,q2d-w1*c3-w3*s3,q3d-(-w1*s3+w3*c3)*c2/s2-w2]ifrot_order=='232':return[q1d-(w1*c3+w3*s3)/s2,q2d+w1*s3-w3*c3,q3d+(w1*c3+w3*s3)*c2/s2-w2]ifrot_order=='313':return[q1d-(w1*s3+w2*c3)/s2,q2d-w1*c3+w2*s3,q3d+(w1*s3+w2*c3)*c2/s2-w3]ifrot_order=='323':return[q1d-(-w1*c3+w2*s3)/s2,q2d-w1*s3-w2*c3,q3d-(w1*c3-w2*s3)*c2/s2-w3]ifrot_type.lower()=='space':ifrot_order=='123':return[q1d-w1-(w2*s1+w3*c1)*s2/c2,q2d-w2*c1+w3*s1,q3d-(w2*s1+w3*c1)/c2]ifrot_order=='231':return[q1d-(w1*c1+w3*s1)*s2/c2-w2,q2d+w1*s1-w3*c1,q3d-(w1*c1+w3*s1)/c2]ifrot_order=='312':return[q1d-(w1*s1+w2*c1)*s2/c2-w3,q2d-w1*c1+w2*s1,q3d-(w1*s1+w2*c1)/c2]ifrot_order=='132':return[q1d-w1-(-w2*c1+w3*s1)*s2/c2,q2d-w2*s1-w3*c1,q3d-(w2*c1-w3*s1)/c2]ifrot_order=='213':return[q1d-(w1*s1-w3*c1)*s2/c2-w2,q2d-w1*c1-w3*s1,q3d-(-w1*s1+w3*c1)/c2]ifrot_order=='321':return[q1d-(-w1*c1+w2*s1)*s2/c2-w3,q2d-w1*s1-w2*c1,q3d-(w1*c1-w2*s1)/c2]ifrot_order=='121':return[q1d-w1+(w2*s1+w3*c1)*c2/s2,q2d-w2*c1+w3*s1,q3d-(w2*s1+w3*c1)/s2]ifrot_order=='131':return[q1d-w1-(w2*c1-w3*s1)*c2/s2,q2d-w2*s1-w3*c1,q3d-(-w2*c1+w3*s1)/s2]ifrot_order=='212':return[q1d-(-w1*s1+w3*c1)*c2/s2-w2,q2d-w1*c1-w3*s1,q3d-(w1*s1-w3*c1)/s2]ifrot_order=='232':return[q1d+(w1*c1+w3*s1)*c2/s2-w2,q2d+w1*s1-w3*c1,q3d-(w1*c1+w3*s1)/s2]ifrot_order=='313':return[q1d+(w1*s1+w2*c1)*c2/s2-w3,q2d-w1*c1+w2*s1,q3d-(w1*s1+w2*c1)/s2]ifrot_order=='323':return[q1d-(w1*c1-w2*s1)*c2/s2-w3,q2d-w1*s1-w2*c1,q3d-(-w1*c1+w2*s1)/s2]elifrot_type.lower()=='quaternion':ifrot_order!='':raiseValueError('Cannot have rotation order for quaternion')iflen(coords)!=4:raiseValueError('Need 4 coordinates for quaternion')# Actual hard-coded kinematic differential equationse0,e1,e2,e3=coordsw=Matrix(speeds+[0])E=Matrix([[e0,-e3,e2,e1],[e3,e0,-e1,e2],[-e2,e1,e0,e3],[-e1,-e2,-e3,e0]])edots=Matrix([diff(i,dynamicsymbols._t)foriin[e1,e2,e3,e0]])returnlist(edots.T-0.5*w.T*E.T)else:raiseValueError('Not an approved rotation type for this function')

[docs]defpartial_velocity(vel_list,u_list,frame):"""Returns a list of partial velocities. For a list of velocity or angular velocity vectors the partial derivatives with respect to the supplied generalized speeds are computed, in the specified ReferenceFrame. The output is a list of lists. The outer list has a number of elements equal to the number of supplied velocity vectors. The inner lists are, for each velocity vector, the partial derivatives of that velocity vector with respect to the generalized speeds supplied. Parameters ========== vel_list : list List of velocities of Point's and angular velocities of ReferenceFrame's u_list : list List of independent generalized speeds. frame : ReferenceFrame The ReferenceFrame the partial derivatives are going to be taken in. Examples ======== >>> from sympy.physics.mechanics import Point, ReferenceFrame >>> from sympy.physics.mechanics import dynamicsymbols >>> from sympy.physics.mechanics import partial_velocity >>> u = dynamicsymbols('u') >>> N = ReferenceFrame('N') >>> P = Point('P') >>> P.set_vel(N, u * N.x) >>> vel_list = [P.vel(N)] >>> u_list = [u] >>> partial_velocity(vel_list, u_list, N) [[N.x]] """ifnothasattr(vel_list,'__iter__'):raiseTypeError('Provide velocities in an iterable')ifnothasattr(u_list,'__iter__'):raiseTypeError('Provide speeds in an iterable')list_of_pvlists=[]foriinvel_list:pvlist=[]forjinu_list:vel=i.diff(j,frame)pvlist+=[vel]list_of_pvlists+=[pvlist]returnlist_of_pvlists