C $Id: icss_transf_att.f,v 1.2 1998/07/24 21:54:41 asc Exp $
CCCC
C
C  ICSS_TRANSF_ATT - converts a spin stabilized attitude position vector 
C		     from one coordinate system to another.
C 
C  PURPOSE:  Spacecraft spin stabilized attitude vectors in GCI, GSE, or GSM
C	     coordinates are accepted and transformed into the user's choice
C	     of GCI, GSE, or GSM.
C
C  UNIT TYPE:  SUBROUTINE
C
C  INVOCATION METHOD:  CALL ICSS_TRANSF_ATT (src_sys, 
C                                            target_sys,
C	                                     att_pos, 
C                                            att_pos_time, 
C                                            trans_att_pos, 
C					     rotation_matrix,
C                                            trans_att_stat)
C
C  ARGUMENT LIST:
C
C  NAME	             TYPE     USE     DESCRIPTION
C  ----              ----     ---     -----------
C  SRC_SYS           I*4      I       COORDINATE SYS OF ENTERED ATT VECTOR
C  TARGET_SYS        I*4      I       REQ. COORD. SYS OF TRANSFORMED ATT VECTOR
C  ATT_POS(3)        R*8      I       ATT VECTOR TO BE TRANSFORMED
C  ATT_POS_TIME(2)   I*4      I       TIME OF ATT. VECTOR, YEAR-DAY,MILLI OF DAY
C  TRANS_ATT_POS(3)  R*8      O       TRANSFORMED ATT VECTOR
C  ROTATION_MATRIX(9)R*8      O	      ROTATION MATRIX
C  TRANS_ATT_STAT    I*4      O       FLAG SHOWING STATUS OF TRANS. REQUEST
C
C  FILE/RECORD REFERENCES:  NONE
C  
C  EXTERNAL VARIABLES:  NONE
C
C  EXTERNAL REFERENCES:
C    IC_GCI_TO_GSE	    Returns the GCI to GSE transformation matrix
C    IC_GCI_TO_GSM	    Returns the GCI to GSM transformation matrix
C    MXTRP8		    routine that transposes matrices, but also
C                            inverts rotation matrices (the matrix that
C                            transforms a vector from one system to another)
C    IC_GSE_TO_GSM	    Returns the GSE to GSM transformation matrix
C    MULMAT		    routine that multiplies two matrices
C    IC_VECTOR_TO_ANGLES    Converts from vector form to rt asc and decl angles
C    IC_ANGLES_TO_VECTOR    Converts from rt asc and decl angles to vector 
C
C  ABNORMAL TERMINATION CONDITIONS, ERROR MESSAGES:
C
C  THE RETURN STATUS IS SET TO A NON-ZERO STATUS FROM A SUBORDINATE UNIT
C  THAT RETURNS AN ERROR
C
C  ASSUMPTIONS, CONSTRAINTS, RESTRICTIONS:  NONE
C
C  DEVELOPMENT HISTORY
C
C  AUTHOR	CHANGE ID	RELEASE	  DATE	    DESCRIPTION OF CHANGE
C  ------	---------	-------   ----	    ---------------------
C  J. LUBELCZYK                 B1R1      12/04/90  INITIAL PDL
C  J. LUBELCZYK                 B1R1      12/11/90  CODING
C  J. LUBELCZYK                           09/12/91  Return Transform matrix
C  J. LUBELCZYK                           09/19/91  Added error handling
C  J. LUBELCZYK ICCR #83, CCR #'S 130, 137 11/91    B3 update
C  J. Rizzello  ICCR #0761                11/26/91  Use local variables for
C						     upper case conversion
C  J. Rizzello  ICCR #0558                02/11/92  Return SS$_NORMAL to
C                                                    caller when successful
C  B. SAMUELSON SPOF PORT                 04/11/94  Change: required to port
C     (CSC)     (see notes)                          icss routines to SPOF
C
C
C  NOTES:
C
C 1.  The spin portion of the attitude vector is not used in any calls, such as
C     IC_ANGLES_TO_VECTOR and IC_VECTOR_TO_ANGLES.  Therefore, only the 2nd
C     and 3rd elements of the ATT_POS array are altered.
C
C 2.  The changes recorded under ID SPOF-PORT are required to make the
C     ICSS coordinate conversion routines, originally developed under
C     VAX-VMS 5.4 run on the UNIX-based workstations of the SPOF.  (Sun
C     SPARCstations and DEC DECstations).  The changes are as follows:
C        a.  Delete references to ICSS_INC
C        b.  Define Message texts or files to correspond to the messages
C            ICSS_SUCCESSFUL, etc. which are embedded in the error handling.
C        c.  Remove references to the NAG routines F01CRF and F01CKF (matrix
C            transposition and matrix multiplication routines).
C
C 3.  In addition, to successfully run the software packages, copies of the
C     Solar/Lunar/Planetary (SLP) file and timing coefficients file (TCC)
C     must be ported onto the SPOF.
C
C 4.  This version uses numbers to indicate source an target coordinate 
C     systems instead of characters to simplify conversion to different 
C     platforms. The values are as follows:
C      GCI = 1
C      GSE = 2
C      GSM = 3
C
CCCC
C
C  PDL:
C
C  if the source or target system are in valid then
C     SET error status
C     ABORT TO 990
C  endif
C  if the source system equals the target system then
C     TRANS_ATT_POS = ATT_POS
C     ABORT TO 990
C  endif
C  call IC_ANGLES_TO_VECTOR to convert right ascension and declination to
C   vector format 
C
C  docase KEY ON ATTITUDE SOURCE SYSTEM
C  case 1 (SRC_SYS is equal to GCI)
C
C     docase SOURCE SYS IS GCI, GET CORRESPONDING ATTITUDE TARGET SYSTEM
C     case 1 (TARGET_SYS is equal to GSE)
C        call IC_GCI_TO_GSE to get the gci to gse TRANSFORM_MATRIX
C     case 2 (TARGET_SYS is equal to GSM)
C        call IC_GCI_TO_GSM to get the gci to gsm TRANSFORM_MATRIX
C     enddo
C
C  case 2 (SRC_SYS is equal to GSE)
C
C     docase SOURCE SYS IS GSE, GET CORRESPONDING ATTITUDE TARGET SYSTEM
C     case 1 (TARGET_SYS is equal to GCI)
C        call IC_GCI_TO_GSE to get the gci to gse TRANSFORM_MATRIX
C        call MXTRP8 routine to invert the TRANSFORM_MATRIX resulting
C         in the gse to gci TRANSFORM_MATRIX
C     case 2 (TARGET_SYS is equal to GSM)
C        call IC_GSE_TO_GSM to get the gse to gsm TRANSFORM_MATRIX
C     enddo
C
C  case 3 (SRC_SYS is equal to GSM)
C
C     docase SOURCE SYS IS GSM, GET CORRESPONDING ATTITUDE TARGET SYSTEM
C     case 1 (TARGET_SYS is equal to GCI)
C        call IC_GCI_TO_GSM to get the gci to gsm TRANSFORM_MATRIX
C        call MXTRP8 routine to invert the TRANSFORM_MATRIX resulting
C         in the gsm to gci TRANSFORM_MATRIX
C     case 2 (TARGET_SYS is equal to GSE)
C        call IC_GSE_TO_GSM to get the gse to gsm TRANSFORM_MATRIX
C        call MXTRP8 routine to invert the TRANSFORM_MATRIX resulting
C         in the gsm to gse TRANSFORM_MATRIX
C     enddo
C
C  enddo
C
C  if (getting the transformation matrix was not successful) abort to 990
C
C  call MXTRP8 routine to multiply the TRANSFORM_MATRIX and 
C   the given ATT_POS vector.  The result will be the TRANS_ATT_POS.
C
C  call IC_VECTOR_TO_ANGLES to get the right ascension and declination angles.
C     The 1st element, spin, of ATT_POS is retained from IC_ANGLES_TO_VECTOR
C
C  copy spin from ATT_POS to TRANS_ATT_POS
C
C  Return the transformation matrix in 9 element single dimension format
C
C990 CONTINUE
C
C  RETURN
C
CCCC
	subroutine icss_transf_att (SRC_SYS,
     -                              TARGET_SYS,
     -                              ATT_POS,
     -                              ATT_POS_TIME,
     -                              TRANS_ATT_POS,
     -				    ROTATION_MATRIX,
     -                              TRANS_ATT_STAT)
C
	implicit none
C
C*  Calling parameters
C
	integer*4   SRC_SYS    !Attitude vector's coordinate system
	integer*4   TARGET_SYS !Requested coordinate system that
C                              !attitude vector is to be transformed to.
	real*8	    ATT_POS(3)     !attitude vector to be transformed
	real*8	    TRANS_ATT_POS(3) !transformed attitude vector
	integer*4   ATT_POS_TIME(2)  !time of att vector, YYYYDDD, milli of day
	real*8	    ROTATION_MATRIX(9) !Rotation matrix
	integer*4   TRANS_ATT_STAT     !status of transformation request
C
C*  Other Variables
C
	real*8	    TRANSFORM_MATRIX(3,3)  !Transformation matrix
        real*8      TEMP_MATRIX(3,3)  !temporary result matrix
	real*8	    ATT_POS_VECT(3) !attitude position converted to vector form
	real*8	    TRANS_ATT_POS_VECT(3) !transformed att pos in vector form
        real*8      DUMMY(3,3)
        integer*4   INTDUMMY /0/
	integer*4   STATUS	 !local status of transformation
C
C*  Include
C
C
C*  Start Executable Code
C

C
C* Check for invalid source or target coordinate systems 
C
	TRANS_ATT_STAT = 0 
        if ((SRC_SYS .lt. 1) .or. (SRC_SYS .gt. 3)) then
           TRANS_ATT_STAT = 1
           goto 990
        else if ((TARGET_SYS .lt. 1) .or. (TARGET_SYS .gt. 3)) then
           TRANS_ATT_STAT = 1
           goto 990
        endif 
