Source code for irfpy.jdc.frame1

r''' Frame definition. Based on JUI-ADST-INST-TN-000122_01

The frame of the JDC is defined, though it is not the final.
JDC's frame0

**Spacecraft frame**

* +z: nadir deck
* -z: zenith deck.
* -x: HGA

JDC will be located at the edge of +x/-z.

**JDC1 frame**

* +z: JDC symmetric axis.  The JDC looking hemisphere is +x hemisphere.
* +x: Open direction (same direction as SC frame)
* -x: Toward the thruster (and HGA direction)

Note also that JDC would have a tilt around y axis, due to the contamination from
the thrusters.
The angle of tilt is not yet determined.
Thus, this angle would be given as a parameter.

**Conversion between JDC & SC**

The conversion matrix is as follows:

.. math::

    x_SC        \cos\theta     0     \sin\theta         x_JDC
    y_SC   =         0        -1          0             y_JDC
    z_SC        \sin\theta     0    -\cos\theta         z_JDC


**Convert between the JDC0 angles and vectors**

The converion of the angles to JDC1 frame is implemented.
See :func:`angles2jdc` and :func:`jdc2angles`.
The definition follows the definition of myself.
Thus, the coordinate system may be chagned in the future.

The definition is consistent to the one defined in :mod:`fov1 <irfpy.jdc.fov1>`.
The elevation angle, :math:`\theta`, 0 is the zenith (z axis) and 180 for the nadir looking direction.
The azimutha angle, :math:`\phi`, 0 is x axis and 90 for y axis.

Angle :math:`\theta` and :math:`\phi` is the polar coordinate system
of the JDC1 frame.


**Convert from NSC vectors to physical frame**

The conversion is implemented in :mod:`irfpy.pep.pep_attitude` module.
'''
import numpy as np

[docs]def angles2jdc(theta, phi): r''' Return the unit vector corresponding to the given angles. :param theta: Theta in degrees. Float or (N,) shape np.array. :type theta: float :param phi: Phi in degrees. Float or (N,) shape np.array. :type phi: float :returns: The corresponding vector with shape of (3,) or (3, N) :rtype: ``np.array`` >>> print(angles2jdc(0, 0)) [ 0. 0. 1.] The following returns the corresponding vector for :math:`(\theta, \phi) = (0, 0), (1, 1), (2, 2), ...` at once. >>> print(angles2jdc(np.arange(181), np.arange(181)).shape) (3, 181) ''' t = np.deg2rad(theta); p = np.deg2rad(phi) x = np.sin(t) * np.cos(p) y = np.sin(t) * np.sin(p) z = np.cos(t) return np.array([x, y, z])
[docs]def jdc2angles(vec): ''' Return the JDC angle for the corresponding JDC vector. :param vec: np.array, with (3,) or (3, N) shape. :type vec: np.array :returns: Theta and Phi :rtype: np.array with (2,) or (2, N) shape. >>> print(jdc2angles([1, 0, 0])) [90. 0.] For multiple vectors, you can convert to angles. Note that the shape should be (3, N), thus, the array should look like ``np.array([[x0, x1, x2, ...], [y0, y1, y2, ...], [z0, z1, z2, ...]])`` >>> print(jdc2angles([[1, 10, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]])) [[90. 90. 90. 45.] [ 0. 0. 90. 0.]] ''' # vec is (3,) or (3, N) veclen = np.sqrt((np.array(vec) ** 2).sum(0)) # Now, scalar or (N,) vu = vec / veclen # Now, (3,) or (3, N) t = np.arccos(vu[2]) p = np.arctan2(vu[1], vu[0]) return np.array([np.rad2deg(t), np.rad2deg(p)])
[docs]def nsc2jdc(vecnsc, tilt=0): ''' Convert from NSC to JDC. :param vec: (3,) or (3,N) array. :param tilt: Tilt angle in degrees. vec should be (3,) or (3,N) array. >>> nsc = [ 1., -2., 3.] >>> print(nsc2jdc(nsc)) [ 1. 2. -3.] >>> nsc = [-1.41421356, -2., 2.82842712] >>> print(nsc2jdc(nsc, tilt=45)) [ 1. 2. -2.99999999] >>> nscs = [[ 2., 1., 0., -1., 2.,], ... [-1., -1., -1., -1., -1.], ... [-3., -1., 0., 1., 3.]] >>> print(nsc2jdc(nscs)) [[ 2. 1. 0. -1. 2.] [ 1. 1. 1. 1. 1.] [ 3. 1. 0. -1. -3.]] ''' c = np.cos(np.deg2rad(tilt)) s = np.sin(np.deg2rad(tilt)) mat = np.array([[c, 0, s], [0, -1, 0], [s, 0, -c]]).T vecjdc = mat.dot(vecnsc) return vecjdc
[docs]def jdc2nsc(vecjdc, tilt=0): ''' Convert from JDC to (N)SC. :param vec: (3,) or (3,N) array. :param tilt: Tilt angle in degrees. .. math:: x_SC \cos\theta 0 \sin\theta x_JDC y_SC = 0 -1 0 y_JDC z_SC \sin\theta 0 -\cos\theta z_JDC >>> jdc = [1, 2, -3] >>> print(jdc2nsc(jdc)) [ 1. -2. 3.] >>> print(jdc2nsc(jdc, tilt=45)) [-1.41421356 -2. 2.82842712] >>> jdcs = [ [ 2, 1, 0, -1, 2], ... [ 1, 1, 1, 1, 1], ... [ 3, 1, 0, -1, -3]] >>> print(jdc2nsc(jdcs)) [[ 2. 1. 0. -1. 2.] [-1. -1. -1. -1. -1.] [-3. -1. 0. 1. 3.]] ''' c = np.cos(np.deg2rad(tilt)) s = np.sin(np.deg2rad(tilt)) mat = np.array([[c, 0, s], [0, -1, 0], [s, 0, -c]]) vecnsc = mat.dot(vecjdc) return vecnsc
import unittest import doctest
[docs]def doctests(): return unittest.TestSuite(( doctest.DocTestSuite(), ))
if __name__ == '__main__': unittest.main(defaultTest='doctests')