C$Procedure TGTGT C SUBROUTINE TGTGT ( TESTCASE, & STRAT , TARGET_STRAT , DAYS , & ORBIN , DATIN, REV, & DVIN, PITCH, YAW, DVQUANTA, & M , JEARTH , & LTOP , LSFLAG , DRAG , cd, dsmadt, & tsmaswitch, sigma_dsma, dragbiasmode, & BOUNDS , BNDFUZ , & TIMTGT , TIMFUZ , & ORBITS , XINGS , & WATCH , watchint , & DV_FIXED, DV_PROP, DA_OD, SF_DVOD, sf_drag, & sf_boost, & NDRAG_BIAS, DRAG_BIAS, dvbracket, & ATARGONLY, Page , & ORBEND , DATEND , PLOTDATE, WINDO, boot, & plot, plot_components, plotcycle & ) C C C******************************************************************************* C C Copyright (C) 1993, California Institute of Technology. U.S. C Government Sponsorhip under NASA Contract NAS7-918 is C acknowledged. C C******************************************************************************* C C$ Log C C Date Name Description C ----------------------------------------------------------------------------- C 30-JUL-1990 Eric Cannell creation of TGTGT C 31-JUL-1991 Bruce Shapiro allow CLASS=3 or 6 in first guess, i.e., C too small or to large first dv. C Add call to FIRSTGUESS (atarg) C Add Delta-v quantization C Add ground track biasing (east & west) C Add post-targ runouts C Add spreadsheet-like output table C 20-APR-1992 B.E.S. Replace DODV with DOMNVR from OAMS C C$ Purpose C C TGTGT determines the dV that properly targets the ground track in C accordance to the criteria established by the selected targeting C strategy. C C$ Input_Arguments C C Name Type Dim Units Description C ----------------------------------------------------------------------------- C STRAT C*6 1 - see Purpose C TARGET_STRAT C*8 1 - for STRAT other than RUNOUT: C 'UNBIASED' - target on UNBIASED TRACK C 'WESTGT' - target on 95% west track C 'EASTGT' - target on 95% east track C DAYS I 1 days if DAYS>0, the ground track is run out C DAYS days, regardless of whether or not C the ground lies within or without the C valid band defined by BOUNDS. if DAYS=<0, C the ground track is run out until it C leaves the valid band as defined by input C BOUNDS. However, if a ground track lies C completely outside of the valid band, C TGTGT will terminate the track after C TOLONG days. C ORBIN DP 6 km,deg input orbit of (a,e,i,LAN,w,M) C DATIN C*25 1 --> input epoch of ORBIT in TIMETRANS format C 'dd-mmm-yyyy hh:mm:ss.fff C REV rev # of maneuver C DVIN DP 1 mm/sec initial guess of dV C DVQUANTA DP 1 mm/sec quantization of dv C if <= 0 then do not quantize C M I 1 - forces TGTGT to examine every M-th C ascending node. For example, one hopes C that M=4 is a lot faster computationally C and almost as accurate as M=1. C LTOP I 1 - the maximum L index to consider in LSRGP's C Earth gravity model (i.e., LTOP=17 means C model up to J17). C LSFLAG L 1 - if true, luni-solar effects are ON in the C LSRGP library C DRAG L 1 - if true, atmospheric drag effects are ON C in the PROP subroutine. Note that only C drag can affect semi-major axis. C Cd dp C dsmadt dp 2 m/day extra d/dt of SMA to include C tsmaswitch dp time, seconds, to switch dsmadt C dragbiasmode c*4 1 - 'FLUX' = use the flux sigmas C 'GT' = use the gtbiase sigmas C to determine the drag bias C BOUNDS DP 2 km the low and high boundaries (in that order) C of the valid ground track band as measured C from the reference ground track. Usually, C BOUNDS will be something like -/+ 1 km. C But, BOUNDS could be (.5,1.5), i.e., fully C right of the reference ground track. C BOUNDS is used only when DAYS=<0. C BNDFUZ DP 1 km when longitude targeting a ground track C to the west boundary, BNDFUZ is the C fuzziness of BOUNDS(1). In essence, if C ground is within BNDFUZ of BOUNDS(1), C then that is close enough. C TIMTGT DP 1 days if STRAT='EAST' or STRAT='WEST', then C TIMTGT is the desired target time to the C east or west boundary. C TIMFUZ DP 1 days if a ground track crosses the selected C boundary within TIMFUZ days of the desired C TIMTGT days, then that is close enough and C the ground track is considered properly C targeted C ORBITS I 1 - number of equator crossings XINGS C XINGS DP ORBITS deg reference equator crossings from REF_EQXING C JEARTH DP (2:29) - earth zonals C WATCH L 1 monitor calculations, true/false C WATCHINT L 1 - if true, then GTARG also records the C intermediate ground tracks that are found C prior before the properly targeted one C DV_FIXED, DP 1 mm/sec Fixed error C DV_PROP, DP 1 - Proportional error, proportion of dv C DA_OD, DP 1 m od error in a C SF_DVOD, DP 1 - scale factor for gt bias (dv & od comps) C sf_drag dp 1 - scale factor for gt bias (drag comp) C sf_boost dp 1 - scale factor for boost C NDRAG_BIAS, I 1 - number of drag bias points C DRAG_BIAS, DP NDRAG_BIAS km bias in gt due to drag C dvbracket i 3 counts to bracket target with subsequent C runouts C ATARGONLY L 1 - if true, just calculate the first guess C and do nothing else C Page i 1 - page number to start with C PLOT C PLOT_COMPONENTS C PLOTCYCLE C C$ Output_Arguments C C Name Type Dim Units Description C ----------------------------------------------------------------------------- C ORBEND DP 6 km,deg final orbit C DATEND C*25 1 - epoch of ORBEND C C$ Namelist_Output C C Namelist: $ZLINE: defines curves, not plot frame C Name Type Dim Units Description C ----------------------------------------------------------------------------- C NPTS I 1 - number of (x,y) data points C STYLE I 1 - PGPLOT line style: C STYLE = 1 --> solid C style = 2 --> dashed C STYLE = 4 --> dotted C style = 5 --> ...-...- C X RL MXNODE - x-data in world coordinates C Y RL MXNODE - y-data in world coordinates C C$ Parameters C INTEGER MXNODE PARAMETER ( MXNODE = 20000 ) C C$ Declarations_of_Input_and_Output_Arguments C Logical atargonly, boot DOUBLE PRECISION BNDFUZ DOUBLE PRECISION BOUNDS ( 2 ), tplotdate CHARACTER*25 DATEND, PLOTDATE REAL*4 WINDO(4) CHARACTER*25 DATIN INTEGER DAYS LOGICAL DRAG character*4 dragbiasmode double precision cd, dsmadt(2), tsmaswitch DOUBLE PRECISION DVIN, sigma_dsma(2) integer dvbracket ( 3 ) DOUBLE PRECISION DVQUANTA double precision jearth ( 2:29 ) LOGICAL LSFLAG INTEGER LTOP INTEGER M DOUBLE PRECISION ORBEND ( 6 ) DOUBLE PRECISION ORBIN ( 6 ) INTEGER ORBITS double precision pitch, yaw integer rev CHARACTER*6 STRAT CHARACTER*8 TARGET_STRAT, TESTCASE*80 DOUBLE PRECISION TIMFUZ DOUBLE PRECISION TIMTGT logical plot, plot_components, plotcycle LOGICAL WATCH, WATCHINT DOUBLE PRECISION XINGS ( ORBITS ) DOUBLE PRECISION DV_FIXED DOUBLE PRECISION DV_PROP DOUBLE PRECISION DA_OD DOUBLE PRECISION SF_DVOD, sf_drag, sf_boost INTEGER NDRAG_BIAS DOUBLE PRECISION DRAG_BIAS ( NDRAG_BIAS ) DOUBLE PRECISION GT_TABLE ( 6, MXNODE ) DOUBLE PRECISION DV_LABELS ( 6 ) C C via COMMON block tt C character*12 terminal common /tt/ terminal common /boost/ ndsmadt_data, dsmadt_data, dsmadt_epoch, & dsmadt_data_sigma, plot_boost, dsmadt_dates double precision dsmadt_data(1000) double precision dsmadt_data_sigma character*25 dsmadt_epoch, dsmadt_dates(1000) integer ndsmadt_data logical plot_boost real plot_datax(1000), plot_datay(1000) C C Via $ZLINE. C INTEGER NPTS INTEGER STYLE REAL X ( MXNODE ) REAL Y ( MXNODE ) C C$ Declarations_of_Local_Variables C C Name Type Dim Units Description C ----------------------------------------------------------------------------- C DVBND DP 2 mm/sec smallest range of dV's known to bound C the target dV: C DVBND(1) = largest dV < target dV C DVBND(2) = smallest dV > target dV C LIMITS DP 4,2 days,km with regard to ascending nodes, the C time (in days) and ground track offset C (in km) of the first node, the furthest C west node, the furthest east node, and C the last node of the ground track. LIMITS C allows GTARG to classify the ground track. C time offset C |------|--------| C first node | days | km | C furthest west node | days | km | C furthest east node | days | km | C final node | days | km | C |------|--------| C LIMITS_WEST DP 4,2 days, km see LIMITS; same, but for 95 percentile C LIMITS_EAST DP 4,2 westernmost track; LIMITS is for the C targeted ground track (error-free case) C DOUBLE PRECISION A0 DOUBLE PRECISION ABSDDV character adate*9, atime*8 DOUBLE PRECISION BETAP DOUBLE PRECISION DVBND ( 2 ) DOUBLE PRECISION DVNOW DOUBLE PRECISION DVOLD, dvvec(3), dvlcr(3) character*23 dvlabel INTEGER CLASS INTEGER CLSNOW INTEGER CLSOLD INTEGER GTID DOUBLE PRECISION LIMITS ( 4 , 2 ) DOUBLE PRECISION LIMITS_EAST ( 4, 2 ) DOUBLE PRECISION LIMITS_WEST ( 4, 2 ) integer norbits ( 3 ) DOUBLE PRECISION ORBWRK ( 6 ), opre(6), opost(6) integer page LOGICAL SUCCES DOUBLE PRECISION TARGET double precision tmaneuver ( 3 ) DOUBLE PRECISION VALNOW DOUBLE PRECISION VALOLD REAL XW (MXNODE), XE (MXNODE) DOUBLE PRECISION DPXW (MXNODE), DPXE (MXNODE) DOUBLE PRECISION DPX (MXNODE), DPY (MXNODE) C double precision evsw (MXNODE, 2) integer REFIDX (MXNODE) double precision ECL ( MXNODE ), x1, x2, y1, y2 real xtmp(2), ytmp(2) real bias_ode(mxnode), bias_dve(mxnode) real bias_fluxe(mxnode), bias_booste(mxnode) real bias_odw(mxnode), bias_dvw(mxnode) real bias_fluxw(mxnode), bias_boostw(mxnode) real plotdelta, boostdelta double precision t0, ti, ch2sec, drate external ch2sec, sec2ch logical error character*25 dati, sec2ch, dnode DOUBLE PRECISION DVA DOUBLE PRECISION DVB C C the following local variables are required because the quantization C algorithm may cause an iteration to repeat a delta-v calculation C which which was performed 2-iterations earlier. This will only happen C on the final (converging) iteration, and will require the entire C recalculation of all results for that iteration. Save the results C and check - and maybe the final iteration can be avoided. C double precision saved_orbend ( 6 ) double precision saved_orbwrk ( 6 ) character * 25 saved_datend double precision saved_limits ( 4, 2 ) double precision saved_limits_east ( 4, 2 ) double precision saved_limits_west ( 4, 2 ) integer saved_npts, saved_norbits(3) double precision saved_y ( mxnode), saved_x (mxnode) double precision saved_xw ( mxnode), saved_xe (mxnode) double precision saved_tmaneuver ( 3 ) C, saved_evsw(mxnode, 2) double precision saved_dvold, saved_dvvec(3), saved_dvlcr(3) double precision saved_ecl ( mxnode ) double precision bootdata(mxnode, 6), saved_bootdata(6, mxnode) integer saved_class, saved_refidx ( mxnode ) C C external declarations C CHARACTER*8 goto_string external goto_string C C$ Namelists C NAMELIST / ZLINE / NPTS , STYLE , X , Y C C$ Data_Statements C DATA DVBND / -1D10 , +1D10 / C C$ Method C-& plotdelta = ( CH2SEC ( datin, .TRUE., ERROR ) - & CH2SEC ( plotdate, .TRUE., ERROR ) )/86400.0d0 call clear_screen call screen_header ( TESTCASE, & strat, target_strat, bounds, & bndfuz, timfuz, datin, orbin, dvquanta, lsflag, & drag, m, ltop, dvbracket, atargonly, days, dragbiasmode, & sf_dvod, sf_drag, dv_fixed, dv_prop, da_od, cd, & dsmadt, sigma_dsma ) C Initialize --- 7/31/91 mod CLASS = 0 GTID = 0 C ----- end mod 7/31/91 C1 Set the target value, whether it will be the west boundary or C1 some time target. IF ( STRAT .EQ. 'LONG' ) THEN TARGET = BOUNDS(1) ELSE IF ( STRAT .EQ. 'EAST' ) THEN TARGET = TIMTGT ELSE IF ( STRAT .EQ. 'WEST' ) THEN TARGET = TIMTGT END IF C Iterate until first guess at Delta V is appropriate --- 7/31/91 if ( ( (DVIN .eq. 0) .AND. (STRAT .NE. 'RUNOUT') ) .or. & ATARGONLY ) THEN call firstguess ( STRAT, ORBIN, DATIN, TIMTGT, & BOUNDS, JEARTH, LTOP, LSFLAG, ORBITS, & XINGS, DVIN, betap ) C write(8,*) 'TGTGT(post firstguess) BETAP=',BETAP if (terminal .eq. 'VT100') & write (6,110) goto_string(7,45), dvin 110 format (' ',A8,F10.5) END IF if ( atargonly .and. TERMINAL .eq. 'VT100') then write(6,115) goto_string(14,1) 115 format(' ',A8) C & , 'First guess delta-v is ',F10.3,' mm/second.') stop 'First guess delta-v is shown. GTARG complete.' end if 200 CONTINUE GTID = GTID + 1 if (terminal .eq. 'VT100') & write (6,110) goto_string(7,45), dvin if (terminal .eq. 'VT100') & write ( 6, 94 ) goto_String(7,34), gtid 94 format (1x,a8,i4) if ((strat .ne. 'RUNOUT') .and. (dvquanta .gt. 0) ) then dvin = dvin - dmod ( dvin, dvquanta ) if (terminal .eq. 'VT100') & write (6,110) goto_string(7,45), dvin end if DVB = DVA DVA = DVIN if ( ( strat .ne. 'RUNOUT' ) .and. & ( dvquanta .gt. 0 ) .and. & ( dabs (dvb - dva) .lt. dvquanta ) )then write (6, *) goto_string(5,24), & 'ERROR: DVQUANTA = ', dvquanta, ' to big.' goto 902 end if C write (6, *) 'DVIN, DVA, DVB= ', dvin, dva, dvb C --- end mod 7/31/91 C1 Copy the input orbit into work areas. A0 = ORBIN(1) CALL DVMOVE ( 6 , ORBIN , ORBWRK ) C1 If this is simply a runout of the given dV, then compute the C1 ground track for DAYS days. Otherwise, set DAYS to zero for COMPGT. IF ( STRAT .NE. 'RUNOUT' ) DAYS = 0 C1 Execute the initial dV guess provided by user, run out the ground C1 track, and then classify the ground track. This first runout is C1 computed regardless of what the strategy is. C write(8,*) 'ORBIN=(PRE DOMNVR)',ORBIN call DVMOVE ( 6, ORBIN, OPRE) c CALL DODV ( A0 , DVIN , ORBWRK ) c write(8,*) 'ORBIN=(POST DODV)',ORBIN call DOMNVR ( OPRE, 0.001*DVIN, PITCH, YAW, opost, dvvec, dvlcr) C write ( 8, 900 ) (OPRE(KK), ORBWRK(KK), OPOST(KK),KK=1,6) 900 format(1x,'Pre',T20,'DODV',T40,'DOMNVR',/ & 6(1x,3F20.10,/)) c write(8,*) 'ORBIN=(POST DOMNVR)',ORBIN CALL DVMOVE(6, OPOST, ORBWRK) c write(8,*) 'ORBIN=(PRE COMPGT)',ORBIN C write(8,*) 'TGTGT:OPOST=',OPOST C write(8,*) 'TGTGT:ORBWRK=',ORBWRK CALL COMPGT ( ORBWRK , DATIN , & M , JEARTH, & LTOP , LSFLAG , DRAG, & dsmadt, tsmaswitch, sigma_dsma, dragbiasmode, & DAYS , BOUNDS , & ORBITS , XINGS , WATCH, & DV_FIXED, DV_PROP, DA_OD, & SF_DVOD, sf_drag, sf_boost, & NDRAG_BIAS, DRAG_BIAS, DVIN, target_strat, & bias_ode, bias_dve, bias_fluxe, bias_booste, & bias_odw, bias_dvw, bias_fluxw, bias_boostw, & ORBEND , DATEND , & LIMITS , LIMITS_WEST, LIMITS_EAST, & NPTS , DPY, DPX , DPXW , DPXE, tmaneuver, betap, & norbits, ecl, refidx, bootdata, PAGE ) CALL COPY84(DPX,X,NPTS) CALL COPY84(DPY,Y,NPTS) call shift4(Y, PLOTDELTA, NPTS) CALL COPY84(DPXE,XE,NPTS) CALL COPY84(DPXW,XW,NPTS) C write(8,*) 'TGTGT:after COMPGT BETAP=',betap CLSOLD = CLASS c write(8,*) 'ORBIN=(PRE FIND_CLASS)',ORBIN call find_class ( target_strat, limits, & limits_west, limits_east, bounds, class ) C1 If the use simply wants to runout a ground track, then skip to end C1 of TGTGT and record the ground track. IF ( STRAT .EQ. 'RUNOUT' ) then c write(8,*) 'ORBIN=(IF RUNOUT)',ORBIN dvnow = dvin GO TO 902 end if C1 Check if the initial dV guess was sufficiently good. The first ground C1 should not be a class 3 or 6. IF ( CLASS .EQ. 3 .OR. CLASS .EQ. 6 ) THEN WRITE(8,302) DVIN, CLASS 302 FORMAT(/,1X,'GTARG: DVIN(',D24.12,') CLASS ',I2,' FAILURE.') IF ( CLASS .EQ. 3 ) THEN write (8,*) 'CLASS = 3: GT always East of East Bounds' ELSE if (class .eq. 6) then write (8,*) 'CLASS = 6: GT always West of West Bounds' end if END IF C1 Check if the user got lucky and provided an initial dV guess that C1 solved the problem. call check_success ( STRAT , TARGET_STRAT, & CLASS , LIMITS, LIMITS_WEST, LIMITS_EAST , & BNDFUZ , TIMFUZ , TARGET , & SUCCES ) C1 Record data regarding this ground track. call display_limits ( 18, 1, limits, & limits_west, limits_east, .true. ) C2 Print record to OFILE. IF ( WATCHINT ) THEN IF ( MOD(GTID,3).EQ.1) THEN CALL NEWPAGE(PAGE,2) END IF WRITE(8,304) GTID , SUCCES , CLASS , DVIN call write_limits ( 8, LIMITS, LIMITS_WEST, LIMITS_EAST) C WRITE(8,305) ' Nominal Track ', LIMITS C WRITE(8,305) '95 Percentile West', LIMITS_WEST C WRITE(8,305) '95 Percentile East', LIMITS_EAST C2 Write $ZLINE namelist to EZPLOT data file. STYLE = 4 if (plot) WRITE(11,ZLINE) END IF 304 FORMAT(1X, 77('-'), & /,1X,'|', 25x,' Ground Track Trial ID: ',I3,1X,22x,'|', & /,1X,'| Success? : ',L3,T78,'|', & /,1X,'| Classification : ',I3,T78,'|', & /,1X,'| Maneuver Magnitude : ',F12.6,' mm/sec',T78,'|', & /,1x,'|', t78,'|') C1 If ground was successfully targeted, then we are done. IF ( SUCCES ) then dvnow = dvin GO TO 902 end if C iterate if still class 3 or class 6 --- 7/31/91 IF ( (CLASS .EQ. 3) .AND. (CLSOLD .EQ. 6) .OR. & (CLASS .EQ. 6) .AND. (CLSOLD .EQ. 3 ) ) THEN C DVIN = (DVNOW + DVOLD)/2.0 DVIN = (DVA + DVB)/2.0 GO TO 200 ELSE IF (CLASS .EQ. 3) THEN C DVIN = 2.0 * DVNOW DVIN = 2.0 * DVA GO TO 200 ELSE IF (CLASS .EQ. 6) THEN C DVIN = DVNOW/2.0 DVIN = DVA / 2.0 GO TO 200 END IF C ---- end mod 7/31/91 C1 As the initial dV guess did not solve the problem, set up "OLD" C1 and "NOW" variables prior to entry into the iterative search loop. CLSNOW = CLASS DVOLD = DVIN saved_dvold = dvold do i=1,3 saved_dvvec(i) = dvvec(i) saved_dvlcr(i) = dvlcr(i) end do IF ( STRAT .EQ. 'LONG' ) THEN if ( target_strat .eq. 'UNBIASED' ) then VALNOW = LIMITS(2,2) else if ( target_strat .eq. 'WESTGT' ) then VALNOW = LIMITS_WEST(2,2) else if ( target_strat .eq. 'EASTGT' ) then VALNOW = LIMITS_EAST(2,2) end if ELSE if ( target_strat .eq. 'UNBIASED' ) then VALNOW = LIMITS(4,1) else if ( target_strat .eq. 'WESTGT' ) then VALNOW = LIMITS_WEST(4,1) else if ( target_strat .eq. 'EASTGT' ) then VALNOW = LIMITS_EAST(4,1) end if END IF C1 Check if DVIN will restrict the range of possible dV's. Obviously, C1 it will. CALL CHKDV ( STRAT , CLSNOW , DVIN , VALNOW , TARGET , DVBND ) C1 Determine the second dV guess. Set this up as the "NOW" guess. Note C1 that within the loop TGTGT uses both "OLD" and "NOW" varaibles to C1 compute the new dV; however, for the second dV use an almost arbitrary C1 guess. ABSDDV = DABS( .2D0 * DVIN ) IF ( ( CLASS .EQ. 1 & .OR. CLASS .EQ. 2 & ) & .AND. ( STRAT .EQ. 'LONG' & .OR. STRAT .EQ. 'WEST' & ) & ) THEN DVNOW = DVIN + ABSDDV ELSE IF ( ( CLASS .EQ. 4 & .OR. CLASS .EQ. 5 & ) & .AND. ( STRAT .EQ. 'LONG' & .OR. STRAT .EQ. 'EAST' & ) & ) THEN DVNOW = DVIN - ABSDDV ELSE IF ( ( CLASS .EQ. 1 & .OR. CLASS .EQ. 2 & ) & .AND. ( STRAT .EQ. 'EAST' & ) & ) THEN IF ( VALNOW .LT. TARGET ) THEN DVNOW = DVIN + ABSDDV ELSE DVNOW = DVIN - ABSDDV END IF ELSE IF ( ( CLASS .EQ. 4 & .OR. CLASS .EQ. 5 & ) & .AND. ( STRAT .EQ. 'WEST' & ) & ) THEN IF ( VALNOW .LT. TARGET ) THEN DVNOW = DVIN - ABSDDV ELSE DVNOW = DVIN + ABSDDV END IF END IF C1 Continue guessing at dV until the dV is properly targeted. C1 C1 Do Loop... C write(8,*) 'TGTGT PRE 901: DVNOW=',DVNOW 901 CONTINUE if (terminal .eq. 'VT100') & write (6,110) goto_string(7,45), dvnow if ( (dvquanta .gt. 0) ) then C write(8,*)'TGTGT 901: DVNOW=',DVNOW dvnow = dvnow - dmod ( dvnow, dvquanta ) if (terminal .eq. 'VT100') & write (6,110) goto_string(7,45), dvnow C C check for convergence (will occur if approaching the C result from one side) C if ( ( dabs (dvnow - dvold) .lt. 0.9999*dvquanta ) )then goto 902 end if C C check for repeat of earlier guess (will occur if last 2 C iterations have bounded the result within a single C quanta) C if ( dvnow .eq. saved_dvold ) then C C recover the results from 2 iterations back C do i=1,3 dvvec(i) = saved_dvvec(i) dvlcr(i) = saved_dvlcr(i) end do class = saved_class do i = 1,6 orbend (i) = saved_orbend (i) orbwrk (i) = saved_orbwrk (i) end do datend = saved_datend do i = 1, 4 do ii = 1, 2 limits (i,ii) = saved_limits (i, ii) limits_east (i,ii) = saved_limits_east (i, ii) limits_west (i, ii) = saved_limits_west (i, ii) end do end do npts = saved_npts CALL COPY84(SAVED_Y,Y,NPTS) CALL COPY84(SAVED_X,X,NPTS) CALL COPY84(SAVED_XW,XW,NPTS) CALL COPY84(SAVED_XE,XE,NPTS) CALL COPY88(SAVED_Y,DPY,NPTS) CALL COPY88(SAVED_X,DPX,NPTS) CALL COPY88(SAVED_XW,DPXW,NPTS) CALL COPY88(SAVED_XE,DPXE,NPTS) do i = 1, npts C evsw(i,1) = saved_evsw(i,1) C evsw(i,2) = saved_evsw(i,2) ecl(i) = saved_ecl(i) refidx(i) = saved_refidx(i) do j=1,6 bootdata(i,j) = saved_bootdata(i,j) end do end do do i = 1, 3 tmaneuver(i) = saved_tmaneuver (i) norbits(i) = saved_norbits(i) end do goto 902 end if end if C2 Update the ground track iteration counter. GTID = GTID + 1 if (terminal .eq. 'VT100') & write ( 6, 94 ) goto_String(7,34), gtid C C save the previous iteration results just in case they C are needed C do i=1,3 saved_dvvec(i) = dvvec(i) saved_dvlcr(i) = dvlcr(i) end do saved_class = class do i = 1,6 saved_orbend (i) = orbend ( i ) saved_orbwrk (i) = orbwrk ( i ) end do saved_datend = datend do i = 1, 4 do ii = 1, 2 saved_limits (i,ii) = limits (i, ii) saved_limits_east (i,ii) = limits_east (i, ii) saved_limits_west (i, ii) = limits_west (i, ii) end do end do saved_npts = npts CALL COPY88(DPY,SAVED_Y,NPTS) CALL COPY88(DPX,SAVED_X,NPTS) CALL COPY88(DPXW,SAVED_XW,NPTS) CALL COPY88(DPXE,SAVED_XE,NPTS) do i = 1, npts C saved_evsw(i,1) = evsw (i,1) C saved_evsw(i,2) = evsw (i,2) saved_ecl(i) = ecl(i) saved_refidx(i) = refidx(i) do j = 1, 6 saved_bootdata(i,j) = bootdata(i,j) end do end do do i = 1, 3 saved_tmaneuver(i) = tmaneuver (i) saved_norbits(i) = norbits(i) end do C2 Execute the "NOW" dV, run out the ground track, and then classify C2 the ground track. call DVMOVE ( 6, ORBIN, OPRE) c CALL DODV ( A0 , DVNOW , ORBWRK ) C write(8,*) 'TGTGT:ORBWRK=',ORBWRK C write(8,*) 'TGTGT:OPRE=',OPRE C write(8,*) 'TGTGT(PREDMNVR):DVNOW=',DVNOW call DOMNVR ( OPRE,0.001*DVNOW, PITCH, YAW, & opost, dvvec, dvlcr) c write ( 8, 900 ) (OPRE(KK), ORBWRK(KK), OPOST(KK),KK=1,6) CALL DVMOVE(6, OPOST, ORBWRK) C write(8,*) 'TGTGT(POSTDMNVR):DVNOW=',DVNOW C write(8,*) 'TGTGT:OPRE=',OPRE C write(8,*) 'TGTGT:OPOST=',OPOST C write(8,*) 'TGTGT:ORBWRK=',ORBWRK CALL COMPGT ( ORBWRK , DATIN , & M , JEARTH , & LTOP , LSFLAG , DRAG, & dsmadt, tsmaswitch, sigma_dsma, dragbiasmode, & 0 , BOUNDS , & ORBITS , XINGS , WATCH , & DV_FIXED, DV_PROP, DA_OD, & SF_DVOD, sf_drag, sf_boost, & NDRAG_BIAS, DRAG_BIAS, DVNOW, target_strat, & bias_ode, bias_dve, bias_fluxe, bias_booste, & bias_odw, bias_dvw, bias_fluxw, bias_boostw, & ORBEND , DATEND , & LIMITS , LIMITS_WEST, LIMITS_EAST, & NPTS , DPY, DPX,DPXW,DPXE, tmaneuver, betap, & norbits, ecl, refidx, bootdata, PAGE ) CALL COPY84(DPX,X,NPTS) CALL COPY84(DPY,Y,NPTS) call shift4(Y, PLOTDELTA, NPTS) CALL COPY84(DPXE,XE,NPTS) CALL COPY84(DPXW,XW,NPTS) C write(8,*)'TGTGT:POST iterative COMPGT: betap=',betap C2 Check if "NOW" dV properly targets the ground track. call find_class ( target_strat, limits, & limits_west, limits_east, bounds, class ) call check_success ( STRAT , TARGET_STRAT, & CLASS , LIMITS, LIMITS_WEST, LIMITS_EAST , & BNDFUZ , TIMFUZ , TARGET , & SUCCES ) C1 If ground track was targeted properly, the exit loop. IF ( SUCCES ) GO TO 902 C2 If the user wants to record this ground track... call display_limits ( 18, 1, limits, & limits_west, limits_east, .false. ) IF ( WATCHINT ) THEN C3 Start a new page if necessary. IF ( ( MOD( GTID, 3 ) .EQ. 1 ) )then CALL NEWPAGE(PAGE,2) end if C3 Print record to OFILE. WRITE(8,304) GTID , SUCCES , CLASS , DVNOW call write_limits ( 8, LIMITS, LIMITS_WEST, LIMITS_EAST) C WRITE(8,305) ' Nominal Track ', LIMITS C WRITE(8,305) '95 Percentile West', LIMITS_WEST C WRITE(8,305) '95 Percentile East', LIMITS_EAST C3 Write $ZLINE namelist to EZPLOT data file. STYLE = 4 if (plot) WRITE(11,ZLINE) END IF C C Check maximum iterations --- 7/31/91 addition C -- future mod: add namelist input for maximum value IF (GTID .GE. 25) THEN call clear_screen STOP '>> ERROR EXIT: Algorithm does not converge.' END IF C End check --- 7/31/91 C2 Otherwise, update the remaining "OLD" and "NEW" variables. Note that C2 the class and independent value (distance west or time to boundary) C2 variables are updated here, but the "NOW" dV variable was updated C2 in the previous loop: i.e., one must find and execute a new dV C2 before the class and independent value can be assessed. CLSOLD = CLSNOW CLSNOW = CLASS VALOLD = VALNOW IF ( STRAT .EQ. 'LONG' ) THEN if ( target_strat .eq. 'UNBIASED' ) then VALNOW = LIMITS(2,2) else if ( target_strat .eq. 'WESTGT' ) then VALNOW = LIMITS_WEST(2,2) else if ( target_strat .eq. 'EASTGT' ) then VALNOW = LIMITS_EAST(2,2) end if ELSE if ( target_strat .eq. 'UNBIASED' ) then VALNOW = LIMITS(4,1) else if ( target_strat .eq. 'WESTGT' ) then VALNOW = LIMITS_WEST(4,1) else if ( target_strat .eq. 'EASTGT' ) then VALNOW = LIMITS_EAST(4,1) end if END IF C2 Check if dV will restrict range of possible dV's. CALL CHKDV( STRAT , CLSNOW , DVNOW , VALNOW , TARGET , DVBND ) C2 Compute the next dV. FNDDV takes care of transfering "NOW" dV to C2 "OLD" dV. saved_dvold = dvold C write(8,*) 'TGTGT PRE FINDV:DVNOW=',DVNOW,' DVOLD=',DVOLD CALL FNDDV ( STRAT , & CLSOLD , CLSNOW , & DVOLD , DVNOW , DVBND , & VALOLD , VALNOW , TARGET ) C2 Return to top of loop and test this new dV. C write(8,*) 'TGTGT POST FINDV:DVNOW=',DVNOW,' DVOLD=',DVOLD GO TO 901 C1 End of loop. 902 CONTINUE C1 Print the targeted ground track vital statistics. CALL NEWPAGE (PAGE,2) call clear_screen if (TERMINAL.eq.'VT100') print 1710, goto_string(1, 1) 1710 format(1x,a8,28('-'),1x,'Ground Track Results',1x,29('-')) if (TERMINAL .eq. 'VT100') & call display_limits ( 2, 1, limits, & limits_west, limits_east, .true. ) WRITE(8,304) GTID , SUCCES , CLASS , DVNOW call write_limits ( 8, LIMITS, LIMITS_WEST, LIMITS_EAST) C1 Use SUMMRY to print GTARG's Executive Summary following the C1 the targeted ground track's vitals on the last page. c write(8,*) 'ORBIN=(PRE-SUMMRY)',ORBIN CALL SUMMRY( STRAT , & ORBIN , DATIN , rev, & DVNOW , dvlcr, PITCH, YAW, ORBWRK , & LIMITS , & ORBEND , DATEND , tmaneuver, betap, norbits ) t0 = ch2sec ( datin, .true., error ) C C print kepler state summary C do i = 1, npts if (mod(i-1,50) .eq. 0 ) then CALL NEWPAGE(PAGE,2) write (8,83824) end if ti = dpy(i) * 86400.0d0 + t0 dati = sec2ch (ti) write (8,83825) dati(1:20),(bootdata(i,j),j=1,5) end do C C print ground track summary C do i = 1, npts if (mod(i-1,50) .eq. 0 ) then CALL NEWPAGE(PAGE,2) write (8,837) end if ti = dpy(i) * 86400.0d0 + t0 dati = sec2ch (ti) if ( i .gt. 1 .and. i .lt. npts ) then drate = 1000.0*(dpx(i+1) - dpx(i-1))/(dpy(i+1)-dpy(i-1)) write (8, 8382) rev+i*m, dati(1:20), * dpxw(i), dpx(i), dpxe(i), * refidx(i), ecl(i), * drate else write (8, 838) rev+i*m, dati(1:20), * dpxw(i), dpx(i), dpxe(i), * refidx(i), ecl(i) end if 837 format (1x, 2x, 'Orbit', 1x, 16x, 4x, * 1x, '-- Ground Track (km) --' * 8x, 8x, 2x, 'Drift', * /1x,' Number',1x,7x,'Date', 6x,'UTC', * 4x, 'West', 1x, 'Nominal' * 4x, 'East', * 1x,'Rev',3x,' long', 6x,'m/day', * /1x,7('-'),1x, 11('-'), 1x, 8('-'), 3(1x,7('-')), * 1x,'---',1x,7('-'),1x,10('-') * ) 838 format (1x, I7, 1x, A20, 3f8.3, i4, f8.3) 8382 format (1x, I7, 1x, A20, 3f8.3, i4, f8.3, f11.4) 83824 format (1x,7x,'Date',6x,'UTC',15x,'a',10x, * 'e',8x,'i',5x,'RAAN',6x,'AOP', * /1x,11('-'),1x,8('-'),1x,15('-'),1x,10('-'), * 3(1x,8('-'))) 83825 format (1x,A20,F16.8,f11.7, 3f9.3) if (boot) write (12,8385) dati, (bootdata(i,j), j=1,6) 8385 format(1x,'DATE = ''',A25,'''', * / 1x, 'ORBIT = ',3(F20.10,',',1x), * /1x,8x,3(F20.10,',',1x)) end do C C write ground track biasing components C do i = 1, npts if (mod(i-1,50) .eq. 0 ) then CALL NEWPAGE(PAGE,2) write (8,8390) end if ti = dpy(i) * 86400.0d0 + t0 dati = sec2ch (ti) write (8, 8392) dati(1:20), * abs(bias_odw(i)-dpx(i)), abs(bias_dvw(i)-dpx(i)), * abs(bias_boostw(i)-dpx(i)), abs(bias_fluxw(i)-dpx(i)), * abs(dpxw(i)-dpx(i)), abs(bias_fluxe(i)-dpx(i)), * abs(dpxe(i)-dpx(i)) end do 8390 format (1x,44x,4x,'West',4x,'West',4x, 'East',4x,'East' * /1x,7x,'Date',6x,'UTC', * 6x, 'OD', 6x,'DV', 3x,'BOOST',4x,'Drag', * ' Total',4x,'Drag', ' Total', * /1x,11('-'),1x,8('-'), 7(1x,'-------')) 8392 format (1x, A20, 7F8.4) C1 Write $ZLINE namelist describing the targeting ground track to C1 EZPLOT data file. Note that the targeted ground track is a solid C1 line, where as the un-targeted tracks were dotted lines. STYLE = 1 if (plot) then WRITE(11,ZLINE) if (plot_components) write(16,zline) C EAST/WEST 95 Percentile Tracks call write_curve ( 11, npts, xw, y, 2 ) call write_curve ( 11, npts, xe, y, 2) C C plot the boost/deboost (unmodeled forces) C if ( plot_boost ) then tplotdate = ch2sec (plotdate, .true., ERROR) if (dsmadt_epoch .ne. ' ') then boostdelta = & ( ch2sec ( dsmadt_epoch, .true., ERROR) - & tplotdate ) / 86400.0 do i = 1, ndsmadt_data plot_datay(i) = i - 1 + boostdelta plot_datax(i) = dsmadt_data(i) end do else do i = 1, ndsmadt_data plot_datay(i) = & ( ch2sec ( dsmadt_dates(i), .true., ERROR) - & tplotdate ) / 86400.0 plot_datax(i) = dsmadt_data(i) end do end if call write_curve ( 11, ndsmadt_data, plot_datax, & plot_datay, 1 ) end if C C label the cycle boundaries C if (plotcycle) then do i = 2, npts if (refidx(i) .lt. refidx (i-1)) then x1 = dble(real(refidx(i-1))) x2 = dble(real(refidx(i))) + dble(real(orbits)) y1 = dpy(i-1) y2 = dpy(i) y2 = y1 + ( 1.0d0 + dble(real(orbits)) & - real(refidx(i-1)) ) & * (y2-y1)/(x2-x1) ti = y2 * 86400.0d0 + t0 dnode = sec2ch ( ti ) xtmp(1) = windo(1) xtmp(2) = windo(2) ytmp(1) = y2 + plotdelta ytmp(2) = y2 + plotdelta call write_labeled_curve ( 11, 2, xtmp, ytmp, 4, & WINDO(1) + (WINDO(2)-WINDO(1))*0.01, & Ytmp(1) + (windo(4)-windo(3))*0.0075, & '\fr'//dnode(1:17) ) end if end do end if call write_label ( 11, windo(1), & windo(3)-0.0522*(windo(4)-windo(3)), & '\frData Epoch: '//datin) write(dvlabel, 8400) dvnow 8400 format('\gDV =',f10.5,' mm/sec') call write_label ( 11, windo(1)+0.8235*(windo(2)-windo(1)), & windo(3)-0.0522*(windo(4)-windo(3)), & '\fr'//dvlabel) C Break down bias into components for plot if (plot_components) then call write_curve ( 16, npts, xw, y, 5 ) call write_curve ( 16, npts, xe, y, 5) call write_curve ( 16, npts, bias_ode, y, 2 ) call write_curve ( 16, npts, bias_dve, y, 3 ) call write_curve ( 16, npts, bias_fluxe, y, 4 ) call write_curve ( 16, npts, bias_booste, y, 1) call write_curve ( 16, npts, bias_odw, y, 2 ) call write_curve ( 16, npts, bias_dvw, y, 3 ) call write_curve ( 16, npts, bias_fluxw, y, 4 ) call write_curve ( 16, npts, bias_boostw, y, 1) end if end if if ( dvbracket(1) .ge. dvbracket(2) ) return C C Do post-targeting runouts C if ( strat .ne. 'RUNOUT' ) then if ( target_strat .eq. 'UNBIASED' ) then days = int ( limits ( 4, 1) ) + 1 else if ( target_strat .eq. 'WESTGT' ) then days = int ( limits_west ( 4, 1) ) + 1 else if ( target_strat .eq. 'EASTGT' ) then days = int ( limits_east ( 4, 1) ) + 1 endif end if strat = 'RUNOUT' DVIN = DVNOW jcolumn = 0 do j = dvbracket(1), dvbracket(2), dvbracket(3) if (terminal .eq. 'VT100') print 2001, goto_string(12,1), j 2001 format(' ',a8,27('-'),' Post-Targeting Runout ', & i2,1x, 27('-')) if ( j .ne. 0 ) then jcolumn = jcolumn + 1 dvnow = dvin + dble(j) * dvquanta call DVMOVE ( 6, ORBIN, OPRE) c call dodv ( a0, dvnow, orbwrk ) call DOMNVR ( OPRE, 0.001*DVNOW, PITCH, YAW, & opost, dvvec, dvlcr) c write ( 8, 900 ) (OPRE(KK), ORBWRK(KK), OPOST(KK),KK=1,6) CALL DVMOVE(6, OPOST, ORBWRK) C write(8,*) 'TGTGT:OPOST=',OPOST C write(8,*) 'TGTGT:ORBWRK=',ORBWRK CALL COMPGT ( ORBWRK , DATIN , & M , JEARTH , & LTOP , LSFLAG , DRAG, & dsmadt, tsmaswitch, sigma_dsma, dragbiasmode, & DAYS , BOUNDS , & ORBITS , XINGS , WATCH , & DV_FIXED, DV_PROP, DA_OD, & SF_DVOD, sf_drag, sf_boost, & NDRAG_BIAS, DRAG_BIAS, DVNOW, target_strat, & bias_ode, bias_dve, bias_fluxe, bias_booste, & bias_odw, bias_dvw, bias_fluxw, bias_boostw, & ORBEND , DATEND , & LIMITS , LIMITS_WEST, LIMITS_EAST, & NPTS ,DPY,DPX ,DPXW,DPXE, tmaneuver, betap, & norbits, ecl, refidx, bootdata, PAGE) CALL COPY84(DPX,X,NPTS) CALL COPY84(DPY,Y,NPTS) call shift4(Y, PLOTDELTA, NPTS) CALL COPY84(DPXE,XE,NPTS) CALL COPY84(DPXW,XW,NPTS) call display_limits ( 18, 1, limits, & limits_west, limits_east, .true. ) C write(8,*) '**** DV BRACKET = ', j,' ****' CALL NEWPAGE(PAGE,2) write(8,399) j, DVNOW 399 format(' ', & /,1x,77('-'), & /,1x,'|',t78,'|', & /,1x,'|', 5x, 'Delta-V Bracketing Runout, Delta = ',i2, & ' counts, dv = ',f7.2,' mm/sec.',t78,'|', & /,1x,'|',t78,'|', & /,1x,77('-'), * /,1x,'|',t78,'|') C WRITE(8,304) GTID , SUCCES , CLASS , DVNOW call write_limits ( 8, LIMITS, LIMITS_WEST, LIMITS_EAST) CALL SUMMRY( STRAT , ORBIN , DATIN , rev, & DVNOW , dvlcr, PITCH, YAW, & ORBWRK , LIMITS , ORBEND , DATEND , & tmaneuver, OPRE, betap, norbits ) STYLE = 5 if (plot) WRITE(11,ZLINE) C C save the data in the table for output to the spreadsheet file C dv_labels ( jcolumn ) = dvnow do istep = 1, npts gt_table ( jcolumn, istep ) = x(istep) end do end if C C write bracketing data to the spread sheet file if time C C if ( (jcolumn .eq. 6) .or. C & (j .gt. dvbracket(2)-dvbracket(3) ) ) then C write ( 13, * ) '***** dv braketing runout *****' C write ( 13, 989 ) ( dv_labels ( k ), k = 1, jcolumn ) C do istep = 1, npts C write ( 13, 990 ) y(istep), C & ( gt_table(k,istep), k=1,jcolumn ) C end do C C989 format (1x, ' Time', 7f11.3) C990 format ( 1x, 7f11.6) C jcolumn = 0 C end if end do C1 End of TGTGT. RETURN END