Initialisation du repository de Beta
This commit is contained in:
commit
14985f6dbb
9469 changed files with 1903273 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,123 @@
|
|||
from sympy.core.numbers import (Float, pi)
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
|
||||
from sympy.physics.vector import ReferenceFrame, dynamicsymbols, outer
|
||||
from sympy.physics.vector.dyadic import _check_dyadic
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
|
||||
|
||||
def test_dyadic():
|
||||
d1 = A.x | A.x
|
||||
d2 = A.y | A.y
|
||||
d3 = A.x | A.y
|
||||
assert d1 * 0 == 0
|
||||
assert d1 != 0
|
||||
assert d1 * 2 == 2 * A.x | A.x
|
||||
assert d1 / 2. == 0.5 * d1
|
||||
assert d1 & (0 * d1) == 0
|
||||
assert d1 & d2 == 0
|
||||
assert d1 & A.x == A.x
|
||||
assert d1 ^ A.x == 0
|
||||
assert d1 ^ A.y == A.x | A.z
|
||||
assert d1 ^ A.z == - A.x | A.y
|
||||
assert d2 ^ A.x == - A.y | A.z
|
||||
assert A.x ^ d1 == 0
|
||||
assert A.y ^ d1 == - A.z | A.x
|
||||
assert A.z ^ d1 == A.y | A.x
|
||||
assert A.x & d1 == A.x
|
||||
assert A.y & d1 == 0
|
||||
assert A.y & d2 == A.y
|
||||
assert d1 & d3 == A.x | A.y
|
||||
assert d3 & d1 == 0
|
||||
assert d1.dt(A) == 0
|
||||
q = dynamicsymbols('q')
|
||||
qd = dynamicsymbols('q', 1)
|
||||
B = A.orientnew('B', 'Axis', [q, A.z])
|
||||
assert d1.express(B) == d1.express(B, B)
|
||||
assert d1.express(B) == ((cos(q)**2) * (B.x | B.x) + (-sin(q) * cos(q)) *
|
||||
(B.x | B.y) + (-sin(q) * cos(q)) * (B.y | B.x) + (sin(q)**2) *
|
||||
(B.y | B.y))
|
||||
assert d1.express(B, A) == (cos(q)) * (B.x | A.x) + (-sin(q)) * (B.y | A.x)
|
||||
assert d1.express(A, B) == (cos(q)) * (A.x | B.x) + (-sin(q)) * (A.x | B.y)
|
||||
assert d1.dt(B) == (-qd) * (A.y | A.x) + (-qd) * (A.x | A.y)
|
||||
|
||||
assert d1.to_matrix(A) == Matrix([[1, 0, 0], [0, 0, 0], [0, 0, 0]])
|
||||
assert d1.to_matrix(A, B) == Matrix([[cos(q), -sin(q), 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]])
|
||||
assert d3.to_matrix(A) == Matrix([[0, 1, 0], [0, 0, 0], [0, 0, 0]])
|
||||
a, b, c, d, e, f = symbols('a, b, c, d, e, f')
|
||||
v1 = a * A.x + b * A.y + c * A.z
|
||||
v2 = d * A.x + e * A.y + f * A.z
|
||||
d4 = v1.outer(v2)
|
||||
assert d4.to_matrix(A) == Matrix([[a * d, a * e, a * f],
|
||||
[b * d, b * e, b * f],
|
||||
[c * d, c * e, c * f]])
|
||||
d5 = v1.outer(v1)
|
||||
C = A.orientnew('C', 'Axis', [q, A.x])
|
||||
for expected, actual in zip(C.dcm(A) * d5.to_matrix(A) * C.dcm(A).T,
|
||||
d5.to_matrix(C)):
|
||||
assert (expected - actual).simplify() == 0
|
||||
|
||||
raises(TypeError, lambda: d1.applyfunc(0))
|
||||
|
||||
|
||||
def test_dyadic_simplify():
|
||||
x, y, z, k, n, m, w, f, s, A = symbols('x, y, z, k, n, m, w, f, s, A')
|
||||
N = ReferenceFrame('N')
|
||||
|
||||
dy = N.x | N.x
|
||||
test1 = (1 / x + 1 / y) * dy
|
||||
assert (N.x & test1 & N.x) != (x + y) / (x * y)
|
||||
test1 = test1.simplify()
|
||||
assert (N.x & test1 & N.x) == (x + y) / (x * y)
|
||||
|
||||
test2 = (A**2 * s**4 / (4 * pi * k * m**3)) * dy
|
||||
test2 = test2.simplify()
|
||||
assert (N.x & test2 & N.x) == (A**2 * s**4 / (4 * pi * k * m**3))
|
||||
|
||||
test3 = ((4 + 4 * x - 2 * (2 + 2 * x)) / (2 + 2 * x)) * dy
|
||||
test3 = test3.simplify()
|
||||
assert (N.x & test3 & N.x) == 0
|
||||
|
||||
test4 = ((-4 * x * y**2 - 2 * y**3 - 2 * x**2 * y) / (x + y)**2) * dy
|
||||
test4 = test4.simplify()
|
||||
assert (N.x & test4 & N.x) == -2 * y
|
||||
|
||||
|
||||
def test_dyadic_subs():
|
||||
N = ReferenceFrame('N')
|
||||
s = symbols('s')
|
||||
a = s*(N.x | N.x)
|
||||
assert a.subs({s: 2}) == 2*(N.x | N.x)
|
||||
|
||||
|
||||
def test_check_dyadic():
|
||||
raises(TypeError, lambda: _check_dyadic(0))
|
||||
|
||||
|
||||
def test_dyadic_evalf():
|
||||
N = ReferenceFrame('N')
|
||||
a = pi * (N.x | N.x)
|
||||
assert a.evalf(3) == Float('3.1416', 3) * (N.x | N.x)
|
||||
s = symbols('s')
|
||||
a = 5 * s * pi* (N.x | N.x)
|
||||
assert a.evalf(2) == Float('5', 2) * Float('3.1416', 2) * s * (N.x | N.x)
|
||||
assert a.evalf(9, subs={s: 5.124}) == Float('80.48760378', 9) * (N.x | N.x)
|
||||
|
||||
|
||||
def test_dyadic_xreplace():
|
||||
x, y, z = symbols('x y z')
|
||||
N = ReferenceFrame('N')
|
||||
D = outer(N.x, N.x)
|
||||
v = x*y * D
|
||||
assert v.xreplace({x : cos(x)}) == cos(x)*y * D
|
||||
assert v.xreplace({x*y : pi}) == pi * D
|
||||
v = (x*y)**z * D
|
||||
assert v.xreplace({(x*y)**z : 1}) == D
|
||||
assert v.xreplace({x:1, z:0}) == D
|
||||
raises(TypeError, lambda: v.xreplace())
|
||||
raises(TypeError, lambda: v.xreplace([x, y]))
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.physics.vector import ReferenceFrame, Vector, Point, \
|
||||
dynamicsymbols
|
||||
from sympy.physics.vector.fieldfunctions import divergence, \
|
||||
gradient, curl, is_conservative, is_solenoidal, \
|
||||
scalar_potential, scalar_potential_difference
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
R = ReferenceFrame('R')
|
||||
q = dynamicsymbols('q')
|
||||
P = R.orientnew('P', 'Axis', [q, R.z])
|
||||
|
||||
|
||||
def test_curl():
|
||||
assert curl(Vector(0), R) == Vector(0)
|
||||
assert curl(R.x, R) == Vector(0)
|
||||
assert curl(2*R[1]**2*R.y, R) == Vector(0)
|
||||
assert curl(R[0]*R[1]*R.z, R) == R[0]*R.x - R[1]*R.y
|
||||
assert curl(R[0]*R[1]*R[2] * (R.x+R.y+R.z), R) == \
|
||||
(-R[0]*R[1] + R[0]*R[2])*R.x + (R[0]*R[1] - R[1]*R[2])*R.y + \
|
||||
(-R[0]*R[2] + R[1]*R[2])*R.z
|
||||
assert curl(2*R[0]**2*R.y, R) == 4*R[0]*R.z
|
||||
assert curl(P[0]**2*R.x + P.y, R) == \
|
||||
- 2*(R[0]*cos(q) + R[1]*sin(q))*sin(q)*R.z
|
||||
assert curl(P[0]*R.y, P) == cos(q)*P.z
|
||||
|
||||
|
||||
def test_divergence():
|
||||
assert divergence(Vector(0), R) is S.Zero
|
||||
assert divergence(R.x, R) is S.Zero
|
||||
assert divergence(R[0]**2*R.x, R) == 2*R[0]
|
||||
assert divergence(R[0]*R[1]*R[2] * (R.x+R.y+R.z), R) == \
|
||||
R[0]*R[1] + R[0]*R[2] + R[1]*R[2]
|
||||
assert divergence((1/(R[0]*R[1]*R[2])) * (R.x+R.y+R.z), R) == \
|
||||
-1/(R[0]*R[1]*R[2]**2) - 1/(R[0]*R[1]**2*R[2]) - \
|
||||
1/(R[0]**2*R[1]*R[2])
|
||||
v = P[0]*P.x + P[1]*P.y + P[2]*P.z
|
||||
assert divergence(v, P) == 3
|
||||
assert divergence(v, R).simplify() == 3
|
||||
assert divergence(P[0]*R.x + R[0]*P.x, R) == 2*cos(q)
|
||||
|
||||
|
||||
def test_gradient():
|
||||
a = Symbol('a')
|
||||
assert gradient(0, R) == Vector(0)
|
||||
assert gradient(R[0], R) == R.x
|
||||
assert gradient(R[0]*R[1]*R[2], R) == \
|
||||
R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
|
||||
assert gradient(2*R[0]**2, R) == 4*R[0]*R.x
|
||||
assert gradient(a*sin(R[1])/R[0], R) == \
|
||||
- a*sin(R[1])/R[0]**2*R.x + a*cos(R[1])/R[0]*R.y
|
||||
assert gradient(P[0]*P[1], R) == \
|
||||
((-R[0]*sin(q) + R[1]*cos(q))*cos(q) - (R[0]*cos(q) + R[1]*sin(q))*sin(q))*R.x + \
|
||||
((-R[0]*sin(q) + R[1]*cos(q))*sin(q) + (R[0]*cos(q) + R[1]*sin(q))*cos(q))*R.y
|
||||
assert gradient(P[0]*R[2], P) == P[2]*P.x + P[0]*P.z
|
||||
|
||||
|
||||
scalar_field = 2*R[0]**2*R[1]*R[2]
|
||||
grad_field = gradient(scalar_field, R)
|
||||
vector_field = R[1]**2*R.x + 3*R[0]*R.y + 5*R[1]*R[2]*R.z
|
||||
curl_field = curl(vector_field, R)
|
||||
|
||||
|
||||
def test_conservative():
|
||||
assert is_conservative(0) is True
|
||||
assert is_conservative(R.x) is True
|
||||
assert is_conservative(2 * R.x + 3 * R.y + 4 * R.z) is True
|
||||
assert is_conservative(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z) is \
|
||||
True
|
||||
assert is_conservative(R[0] * R.y) is False
|
||||
assert is_conservative(grad_field) is True
|
||||
assert is_conservative(curl_field) is False
|
||||
assert is_conservative(4*R[0]*R[1]*R[2]*R.x + 2*R[0]**2*R[2]*R.y) is \
|
||||
False
|
||||
assert is_conservative(R[2]*P.x + P[0]*R.z) is True
|
||||
|
||||
|
||||
def test_solenoidal():
|
||||
assert is_solenoidal(0) is True
|
||||
assert is_solenoidal(R.x) is True
|
||||
assert is_solenoidal(2 * R.x + 3 * R.y + 4 * R.z) is True
|
||||
assert is_solenoidal(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z) is \
|
||||
True
|
||||
assert is_solenoidal(R[1] * R.y) is False
|
||||
assert is_solenoidal(grad_field) is False
|
||||
assert is_solenoidal(curl_field) is True
|
||||
assert is_solenoidal((-2*R[1] + 3)*R.z) is True
|
||||
assert is_solenoidal(cos(q)*R.x + sin(q)*R.y + cos(q)*P.z) is True
|
||||
assert is_solenoidal(R[2]*P.x + P[0]*R.z) is True
|
||||
|
||||
|
||||
def test_scalar_potential():
|
||||
assert scalar_potential(0, R) == 0
|
||||
assert scalar_potential(R.x, R) == R[0]
|
||||
assert scalar_potential(R.y, R) == R[1]
|
||||
assert scalar_potential(R.z, R) == R[2]
|
||||
assert scalar_potential(R[1]*R[2]*R.x + R[0]*R[2]*R.y + \
|
||||
R[0]*R[1]*R.z, R) == R[0]*R[1]*R[2]
|
||||
assert scalar_potential(grad_field, R) == scalar_field
|
||||
assert scalar_potential(R[2]*P.x + P[0]*R.z, R) == \
|
||||
R[0]*R[2]*cos(q) + R[1]*R[2]*sin(q)
|
||||
assert scalar_potential(R[2]*P.x + P[0]*R.z, P) == P[0]*P[2]
|
||||
raises(ValueError, lambda: scalar_potential(R[0] * R.y, R))
|
||||
|
||||
|
||||
def test_scalar_potential_difference():
|
||||
origin = Point('O')
|
||||
point1 = origin.locatenew('P1', 1*R.x + 2*R.y + 3*R.z)
|
||||
point2 = origin.locatenew('P2', 4*R.x + 5*R.y + 6*R.z)
|
||||
genericpointR = origin.locatenew('RP', R[0]*R.x + R[1]*R.y + R[2]*R.z)
|
||||
genericpointP = origin.locatenew('PP', P[0]*P.x + P[1]*P.y + P[2]*P.z)
|
||||
assert scalar_potential_difference(S.Zero, R, point1, point2, \
|
||||
origin) == 0
|
||||
assert scalar_potential_difference(scalar_field, R, origin, \
|
||||
genericpointR, origin) == \
|
||||
scalar_field
|
||||
assert scalar_potential_difference(grad_field, R, origin, \
|
||||
genericpointR, origin) == \
|
||||
scalar_field
|
||||
assert scalar_potential_difference(grad_field, R, point1, point2,
|
||||
origin) == 948
|
||||
assert scalar_potential_difference(R[1]*R[2]*R.x + R[0]*R[2]*R.y + \
|
||||
R[0]*R[1]*R.z, R, point1,
|
||||
genericpointR, origin) == \
|
||||
R[0]*R[1]*R[2] - 6
|
||||
potential_diff_P = 2*P[2]*(P[0]*sin(q) + P[1]*cos(q))*\
|
||||
(P[0]*cos(q) - P[1]*sin(q))**2
|
||||
assert scalar_potential_difference(grad_field, P, origin, \
|
||||
genericpointP, \
|
||||
origin).simplify() == \
|
||||
potential_diff_P
|
||||
|
|
@ -0,0 +1,761 @@
|
|||
from sympy.core.numbers import pi
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.simplify import trigsimp
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.matrices.dense import (eye, zeros)
|
||||
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.physics.vector import (ReferenceFrame, Vector, CoordinateSym,
|
||||
dynamicsymbols, time_derivative, express,
|
||||
dot)
|
||||
from sympy.physics.vector.frame import _check_frame
|
||||
from sympy.physics.vector.vector import VectorTypeError
|
||||
from sympy.testing.pytest import raises
|
||||
import warnings
|
||||
import pickle
|
||||
|
||||
|
||||
def test_dict_list():
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
D = ReferenceFrame('D')
|
||||
E = ReferenceFrame('E')
|
||||
F = ReferenceFrame('F')
|
||||
|
||||
B.orient_axis(A, A.x, 1.0)
|
||||
C.orient_axis(B, B.x, 1.0)
|
||||
D.orient_axis(C, C.x, 1.0)
|
||||
|
||||
assert D._dict_list(A, 0) == [D, C, B, A]
|
||||
|
||||
E.orient_axis(D, D.x, 1.0)
|
||||
|
||||
assert C._dict_list(A, 0) == [C, B, A]
|
||||
assert C._dict_list(E, 0) == [C, D, E]
|
||||
|
||||
# only 0, 1, 2 permitted for second argument
|
||||
raises(ValueError, lambda: C._dict_list(E, 5))
|
||||
# no connecting path
|
||||
raises(ValueError, lambda: F._dict_list(A, 0))
|
||||
|
||||
|
||||
def test_coordinate_vars():
|
||||
"""Tests the coordinate variables functionality"""
|
||||
A = ReferenceFrame('A')
|
||||
assert CoordinateSym('Ax', A, 0) == A[0]
|
||||
assert CoordinateSym('Ax', A, 1) == A[1]
|
||||
assert CoordinateSym('Ax', A, 2) == A[2]
|
||||
raises(ValueError, lambda: CoordinateSym('Ax', A, 3))
|
||||
q = dynamicsymbols('q')
|
||||
qd = dynamicsymbols('q', 1)
|
||||
assert isinstance(A[0], CoordinateSym) and \
|
||||
isinstance(A[0], CoordinateSym) and \
|
||||
isinstance(A[0], CoordinateSym)
|
||||
assert A.variable_map(A) == {A[0]:A[0], A[1]:A[1], A[2]:A[2]}
|
||||
assert A[0].frame == A
|
||||
B = A.orientnew('B', 'Axis', [q, A.z])
|
||||
assert B.variable_map(A) == {B[2]: A[2], B[1]: -A[0]*sin(q) + A[1]*cos(q),
|
||||
B[0]: A[0]*cos(q) + A[1]*sin(q)}
|
||||
assert A.variable_map(B) == {A[0]: B[0]*cos(q) - B[1]*sin(q),
|
||||
A[1]: B[0]*sin(q) + B[1]*cos(q), A[2]: B[2]}
|
||||
assert time_derivative(B[0], A) == -A[0]*sin(q)*qd + A[1]*cos(q)*qd
|
||||
assert time_derivative(B[1], A) == -A[0]*cos(q)*qd - A[1]*sin(q)*qd
|
||||
assert time_derivative(B[2], A) == 0
|
||||
assert express(B[0], A, variables=True) == A[0]*cos(q) + A[1]*sin(q)
|
||||
assert express(B[1], A, variables=True) == -A[0]*sin(q) + A[1]*cos(q)
|
||||
assert express(B[2], A, variables=True) == A[2]
|
||||
assert time_derivative(A[0]*A.x + A[1]*A.y + A[2]*A.z, B) == A[1]*qd*A.x - A[0]*qd*A.y
|
||||
assert time_derivative(B[0]*B.x + B[1]*B.y + B[2]*B.z, A) == - B[1]*qd*B.x + B[0]*qd*B.y
|
||||
assert express(B[0]*B[1]*B[2], A, variables=True) == \
|
||||
A[2]*(-A[0]*sin(q) + A[1]*cos(q))*(A[0]*cos(q) + A[1]*sin(q))
|
||||
assert (time_derivative(B[0]*B[1]*B[2], A) -
|
||||
(A[2]*(-A[0]**2*cos(2*q) -
|
||||
2*A[0]*A[1]*sin(2*q) +
|
||||
A[1]**2*cos(2*q))*qd)).trigsimp() == 0
|
||||
assert express(B[0]*B.x + B[1]*B.y + B[2]*B.z, A) == \
|
||||
(B[0]*cos(q) - B[1]*sin(q))*A.x + (B[0]*sin(q) + \
|
||||
B[1]*cos(q))*A.y + B[2]*A.z
|
||||
assert express(B[0]*B.x + B[1]*B.y + B[2]*B.z, A,
|
||||
variables=True).simplify() == A[0]*A.x + A[1]*A.y + A[2]*A.z
|
||||
assert express(A[0]*A.x + A[1]*A.y + A[2]*A.z, B) == \
|
||||
(A[0]*cos(q) + A[1]*sin(q))*B.x + \
|
||||
(-A[0]*sin(q) + A[1]*cos(q))*B.y + A[2]*B.z
|
||||
assert express(A[0]*A.x + A[1]*A.y + A[2]*A.z, B,
|
||||
variables=True).simplify() == B[0]*B.x + B[1]*B.y + B[2]*B.z
|
||||
N = B.orientnew('N', 'Axis', [-q, B.z])
|
||||
assert ({k: v.simplify() for k, v in N.variable_map(A).items()} ==
|
||||
{N[0]: A[0], N[2]: A[2], N[1]: A[1]})
|
||||
C = A.orientnew('C', 'Axis', [q, A.x + A.y + A.z])
|
||||
mapping = A.variable_map(C)
|
||||
assert trigsimp(mapping[A[0]]) == (2*C[0]*cos(q)/3 + C[0]/3 -
|
||||
2*C[1]*sin(q + pi/6)/3 +
|
||||
C[1]/3 - 2*C[2]*cos(q + pi/3)/3 +
|
||||
C[2]/3)
|
||||
assert trigsimp(mapping[A[1]]) == -2*C[0]*cos(q + pi/3)/3 + \
|
||||
C[0]/3 + 2*C[1]*cos(q)/3 + C[1]/3 - 2*C[2]*sin(q + pi/6)/3 + C[2]/3
|
||||
assert trigsimp(mapping[A[2]]) == -2*C[0]*sin(q + pi/6)/3 + C[0]/3 - \
|
||||
2*C[1]*cos(q + pi/3)/3 + C[1]/3 + 2*C[2]*cos(q)/3 + C[2]/3
|
||||
|
||||
|
||||
def test_ang_vel():
|
||||
q1, q2, q3, q4 = dynamicsymbols('q1 q2 q3 q4')
|
||||
q1d, q2d, q3d, q4d = dynamicsymbols('q1 q2 q3 q4', 1)
|
||||
N = ReferenceFrame('N')
|
||||
A = N.orientnew('A', 'Axis', [q1, N.z])
|
||||
B = A.orientnew('B', 'Axis', [q2, A.x])
|
||||
C = B.orientnew('C', 'Axis', [q3, B.y])
|
||||
D = N.orientnew('D', 'Axis', [q4, N.y])
|
||||
u1, u2, u3 = dynamicsymbols('u1 u2 u3')
|
||||
assert A.ang_vel_in(N) == (q1d)*A.z
|
||||
assert B.ang_vel_in(N) == (q2d)*B.x + (q1d)*A.z
|
||||
assert C.ang_vel_in(N) == (q3d)*C.y + (q2d)*B.x + (q1d)*A.z
|
||||
|
||||
A2 = N.orientnew('A2', 'Axis', [q4, N.y])
|
||||
assert N.ang_vel_in(N) == 0
|
||||
assert N.ang_vel_in(A) == -q1d*N.z
|
||||
assert N.ang_vel_in(B) == -q1d*A.z - q2d*B.x
|
||||
assert N.ang_vel_in(C) == -q1d*A.z - q2d*B.x - q3d*B.y
|
||||
assert N.ang_vel_in(A2) == -q4d*N.y
|
||||
|
||||
assert A.ang_vel_in(N) == q1d*N.z
|
||||
assert A.ang_vel_in(A) == 0
|
||||
assert A.ang_vel_in(B) == - q2d*B.x
|
||||
assert A.ang_vel_in(C) == - q2d*B.x - q3d*B.y
|
||||
assert A.ang_vel_in(A2) == q1d*N.z - q4d*N.y
|
||||
|
||||
assert B.ang_vel_in(N) == q1d*A.z + q2d*A.x
|
||||
assert B.ang_vel_in(A) == q2d*A.x
|
||||
assert B.ang_vel_in(B) == 0
|
||||
assert B.ang_vel_in(C) == -q3d*B.y
|
||||
assert B.ang_vel_in(A2) == q1d*A.z + q2d*A.x - q4d*N.y
|
||||
|
||||
assert C.ang_vel_in(N) == q1d*A.z + q2d*A.x + q3d*B.y
|
||||
assert C.ang_vel_in(A) == q2d*A.x + q3d*C.y
|
||||
assert C.ang_vel_in(B) == q3d*B.y
|
||||
assert C.ang_vel_in(C) == 0
|
||||
assert C.ang_vel_in(A2) == q1d*A.z + q2d*A.x + q3d*B.y - q4d*N.y
|
||||
|
||||
assert A2.ang_vel_in(N) == q4d*A2.y
|
||||
assert A2.ang_vel_in(A) == q4d*A2.y - q1d*N.z
|
||||
assert A2.ang_vel_in(B) == q4d*N.y - q1d*A.z - q2d*A.x
|
||||
assert A2.ang_vel_in(C) == q4d*N.y - q1d*A.z - q2d*A.x - q3d*B.y
|
||||
assert A2.ang_vel_in(A2) == 0
|
||||
|
||||
C.set_ang_vel(N, u1*C.x + u2*C.y + u3*C.z)
|
||||
assert C.ang_vel_in(N) == (u1)*C.x + (u2)*C.y + (u3)*C.z
|
||||
assert N.ang_vel_in(C) == (-u1)*C.x + (-u2)*C.y + (-u3)*C.z
|
||||
assert C.ang_vel_in(D) == (u1)*C.x + (u2)*C.y + (u3)*C.z + (-q4d)*D.y
|
||||
assert D.ang_vel_in(C) == (-u1)*C.x + (-u2)*C.y + (-u3)*C.z + (q4d)*D.y
|
||||
|
||||
q0 = dynamicsymbols('q0')
|
||||
q0d = dynamicsymbols('q0', 1)
|
||||
E = N.orientnew('E', 'Quaternion', (q0, q1, q2, q3))
|
||||
assert E.ang_vel_in(N) == (
|
||||
2 * (q1d * q0 + q2d * q3 - q3d * q2 - q0d * q1) * E.x +
|
||||
2 * (q2d * q0 + q3d * q1 - q1d * q3 - q0d * q2) * E.y +
|
||||
2 * (q3d * q0 + q1d * q2 - q2d * q1 - q0d * q3) * E.z)
|
||||
|
||||
F = N.orientnew('F', 'Body', (q1, q2, q3), 313)
|
||||
assert F.ang_vel_in(N) == ((sin(q2)*sin(q3)*q1d + cos(q3)*q2d)*F.x +
|
||||
(sin(q2)*cos(q3)*q1d - sin(q3)*q2d)*F.y + (cos(q2)*q1d + q3d)*F.z)
|
||||
G = N.orientnew('G', 'Axis', (q1, N.x + N.y))
|
||||
assert G.ang_vel_in(N) == q1d * (N.x + N.y).normalize()
|
||||
assert N.ang_vel_in(G) == -q1d * (N.x + N.y).normalize()
|
||||
|
||||
|
||||
def test_dcm():
|
||||
q1, q2, q3, q4 = dynamicsymbols('q1 q2 q3 q4')
|
||||
N = ReferenceFrame('N')
|
||||
A = N.orientnew('A', 'Axis', [q1, N.z])
|
||||
B = A.orientnew('B', 'Axis', [q2, A.x])
|
||||
C = B.orientnew('C', 'Axis', [q3, B.y])
|
||||
D = N.orientnew('D', 'Axis', [q4, N.y])
|
||||
E = N.orientnew('E', 'Space', [q1, q2, q3], '123')
|
||||
assert N.dcm(C) == Matrix([
|
||||
[- sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3), - sin(q1) *
|
||||
cos(q2), sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1)], [sin(q1) *
|
||||
cos(q3) + sin(q2) * sin(q3) * cos(q1), cos(q1) * cos(q2), sin(q1) *
|
||||
sin(q3) - sin(q2) * cos(q1) * cos(q3)], [- sin(q3) * cos(q2), sin(q2),
|
||||
cos(q2) * cos(q3)]])
|
||||
# This is a little touchy. Is it ok to use simplify in assert?
|
||||
test_mat = D.dcm(C) - Matrix(
|
||||
[[cos(q1) * cos(q3) * cos(q4) - sin(q3) * (- sin(q4) * cos(q2) +
|
||||
sin(q1) * sin(q2) * cos(q4)), - sin(q2) * sin(q4) - sin(q1) *
|
||||
cos(q2) * cos(q4), sin(q3) * cos(q1) * cos(q4) + cos(q3) * (- sin(q4) *
|
||||
cos(q2) + sin(q1) * sin(q2) * cos(q4))], [sin(q1) * cos(q3) +
|
||||
sin(q2) * sin(q3) * cos(q1), cos(q1) * cos(q2), sin(q1) * sin(q3) -
|
||||
sin(q2) * cos(q1) * cos(q3)], [sin(q4) * cos(q1) * cos(q3) -
|
||||
sin(q3) * (cos(q2) * cos(q4) + sin(q1) * sin(q2) * sin(q4)), sin(q2) *
|
||||
cos(q4) - sin(q1) * sin(q4) * cos(q2), sin(q3) * sin(q4) * cos(q1) +
|
||||
cos(q3) * (cos(q2) * cos(q4) + sin(q1) * sin(q2) * sin(q4))]])
|
||||
assert test_mat.expand() == zeros(3, 3)
|
||||
assert E.dcm(N) == Matrix(
|
||||
[[cos(q2)*cos(q3), sin(q3)*cos(q2), -sin(q2)],
|
||||
[sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), sin(q1)*sin(q2)*sin(q3) +
|
||||
cos(q1)*cos(q3), sin(q1)*cos(q2)], [sin(q1)*sin(q3) +
|
||||
sin(q2)*cos(q1)*cos(q3), - sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1),
|
||||
cos(q1)*cos(q2)]])
|
||||
|
||||
def test_w_diff_dcm1():
|
||||
# Ref:
|
||||
# Dynamics Theory and Applications, Kane 1985
|
||||
# Sec. 2.1 ANGULAR VELOCITY
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
|
||||
c11, c12, c13 = dynamicsymbols('C11 C12 C13')
|
||||
c21, c22, c23 = dynamicsymbols('C21 C22 C23')
|
||||
c31, c32, c33 = dynamicsymbols('C31 C32 C33')
|
||||
|
||||
c11d, c12d, c13d = dynamicsymbols('C11 C12 C13', level=1)
|
||||
c21d, c22d, c23d = dynamicsymbols('C21 C22 C23', level=1)
|
||||
c31d, c32d, c33d = dynamicsymbols('C31 C32 C33', level=1)
|
||||
|
||||
DCM = Matrix([
|
||||
[c11, c12, c13],
|
||||
[c21, c22, c23],
|
||||
[c31, c32, c33]
|
||||
])
|
||||
|
||||
B.orient(A, 'DCM', DCM)
|
||||
b1a = (B.x).express(A)
|
||||
b2a = (B.y).express(A)
|
||||
b3a = (B.z).express(A)
|
||||
|
||||
# Equation (2.1.1)
|
||||
B.set_ang_vel(A, B.x*(dot((b3a).dt(A), B.y))
|
||||
+ B.y*(dot((b1a).dt(A), B.z))
|
||||
+ B.z*(dot((b2a).dt(A), B.x)))
|
||||
|
||||
# Equation (2.1.21)
|
||||
expr = ( (c12*c13d + c22*c23d + c32*c33d)*B.x
|
||||
+ (c13*c11d + c23*c21d + c33*c31d)*B.y
|
||||
+ (c11*c12d + c21*c22d + c31*c32d)*B.z)
|
||||
assert B.ang_vel_in(A) - expr == 0
|
||||
|
||||
def test_w_diff_dcm2():
|
||||
q1, q2, q3 = dynamicsymbols('q1:4')
|
||||
N = ReferenceFrame('N')
|
||||
A = N.orientnew('A', 'axis', [q1, N.x])
|
||||
B = A.orientnew('B', 'axis', [q2, A.y])
|
||||
C = B.orientnew('C', 'axis', [q3, B.z])
|
||||
|
||||
DCM = C.dcm(N).T
|
||||
D = N.orientnew('D', 'DCM', DCM)
|
||||
|
||||
# Frames D and C are the same ReferenceFrame,
|
||||
# since they have equal DCM respect to frame N.
|
||||
# Therefore, D and C should have same angle velocity in N.
|
||||
assert D.dcm(N) == C.dcm(N) == Matrix([
|
||||
[cos(q2)*cos(q3), sin(q1)*sin(q2)*cos(q3) +
|
||||
sin(q3)*cos(q1), sin(q1)*sin(q3) -
|
||||
sin(q2)*cos(q1)*cos(q3)], [-sin(q3)*cos(q2),
|
||||
-sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3),
|
||||
sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
|
||||
[sin(q2), -sin(q1)*cos(q2), cos(q1)*cos(q2)]])
|
||||
assert (D.ang_vel_in(N) - C.ang_vel_in(N)).express(N).simplify() == 0
|
||||
|
||||
def test_orientnew_respects_parent_class():
|
||||
class MyReferenceFrame(ReferenceFrame):
|
||||
pass
|
||||
B = MyReferenceFrame('B')
|
||||
C = B.orientnew('C', 'Axis', [0, B.x])
|
||||
assert isinstance(C, MyReferenceFrame)
|
||||
|
||||
|
||||
def test_orientnew_respects_input_indices():
|
||||
N = ReferenceFrame('N')
|
||||
q1 = dynamicsymbols('q1')
|
||||
A = N.orientnew('a', 'Axis', [q1, N.z])
|
||||
#modify default indices:
|
||||
minds = [x+'1' for x in N.indices]
|
||||
B = N.orientnew('b', 'Axis', [q1, N.z], indices=minds)
|
||||
|
||||
assert N.indices == A.indices
|
||||
assert B.indices == minds
|
||||
|
||||
def test_orientnew_respects_input_latexs():
|
||||
N = ReferenceFrame('N')
|
||||
q1 = dynamicsymbols('q1')
|
||||
A = N.orientnew('a', 'Axis', [q1, N.z])
|
||||
|
||||
#build default and alternate latex_vecs:
|
||||
def_latex_vecs = [(r"\mathbf{\hat{%s}_%s}" % (A.name.lower(),
|
||||
A.indices[0])), (r"\mathbf{\hat{%s}_%s}" %
|
||||
(A.name.lower(), A.indices[1])),
|
||||
(r"\mathbf{\hat{%s}_%s}" % (A.name.lower(),
|
||||
A.indices[2]))]
|
||||
|
||||
name = 'b'
|
||||
indices = [x+'1' for x in N.indices]
|
||||
new_latex_vecs = [(r"\mathbf{\hat{%s}_{%s}}" % (name.lower(),
|
||||
indices[0])), (r"\mathbf{\hat{%s}_{%s}}" %
|
||||
(name.lower(), indices[1])),
|
||||
(r"\mathbf{\hat{%s}_{%s}}" % (name.lower(),
|
||||
indices[2]))]
|
||||
|
||||
B = N.orientnew(name, 'Axis', [q1, N.z], latexs=new_latex_vecs)
|
||||
|
||||
assert A.latex_vecs == def_latex_vecs
|
||||
assert B.latex_vecs == new_latex_vecs
|
||||
assert B.indices != indices
|
||||
|
||||
def test_orientnew_respects_input_variables():
|
||||
N = ReferenceFrame('N')
|
||||
q1 = dynamicsymbols('q1')
|
||||
A = N.orientnew('a', 'Axis', [q1, N.z])
|
||||
|
||||
#build non-standard variable names
|
||||
name = 'b'
|
||||
new_variables = ['notb_'+x+'1' for x in N.indices]
|
||||
B = N.orientnew(name, 'Axis', [q1, N.z], variables=new_variables)
|
||||
|
||||
for j,var in enumerate(A.varlist):
|
||||
assert var.name == A.name + '_' + A.indices[j]
|
||||
|
||||
for j,var in enumerate(B.varlist):
|
||||
assert var.name == new_variables[j]
|
||||
|
||||
def test_issue_10348():
|
||||
u = dynamicsymbols('u:3')
|
||||
I = ReferenceFrame('I')
|
||||
I.orientnew('A', 'space', u, 'XYZ')
|
||||
|
||||
|
||||
def test_issue_11503():
|
||||
A = ReferenceFrame("A")
|
||||
A.orientnew("B", "Axis", [35, A.y])
|
||||
C = ReferenceFrame("C")
|
||||
A.orient(C, "Axis", [70, C.z])
|
||||
|
||||
|
||||
def test_partial_velocity():
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
A = ReferenceFrame('A')
|
||||
|
||||
u1, u2 = dynamicsymbols('u1, u2')
|
||||
|
||||
A.set_ang_vel(N, u1 * A.x + u2 * N.y)
|
||||
|
||||
assert N.partial_velocity(A, u1) == -A.x
|
||||
assert N.partial_velocity(A, u1, u2) == (-A.x, -N.y)
|
||||
|
||||
assert A.partial_velocity(N, u1) == A.x
|
||||
assert A.partial_velocity(N, u1, u2) == (A.x, N.y)
|
||||
|
||||
assert N.partial_velocity(N, u1) == 0
|
||||
assert A.partial_velocity(A, u1) == 0
|
||||
|
||||
|
||||
def test_issue_11498():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
|
||||
# Identity transformation
|
||||
A.orient(B, 'DCM', eye(3))
|
||||
assert A.dcm(B) == Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
|
||||
assert B.dcm(A) == Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
|
||||
|
||||
# x -> y
|
||||
# y -> -z
|
||||
# z -> -x
|
||||
A.orient(B, 'DCM', Matrix([[0, 1, 0], [0, 0, -1], [-1, 0, 0]]))
|
||||
assert B.dcm(A) == Matrix([[0, 1, 0], [0, 0, -1], [-1, 0, 0]])
|
||||
assert A.dcm(B) == Matrix([[0, 0, -1], [1, 0, 0], [0, -1, 0]])
|
||||
assert B.dcm(A).T == A.dcm(B)
|
||||
|
||||
|
||||
def test_reference_frame():
|
||||
raises(TypeError, lambda: ReferenceFrame(0))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', 0))
|
||||
raises(ValueError, lambda: ReferenceFrame('N', [0, 1]))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', [0, 1, 2]))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], 0))
|
||||
raises(ValueError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], [0, 1]))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], [0, 1, 2]))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'],
|
||||
['a', 'b', 'c'], 0))
|
||||
raises(ValueError, lambda: ReferenceFrame('N', ['a', 'b', 'c'],
|
||||
['a', 'b', 'c'], [0, 1]))
|
||||
raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'],
|
||||
['a', 'b', 'c'], [0, 1, 2]))
|
||||
N = ReferenceFrame('N')
|
||||
assert N[0] == CoordinateSym('N_x', N, 0)
|
||||
assert N[1] == CoordinateSym('N_y', N, 1)
|
||||
assert N[2] == CoordinateSym('N_z', N, 2)
|
||||
raises(ValueError, lambda: N[3])
|
||||
N = ReferenceFrame('N', ['a', 'b', 'c'])
|
||||
assert N['a'] == N.x
|
||||
assert N['b'] == N.y
|
||||
assert N['c'] == N.z
|
||||
raises(ValueError, lambda: N['d'])
|
||||
assert str(N) == 'N'
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
|
||||
raises(TypeError, lambda: A.orient(B, 'DCM', 0))
|
||||
raises(TypeError, lambda: B.orient(N, 'Space', [q1, q2, q3], '222'))
|
||||
raises(TypeError, lambda: B.orient(N, 'Axis', [q1, N.x + 2 * N.y], '222'))
|
||||
raises(TypeError, lambda: B.orient(N, 'Axis', q1))
|
||||
raises(IndexError, lambda: B.orient(N, 'Axis', [q1]))
|
||||
raises(TypeError, lambda: B.orient(N, 'Quaternion', [q0, q1, q2, q3], '222'))
|
||||
raises(TypeError, lambda: B.orient(N, 'Quaternion', q0))
|
||||
raises(TypeError, lambda: B.orient(N, 'Quaternion', [q0, q1, q2]))
|
||||
raises(NotImplementedError, lambda: B.orient(N, 'Foo', [q0, q1, q2]))
|
||||
raises(TypeError, lambda: B.orient(N, 'Body', [q1, q2], '232'))
|
||||
raises(TypeError, lambda: B.orient(N, 'Space', [q1, q2], '232'))
|
||||
|
||||
N.set_ang_acc(B, 0)
|
||||
assert N.ang_acc_in(B) == Vector(0)
|
||||
N.set_ang_vel(B, 0)
|
||||
assert N.ang_vel_in(B) == Vector(0)
|
||||
|
||||
|
||||
def test_check_frame():
|
||||
raises(VectorTypeError, lambda: _check_frame(0))
|
||||
|
||||
|
||||
def test_dcm_diff_16824():
|
||||
# NOTE : This is a regression test for the bug introduced in PR 14758,
|
||||
# identified in 16824, and solved by PR 16828.
|
||||
|
||||
# This is the solution to Problem 2.2 on page 264 in Kane & Lenvinson's
|
||||
# 1985 book.
|
||||
|
||||
q1, q2, q3 = dynamicsymbols('q1:4')
|
||||
|
||||
s1 = sin(q1)
|
||||
c1 = cos(q1)
|
||||
s2 = sin(q2)
|
||||
c2 = cos(q2)
|
||||
s3 = sin(q3)
|
||||
c3 = cos(q3)
|
||||
|
||||
dcm = Matrix([[c2*c3, s1*s2*c3 - s3*c1, c1*s2*c3 + s3*s1],
|
||||
[c2*s3, s1*s2*s3 + c3*c1, c1*s2*s3 - c3*s1],
|
||||
[-s2, s1*c2, c1*c2]])
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient(A, 'DCM', dcm)
|
||||
|
||||
AwB = B.ang_vel_in(A)
|
||||
|
||||
alpha2 = s3*c2*q1.diff() + c3*q2.diff()
|
||||
beta2 = s1*c2*q3.diff() + c1*q2.diff()
|
||||
|
||||
assert simplify(AwB.dot(A.y) - alpha2) == 0
|
||||
assert simplify(AwB.dot(B.y) - beta2) == 0
|
||||
|
||||
def test_orient_explicit():
|
||||
cxx, cyy, czz = dynamicsymbols('c_{xx}, c_{yy}, c_{zz}')
|
||||
cxy, cxz, cyx = dynamicsymbols('c_{xy}, c_{xz}, c_{yx}')
|
||||
cyz, czx, czy = dynamicsymbols('c_{yz}, c_{zx}, c_{zy}')
|
||||
dcxx, dcyy, dczz = dynamicsymbols('c_{xx}, c_{yy}, c_{zz}', 1)
|
||||
dcxy, dcxz, dcyx = dynamicsymbols('c_{xy}, c_{xz}, c_{yx}', 1)
|
||||
dcyz, dczx, dczy = dynamicsymbols('c_{yz}, c_{zx}, c_{zy}', 1)
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B_C_A = Matrix([[cxx, cxy, cxz],
|
||||
[cyx, cyy, cyz],
|
||||
[czx, czy, czz]])
|
||||
B_w_A = ((cyx*dczx + cyy*dczy + cyz*dczz)*B.x +
|
||||
(czx*dcxx + czy*dcxy + czz*dcxz)*B.y +
|
||||
(cxx*dcyx + cxy*dcyy + cxz*dcyz)*B.z)
|
||||
A.orient_explicit(B, B_C_A)
|
||||
assert B.dcm(A) == B_C_A
|
||||
assert A.ang_vel_in(B) == B_w_A
|
||||
assert B.ang_vel_in(A) == -B_w_A
|
||||
|
||||
def test_orient_dcm():
|
||||
cxx, cyy, czz = dynamicsymbols('c_{xx}, c_{yy}, c_{zz}')
|
||||
cxy, cxz, cyx = dynamicsymbols('c_{xy}, c_{xz}, c_{yx}')
|
||||
cyz, czx, czy = dynamicsymbols('c_{yz}, c_{zx}, c_{zy}')
|
||||
B_C_A = Matrix([[cxx, cxy, cxz],
|
||||
[cyx, cyy, cyz],
|
||||
[czx, czy, czz]])
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_dcm(A, B_C_A)
|
||||
assert B.dcm(A) == Matrix([[cxx, cxy, cxz],
|
||||
[cyx, cyy, cyz],
|
||||
[czx, czy, czz]])
|
||||
|
||||
def test_orient_axis():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
A.orient_axis(B,-B.x, 1)
|
||||
A1 = A.dcm(B)
|
||||
A.orient_axis(B, B.x, -1)
|
||||
A2 = A.dcm(B)
|
||||
A.orient_axis(B, 1, -B.x)
|
||||
A3 = A.dcm(B)
|
||||
assert A1 == A2
|
||||
assert A2 == A3
|
||||
raises(TypeError, lambda: A.orient_axis(B, 1, 1))
|
||||
|
||||
def test_orient_body():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_body_fixed(A, (1,1,0), 'XYX')
|
||||
assert B.dcm(A) == Matrix([[cos(1), sin(1)**2, -sin(1)*cos(1)], [0, cos(1), sin(1)], [sin(1), -sin(1)*cos(1), cos(1)**2]])
|
||||
|
||||
|
||||
def test_orient_body_advanced():
|
||||
q1, q2, q3 = dynamicsymbols('q1:4')
|
||||
c1, c2, c3 = symbols('c1:4')
|
||||
u1, u2, u3 = dynamicsymbols('q1:4', 1)
|
||||
|
||||
# Test with everything as dynamicsymbols
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_body_fixed(A, (q1, q2, q3), 'zxy')
|
||||
assert A.dcm(B) == Matrix([
|
||||
[-sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3), -sin(q1) * cos(q2),
|
||||
sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1)],
|
||||
[sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), cos(q1) * cos(q2),
|
||||
sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)],
|
||||
[-sin(q3) * cos(q2), sin(q2), cos(q2) * cos(q3)]])
|
||||
assert B.ang_vel_in(A).to_matrix(B) == Matrix([
|
||||
[-sin(q3) * cos(q2) * u1 + cos(q3) * u2],
|
||||
[sin(q2) * u1 + u3],
|
||||
[sin(q3) * u2 + cos(q2) * cos(q3) * u1]])
|
||||
|
||||
# Test with constant symbol
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_body_fixed(A, (q1, c2, q3), 131)
|
||||
assert A.dcm(B) == Matrix([
|
||||
[cos(c2), -sin(c2) * cos(q3), sin(c2) * sin(q3)],
|
||||
[sin(c2) * cos(q1), -sin(q1) * sin(q3) + cos(c2) * cos(q1) * cos(q3),
|
||||
-sin(q1) * cos(q3) - sin(q3) * cos(c2) * cos(q1)],
|
||||
[sin(c2) * sin(q1), sin(q1) * cos(c2) * cos(q3) + sin(q3) * cos(q1),
|
||||
-sin(q1) * sin(q3) * cos(c2) + cos(q1) * cos(q3)]])
|
||||
assert B.ang_vel_in(A).to_matrix(B) == Matrix([
|
||||
[cos(c2) * u1 + u3],
|
||||
[-sin(c2) * cos(q3) * u1],
|
||||
[sin(c2) * sin(q3) * u1]])
|
||||
|
||||
# Test all symbols not time dependent
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_body_fixed(A, (c1, c2, c3), 123)
|
||||
assert B.ang_vel_in(A) == Vector(0)
|
||||
|
||||
|
||||
def test_orient_space_advanced():
|
||||
# space fixed is in the end like body fixed only in opposite order
|
||||
q1, q2, q3 = dynamicsymbols('q1:4')
|
||||
c1, c2, c3 = symbols('c1:4')
|
||||
u1, u2, u3 = dynamicsymbols('q1:4', 1)
|
||||
|
||||
# Test with everything as dynamicsymbols
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_space_fixed(A, (q3, q2, q1), 'yxz')
|
||||
assert A.dcm(B) == Matrix([
|
||||
[-sin(q1) * sin(q2) * sin(q3) + cos(q1) * cos(q3), -sin(q1) * cos(q2),
|
||||
sin(q1) * sin(q2) * cos(q3) + sin(q3) * cos(q1)],
|
||||
[sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1), cos(q1) * cos(q2),
|
||||
sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)],
|
||||
[-sin(q3) * cos(q2), sin(q2), cos(q2) * cos(q3)]])
|
||||
assert B.ang_vel_in(A).to_matrix(B) == Matrix([
|
||||
[-sin(q3) * cos(q2) * u1 + cos(q3) * u2],
|
||||
[sin(q2) * u1 + u3],
|
||||
[sin(q3) * u2 + cos(q2) * cos(q3) * u1]])
|
||||
|
||||
# Test with constant symbol
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_space_fixed(A, (q3, c2, q1), 131)
|
||||
assert A.dcm(B) == Matrix([
|
||||
[cos(c2), -sin(c2) * cos(q3), sin(c2) * sin(q3)],
|
||||
[sin(c2) * cos(q1), -sin(q1) * sin(q3) + cos(c2) * cos(q1) * cos(q3),
|
||||
-sin(q1) * cos(q3) - sin(q3) * cos(c2) * cos(q1)],
|
||||
[sin(c2) * sin(q1), sin(q1) * cos(c2) * cos(q3) + sin(q3) * cos(q1),
|
||||
-sin(q1) * sin(q3) * cos(c2) + cos(q1) * cos(q3)]])
|
||||
assert B.ang_vel_in(A).to_matrix(B) == Matrix([
|
||||
[cos(c2) * u1 + u3],
|
||||
[-sin(c2) * cos(q3) * u1],
|
||||
[sin(c2) * sin(q3) * u1]])
|
||||
|
||||
# Test all symbols not time dependent
|
||||
A, B = ReferenceFrame('A'), ReferenceFrame('B')
|
||||
B.orient_space_fixed(A, (c1, c2, c3), 123)
|
||||
assert B.ang_vel_in(A) == Vector(0)
|
||||
|
||||
|
||||
def test_orient_body_simple_ang_vel():
|
||||
"""This test ensures that the simplest form of that linear system solution
|
||||
is returned, thus the == for the expression comparison."""
|
||||
|
||||
psi, theta, phi = dynamicsymbols('psi, theta, varphi')
|
||||
t = dynamicsymbols._t
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_body_fixed(A, (psi, theta, phi), 'ZXZ')
|
||||
A_w_B = B.ang_vel_in(A)
|
||||
assert A_w_B.args[0][1] == B
|
||||
assert A_w_B.args[0][0][0] == (sin(theta)*sin(phi)*psi.diff(t) +
|
||||
cos(phi)*theta.diff(t))
|
||||
assert A_w_B.args[0][0][1] == (sin(theta)*cos(phi)*psi.diff(t) -
|
||||
sin(phi)*theta.diff(t))
|
||||
assert A_w_B.args[0][0][2] == cos(theta)*psi.diff(t) + phi.diff(t)
|
||||
|
||||
|
||||
def test_orient_space():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_space_fixed(A, (0,0,0), '123')
|
||||
assert B.dcm(A) == Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
|
||||
|
||||
def test_orient_quaternion():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_quaternion(A, (0,0,0,0))
|
||||
assert B.dcm(A) == Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
|
||||
|
||||
def test_looped_frame_warning():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
|
||||
a, b, c = symbols('a b c')
|
||||
B.orient_axis(A, A.x, a)
|
||||
C.orient_axis(B, B.x, b)
|
||||
|
||||
with warnings.catch_warnings(record = True) as w:
|
||||
warnings.simplefilter("always")
|
||||
A.orient_axis(C, C.x, c)
|
||||
assert issubclass(w[-1].category, UserWarning)
|
||||
assert 'Loops are defined among the orientation of frames. ' + \
|
||||
'This is likely not desired and may cause errors in your calculations.' in str(w[-1].message)
|
||||
|
||||
def test_frame_dict():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
|
||||
a, b, c = symbols('a b c')
|
||||
|
||||
B.orient_axis(A, A.x, a)
|
||||
assert A._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(a), -sin(a)],[0, sin(a), cos(a)]])}
|
||||
assert B._dcm_dict == {A: Matrix([[1, 0, 0],[0, cos(a), sin(a)],[0, -sin(a), cos(a)]])}
|
||||
assert C._dcm_dict == {}
|
||||
|
||||
B.orient_axis(C, C.x, b)
|
||||
# Previous relation is not wiped
|
||||
assert A._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(a), -sin(a)],[0, sin(a), cos(a)]])}
|
||||
assert B._dcm_dict == {A: Matrix([[1, 0, 0],[0, cos(a), sin(a)],[0, -sin(a), cos(a)]]), \
|
||||
C: Matrix([[1, 0, 0],[0, cos(b), sin(b)],[0, -sin(b), cos(b)]])}
|
||||
assert C._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(b), -sin(b)],[0, sin(b), cos(b)]])}
|
||||
|
||||
A.orient_axis(B, B.x, c)
|
||||
# Previous relation is updated
|
||||
assert B._dcm_dict == {C: Matrix([[1, 0, 0],[0, cos(b), sin(b)],[0, -sin(b), cos(b)]]),\
|
||||
A: Matrix([[1, 0, 0],[0, cos(c), -sin(c)],[0, sin(c), cos(c)]])}
|
||||
assert A._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(c), sin(c)],[0, -sin(c), cos(c)]])}
|
||||
assert C._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(b), -sin(b)],[0, sin(b), cos(b)]])}
|
||||
|
||||
def test_dcm_cache_dict():
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
D = ReferenceFrame('D')
|
||||
|
||||
a, b, c = symbols('a b c')
|
||||
|
||||
B.orient_axis(A, A.x, a)
|
||||
C.orient_axis(B, B.x, b)
|
||||
D.orient_axis(C, C.x, c)
|
||||
|
||||
assert D._dcm_dict == {C: Matrix([[1, 0, 0],[0, cos(c), sin(c)],[0, -sin(c), cos(c)]])}
|
||||
assert C._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(b), sin(b)],[0, -sin(b), cos(b)]]), \
|
||||
D: Matrix([[1, 0, 0],[0, cos(c), -sin(c)],[0, sin(c), cos(c)]])}
|
||||
assert B._dcm_dict == {A: Matrix([[1, 0, 0],[0, cos(a), sin(a)],[0, -sin(a), cos(a)]]), \
|
||||
C: Matrix([[1, 0, 0],[0, cos(b), -sin(b)],[0, sin(b), cos(b)]])}
|
||||
assert A._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(a), -sin(a)],[0, sin(a), cos(a)]])}
|
||||
|
||||
assert D._dcm_dict == D._dcm_cache
|
||||
|
||||
D.dcm(A) # Check calculated dcm relation is stored in _dcm_cache and not in _dcm_dict
|
||||
assert list(A._dcm_cache.keys()) == [A, B, D]
|
||||
assert list(D._dcm_cache.keys()) == [C, A]
|
||||
assert list(A._dcm_dict.keys()) == [B]
|
||||
assert list(D._dcm_dict.keys()) == [C]
|
||||
assert A._dcm_dict != A._dcm_cache
|
||||
|
||||
A.orient_axis(B, B.x, b) # _dcm_cache of A is wiped out and new relation is stored.
|
||||
assert A._dcm_dict == {B: Matrix([[1, 0, 0],[0, cos(b), sin(b)],[0, -sin(b), cos(b)]])}
|
||||
assert A._dcm_dict == A._dcm_cache
|
||||
assert B._dcm_dict == {C: Matrix([[1, 0, 0],[0, cos(b), -sin(b)],[0, sin(b), cos(b)]]), \
|
||||
A: Matrix([[1, 0, 0],[0, cos(b), -sin(b)],[0, sin(b), cos(b)]])}
|
||||
|
||||
def test_xx_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.xx == Vector.outer(N.x, N.x)
|
||||
assert F.xx == Vector.outer(F.x, F.x)
|
||||
|
||||
def test_xy_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.xy == Vector.outer(N.x, N.y)
|
||||
assert F.xy == Vector.outer(F.x, F.y)
|
||||
|
||||
def test_xz_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.xz == Vector.outer(N.x, N.z)
|
||||
assert F.xz == Vector.outer(F.x, F.z)
|
||||
|
||||
def test_yx_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.yx == Vector.outer(N.y, N.x)
|
||||
assert F.yx == Vector.outer(F.y, F.x)
|
||||
|
||||
def test_yy_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.yy == Vector.outer(N.y, N.y)
|
||||
assert F.yy == Vector.outer(F.y, F.y)
|
||||
|
||||
def test_yz_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.yz == Vector.outer(N.y, N.z)
|
||||
assert F.yz == Vector.outer(F.y, F.z)
|
||||
|
||||
def test_zx_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.zx == Vector.outer(N.z, N.x)
|
||||
assert F.zx == Vector.outer(F.z, F.x)
|
||||
|
||||
def test_zy_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.zy == Vector.outer(N.z, N.y)
|
||||
assert F.zy == Vector.outer(F.z, F.y)
|
||||
|
||||
def test_zz_dyad():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.zz == Vector.outer(N.z, N.z)
|
||||
assert F.zz == Vector.outer(F.z, F.z)
|
||||
|
||||
def test_unit_dyadic():
|
||||
N = ReferenceFrame('N')
|
||||
F = ReferenceFrame('F', indices=['1', '2', '3'])
|
||||
assert N.u == N.xx + N.yy + N.zz
|
||||
assert F.u == F.xx + F.yy + F.zz
|
||||
|
||||
|
||||
def test_pickle_frame():
|
||||
N = ReferenceFrame('N')
|
||||
A = ReferenceFrame('A')
|
||||
A.orient_axis(N, N.x, 1)
|
||||
A_C_N = A.dcm(N)
|
||||
N1 = pickle.loads(pickle.dumps(N))
|
||||
A1 = tuple(N1._dcm_dict.keys())[0]
|
||||
assert A1.dcm(N1) == A_C_N
|
||||
|
|
@ -0,0 +1,509 @@
|
|||
from sympy.core.numbers import pi
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.physics.vector import Dyadic, Point, ReferenceFrame, Vector
|
||||
from sympy.physics.vector.functions import (cross, dot, express,
|
||||
time_derivative,
|
||||
kinematic_equations, outer,
|
||||
partial_velocity,
|
||||
get_motion_params, dynamicsymbols)
|
||||
from sympy.simplify import trigsimp
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
q1, q2, q3, q4, q5 = symbols('q1 q2 q3 q4 q5')
|
||||
N = ReferenceFrame('N')
|
||||
A = N.orientnew('A', 'Axis', [q1, N.z])
|
||||
B = A.orientnew('B', 'Axis', [q2, A.x])
|
||||
C = B.orientnew('C', 'Axis', [q3, B.y])
|
||||
|
||||
|
||||
def test_dot():
|
||||
assert dot(A.x, A.x) == 1
|
||||
assert dot(A.x, A.y) == 0
|
||||
assert dot(A.x, A.z) == 0
|
||||
|
||||
assert dot(A.y, A.x) == 0
|
||||
assert dot(A.y, A.y) == 1
|
||||
assert dot(A.y, A.z) == 0
|
||||
|
||||
assert dot(A.z, A.x) == 0
|
||||
assert dot(A.z, A.y) == 0
|
||||
assert dot(A.z, A.z) == 1
|
||||
|
||||
|
||||
def test_dot_different_frames():
|
||||
assert dot(N.x, A.x) == cos(q1)
|
||||
assert dot(N.x, A.y) == -sin(q1)
|
||||
assert dot(N.x, A.z) == 0
|
||||
assert dot(N.y, A.x) == sin(q1)
|
||||
assert dot(N.y, A.y) == cos(q1)
|
||||
assert dot(N.y, A.z) == 0
|
||||
assert dot(N.z, A.x) == 0
|
||||
assert dot(N.z, A.y) == 0
|
||||
assert dot(N.z, A.z) == 1
|
||||
|
||||
assert trigsimp(dot(N.x, A.x + A.y)) == sqrt(2)*cos(q1 + pi/4)
|
||||
assert trigsimp(dot(N.x, A.x + A.y)) == trigsimp(dot(A.x + A.y, N.x))
|
||||
|
||||
assert dot(A.x, C.x) == cos(q3)
|
||||
assert dot(A.x, C.y) == 0
|
||||
assert dot(A.x, C.z) == sin(q3)
|
||||
assert dot(A.y, C.x) == sin(q2)*sin(q3)
|
||||
assert dot(A.y, C.y) == cos(q2)
|
||||
assert dot(A.y, C.z) == -sin(q2)*cos(q3)
|
||||
assert dot(A.z, C.x) == -cos(q2)*sin(q3)
|
||||
assert dot(A.z, C.y) == sin(q2)
|
||||
assert dot(A.z, C.z) == cos(q2)*cos(q3)
|
||||
|
||||
|
||||
def test_cross():
|
||||
assert cross(A.x, A.x) == 0
|
||||
assert cross(A.x, A.y) == A.z
|
||||
assert cross(A.x, A.z) == -A.y
|
||||
|
||||
assert cross(A.y, A.x) == -A.z
|
||||
assert cross(A.y, A.y) == 0
|
||||
assert cross(A.y, A.z) == A.x
|
||||
|
||||
assert cross(A.z, A.x) == A.y
|
||||
assert cross(A.z, A.y) == -A.x
|
||||
assert cross(A.z, A.z) == 0
|
||||
|
||||
|
||||
def test_cross_different_frames():
|
||||
assert cross(N.x, A.x) == sin(q1)*A.z
|
||||
assert cross(N.x, A.y) == cos(q1)*A.z
|
||||
assert cross(N.x, A.z) == -sin(q1)*A.x - cos(q1)*A.y
|
||||
assert cross(N.y, A.x) == -cos(q1)*A.z
|
||||
assert cross(N.y, A.y) == sin(q1)*A.z
|
||||
assert cross(N.y, A.z) == cos(q1)*A.x - sin(q1)*A.y
|
||||
assert cross(N.z, A.x) == A.y
|
||||
assert cross(N.z, A.y) == -A.x
|
||||
assert cross(N.z, A.z) == 0
|
||||
|
||||
assert cross(N.x, A.x) == sin(q1)*A.z
|
||||
assert cross(N.x, A.y) == cos(q1)*A.z
|
||||
assert cross(N.x, A.x + A.y) == sin(q1)*A.z + cos(q1)*A.z
|
||||
assert cross(A.x + A.y, N.x) == -sin(q1)*A.z - cos(q1)*A.z
|
||||
|
||||
assert cross(A.x, C.x) == sin(q3)*C.y
|
||||
assert cross(A.x, C.y) == -sin(q3)*C.x + cos(q3)*C.z
|
||||
assert cross(A.x, C.z) == -cos(q3)*C.y
|
||||
assert cross(C.x, A.x) == -sin(q3)*C.y
|
||||
assert cross(C.y, A.x).express(C).simplify() == sin(q3)*C.x - cos(q3)*C.z
|
||||
assert cross(C.z, A.x) == cos(q3)*C.y
|
||||
|
||||
def test_operator_match():
|
||||
"""Test that the output of dot, cross, outer functions match
|
||||
operator behavior.
|
||||
"""
|
||||
A = ReferenceFrame('A')
|
||||
v = A.x + A.y
|
||||
d = v | v
|
||||
zerov = Vector(0)
|
||||
zerod = Dyadic(0)
|
||||
|
||||
# dot products
|
||||
assert d & d == dot(d, d)
|
||||
assert d & zerod == dot(d, zerod)
|
||||
assert zerod & d == dot(zerod, d)
|
||||
assert d & v == dot(d, v)
|
||||
assert v & d == dot(v, d)
|
||||
assert d & zerov == dot(d, zerov)
|
||||
assert zerov & d == dot(zerov, d)
|
||||
raises(TypeError, lambda: dot(d, S.Zero))
|
||||
raises(TypeError, lambda: dot(S.Zero, d))
|
||||
raises(TypeError, lambda: dot(d, 0))
|
||||
raises(TypeError, lambda: dot(0, d))
|
||||
assert v & v == dot(v, v)
|
||||
assert v & zerov == dot(v, zerov)
|
||||
assert zerov & v == dot(zerov, v)
|
||||
raises(TypeError, lambda: dot(v, S.Zero))
|
||||
raises(TypeError, lambda: dot(S.Zero, v))
|
||||
raises(TypeError, lambda: dot(v, 0))
|
||||
raises(TypeError, lambda: dot(0, v))
|
||||
|
||||
# cross products
|
||||
raises(TypeError, lambda: cross(d, d))
|
||||
raises(TypeError, lambda: cross(d, zerod))
|
||||
raises(TypeError, lambda: cross(zerod, d))
|
||||
assert d ^ v == cross(d, v)
|
||||
assert v ^ d == cross(v, d)
|
||||
assert d ^ zerov == cross(d, zerov)
|
||||
assert zerov ^ d == cross(zerov, d)
|
||||
assert zerov ^ d == cross(zerov, d)
|
||||
raises(TypeError, lambda: cross(d, S.Zero))
|
||||
raises(TypeError, lambda: cross(S.Zero, d))
|
||||
raises(TypeError, lambda: cross(d, 0))
|
||||
raises(TypeError, lambda: cross(0, d))
|
||||
assert v ^ v == cross(v, v)
|
||||
assert v ^ zerov == cross(v, zerov)
|
||||
assert zerov ^ v == cross(zerov, v)
|
||||
raises(TypeError, lambda: cross(v, S.Zero))
|
||||
raises(TypeError, lambda: cross(S.Zero, v))
|
||||
raises(TypeError, lambda: cross(v, 0))
|
||||
raises(TypeError, lambda: cross(0, v))
|
||||
|
||||
# outer products
|
||||
raises(TypeError, lambda: outer(d, d))
|
||||
raises(TypeError, lambda: outer(d, zerod))
|
||||
raises(TypeError, lambda: outer(zerod, d))
|
||||
raises(TypeError, lambda: outer(d, v))
|
||||
raises(TypeError, lambda: outer(v, d))
|
||||
raises(TypeError, lambda: outer(d, zerov))
|
||||
raises(TypeError, lambda: outer(zerov, d))
|
||||
raises(TypeError, lambda: outer(zerov, d))
|
||||
raises(TypeError, lambda: outer(d, S.Zero))
|
||||
raises(TypeError, lambda: outer(S.Zero, d))
|
||||
raises(TypeError, lambda: outer(d, 0))
|
||||
raises(TypeError, lambda: outer(0, d))
|
||||
assert v | v == outer(v, v)
|
||||
assert v | zerov == outer(v, zerov)
|
||||
assert zerov | v == outer(zerov, v)
|
||||
raises(TypeError, lambda: outer(v, S.Zero))
|
||||
raises(TypeError, lambda: outer(S.Zero, v))
|
||||
raises(TypeError, lambda: outer(v, 0))
|
||||
raises(TypeError, lambda: outer(0, v))
|
||||
|
||||
|
||||
def test_express():
|
||||
assert express(Vector(0), N) == Vector(0)
|
||||
assert express(S.Zero, N) is S.Zero
|
||||
assert express(A.x, C) == cos(q3)*C.x + sin(q3)*C.z
|
||||
assert express(A.y, C) == sin(q2)*sin(q3)*C.x + cos(q2)*C.y - \
|
||||
sin(q2)*cos(q3)*C.z
|
||||
assert express(A.z, C) == -sin(q3)*cos(q2)*C.x + sin(q2)*C.y + \
|
||||
cos(q2)*cos(q3)*C.z
|
||||
assert express(A.x, N) == cos(q1)*N.x + sin(q1)*N.y
|
||||
assert express(A.y, N) == -sin(q1)*N.x + cos(q1)*N.y
|
||||
assert express(A.z, N) == N.z
|
||||
assert express(A.x, A) == A.x
|
||||
assert express(A.y, A) == A.y
|
||||
assert express(A.z, A) == A.z
|
||||
assert express(A.x, B) == B.x
|
||||
assert express(A.y, B) == cos(q2)*B.y - sin(q2)*B.z
|
||||
assert express(A.z, B) == sin(q2)*B.y + cos(q2)*B.z
|
||||
assert express(A.x, C) == cos(q3)*C.x + sin(q3)*C.z
|
||||
assert express(A.y, C) == sin(q2)*sin(q3)*C.x + cos(q2)*C.y - \
|
||||
sin(q2)*cos(q3)*C.z
|
||||
assert express(A.z, C) == -sin(q3)*cos(q2)*C.x + sin(q2)*C.y + \
|
||||
cos(q2)*cos(q3)*C.z
|
||||
# Check to make sure UnitVectors get converted properly
|
||||
assert express(N.x, N) == N.x
|
||||
assert express(N.y, N) == N.y
|
||||
assert express(N.z, N) == N.z
|
||||
assert express(N.x, A) == (cos(q1)*A.x - sin(q1)*A.y)
|
||||
assert express(N.y, A) == (sin(q1)*A.x + cos(q1)*A.y)
|
||||
assert express(N.z, A) == A.z
|
||||
assert express(N.x, B) == (cos(q1)*B.x - sin(q1)*cos(q2)*B.y +
|
||||
sin(q1)*sin(q2)*B.z)
|
||||
assert express(N.y, B) == (sin(q1)*B.x + cos(q1)*cos(q2)*B.y -
|
||||
sin(q2)*cos(q1)*B.z)
|
||||
assert express(N.z, B) == (sin(q2)*B.y + cos(q2)*B.z)
|
||||
assert express(N.x, C) == (
|
||||
(cos(q1)*cos(q3) - sin(q1)*sin(q2)*sin(q3))*C.x -
|
||||
sin(q1)*cos(q2)*C.y +
|
||||
(sin(q3)*cos(q1) + sin(q1)*sin(q2)*cos(q3))*C.z)
|
||||
assert express(N.y, C) == (
|
||||
(sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*C.x +
|
||||
cos(q1)*cos(q2)*C.y +
|
||||
(sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*C.z)
|
||||
assert express(N.z, C) == (-sin(q3)*cos(q2)*C.x + sin(q2)*C.y +
|
||||
cos(q2)*cos(q3)*C.z)
|
||||
|
||||
assert express(A.x, N) == (cos(q1)*N.x + sin(q1)*N.y)
|
||||
assert express(A.y, N) == (-sin(q1)*N.x + cos(q1)*N.y)
|
||||
assert express(A.z, N) == N.z
|
||||
assert express(A.x, A) == A.x
|
||||
assert express(A.y, A) == A.y
|
||||
assert express(A.z, A) == A.z
|
||||
assert express(A.x, B) == B.x
|
||||
assert express(A.y, B) == (cos(q2)*B.y - sin(q2)*B.z)
|
||||
assert express(A.z, B) == (sin(q2)*B.y + cos(q2)*B.z)
|
||||
assert express(A.x, C) == (cos(q3)*C.x + sin(q3)*C.z)
|
||||
assert express(A.y, C) == (sin(q2)*sin(q3)*C.x + cos(q2)*C.y -
|
||||
sin(q2)*cos(q3)*C.z)
|
||||
assert express(A.z, C) == (-sin(q3)*cos(q2)*C.x + sin(q2)*C.y +
|
||||
cos(q2)*cos(q3)*C.z)
|
||||
|
||||
assert express(B.x, N) == (cos(q1)*N.x + sin(q1)*N.y)
|
||||
assert express(B.y, N) == (-sin(q1)*cos(q2)*N.x +
|
||||
cos(q1)*cos(q2)*N.y + sin(q2)*N.z)
|
||||
assert express(B.z, N) == (sin(q1)*sin(q2)*N.x -
|
||||
sin(q2)*cos(q1)*N.y + cos(q2)*N.z)
|
||||
assert express(B.x, A) == A.x
|
||||
assert express(B.y, A) == (cos(q2)*A.y + sin(q2)*A.z)
|
||||
assert express(B.z, A) == (-sin(q2)*A.y + cos(q2)*A.z)
|
||||
assert express(B.x, B) == B.x
|
||||
assert express(B.y, B) == B.y
|
||||
assert express(B.z, B) == B.z
|
||||
assert express(B.x, C) == (cos(q3)*C.x + sin(q3)*C.z)
|
||||
assert express(B.y, C) == C.y
|
||||
assert express(B.z, C) == (-sin(q3)*C.x + cos(q3)*C.z)
|
||||
|
||||
assert express(C.x, N) == (
|
||||
(cos(q1)*cos(q3) - sin(q1)*sin(q2)*sin(q3))*N.x +
|
||||
(sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*N.y -
|
||||
sin(q3)*cos(q2)*N.z)
|
||||
assert express(C.y, N) == (
|
||||
-sin(q1)*cos(q2)*N.x + cos(q1)*cos(q2)*N.y + sin(q2)*N.z)
|
||||
assert express(C.z, N) == (
|
||||
(sin(q3)*cos(q1) + sin(q1)*sin(q2)*cos(q3))*N.x +
|
||||
(sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*N.y +
|
||||
cos(q2)*cos(q3)*N.z)
|
||||
assert express(C.x, A) == (cos(q3)*A.x + sin(q2)*sin(q3)*A.y -
|
||||
sin(q3)*cos(q2)*A.z)
|
||||
assert express(C.y, A) == (cos(q2)*A.y + sin(q2)*A.z)
|
||||
assert express(C.z, A) == (sin(q3)*A.x - sin(q2)*cos(q3)*A.y +
|
||||
cos(q2)*cos(q3)*A.z)
|
||||
assert express(C.x, B) == (cos(q3)*B.x - sin(q3)*B.z)
|
||||
assert express(C.y, B) == B.y
|
||||
assert express(C.z, B) == (sin(q3)*B.x + cos(q3)*B.z)
|
||||
assert express(C.x, C) == C.x
|
||||
assert express(C.y, C) == C.y
|
||||
assert express(C.z, C) == C.z == (C.z)
|
||||
|
||||
# Check to make sure Vectors get converted back to UnitVectors
|
||||
assert N.x == express((cos(q1)*A.x - sin(q1)*A.y), N).simplify()
|
||||
assert N.y == express((sin(q1)*A.x + cos(q1)*A.y), N).simplify()
|
||||
assert N.x == express((cos(q1)*B.x - sin(q1)*cos(q2)*B.y +
|
||||
sin(q1)*sin(q2)*B.z), N).simplify()
|
||||
assert N.y == express((sin(q1)*B.x + cos(q1)*cos(q2)*B.y -
|
||||
sin(q2)*cos(q1)*B.z), N).simplify()
|
||||
assert N.z == express((sin(q2)*B.y + cos(q2)*B.z), N).simplify()
|
||||
|
||||
"""
|
||||
These don't really test our code, they instead test the auto simplification
|
||||
(or lack thereof) of SymPy.
|
||||
assert N.x == express((
|
||||
(cos(q1)*cos(q3)-sin(q1)*sin(q2)*sin(q3))*C.x -
|
||||
sin(q1)*cos(q2)*C.y +
|
||||
(sin(q3)*cos(q1)+sin(q1)*sin(q2)*cos(q3))*C.z), N)
|
||||
assert N.y == express((
|
||||
(sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*C.x +
|
||||
cos(q1)*cos(q2)*C.y +
|
||||
(sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*C.z), N)
|
||||
assert N.z == express((-sin(q3)*cos(q2)*C.x + sin(q2)*C.y +
|
||||
cos(q2)*cos(q3)*C.z), N)
|
||||
"""
|
||||
|
||||
assert A.x == express((cos(q1)*N.x + sin(q1)*N.y), A).simplify()
|
||||
assert A.y == express((-sin(q1)*N.x + cos(q1)*N.y), A).simplify()
|
||||
|
||||
assert A.y == express((cos(q2)*B.y - sin(q2)*B.z), A).simplify()
|
||||
assert A.z == express((sin(q2)*B.y + cos(q2)*B.z), A).simplify()
|
||||
|
||||
assert A.x == express((cos(q3)*C.x + sin(q3)*C.z), A).simplify()
|
||||
|
||||
# Tripsimp messes up here too.
|
||||
#print express((sin(q2)*sin(q3)*C.x + cos(q2)*C.y -
|
||||
# sin(q2)*cos(q3)*C.z), A)
|
||||
assert A.y == express((sin(q2)*sin(q3)*C.x + cos(q2)*C.y -
|
||||
sin(q2)*cos(q3)*C.z), A).simplify()
|
||||
|
||||
assert A.z == express((-sin(q3)*cos(q2)*C.x + sin(q2)*C.y +
|
||||
cos(q2)*cos(q3)*C.z), A).simplify()
|
||||
assert B.x == express((cos(q1)*N.x + sin(q1)*N.y), B).simplify()
|
||||
assert B.y == express((-sin(q1)*cos(q2)*N.x +
|
||||
cos(q1)*cos(q2)*N.y + sin(q2)*N.z), B).simplify()
|
||||
|
||||
assert B.z == express((sin(q1)*sin(q2)*N.x -
|
||||
sin(q2)*cos(q1)*N.y + cos(q2)*N.z), B).simplify()
|
||||
|
||||
assert B.y == express((cos(q2)*A.y + sin(q2)*A.z), B).simplify()
|
||||
assert B.z == express((-sin(q2)*A.y + cos(q2)*A.z), B).simplify()
|
||||
assert B.x == express((cos(q3)*C.x + sin(q3)*C.z), B).simplify()
|
||||
assert B.z == express((-sin(q3)*C.x + cos(q3)*C.z), B).simplify()
|
||||
|
||||
"""
|
||||
assert C.x == express((
|
||||
(cos(q1)*cos(q3)-sin(q1)*sin(q2)*sin(q3))*N.x +
|
||||
(sin(q1)*cos(q3)+sin(q2)*sin(q3)*cos(q1))*N.y -
|
||||
sin(q3)*cos(q2)*N.z), C)
|
||||
assert C.y == express((
|
||||
-sin(q1)*cos(q2)*N.x + cos(q1)*cos(q2)*N.y + sin(q2)*N.z), C)
|
||||
assert C.z == express((
|
||||
(sin(q3)*cos(q1)+sin(q1)*sin(q2)*cos(q3))*N.x +
|
||||
(sin(q1)*sin(q3)-sin(q2)*cos(q1)*cos(q3))*N.y +
|
||||
cos(q2)*cos(q3)*N.z), C)
|
||||
"""
|
||||
assert C.x == express((cos(q3)*A.x + sin(q2)*sin(q3)*A.y -
|
||||
sin(q3)*cos(q2)*A.z), C).simplify()
|
||||
assert C.y == express((cos(q2)*A.y + sin(q2)*A.z), C).simplify()
|
||||
assert C.z == express((sin(q3)*A.x - sin(q2)*cos(q3)*A.y +
|
||||
cos(q2)*cos(q3)*A.z), C).simplify()
|
||||
assert C.x == express((cos(q3)*B.x - sin(q3)*B.z), C).simplify()
|
||||
assert C.z == express((sin(q3)*B.x + cos(q3)*B.z), C).simplify()
|
||||
|
||||
|
||||
def test_time_derivative():
|
||||
#The use of time_derivative for calculations pertaining to scalar
|
||||
#fields has been tested in test_coordinate_vars in test_essential.py
|
||||
A = ReferenceFrame('A')
|
||||
q = dynamicsymbols('q')
|
||||
qd = dynamicsymbols('q', 1)
|
||||
B = A.orientnew('B', 'Axis', [q, A.z])
|
||||
d = A.x | A.x
|
||||
assert time_derivative(d, B) == (-qd) * (A.y | A.x) + \
|
||||
(-qd) * (A.x | A.y)
|
||||
d1 = A.x | B.y
|
||||
assert time_derivative(d1, A) == - qd*(A.x|B.x)
|
||||
assert time_derivative(d1, B) == - qd*(A.y|B.y)
|
||||
d2 = A.x | B.x
|
||||
assert time_derivative(d2, A) == qd*(A.x|B.y)
|
||||
assert time_derivative(d2, B) == - qd*(A.y|B.x)
|
||||
d3 = A.x | B.z
|
||||
assert time_derivative(d3, A) == 0
|
||||
assert time_derivative(d3, B) == - qd*(A.y|B.z)
|
||||
q1, q2, q3, q4 = dynamicsymbols('q1 q2 q3 q4')
|
||||
q1d, q2d, q3d, q4d = dynamicsymbols('q1 q2 q3 q4', 1)
|
||||
q1dd, q2dd, q3dd, q4dd = dynamicsymbols('q1 q2 q3 q4', 2)
|
||||
C = B.orientnew('C', 'Axis', [q4, B.x])
|
||||
v1 = q1 * A.z
|
||||
v2 = q2*A.x + q3*B.y
|
||||
v3 = q1*A.x + q2*A.y + q3*A.z
|
||||
assert time_derivative(B.x, C) == 0
|
||||
assert time_derivative(B.y, C) == - q4d*B.z
|
||||
assert time_derivative(B.z, C) == q4d*B.y
|
||||
assert time_derivative(v1, B) == q1d*A.z
|
||||
assert time_derivative(v1, C) == - q1*sin(q)*q4d*A.x + \
|
||||
q1*cos(q)*q4d*A.y + q1d*A.z
|
||||
assert time_derivative(v2, A) == q2d*A.x - q3*qd*B.x + q3d*B.y
|
||||
assert time_derivative(v2, C) == q2d*A.x - q2*qd*A.y + \
|
||||
q2*sin(q)*q4d*A.z + q3d*B.y - q3*q4d*B.z
|
||||
assert time_derivative(v3, B) == (q2*qd + q1d)*A.x + \
|
||||
(-q1*qd + q2d)*A.y + q3d*A.z
|
||||
assert time_derivative(d, C) == - qd*(A.y|A.x) + \
|
||||
sin(q)*q4d*(A.z|A.x) - qd*(A.x|A.y) + sin(q)*q4d*(A.x|A.z)
|
||||
raises(ValueError, lambda: time_derivative(B.x, C, order=0.5))
|
||||
raises(ValueError, lambda: time_derivative(B.x, C, order=-1))
|
||||
|
||||
|
||||
def test_get_motion_methods():
|
||||
#Initialization
|
||||
t = dynamicsymbols._t
|
||||
s1, s2, s3 = symbols('s1 s2 s3')
|
||||
S1, S2, S3 = symbols('S1 S2 S3')
|
||||
S4, S5, S6 = symbols('S4 S5 S6')
|
||||
t1, t2 = symbols('t1 t2')
|
||||
a, b, c = dynamicsymbols('a b c')
|
||||
ad, bd, cd = dynamicsymbols('a b c', 1)
|
||||
a2d, b2d, c2d = dynamicsymbols('a b c', 2)
|
||||
v0 = S1*N.x + S2*N.y + S3*N.z
|
||||
v01 = S4*N.x + S5*N.y + S6*N.z
|
||||
v1 = s1*N.x + s2*N.y + s3*N.z
|
||||
v2 = a*N.x + b*N.y + c*N.z
|
||||
v2d = ad*N.x + bd*N.y + cd*N.z
|
||||
v2dd = a2d*N.x + b2d*N.y + c2d*N.z
|
||||
#Test position parameter
|
||||
assert get_motion_params(frame = N) == (0, 0, 0)
|
||||
assert get_motion_params(N, position=v1) == (0, 0, v1)
|
||||
assert get_motion_params(N, position=v2) == (v2dd, v2d, v2)
|
||||
#Test velocity parameter
|
||||
assert get_motion_params(N, velocity=v1) == (0, v1, v1 * t)
|
||||
assert get_motion_params(N, velocity=v1, position=v0, timevalue1=t1) == \
|
||||
(0, v1, v0 + v1*(t - t1))
|
||||
answer = get_motion_params(N, velocity=v1, position=v2, timevalue1=t1)
|
||||
answer_expected = (0, v1, v1*t - v1*t1 + v2.subs(t, t1))
|
||||
assert answer == answer_expected
|
||||
|
||||
answer = get_motion_params(N, velocity=v2, position=v0, timevalue1=t1)
|
||||
integral_vector = Integral(a, (t, t1, t))*N.x + Integral(b, (t, t1, t))*N.y \
|
||||
+ Integral(c, (t, t1, t))*N.z
|
||||
answer_expected = (v2d, v2, v0 + integral_vector)
|
||||
assert answer == answer_expected
|
||||
|
||||
#Test acceleration parameter
|
||||
assert get_motion_params(N, acceleration=v1) == \
|
||||
(v1, v1 * t, v1 * t**2/2)
|
||||
assert get_motion_params(N, acceleration=v1, velocity=v0,
|
||||
position=v2, timevalue1=t1, timevalue2=t2) == \
|
||||
(v1, (v0 + v1*t - v1*t2),
|
||||
-v0*t1 + v1*t**2/2 + v1*t2*t1 - \
|
||||
v1*t1**2/2 + t*(v0 - v1*t2) + \
|
||||
v2.subs(t, t1))
|
||||
assert get_motion_params(N, acceleration=v1, velocity=v0,
|
||||
position=v01, timevalue1=t1, timevalue2=t2) == \
|
||||
(v1, v0 + v1*t - v1*t2,
|
||||
-v0*t1 + v01 + v1*t**2/2 + \
|
||||
v1*t2*t1 - v1*t1**2/2 + \
|
||||
t*(v0 - v1*t2))
|
||||
answer = get_motion_params(N, acceleration=a*N.x, velocity=S1*N.x,
|
||||
position=S2*N.x, timevalue1=t1, timevalue2=t2)
|
||||
i1 = Integral(a, (t, t2, t))
|
||||
answer_expected = (a*N.x, (S1 + i1)*N.x, \
|
||||
(S2 + Integral(S1 + i1, (t, t1, t)))*N.x)
|
||||
assert answer == answer_expected
|
||||
|
||||
|
||||
def test_kin_eqs():
|
||||
q0, q1, q2, q3 = dynamicsymbols('q0 q1 q2 q3')
|
||||
q0d, q1d, q2d, q3d = dynamicsymbols('q0 q1 q2 q3', 1)
|
||||
u1, u2, u3 = dynamicsymbols('u1 u2 u3')
|
||||
ke = kinematic_equations([u1,u2,u3], [q1,q2,q3], 'body', 313)
|
||||
assert ke == kinematic_equations([u1,u2,u3], [q1,q2,q3], 'body', '313')
|
||||
kds = kinematic_equations([u1, u2, u3], [q0, q1, q2, q3], 'quaternion')
|
||||
assert kds == [-0.5 * q0 * u1 - 0.5 * q2 * u3 + 0.5 * q3 * u2 + q1d,
|
||||
-0.5 * q0 * u2 + 0.5 * q1 * u3 - 0.5 * q3 * u1 + q2d,
|
||||
-0.5 * q0 * u3 - 0.5 * q1 * u2 + 0.5 * q2 * u1 + q3d,
|
||||
0.5 * q1 * u1 + 0.5 * q2 * u2 + 0.5 * q3 * u3 + q0d]
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2], 'quaternion'))
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2, q3], 'quaternion', '123'))
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2, q3], 'foo'))
|
||||
raises(TypeError, lambda: kinematic_equations(u1, [q0, q1, q2, q3], 'quaternion'))
|
||||
raises(TypeError, lambda: kinematic_equations([u1], [q0, q1, q2, q3], 'quaternion'))
|
||||
raises(TypeError, lambda: kinematic_equations([u1, u2, u3], q0, 'quaternion'))
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2, q3], 'body'))
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2, q3], 'space'))
|
||||
raises(ValueError, lambda: kinematic_equations([u1, u2, u3], [q0, q1, q2], 'body', '222'))
|
||||
assert kinematic_equations([0, 0, 0], [q0, q1, q2], 'space') == [S.Zero, S.Zero, S.Zero]
|
||||
|
||||
|
||||
def test_partial_velocity():
|
||||
q1, q2, q3, u1, u2, u3 = dynamicsymbols('q1 q2 q3 u1 u2 u3')
|
||||
u4, u5 = dynamicsymbols('u4, u5')
|
||||
r = symbols('r')
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
Y = N.orientnew('Y', 'Axis', [q1, N.z])
|
||||
L = Y.orientnew('L', 'Axis', [q2, Y.x])
|
||||
R = L.orientnew('R', 'Axis', [q3, L.y])
|
||||
R.set_ang_vel(N, u1 * L.x + u2 * L.y + u3 * L.z)
|
||||
|
||||
C = Point('C')
|
||||
C.set_vel(N, u4 * L.x + u5 * (Y.z ^ L.x))
|
||||
Dmc = C.locatenew('Dmc', r * L.z)
|
||||
Dmc.v2pt_theory(C, N, R)
|
||||
|
||||
vel_list = [Dmc.vel(N), C.vel(N), R.ang_vel_in(N)]
|
||||
u_list = [u1, u2, u3, u4, u5]
|
||||
assert (partial_velocity(vel_list, u_list, N) ==
|
||||
[[- r*L.y, r*L.x, 0, L.x, cos(q2)*L.y - sin(q2)*L.z],
|
||||
[0, 0, 0, L.x, cos(q2)*L.y - sin(q2)*L.z],
|
||||
[L.x, L.y, L.z, 0, 0]])
|
||||
|
||||
# Make sure that partial velocities can be computed regardless if the
|
||||
# orientation between frames is defined or not.
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
v = u4 * A.x + u5 * B.y
|
||||
assert partial_velocity((v, ), (u4, u5), A) == [[A.x, B.y]]
|
||||
|
||||
raises(TypeError, lambda: partial_velocity(Dmc.vel(N), u_list, N))
|
||||
raises(TypeError, lambda: partial_velocity(vel_list, u1, N))
|
||||
|
||||
def test_dynamicsymbols():
|
||||
#Tests to check the assumptions applied to dynamicsymbols
|
||||
f1 = dynamicsymbols('f1')
|
||||
f2 = dynamicsymbols('f2', real=True)
|
||||
f3 = dynamicsymbols('f3', positive=True)
|
||||
f4, f5 = dynamicsymbols('f4,f5', commutative=False)
|
||||
f6 = dynamicsymbols('f6', integer=True)
|
||||
assert f1.is_real is None
|
||||
assert f2.is_real
|
||||
assert f3.is_positive
|
||||
assert f4*f5 != f5*f4
|
||||
assert f6.is_integer
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
from sympy.core.singleton import S
|
||||
from sympy.physics.vector import Vector, ReferenceFrame, Dyadic
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
|
||||
|
||||
def test_output_type():
|
||||
A = ReferenceFrame('A')
|
||||
v = A.x + A.y
|
||||
d = v | v
|
||||
zerov = Vector(0)
|
||||
zerod = Dyadic(0)
|
||||
|
||||
# dot products
|
||||
assert isinstance(d & d, Dyadic)
|
||||
assert isinstance(d & zerod, Dyadic)
|
||||
assert isinstance(zerod & d, Dyadic)
|
||||
assert isinstance(d & v, Vector)
|
||||
assert isinstance(v & d, Vector)
|
||||
assert isinstance(d & zerov, Vector)
|
||||
assert isinstance(zerov & d, Vector)
|
||||
raises(TypeError, lambda: d & S.Zero)
|
||||
raises(TypeError, lambda: S.Zero & d)
|
||||
raises(TypeError, lambda: d & 0)
|
||||
raises(TypeError, lambda: 0 & d)
|
||||
assert not isinstance(v & v, (Vector, Dyadic))
|
||||
assert not isinstance(v & zerov, (Vector, Dyadic))
|
||||
assert not isinstance(zerov & v, (Vector, Dyadic))
|
||||
raises(TypeError, lambda: v & S.Zero)
|
||||
raises(TypeError, lambda: S.Zero & v)
|
||||
raises(TypeError, lambda: v & 0)
|
||||
raises(TypeError, lambda: 0 & v)
|
||||
|
||||
# cross products
|
||||
raises(TypeError, lambda: d ^ d)
|
||||
raises(TypeError, lambda: d ^ zerod)
|
||||
raises(TypeError, lambda: zerod ^ d)
|
||||
assert isinstance(d ^ v, Dyadic)
|
||||
assert isinstance(v ^ d, Dyadic)
|
||||
assert isinstance(d ^ zerov, Dyadic)
|
||||
assert isinstance(zerov ^ d, Dyadic)
|
||||
assert isinstance(zerov ^ d, Dyadic)
|
||||
raises(TypeError, lambda: d ^ S.Zero)
|
||||
raises(TypeError, lambda: S.Zero ^ d)
|
||||
raises(TypeError, lambda: d ^ 0)
|
||||
raises(TypeError, lambda: 0 ^ d)
|
||||
assert isinstance(v ^ v, Vector)
|
||||
assert isinstance(v ^ zerov, Vector)
|
||||
assert isinstance(zerov ^ v, Vector)
|
||||
raises(TypeError, lambda: v ^ S.Zero)
|
||||
raises(TypeError, lambda: S.Zero ^ v)
|
||||
raises(TypeError, lambda: v ^ 0)
|
||||
raises(TypeError, lambda: 0 ^ v)
|
||||
|
||||
# outer products
|
||||
raises(TypeError, lambda: d | d)
|
||||
raises(TypeError, lambda: d | zerod)
|
||||
raises(TypeError, lambda: zerod | d)
|
||||
raises(TypeError, lambda: d | v)
|
||||
raises(TypeError, lambda: v | d)
|
||||
raises(TypeError, lambda: d | zerov)
|
||||
raises(TypeError, lambda: zerov | d)
|
||||
raises(TypeError, lambda: zerov | d)
|
||||
raises(TypeError, lambda: d | S.Zero)
|
||||
raises(TypeError, lambda: S.Zero | d)
|
||||
raises(TypeError, lambda: d | 0)
|
||||
raises(TypeError, lambda: 0 | d)
|
||||
assert isinstance(v | v, Dyadic)
|
||||
assert isinstance(v | zerov, Dyadic)
|
||||
assert isinstance(zerov | v, Dyadic)
|
||||
raises(TypeError, lambda: v | S.Zero)
|
||||
raises(TypeError, lambda: S.Zero | v)
|
||||
raises(TypeError, lambda: v | 0)
|
||||
raises(TypeError, lambda: 0 | v)
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
from sympy.physics.vector import dynamicsymbols, Point, ReferenceFrame
|
||||
from sympy.testing.pytest import raises, ignore_warnings
|
||||
import warnings
|
||||
|
||||
def test_point_v1pt_theorys():
|
||||
q, q2 = dynamicsymbols('q q2')
|
||||
qd, q2d = dynamicsymbols('q q2', 1)
|
||||
qdd, q2dd = dynamicsymbols('q q2', 2)
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
B.set_ang_vel(N, qd * B.z)
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', B.x)
|
||||
P.set_vel(B, 0)
|
||||
O.set_vel(N, 0)
|
||||
assert P.v1pt_theory(O, N, B) == qd * B.y
|
||||
O.set_vel(N, N.x)
|
||||
assert P.v1pt_theory(O, N, B) == N.x + qd * B.y
|
||||
P.set_vel(B, B.z)
|
||||
assert P.v1pt_theory(O, N, B) == B.z + N.x + qd * B.y
|
||||
|
||||
|
||||
def test_point_a1pt_theorys():
|
||||
q, q2 = dynamicsymbols('q q2')
|
||||
qd, q2d = dynamicsymbols('q q2', 1)
|
||||
qdd, q2dd = dynamicsymbols('q q2', 2)
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
B.set_ang_vel(N, qd * B.z)
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', B.x)
|
||||
P.set_vel(B, 0)
|
||||
O.set_vel(N, 0)
|
||||
assert P.a1pt_theory(O, N, B) == -(qd**2) * B.x + qdd * B.y
|
||||
P.set_vel(B, q2d * B.z)
|
||||
assert P.a1pt_theory(O, N, B) == -(qd**2) * B.x + qdd * B.y + q2dd * B.z
|
||||
O.set_vel(N, q2d * B.x)
|
||||
assert P.a1pt_theory(O, N, B) == ((q2dd - qd**2) * B.x + (q2d * qd + qdd) * B.y +
|
||||
q2dd * B.z)
|
||||
|
||||
|
||||
def test_point_v2pt_theorys():
|
||||
q = dynamicsymbols('q')
|
||||
qd = dynamicsymbols('q', 1)
|
||||
N = ReferenceFrame('N')
|
||||
B = N.orientnew('B', 'Axis', [q, N.z])
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', 0)
|
||||
O.set_vel(N, 0)
|
||||
assert P.v2pt_theory(O, N, B) == 0
|
||||
P = O.locatenew('P', B.x)
|
||||
assert P.v2pt_theory(O, N, B) == (qd * B.z ^ B.x)
|
||||
O.set_vel(N, N.x)
|
||||
assert P.v2pt_theory(O, N, B) == N.x + qd * B.y
|
||||
|
||||
|
||||
def test_point_a2pt_theorys():
|
||||
q = dynamicsymbols('q')
|
||||
qd = dynamicsymbols('q', 1)
|
||||
qdd = dynamicsymbols('q', 2)
|
||||
N = ReferenceFrame('N')
|
||||
B = N.orientnew('B', 'Axis', [q, N.z])
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', 0)
|
||||
O.set_vel(N, 0)
|
||||
assert P.a2pt_theory(O, N, B) == 0
|
||||
P.set_pos(O, B.x)
|
||||
assert P.a2pt_theory(O, N, B) == (-qd**2) * B.x + (qdd) * B.y
|
||||
|
||||
|
||||
def test_point_funcs():
|
||||
q, q2 = dynamicsymbols('q q2')
|
||||
qd, q2d = dynamicsymbols('q q2', 1)
|
||||
qdd, q2dd = dynamicsymbols('q q2', 2)
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
B.set_ang_vel(N, 5 * B.y)
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', q * B.x + q2 * B.y)
|
||||
assert P.pos_from(O) == q * B.x + q2 * B.y
|
||||
P.set_vel(B, qd * B.x + q2d * B.y)
|
||||
assert P.vel(B) == qd * B.x + q2d * B.y
|
||||
O.set_vel(N, 0)
|
||||
assert O.vel(N) == 0
|
||||
assert P.a1pt_theory(O, N, B) == ((-25 * q + qdd) * B.x + (q2dd) * B.y +
|
||||
(-10 * qd) * B.z)
|
||||
|
||||
B = N.orientnew('B', 'Axis', [q, N.z])
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', 10 * B.x)
|
||||
O.set_vel(N, 5 * N.x)
|
||||
assert O.vel(N) == 5 * N.x
|
||||
assert P.a2pt_theory(O, N, B) == (-10 * qd**2) * B.x + (10 * qdd) * B.y
|
||||
|
||||
B.set_ang_vel(N, 5 * B.y)
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', q * B.x + q2 * B.y)
|
||||
P.set_vel(B, qd * B.x + q2d * B.y)
|
||||
O.set_vel(N, 0)
|
||||
assert P.v1pt_theory(O, N, B) == qd * B.x + q2d * B.y - 5 * q * B.z
|
||||
|
||||
|
||||
def test_point_pos():
|
||||
q = dynamicsymbols('q')
|
||||
N = ReferenceFrame('N')
|
||||
B = N.orientnew('B', 'Axis', [q, N.z])
|
||||
O = Point('O')
|
||||
P = O.locatenew('P', 10 * N.x + 5 * B.x)
|
||||
assert P.pos_from(O) == 10 * N.x + 5 * B.x
|
||||
Q = P.locatenew('Q', 10 * N.y + 5 * B.y)
|
||||
assert Q.pos_from(P) == 10 * N.y + 5 * B.y
|
||||
assert Q.pos_from(O) == 10 * N.x + 10 * N.y + 5 * B.x + 5 * B.y
|
||||
assert O.pos_from(Q) == -10 * N.x - 10 * N.y - 5 * B.x - 5 * B.y
|
||||
|
||||
def test_point_partial_velocity():
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
A = ReferenceFrame('A')
|
||||
|
||||
p = Point('p')
|
||||
|
||||
u1, u2 = dynamicsymbols('u1, u2')
|
||||
|
||||
p.set_vel(N, u1 * A.x + u2 * N.y)
|
||||
|
||||
assert p.partial_velocity(N, u1) == A.x
|
||||
assert p.partial_velocity(N, u1, u2) == (A.x, N.y)
|
||||
raises(ValueError, lambda: p.partial_velocity(A, u1))
|
||||
|
||||
def test_point_vel(): #Basic functionality
|
||||
q1, q2 = dynamicsymbols('q1 q2')
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
Q = Point('Q')
|
||||
O = Point('O')
|
||||
Q.set_pos(O, q1 * N.x)
|
||||
raises(ValueError , lambda: Q.vel(N)) # Velocity of O in N is not defined
|
||||
O.set_vel(N, q2 * N.y)
|
||||
assert O.vel(N) == q2 * N.y
|
||||
raises(ValueError , lambda : O.vel(B)) #Velocity of O is not defined in B
|
||||
|
||||
def test_auto_point_vel():
|
||||
t = dynamicsymbols._t
|
||||
q1, q2 = dynamicsymbols('q1 q2')
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
O = Point('O')
|
||||
Q = Point('Q')
|
||||
Q.set_pos(O, q1 * N.x)
|
||||
O.set_vel(N, q2 * N.y)
|
||||
assert Q.vel(N) == q1.diff(t) * N.x + q2 * N.y # Velocity of Q using O
|
||||
P1 = Point('P1')
|
||||
P1.set_pos(O, q1 * B.x)
|
||||
P2 = Point('P2')
|
||||
P2.set_pos(P1, q2 * B.z)
|
||||
raises(ValueError, lambda : P2.vel(B)) # O's velocity is defined in different frame, and no
|
||||
#point in between has its velocity defined
|
||||
raises(ValueError, lambda: P2.vel(N)) # Velocity of O not defined in N
|
||||
|
||||
def test_auto_point_vel_multiple_point_path():
|
||||
t = dynamicsymbols._t
|
||||
q1, q2 = dynamicsymbols('q1 q2')
|
||||
B = ReferenceFrame('B')
|
||||
P = Point('P')
|
||||
P.set_vel(B, q1 * B.x)
|
||||
P1 = Point('P1')
|
||||
P1.set_pos(P, q2 * B.y)
|
||||
P1.set_vel(B, q1 * B.z)
|
||||
P2 = Point('P2')
|
||||
P2.set_pos(P1, q1 * B.z)
|
||||
P3 = Point('P3')
|
||||
P3.set_pos(P2, 10 * q1 * B.y)
|
||||
assert P3.vel(B) == 10 * q1.diff(t) * B.y + (q1 + q1.diff(t)) * B.z
|
||||
|
||||
def test_auto_vel_dont_overwrite():
|
||||
t = dynamicsymbols._t
|
||||
q1, q2, u1 = dynamicsymbols('q1, q2, u1')
|
||||
N = ReferenceFrame('N')
|
||||
P = Point('P1')
|
||||
P.set_vel(N, u1 * N.x)
|
||||
P1 = Point('P1')
|
||||
P1.set_pos(P, q2 * N.y)
|
||||
assert P1.vel(N) == q2.diff(t) * N.y + u1 * N.x
|
||||
assert P.vel(N) == u1 * N.x
|
||||
P1.set_vel(N, u1 * N.z)
|
||||
assert P1.vel(N) == u1 * N.z
|
||||
|
||||
def test_auto_point_vel_if_tree_has_vel_but_inappropriate_pos_vector():
|
||||
q1, q2 = dynamicsymbols('q1 q2')
|
||||
B = ReferenceFrame('B')
|
||||
S = ReferenceFrame('S')
|
||||
P = Point('P')
|
||||
P.set_vel(B, q1 * B.x)
|
||||
P1 = Point('P1')
|
||||
P1.set_pos(P, S.y)
|
||||
raises(ValueError, lambda : P1.vel(B)) # P1.pos_from(P) can't be expressed in B
|
||||
raises(ValueError, lambda : P1.vel(S)) # P.vel(S) not defined
|
||||
|
||||
def test_auto_point_vel_shortest_path():
|
||||
t = dynamicsymbols._t
|
||||
q1, q2, u1, u2 = dynamicsymbols('q1 q2 u1 u2')
|
||||
B = ReferenceFrame('B')
|
||||
P = Point('P')
|
||||
P.set_vel(B, u1 * B.x)
|
||||
P1 = Point('P1')
|
||||
P1.set_pos(P, q2 * B.y)
|
||||
P1.set_vel(B, q1 * B.z)
|
||||
P2 = Point('P2')
|
||||
P2.set_pos(P1, q1 * B.z)
|
||||
P3 = Point('P3')
|
||||
P3.set_pos(P2, 10 * q1 * B.y)
|
||||
P4 = Point('P4')
|
||||
P4.set_pos(P3, q1 * B.x)
|
||||
O = Point('O')
|
||||
O.set_vel(B, u2 * B.y)
|
||||
O1 = Point('O1')
|
||||
O1.set_pos(O, q2 * B.z)
|
||||
P4.set_pos(O1, q1 * B.x + q2 * B.z)
|
||||
with warnings.catch_warnings(): #There are two possible paths in this point tree, thus a warning is raised
|
||||
warnings.simplefilter('error')
|
||||
with ignore_warnings(UserWarning):
|
||||
assert P4.vel(B) == q1.diff(t) * B.x + u2 * B.y + 2 * q2.diff(t) * B.z
|
||||
|
||||
def test_auto_point_vel_connected_frames():
|
||||
t = dynamicsymbols._t
|
||||
q, q1, q2, u = dynamicsymbols('q q1 q2 u')
|
||||
N = ReferenceFrame('N')
|
||||
B = ReferenceFrame('B')
|
||||
O = Point('O')
|
||||
O.set_vel(N, u * N.x)
|
||||
P = Point('P')
|
||||
P.set_pos(O, q1 * N.x + q2 * B.y)
|
||||
raises(ValueError, lambda: P.vel(N))
|
||||
N.orient(B, 'Axis', (q, B.x))
|
||||
assert P.vel(N) == (u + q1.diff(t)) * N.x + q2.diff(t) * B.y - q2 * q.diff(t) * B.z
|
||||
|
||||
def test_auto_point_vel_multiple_paths_warning_arises():
|
||||
q, u = dynamicsymbols('q u')
|
||||
N = ReferenceFrame('N')
|
||||
O = Point('O')
|
||||
P = Point('P')
|
||||
Q = Point('Q')
|
||||
R = Point('R')
|
||||
P.set_vel(N, u * N.x)
|
||||
Q.set_vel(N, u *N.y)
|
||||
R.set_vel(N, u * N.z)
|
||||
O.set_pos(P, q * N.z)
|
||||
O.set_pos(Q, q * N.y)
|
||||
O.set_pos(R, q * N.x)
|
||||
with warnings.catch_warnings(): #There are two possible paths in this point tree, thus a warning is raised
|
||||
warnings.simplefilter("error")
|
||||
raises(UserWarning ,lambda: O.vel(N))
|
||||
|
||||
def test_auto_vel_cyclic_warning_arises():
|
||||
P = Point('P')
|
||||
P1 = Point('P1')
|
||||
P2 = Point('P2')
|
||||
P3 = Point('P3')
|
||||
N = ReferenceFrame('N')
|
||||
P.set_vel(N, N.x)
|
||||
P1.set_pos(P, N.x)
|
||||
P2.set_pos(P1, N.y)
|
||||
P3.set_pos(P2, N.z)
|
||||
P1.set_pos(P3, N.x + N.y)
|
||||
with warnings.catch_warnings(): #The path is cyclic at P1, thus a warning is raised
|
||||
warnings.simplefilter("error")
|
||||
raises(UserWarning ,lambda: P2.vel(N))
|
||||
|
||||
def test_auto_vel_cyclic_warning_msg():
|
||||
P = Point('P')
|
||||
P1 = Point('P1')
|
||||
P2 = Point('P2')
|
||||
P3 = Point('P3')
|
||||
N = ReferenceFrame('N')
|
||||
P.set_vel(N, N.x)
|
||||
P1.set_pos(P, N.x)
|
||||
P2.set_pos(P1, N.y)
|
||||
P3.set_pos(P2, N.z)
|
||||
P1.set_pos(P3, N.x + N.y)
|
||||
with warnings.catch_warnings(record = True) as w: #The path is cyclic at P1, thus a warning is raised
|
||||
warnings.simplefilter("always")
|
||||
P2.vel(N)
|
||||
msg = str(w[-1].message).replace("\n", " ")
|
||||
assert issubclass(w[-1].category, UserWarning)
|
||||
assert 'Kinematic loops are defined among the positions of points. This is likely not desired and may cause errors in your calculations.' in msg
|
||||
|
||||
def test_auto_vel_multiple_path_warning_msg():
|
||||
N = ReferenceFrame('N')
|
||||
O = Point('O')
|
||||
P = Point('P')
|
||||
Q = Point('Q')
|
||||
P.set_vel(N, N.x)
|
||||
Q.set_vel(N, N.y)
|
||||
O.set_pos(P, N.z)
|
||||
O.set_pos(Q, N.y)
|
||||
with warnings.catch_warnings(record = True) as w: #There are two possible paths in this point tree, thus a warning is raised
|
||||
warnings.simplefilter("always")
|
||||
O.vel(N)
|
||||
msg = str(w[-1].message).replace("\n", " ")
|
||||
assert issubclass(w[-1].category, UserWarning)
|
||||
assert 'Velocity' in msg
|
||||
assert 'automatically calculated based on point' in msg
|
||||
assert 'Velocities from these points are not necessarily the same. This may cause errors in your calculations.' in msg
|
||||
|
||||
def test_auto_vel_derivative():
|
||||
q1, q2 = dynamicsymbols('q1:3')
|
||||
u1, u2 = dynamicsymbols('u1:3', 1)
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
B.orient_axis(A, A.z, q1)
|
||||
B.set_ang_vel(A, u1 * A.z)
|
||||
C.orient_axis(B, B.z, q2)
|
||||
C.set_ang_vel(B, u2 * B.z)
|
||||
|
||||
Am = Point('Am')
|
||||
Am.set_vel(A, 0)
|
||||
Bm = Point('Bm')
|
||||
Bm.set_pos(Am, B.x)
|
||||
Bm.set_vel(B, 0)
|
||||
Bm.set_vel(C, 0)
|
||||
Cm = Point('Cm')
|
||||
Cm.set_pos(Bm, C.x)
|
||||
Cm.set_vel(C, 0)
|
||||
temp = Cm._vel_dict.copy()
|
||||
assert Cm.vel(A) == (u1 * B.y + (u1 + u2) * C.y)
|
||||
Cm._vel_dict = temp
|
||||
Cm.v2pt_theory(Bm, B, C)
|
||||
assert Cm.vel(A) == (u1 * B.y + (u1 + u2) * C.y)
|
||||
|
||||
def test_auto_point_acc_zero_vel():
|
||||
N = ReferenceFrame('N')
|
||||
O = Point('O')
|
||||
O.set_vel(N, 0)
|
||||
assert O.acc(N) == 0 * N.x
|
||||
|
||||
def test_auto_point_acc_compute_vel():
|
||||
t = dynamicsymbols._t
|
||||
q1 = dynamicsymbols('q1')
|
||||
N = ReferenceFrame('N')
|
||||
A = ReferenceFrame('A')
|
||||
A.orient_axis(N, N.z, q1)
|
||||
|
||||
O = Point('O')
|
||||
O.set_vel(N, 0)
|
||||
P = Point('P')
|
||||
P.set_pos(O, A.x)
|
||||
assert P.acc(N) == -q1.diff(t) ** 2 * A.x + q1.diff(t, 2) * A.y
|
||||
|
||||
def test_auto_acc_derivative():
|
||||
# Tests whether the Point.acc method gives the correct acceleration of the
|
||||
# end point of two linkages in series, while getting minimal information.
|
||||
q1, q2 = dynamicsymbols('q1:3')
|
||||
u1, u2 = dynamicsymbols('q1:3', 1)
|
||||
v1, v2 = dynamicsymbols('q1:3', 2)
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
C = ReferenceFrame('C')
|
||||
B.orient_axis(A, A.z, q1)
|
||||
C.orient_axis(B, B.z, q2)
|
||||
|
||||
Am = Point('Am')
|
||||
Am.set_vel(A, 0)
|
||||
Bm = Point('Bm')
|
||||
Bm.set_pos(Am, B.x)
|
||||
Bm.set_vel(B, 0)
|
||||
Bm.set_vel(C, 0)
|
||||
Cm = Point('Cm')
|
||||
Cm.set_pos(Bm, C.x)
|
||||
Cm.set_vel(C, 0)
|
||||
|
||||
# Copy dictionaries to later check the calculation using the 2pt_theories
|
||||
Bm_vel_dict, Cm_vel_dict = Bm._vel_dict.copy(), Cm._vel_dict.copy()
|
||||
Bm_acc_dict, Cm_acc_dict = Bm._acc_dict.copy(), Cm._acc_dict.copy()
|
||||
check = -u1 ** 2 * B.x + v1 * B.y - (u1 + u2) ** 2 * C.x + (v1 + v2) * C.y
|
||||
assert Cm.acc(A) == check
|
||||
Bm._vel_dict, Cm._vel_dict = Bm_vel_dict, Cm_vel_dict
|
||||
Bm._acc_dict, Cm._acc_dict = Bm_acc_dict, Cm_acc_dict
|
||||
Bm.v2pt_theory(Am, A, B)
|
||||
Cm.v2pt_theory(Bm, A, C)
|
||||
Bm.a2pt_theory(Am, A, B)
|
||||
assert Cm.a2pt_theory(Bm, A, C) == check
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from sympy.core.function import Function
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (asin, cos, sin)
|
||||
from sympy.physics.vector import ReferenceFrame, dynamicsymbols, Dyadic
|
||||
from sympy.physics.vector.printing import (VectorLatexPrinter, vpprint,
|
||||
vsprint, vsstrrepr, vlatex)
|
||||
|
||||
|
||||
a, b, c = symbols('a, b, c')
|
||||
alpha, omega, beta = dynamicsymbols('alpha, omega, beta')
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
N = ReferenceFrame('N')
|
||||
|
||||
v = a ** 2 * N.x + b * N.y + c * sin(alpha) * N.z
|
||||
w = alpha * N.x + sin(omega) * N.y + alpha * beta * N.z
|
||||
ww = alpha * N.x + asin(omega) * N.y - alpha.diff() * beta * N.z
|
||||
o = a/b * N.x + (c+b)/a * N.y + c**2/b * N.z
|
||||
|
||||
y = a ** 2 * (N.x | N.y) + b * (N.y | N.y) + c * sin(alpha) * (N.z | N.y)
|
||||
x = alpha * (N.x | N.x) + sin(omega) * (N.y | N.z) + alpha * beta * (N.z | N.x)
|
||||
xx = N.x | (-N.y - N.z)
|
||||
xx2 = N.x | (N.y + N.z)
|
||||
|
||||
def ascii_vpretty(expr):
|
||||
return vpprint(expr, use_unicode=False, wrap_line=False)
|
||||
|
||||
|
||||
def unicode_vpretty(expr):
|
||||
return vpprint(expr, use_unicode=True, wrap_line=False)
|
||||
|
||||
|
||||
def test_latex_printer():
|
||||
r = Function('r')('t')
|
||||
assert VectorLatexPrinter().doprint(r ** 2) == "r^{2}"
|
||||
r2 = Function('r^2')('t')
|
||||
assert VectorLatexPrinter().doprint(r2.diff()) == r'\dot{r^{2}}'
|
||||
ra = Function('r__a')('t')
|
||||
assert VectorLatexPrinter().doprint(ra.diff().diff()) == r'\ddot{r^{a}}'
|
||||
|
||||
|
||||
def test_vector_pretty_print():
|
||||
|
||||
# TODO : The unit vectors should print with subscripts but they just
|
||||
# print as `n_x` instead of making `x` a subscript with unicode.
|
||||
|
||||
# TODO : The pretty print division does not print correctly here:
|
||||
# w = alpha * N.x + sin(omega) * N.y + alpha / beta * N.z
|
||||
|
||||
expected = """\
|
||||
2 \n\
|
||||
a n_x + b n_y + c*sin(alpha) n_z\
|
||||
"""
|
||||
uexpected = """\
|
||||
2 \n\
|
||||
a n_x + b n_y + c⋅sin(α) n_z\
|
||||
"""
|
||||
|
||||
assert ascii_vpretty(v) == expected
|
||||
assert unicode_vpretty(v) == uexpected
|
||||
|
||||
expected = 'alpha n_x + sin(omega) n_y + alpha*beta n_z'
|
||||
uexpected = 'α n_x + sin(ω) n_y + α⋅β n_z'
|
||||
|
||||
assert ascii_vpretty(w) == expected
|
||||
assert unicode_vpretty(w) == uexpected
|
||||
|
||||
expected = """\
|
||||
2 \n\
|
||||
a b + c c \n\
|
||||
- n_x + ----- n_y + -- n_z\n\
|
||||
b a b \
|
||||
"""
|
||||
uexpected = """\
|
||||
2 \n\
|
||||
a b + c c \n\
|
||||
─ n_x + ───── n_y + ── n_z\n\
|
||||
b a b \
|
||||
"""
|
||||
|
||||
assert ascii_vpretty(o) == expected
|
||||
assert unicode_vpretty(o) == uexpected
|
||||
|
||||
# https://github.com/sympy/sympy/issues/26731
|
||||
assert ascii_vpretty(-A.x) == '-a_x'
|
||||
assert unicode_vpretty(-A.x) == '-a_x'
|
||||
|
||||
# https://github.com/sympy/sympy/issues/26799
|
||||
assert ascii_vpretty(0*A.x) == '0'
|
||||
assert unicode_vpretty(0*A.x) == '0'
|
||||
|
||||
|
||||
def test_vector_latex():
|
||||
|
||||
a, b, c, d, omega = symbols('a, b, c, d, omega')
|
||||
|
||||
v = (a ** 2 + b / c) * A.x + sqrt(d) * A.y + cos(omega) * A.z
|
||||
|
||||
assert vlatex(v) == (r'(a^{2} + \frac{b}{c})\mathbf{\hat{a}_x} + '
|
||||
r'\sqrt{d}\mathbf{\hat{a}_y} + '
|
||||
r'\cos{\left(\omega \right)}'
|
||||
r'\mathbf{\hat{a}_z}')
|
||||
|
||||
theta, omega, alpha, q = dynamicsymbols('theta, omega, alpha, q')
|
||||
|
||||
v = theta * A.x + omega * omega * A.y + (q * alpha) * A.z
|
||||
|
||||
assert vlatex(v) == (r'\theta\mathbf{\hat{a}_x} + '
|
||||
r'\omega^{2}\mathbf{\hat{a}_y} + '
|
||||
r'\alpha q\mathbf{\hat{a}_z}')
|
||||
|
||||
phi1, phi2, phi3 = dynamicsymbols('phi1, phi2, phi3')
|
||||
theta1, theta2, theta3 = symbols('theta1, theta2, theta3')
|
||||
|
||||
v = (sin(theta1) * A.x +
|
||||
cos(phi1) * cos(phi2) * A.y +
|
||||
cos(theta1 + phi3) * A.z)
|
||||
|
||||
assert vlatex(v) == (r'\sin{\left(\theta_{1} \right)}'
|
||||
r'\mathbf{\hat{a}_x} + \cos{'
|
||||
r'\left(\phi_{1} \right)} \cos{'
|
||||
r'\left(\phi_{2} \right)}\mathbf{\hat{a}_y} + '
|
||||
r'\cos{\left(\theta_{1} + '
|
||||
r'\phi_{3} \right)}\mathbf{\hat{a}_z}')
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
|
||||
a, b, c, d, omega = symbols('a, b, c, d, omega')
|
||||
|
||||
v = (a ** 2 + b / c) * N.x + sqrt(d) * N.y + cos(omega) * N.z
|
||||
|
||||
expected = (r'(a^{2} + \frac{b}{c})\mathbf{\hat{n}_x} + '
|
||||
r'\sqrt{d}\mathbf{\hat{n}_y} + '
|
||||
r'\cos{\left(\omega \right)}'
|
||||
r'\mathbf{\hat{n}_z}')
|
||||
|
||||
assert vlatex(v) == expected
|
||||
|
||||
# Try custom unit vectors.
|
||||
|
||||
N = ReferenceFrame('N', latexs=(r'\hat{i}', r'\hat{j}', r'\hat{k}'))
|
||||
|
||||
v = (a ** 2 + b / c) * N.x + sqrt(d) * N.y + cos(omega) * N.z
|
||||
|
||||
expected = (r'(a^{2} + \frac{b}{c})\hat{i} + '
|
||||
r'\sqrt{d}\hat{j} + '
|
||||
r'\cos{\left(\omega \right)}\hat{k}')
|
||||
assert vlatex(v) == expected
|
||||
|
||||
expected = r'\alpha\mathbf{\hat{n}_x} + \operatorname{asin}{\left(\omega ' \
|
||||
r'\right)}\mathbf{\hat{n}_y} - \beta \dot{\alpha}\mathbf{\hat{n}_z}'
|
||||
assert vlatex(ww) == expected
|
||||
|
||||
expected = r'- \mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} - ' \
|
||||
r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_z}'
|
||||
assert vlatex(xx) == expected
|
||||
|
||||
expected = r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} + ' \
|
||||
r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_z}'
|
||||
assert vlatex(xx2) == expected
|
||||
|
||||
|
||||
def test_vector_latex_arguments():
|
||||
assert vlatex(N.x * 3.0, full_prec=False) == r'3.0\mathbf{\hat{n}_x}'
|
||||
assert vlatex(N.x * 3.0, full_prec=True) == r'3.00000000000000\mathbf{\hat{n}_x}'
|
||||
|
||||
|
||||
def test_vector_latex_with_functions():
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
|
||||
omega, alpha = dynamicsymbols('omega, alpha')
|
||||
|
||||
v = omega.diff() * N.x
|
||||
|
||||
assert vlatex(v) == r'\dot{\omega}\mathbf{\hat{n}_x}'
|
||||
|
||||
v = omega.diff() ** alpha * N.x
|
||||
|
||||
assert vlatex(v) == (r'\dot{\omega}^{\alpha}'
|
||||
r'\mathbf{\hat{n}_x}')
|
||||
|
||||
|
||||
def test_dyadic_pretty_print():
|
||||
|
||||
expected = """\
|
||||
2
|
||||
a n_x|n_y + b n_y|n_y + c*sin(alpha) n_z|n_y\
|
||||
"""
|
||||
|
||||
uexpected = """\
|
||||
2
|
||||
a n_x⊗n_y + b n_y⊗n_y + c⋅sin(α) n_z⊗n_y\
|
||||
"""
|
||||
assert ascii_vpretty(y) == expected
|
||||
assert unicode_vpretty(y) == uexpected
|
||||
|
||||
expected = 'alpha n_x|n_x + sin(omega) n_y|n_z + alpha*beta n_z|n_x'
|
||||
uexpected = 'α n_x⊗n_x + sin(ω) n_y⊗n_z + α⋅β n_z⊗n_x'
|
||||
assert ascii_vpretty(x) == expected
|
||||
assert unicode_vpretty(x) == uexpected
|
||||
|
||||
assert ascii_vpretty(Dyadic([])) == '0'
|
||||
assert unicode_vpretty(Dyadic([])) == '0'
|
||||
|
||||
assert ascii_vpretty(xx) == '- n_x|n_y - n_x|n_z'
|
||||
assert unicode_vpretty(xx) == '- n_x⊗n_y - n_x⊗n_z'
|
||||
|
||||
assert ascii_vpretty(xx2) == 'n_x|n_y + n_x|n_z'
|
||||
assert unicode_vpretty(xx2) == 'n_x⊗n_y + n_x⊗n_z'
|
||||
|
||||
|
||||
def test_dyadic_latex():
|
||||
|
||||
expected = (r'a^{2}\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} + '
|
||||
r'b\mathbf{\hat{n}_y}\otimes \mathbf{\hat{n}_y} + '
|
||||
r'c \sin{\left(\alpha \right)}'
|
||||
r'\mathbf{\hat{n}_z}\otimes \mathbf{\hat{n}_y}')
|
||||
|
||||
assert vlatex(y) == expected
|
||||
|
||||
expected = (r'\alpha\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_x} + '
|
||||
r'\sin{\left(\omega \right)}\mathbf{\hat{n}_y}'
|
||||
r'\otimes \mathbf{\hat{n}_z} + '
|
||||
r'\alpha \beta\mathbf{\hat{n}_z}\otimes \mathbf{\hat{n}_x}')
|
||||
|
||||
assert vlatex(x) == expected
|
||||
|
||||
assert vlatex(Dyadic([])) == '0'
|
||||
|
||||
|
||||
def test_dyadic_str():
|
||||
assert vsprint(Dyadic([])) == '0'
|
||||
assert vsprint(y) == 'a**2*(N.x|N.y) + b*(N.y|N.y) + c*sin(alpha)*(N.z|N.y)'
|
||||
assert vsprint(x) == 'alpha*(N.x|N.x) + sin(omega)*(N.y|N.z) + alpha*beta*(N.z|N.x)'
|
||||
assert vsprint(ww) == "alpha*N.x + asin(omega)*N.y - beta*alpha'*N.z"
|
||||
assert vsprint(xx) == '- (N.x|N.y) - (N.x|N.z)'
|
||||
assert vsprint(xx2) == '(N.x|N.y) + (N.x|N.z)'
|
||||
|
||||
|
||||
def test_vlatex(): # vlatex is broken #12078
|
||||
from sympy.physics.vector import vlatex
|
||||
|
||||
x = symbols('x')
|
||||
J = symbols('J')
|
||||
|
||||
f = Function('f')
|
||||
g = Function('g')
|
||||
h = Function('h')
|
||||
|
||||
expected = r'J \left(\frac{d}{d x} g{\left(x \right)} - \frac{d}{d x} h{\left(x \right)}\right)'
|
||||
|
||||
expr = J*f(x).diff(x).subs(f(x), g(x)-h(x))
|
||||
|
||||
assert vlatex(expr) == expected
|
||||
|
||||
|
||||
def test_issue_13354():
|
||||
"""
|
||||
Test for proper pretty printing of physics vectors with ADD
|
||||
instances in arguments.
|
||||
|
||||
Test is exactly the one suggested in the original bug report by
|
||||
@moorepants.
|
||||
"""
|
||||
|
||||
a, b, c = symbols('a, b, c')
|
||||
A = ReferenceFrame('A')
|
||||
v = a * A.x + b * A.y + c * A.z
|
||||
w = b * A.x + c * A.y + a * A.z
|
||||
z = w + v
|
||||
|
||||
expected = """(a + b) a_x + (b + c) a_y + (a + c) a_z"""
|
||||
|
||||
assert ascii_vpretty(z) == expected
|
||||
|
||||
|
||||
def test_vector_derivative_printing():
|
||||
# First order
|
||||
v = omega.diff() * N.x
|
||||
assert unicode_vpretty(v) == 'ω̇ n_x'
|
||||
assert ascii_vpretty(v) == "omega'(t) n_x"
|
||||
|
||||
# Second order
|
||||
v = omega.diff().diff() * N.x
|
||||
|
||||
assert vlatex(v) == r'\ddot{\omega}\mathbf{\hat{n}_x}'
|
||||
assert unicode_vpretty(v) == 'ω̈ n_x'
|
||||
assert ascii_vpretty(v) == "omega''(t) n_x"
|
||||
|
||||
# Third order
|
||||
v = omega.diff().diff().diff() * N.x
|
||||
|
||||
assert vlatex(v) == r'\dddot{\omega}\mathbf{\hat{n}_x}'
|
||||
assert unicode_vpretty(v) == 'ω⃛ n_x'
|
||||
assert ascii_vpretty(v) == "omega'''(t) n_x"
|
||||
|
||||
# Fourth order
|
||||
v = omega.diff().diff().diff().diff() * N.x
|
||||
|
||||
assert vlatex(v) == r'\ddddot{\omega}\mathbf{\hat{n}_x}'
|
||||
assert unicode_vpretty(v) == 'ω⃜ n_x'
|
||||
assert ascii_vpretty(v) == "omega''''(t) n_x"
|
||||
|
||||
# Fifth order
|
||||
v = omega.diff().diff().diff().diff().diff() * N.x
|
||||
|
||||
assert vlatex(v) == r'\frac{d^{5}}{d t^{5}} \omega\mathbf{\hat{n}_x}'
|
||||
expected = '''\
|
||||
5 \n\
|
||||
d \n\
|
||||
---(omega) n_x\n\
|
||||
5 \n\
|
||||
dt \
|
||||
'''
|
||||
uexpected = '''\
|
||||
5 \n\
|
||||
d \n\
|
||||
───(ω) n_x\n\
|
||||
5 \n\
|
||||
dt \
|
||||
'''
|
||||
assert unicode_vpretty(v) == uexpected
|
||||
assert ascii_vpretty(v) == expected
|
||||
|
||||
|
||||
def test_vector_str_printing():
|
||||
assert vsprint(w) == 'alpha*N.x + sin(omega)*N.y + alpha*beta*N.z'
|
||||
assert vsprint(omega.diff() * N.x) == "omega'*N.x"
|
||||
assert vsstrrepr(w) == 'alpha*N.x + sin(omega)*N.y + alpha*beta*N.z'
|
||||
|
||||
|
||||
def test_vector_str_arguments():
|
||||
assert vsprint(N.x * 3.0, full_prec=False) == '3.0*N.x'
|
||||
assert vsprint(N.x * 3.0, full_prec=True) == '3.00000000000000*N.x'
|
||||
|
||||
|
||||
def test_issue_14041():
|
||||
import sympy.physics.mechanics as me
|
||||
|
||||
A_frame = me.ReferenceFrame('A')
|
||||
thetad, phid = me.dynamicsymbols('theta, phi', 1)
|
||||
L = symbols('L')
|
||||
|
||||
assert vlatex(L*(phid + thetad)**2*A_frame.x) == \
|
||||
r"L \left(\dot{\phi} + \dot{\theta}\right)^{2}\mathbf{\hat{a}_x}"
|
||||
assert vlatex((phid + thetad)**2*A_frame.x) == \
|
||||
r"\left(\dot{\phi} + \dot{\theta}\right)^{2}\mathbf{\hat{a}_x}"
|
||||
assert vlatex((phid*thetad)**a*A_frame.x) == \
|
||||
r"\left(\dot{\phi} \dot{\theta}\right)^{a}\mathbf{\hat{a}_x}"
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
from sympy.core.numbers import (Float, pi)
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.core.sorting import ordered
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.matrices.immutable import ImmutableDenseMatrix as Matrix
|
||||
from sympy.physics.vector import ReferenceFrame, Vector, dynamicsymbols, dot
|
||||
from sympy.physics.vector.vector import VectorTypeError
|
||||
from sympy.abc import x, y, z
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
A = ReferenceFrame('A')
|
||||
|
||||
|
||||
def test_free_dynamicsymbols():
|
||||
A, B, C, D = symbols('A, B, C, D', cls=ReferenceFrame)
|
||||
a, b, c, d, e, f = dynamicsymbols('a, b, c, d, e, f')
|
||||
B.orient_axis(A, a, A.x)
|
||||
C.orient_axis(B, b, B.y)
|
||||
D.orient_axis(C, c, C.x)
|
||||
|
||||
v = d*D.x + e*D.y + f*D.z
|
||||
|
||||
assert set(ordered(v.free_dynamicsymbols(A))) == {a, b, c, d, e, f}
|
||||
assert set(ordered(v.free_dynamicsymbols(B))) == {b, c, d, e, f}
|
||||
assert set(ordered(v.free_dynamicsymbols(C))) == {c, d, e, f}
|
||||
assert set(ordered(v.free_dynamicsymbols(D))) == {d, e, f}
|
||||
|
||||
|
||||
def test_Vector():
|
||||
assert A.x != A.y
|
||||
assert A.y != A.z
|
||||
assert A.z != A.x
|
||||
|
||||
assert A.x + 0 == A.x
|
||||
|
||||
v1 = x*A.x + y*A.y + z*A.z
|
||||
v2 = x**2*A.x + y**2*A.y + z**2*A.z
|
||||
v3 = v1 + v2
|
||||
v4 = v1 - v2
|
||||
|
||||
assert isinstance(v1, Vector)
|
||||
assert dot(v1, A.x) == x
|
||||
assert dot(v1, A.y) == y
|
||||
assert dot(v1, A.z) == z
|
||||
|
||||
assert isinstance(v2, Vector)
|
||||
assert dot(v2, A.x) == x**2
|
||||
assert dot(v2, A.y) == y**2
|
||||
assert dot(v2, A.z) == z**2
|
||||
|
||||
assert isinstance(v3, Vector)
|
||||
# We probably shouldn't be using simplify in dot...
|
||||
assert dot(v3, A.x) == x**2 + x
|
||||
assert dot(v3, A.y) == y**2 + y
|
||||
assert dot(v3, A.z) == z**2 + z
|
||||
|
||||
assert isinstance(v4, Vector)
|
||||
# We probably shouldn't be using simplify in dot...
|
||||
assert dot(v4, A.x) == x - x**2
|
||||
assert dot(v4, A.y) == y - y**2
|
||||
assert dot(v4, A.z) == z - z**2
|
||||
|
||||
assert v1.to_matrix(A) == Matrix([[x], [y], [z]])
|
||||
q = symbols('q')
|
||||
B = A.orientnew('B', 'Axis', (q, A.x))
|
||||
assert v1.to_matrix(B) == Matrix([[x],
|
||||
[ y * cos(q) + z * sin(q)],
|
||||
[-y * sin(q) + z * cos(q)]])
|
||||
|
||||
#Test the separate method
|
||||
B = ReferenceFrame('B')
|
||||
v5 = x*A.x + y*A.y + z*B.z
|
||||
assert Vector(0).separate() == {}
|
||||
assert v1.separate() == {A: v1}
|
||||
assert v5.separate() == {A: x*A.x + y*A.y, B: z*B.z}
|
||||
|
||||
#Test the free_symbols property
|
||||
v6 = x*A.x + y*A.y + z*A.z
|
||||
assert v6.free_symbols(A) == {x,y,z}
|
||||
|
||||
raises(TypeError, lambda: v3.applyfunc(v1))
|
||||
|
||||
|
||||
def test_Vector_diffs():
|
||||
q1, q2, q3, q4 = dynamicsymbols('q1 q2 q3 q4')
|
||||
q1d, q2d, q3d, q4d = dynamicsymbols('q1 q2 q3 q4', 1)
|
||||
q1dd, q2dd, q3dd, q4dd = dynamicsymbols('q1 q2 q3 q4', 2)
|
||||
N = ReferenceFrame('N')
|
||||
A = N.orientnew('A', 'Axis', [q3, N.z])
|
||||
B = A.orientnew('B', 'Axis', [q2, A.x])
|
||||
v1 = q2 * A.x + q3 * N.y
|
||||
v2 = q3 * B.x + v1
|
||||
v3 = v1.dt(B)
|
||||
v4 = v2.dt(B)
|
||||
v5 = q1*A.x + q2*A.y + q3*A.z
|
||||
|
||||
assert v1.dt(N) == q2d * A.x + q2 * q3d * A.y + q3d * N.y
|
||||
assert v1.dt(A) == q2d * A.x + q3 * q3d * N.x + q3d * N.y
|
||||
assert v1.dt(B) == (q2d * A.x + q3 * q3d * N.x + q3d *
|
||||
N.y - q3 * cos(q3) * q2d * N.z)
|
||||
assert v2.dt(N) == (q2d * A.x + (q2 + q3) * q3d * A.y + q3d * B.x + q3d *
|
||||
N.y)
|
||||
assert v2.dt(A) == q2d * A.x + q3d * B.x + q3 * q3d * N.x + q3d * N.y
|
||||
assert v2.dt(B) == (q2d * A.x + q3d * B.x + q3 * q3d * N.x + q3d * N.y -
|
||||
q3 * cos(q3) * q2d * N.z)
|
||||
assert v3.dt(N) == (q2dd * A.x + q2d * q3d * A.y + (q3d**2 + q3 * q3dd) *
|
||||
N.x + q3dd * N.y + (q3 * sin(q3) * q2d * q3d -
|
||||
cos(q3) * q2d * q3d - q3 * cos(q3) * q2dd) * N.z)
|
||||
assert v3.dt(A) == (q2dd * A.x + (2 * q3d**2 + q3 * q3dd) * N.x + (q3dd -
|
||||
q3 * q3d**2) * N.y + (q3 * sin(q3) * q2d * q3d -
|
||||
cos(q3) * q2d * q3d - q3 * cos(q3) * q2dd) * N.z)
|
||||
assert (v3.dt(B) - (q2dd*A.x - q3*cos(q3)*q2d**2*A.y + (2*q3d**2 +
|
||||
q3*q3dd)*N.x + (q3dd - q3*q3d**2)*N.y + (2*q3*sin(q3)*q2d*q3d -
|
||||
2*cos(q3)*q2d*q3d - q3*cos(q3)*q2dd)*N.z)).express(B).simplify() == 0
|
||||
assert v4.dt(N) == (q2dd * A.x + q3d * (q2d + q3d) * A.y + q3dd * B.x +
|
||||
(q3d**2 + q3 * q3dd) * N.x + q3dd * N.y + (q3 *
|
||||
sin(q3) * q2d * q3d - cos(q3) * q2d * q3d - q3 *
|
||||
cos(q3) * q2dd) * N.z)
|
||||
assert v4.dt(A) == (q2dd * A.x + q3dd * B.x + (2 * q3d**2 + q3 * q3dd) *
|
||||
N.x + (q3dd - q3 * q3d**2) * N.y + (q3 * sin(q3) *
|
||||
q2d * q3d - cos(q3) * q2d * q3d - q3 * cos(q3) *
|
||||
q2dd) * N.z)
|
||||
assert (v4.dt(B) - (q2dd*A.x - q3*cos(q3)*q2d**2*A.y + q3dd*B.x +
|
||||
(2*q3d**2 + q3*q3dd)*N.x + (q3dd - q3*q3d**2)*N.y +
|
||||
(2*q3*sin(q3)*q2d*q3d - 2*cos(q3)*q2d*q3d -
|
||||
q3*cos(q3)*q2dd)*N.z)).express(B).simplify() == 0
|
||||
assert v5.dt(B) == q1d*A.x + (q3*q2d + q2d)*A.y + (-q2*q2d + q3d)*A.z
|
||||
assert v5.dt(A) == q1d*A.x + q2d*A.y + q3d*A.z
|
||||
assert v5.dt(N) == (-q2*q3d + q1d)*A.x + (q1*q3d + q2d)*A.y + q3d*A.z
|
||||
assert v3.diff(q1d, N) == 0
|
||||
assert v3.diff(q2d, N) == A.x - q3 * cos(q3) * N.z
|
||||
assert v3.diff(q3d, N) == q3 * N.x + N.y
|
||||
assert v3.diff(q1d, A) == 0
|
||||
assert v3.diff(q2d, A) == A.x - q3 * cos(q3) * N.z
|
||||
assert v3.diff(q3d, A) == q3 * N.x + N.y
|
||||
assert v3.diff(q1d, B) == 0
|
||||
assert v3.diff(q2d, B) == A.x - q3 * cos(q3) * N.z
|
||||
assert v3.diff(q3d, B) == q3 * N.x + N.y
|
||||
assert v4.diff(q1d, N) == 0
|
||||
assert v4.diff(q2d, N) == A.x - q3 * cos(q3) * N.z
|
||||
assert v4.diff(q3d, N) == B.x + q3 * N.x + N.y
|
||||
assert v4.diff(q1d, A) == 0
|
||||
assert v4.diff(q2d, A) == A.x - q3 * cos(q3) * N.z
|
||||
assert v4.diff(q3d, A) == B.x + q3 * N.x + N.y
|
||||
assert v4.diff(q1d, B) == 0
|
||||
assert v4.diff(q2d, B) == A.x - q3 * cos(q3) * N.z
|
||||
assert v4.diff(q3d, B) == B.x + q3 * N.x + N.y
|
||||
|
||||
# diff() should only express vector components in the derivative frame if
|
||||
# the orientation of the component's frame depends on the variable
|
||||
v6 = q2**2*N.y + q2**2*A.y + q2**2*B.y
|
||||
# already expressed in N
|
||||
n_measy = 2*q2
|
||||
# A_C_N does not depend on q2, so don't express in N
|
||||
a_measy = 2*q2
|
||||
# B_C_N depends on q2, so express in N
|
||||
b_measx = (q2**2*B.y).dot(N.x).diff(q2)
|
||||
b_measy = (q2**2*B.y).dot(N.y).diff(q2)
|
||||
b_measz = (q2**2*B.y).dot(N.z).diff(q2)
|
||||
n_comp, a_comp = v6.diff(q2, N).args
|
||||
assert len(v6.diff(q2, N).args) == 2 # only N and A parts
|
||||
assert n_comp[1] == N
|
||||
assert a_comp[1] == A
|
||||
assert n_comp[0] == Matrix([b_measx, b_measy + n_measy, b_measz])
|
||||
assert a_comp[0] == Matrix([0, a_measy, 0])
|
||||
|
||||
|
||||
def test_vector_var_in_dcm():
|
||||
|
||||
N = ReferenceFrame('N')
|
||||
A = ReferenceFrame('A')
|
||||
B = ReferenceFrame('B')
|
||||
u1, u2, u3, u4 = dynamicsymbols('u1 u2 u3 u4')
|
||||
|
||||
v = u1 * u2 * A.x + u3 * N.y + u4**2 * N.z
|
||||
|
||||
assert v.diff(u1, N, var_in_dcm=False) == u2 * A.x
|
||||
assert v.diff(u1, A, var_in_dcm=False) == u2 * A.x
|
||||
assert v.diff(u3, N, var_in_dcm=False) == N.y
|
||||
assert v.diff(u3, A, var_in_dcm=False) == N.y
|
||||
assert v.diff(u3, B, var_in_dcm=False) == N.y
|
||||
assert v.diff(u4, N, var_in_dcm=False) == 2 * u4 * N.z
|
||||
|
||||
raises(ValueError, lambda: v.diff(u1, N))
|
||||
|
||||
|
||||
def test_vector_simplify():
|
||||
x, y, z, k, n, m, w, f, s, A = symbols('x, y, z, k, n, m, w, f, s, A')
|
||||
N = ReferenceFrame('N')
|
||||
|
||||
test1 = (1 / x + 1 / y) * N.x
|
||||
assert (test1 & N.x) != (x + y) / (x * y)
|
||||
test1 = test1.simplify()
|
||||
assert (test1 & N.x) == (x + y) / (x * y)
|
||||
|
||||
test2 = (A**2 * s**4 / (4 * pi * k * m**3)) * N.x
|
||||
test2 = test2.simplify()
|
||||
assert (test2 & N.x) == (A**2 * s**4 / (4 * pi * k * m**3))
|
||||
|
||||
test3 = ((4 + 4 * x - 2 * (2 + 2 * x)) / (2 + 2 * x)) * N.x
|
||||
test3 = test3.simplify()
|
||||
assert (test3 & N.x) == 0
|
||||
|
||||
test4 = ((-4 * x * y**2 - 2 * y**3 - 2 * x**2 * y) / (x + y)**2) * N.x
|
||||
test4 = test4.simplify()
|
||||
assert (test4 & N.x) == -2 * y
|
||||
|
||||
|
||||
def test_vector_evalf():
|
||||
a, b = symbols('a b')
|
||||
v = pi * A.x
|
||||
assert v.evalf(2) == Float('3.1416', 2) * A.x
|
||||
v = pi * A.x + 5 * a * A.y - b * A.z
|
||||
assert v.evalf(3) == Float('3.1416', 3) * A.x + Float('5', 3) * a * A.y - b * A.z
|
||||
assert v.evalf(5, subs={a: 1.234, b:5.8973}) == Float('3.1415926536', 5) * A.x + Float('6.17', 5) * A.y - Float('5.8973', 5) * A.z
|
||||
|
||||
|
||||
def test_vector_angle():
|
||||
A = ReferenceFrame('A')
|
||||
v1 = A.x + A.y
|
||||
v2 = A.z
|
||||
assert v1.angle_between(v2) == pi/2
|
||||
B = ReferenceFrame('B')
|
||||
B.orient_axis(A, A.x, pi)
|
||||
v3 = A.x
|
||||
v4 = B.x
|
||||
assert v3.angle_between(v4) == 0
|
||||
|
||||
|
||||
def test_vector_xreplace():
|
||||
x, y, z = symbols('x y z')
|
||||
v = x**2 * A.x + x*y * A.y + x*y*z * A.z
|
||||
assert v.xreplace({x : cos(x)}) == cos(x)**2 * A.x + y*cos(x) * A.y + y*z*cos(x) * A.z
|
||||
assert v.xreplace({x*y : pi}) == x**2 * A.x + pi * A.y + x*y*z * A.z
|
||||
assert v.xreplace({x*y*z : 1}) == x**2*A.x + x*y*A.y + A.z
|
||||
assert v.xreplace({x:1, z:0}) == A.x + y * A.y
|
||||
raises(TypeError, lambda: v.xreplace())
|
||||
raises(TypeError, lambda: v.xreplace([x, y]))
|
||||
|
||||
def test_issue_23366():
|
||||
u1 = dynamicsymbols('u1')
|
||||
N = ReferenceFrame('N')
|
||||
N_v_A = u1*N.x
|
||||
raises(VectorTypeError, lambda: N_v_A.diff(N, u1))
|
||||
|
||||
|
||||
def test_vector_outer():
|
||||
a, b, c, d, e, f = symbols('a, b, c, d, e, f')
|
||||
N = ReferenceFrame('N')
|
||||
v1 = a*N.x + b*N.y + c*N.z
|
||||
v2 = d*N.x + e*N.y + f*N.z
|
||||
v1v2 = Matrix([[a*d, a*e, a*f],
|
||||
[b*d, b*e, b*f],
|
||||
[c*d, c*e, c*f]])
|
||||
assert v1.outer(v2).to_matrix(N) == v1v2
|
||||
assert (v1 | v2).to_matrix(N) == v1v2
|
||||
v2v1 = Matrix([[d*a, d*b, d*c],
|
||||
[e*a, e*b, e*c],
|
||||
[f*a, f*b, f*c]])
|
||||
assert v2.outer(v1).to_matrix(N) == v2v1
|
||||
assert (v2 | v1).to_matrix(N) == v2v1
|
||||
|
||||
|
||||
def test_overloaded_operators():
|
||||
a, b, c, d, e, f = symbols('a, b, c, d, e, f')
|
||||
N = ReferenceFrame('N')
|
||||
v1 = a*N.x + b*N.y + c*N.z
|
||||
v2 = d*N.x + e*N.y + f*N.z
|
||||
|
||||
assert v1 + v2 == v2 + v1
|
||||
assert v1 - v2 == -v2 + v1
|
||||
assert v1 & v2 == v2 & v1
|
||||
assert v1 ^ v2 == v1.cross(v2)
|
||||
assert v2 ^ v1 == v2.cross(v1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue