Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets
This commit is contained in:
@@ -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]))
|
||||
+133
@@ -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
|
||||
+509
@@ -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)
|
||||
Reference in New Issue
Block a user