C
C*  if source and target systems are the same no need to calculate anything 
C
	if  (SRC_SYS .eq. TARGET_SYS) then
	   TRANS_ATT_POS(1) = ATT_POS(1)
	   TRANS_ATT_POS(2) = ATT_POS(2)
	   TRANS_ATT_POS(3) = ATT_POS(3)
	   goto 990
	endif
C
C*  convert right ascension and declination angles to vector format
C
        call IC_ANGLES_TO_VECTOR (ATT_POS, ATT_POS_VECT)
C
C*  get requested TRANSFORMation_MATRIX
C
	if (SRC_SYS .eq. 1) then

	   if (TARGET_SYS .eq. 2) then
	      call IC_GCI_TO_GSE (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
	   else ! TARGET_SYSTEM equals GSM
	      call IC_GCI_TO_GSM (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
	   endif
C
	else if (SRC_SYS .eq. 2) then
C
	   if (TARGET_SYS .eq. 1) then
	      call IC_GCI_TO_GSE (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
C
C*  call MXTRP8 ROUTINE TO INVERT THE TRANSFORMATION MATRIX
C
	      call MXTRP8 (TRANSFORM_MATRIX, TEMP_MATRIX, 3, 3)
              TRANSFORM_MATRIX(1,1) = TEMP_MATRIX(1,1)
              TRANSFORM_MATRIX(2,1) = TEMP_MATRIX(2,1)
              TRANSFORM_MATRIX(3,1) = TEMP_MATRIX(3,1)
              TRANSFORM_MATRIX(1,2) = TEMP_MATRIX(1,2)
              TRANSFORM_MATRIX(2,2) = TEMP_MATRIX(2,2)
              TRANSFORM_MATRIX(3,2) = TEMP_MATRIX(3,2)
              TRANSFORM_MATRIX(1,3) = TEMP_MATRIX(1,3)
              TRANSFORM_MATRIX(2,3) = TEMP_MATRIX(2,3)
              TRANSFORM_MATRIX(3,3) = TEMP_MATRIX(3,3)
	   else ! TARGET_SYS equals GSM
	      call IC_GSE_TO_GSM (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
	   endif
C
	else ! SRC_SYS equals GSM
C
	   if (TARGET_SYS .eq. 1) then
	      call IC_GCI_TO_GSM (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
C
C*  call MXTRP8 ROUTINE TO INVERT THE TRANSFORMATION MATRIX
C
	      call MXTRP8 (TRANSFORM_MATRIX, TEMP_MATRIX, 3, 3)
              TRANSFORM_MATRIX(1,1) = TEMP_MATRIX(1,1)
              TRANSFORM_MATRIX(2,1) = TEMP_MATRIX(2,1)
              TRANSFORM_MATRIX(3,1) = TEMP_MATRIX(3,1)
              TRANSFORM_MATRIX(1,2) = TEMP_MATRIX(1,2)
              TRANSFORM_MATRIX(2,2) = TEMP_MATRIX(2,2)
              TRANSFORM_MATRIX(3,2) = TEMP_MATRIX(3,2)
              TRANSFORM_MATRIX(1,3) = TEMP_MATRIX(1,3)
              TRANSFORM_MATRIX(2,3) = TEMP_MATRIX(2,3)
              TRANSFORM_MATRIX(3,3) = TEMP_MATRIX(3,3)
	   else ! TARGET_SYS equals GSE
	      call IC_GSE_TO_GSM (ATT_POS_TIME, 
     1                  TRANSFORM_MATRIX, DUMMY, INTDUMMY, STATUS)
C
C*  call MXTRP8 ROUTINE TO INVERT THE TRANSFORMATION MATRIX
C
	      call MXTRP8 (TRANSFORM_MATRIX, TEMP_MATRIX, 3, 3)
              TRANSFORM_MATRIX(1,1) = TEMP_MATRIX(1,1)
              TRANSFORM_MATRIX(2,1) = TEMP_MATRIX(2,1)
              TRANSFORM_MATRIX(3,1) = TEMP_MATRIX(3,1)
              TRANSFORM_MATRIX(1,2) = TEMP_MATRIX(1,2)
              TRANSFORM_MATRIX(2,2) = TEMP_MATRIX(2,2)
              TRANSFORM_MATRIX(3,2) = TEMP_MATRIX(3,2)
              TRANSFORM_MATRIX(1,3) = TEMP_MATRIX(1,3)
              TRANSFORM_MATRIX(2,3) = TEMP_MATRIX(2,3)
              TRANSFORM_MATRIX(3,3) = TEMP_MATRIX(3,3)
	   endif
C
	endif
C
C*  Check status of the transformation matrix
C
	if (STATUS .ne. 0) goto 990
C
C*  call MULMAT LIBRARY ROUTINE TO MULTIPLY THE TRANSFORMATION MATRIX BY
C*   THE GIVEN ATT VECTOR.  THE RESULT WILL BE THE TARGET ATTITUDE POSITION.
C
	call MULMAT (TRANSFORM_MATRIX, ATT_POS_VECT, 3, 3, 1, 
     -               TRANS_ATT_POS_VECT)
C
C*  Get the right ascension and declination angles from ATT_POS_VECT
C
	call IC_VECTOR_TO_ANGLES (TRANS_ATT_POS_VECT, TRANS_ATT_POS)
C
C*  Copy spin from att_pos to trans_att_pos
C
	TRANS_ATT_POS(1) = ATT_POS(1)
C
C*  Return the transformation matrix
C
	ROTATION_MATRIX(1) = TRANSFORM_MATRIX(1,1)
	ROTATION_MATRIX(2) = TRANSFORM_MATRIX(2,1)
	ROTATION_MATRIX(3) = TRANSFORM_MATRIX(3,1)
	ROTATION_MATRIX(4) = TRANSFORM_MATRIX(1,2)
	ROTATION_MATRIX(5) = TRANSFORM_MATRIX(2,2)
	ROTATION_MATRIX(6) = TRANSFORM_MATRIX(3,2)
	ROTATION_MATRIX(7) = TRANSFORM_MATRIX(1,3)
	ROTATION_MATRIX(8) = TRANSFORM_MATRIX(2,3)
	ROTATION_MATRIX(9) = TRANSFORM_MATRIX(3,3)
C
990	if (STATUS .ne. 0) then
	    TRANS_ATT_STAT = STATUS
	endif

	RETURN
C
	END
