@@ -97,11 +97,72 @@ void UpdatePersistentParameters () {
9797 ThrustPersistent = this . finalThrust ;
9898 }
9999
100+ // Calculate demands of each resource
101+ public double [ ] CalculateDemands ( double demandMass ) {
102+ var demands = new double [ pplist . Count ] ;
103+ if ( demandMass > 0 ) {
104+ // Per propellant demand
105+ for ( var i = 0 ; i < pplist . Count ; i ++ ) {
106+ demands [ i ] = pplist [ i ] . Demand ( demandMass ) ;
107+ }
108+ }
109+ return demands ;
110+ }
111+
112+ // Apply demanded resources & return results
113+ // Updated depleted boolean flag if resource request failed
114+ public double [ ] ApplyDemands ( double [ ] demands , ref bool depleted ) {
115+ var demandsOut = new double [ pplist . Count ] ;
116+ for ( var i = 0 ; i < pplist . Count ; i ++ ) {
117+ var pp = pplist [ i ] ;
118+ // Request resources if:
119+ // - resource has mass & request mass flag true
120+ // - resource massless & request massless flag true
121+ if ( ( pp . density > 0 && RequestPropMass ) || ( pp . density == 0 && RequestPropMassless ) ) {
122+ var demandOut = part . RequestResource ( pp . propellant . name , demands [ i ] ) ;
123+ demandsOut [ i ] = demandOut ;
124+ // Test if resource depleted
125+ // TODO test if resource partially depleted: demandOut < demands[i]
126+ // For the moment, just let the full deltaV for time segment dT be applied
127+ if ( demandOut == 0 ) {
128+ depleted = true ;
129+ }
130+ }
131+ // Otherwise demand is 0
132+ else {
133+ demandsOut [ i ] = 0 ;
134+ }
135+ }
136+ // Return demand outputs
137+ return demandsOut ;
138+ }
139+
140+ // Calculate DeltaV vector and update resource demand from mass (demandMass)
141+ public Vector3d CalculateDeltaVV ( double m0 , double dT , float thrust , float isp , Vector3d thrustUV , out double demandMass ) {
142+ // Mass flow rate
143+ var mdot = thrust / ( isp * 9.81f ) ;
144+ // Change in mass over time interval dT
145+ var dm = mdot * dT ;
146+ // Resource demand from propellants with mass
147+ demandMass = dm / densityAverage ;
148+ // Mass at end of time interval dT
149+ var m1 = m0 - dm ;
150+ // deltaV amount
151+ var deltaV = isp * 9.81f * Math . Log ( m0 / m1 ) ;
152+ // Return deltaV vector
153+ return deltaV * thrustUV ;
154+ }
155+
156+ // Apply the deltaV vector at UT and dT to
157+ public static void ApplyDeltaVV ( Vector3d deltaVV , double UT , Orbit orbit ) {
158+ orbit . Perturb ( deltaVV , UT ) ;
159+ }
160+
100161 // Physics update
101162 public override void OnFixedUpdate ( ) {
102163 if ( FlightGlobals . fetch != null && isEnabled ) {
103164 // Time step size
104- double dT = TimeWarp . fixedDeltaTime ;
165+ var dT = TimeWarp . fixedDeltaTime ;
105166
106167 // Realtime mode
107168 if ( ! this . vessel . packed ) {
@@ -112,50 +173,33 @@ public override void OnFixedUpdate() {
112173 }
113174
114175 // Timewarp mode: perturb orbit using thrust
115- else if ( part . vessel . situation != Vessel . Situations . SUB_ORBITAL )
116- {
176+ else if ( part . vessel . situation != Vessel . Situations . SUB_ORBITAL ) {
117177 warpToReal = true ; // Set to true for transition to realtime
118- double UT = Planetarium . GetUniversalTime ( ) ; // Universal time
119- double m0 = this . vessel . GetTotalMass ( ) ; // Current mass
120- float mdot = ThrustPersistent / ( IspPersistent * 9.81f ) ; // Mass flow rate of engine
121- double dm = mdot * dT ; // Change in mass over dT
122- double demandMass = dm / densityAverage ; // Resource demand for sum of massive propellants
123- bool depleted = false ; // Check if resources depleted
124-
125- // Update vessel resources if demand > 0
126- if ( demandMass > 0 ) {
127- foreach ( var pp in pplist ) {
128- // Per propellant demand
129- var demandProp = pp . Demand ( demandMass ) ;
130- if ( ( pp . density > 0 && RequestPropMass ) || ( pp . density == 0 && RequestPropMassless ) ) {
131- var demandPropOut = part . RequestResource ( pp . propellant . name , demandProp ) ;
132- // Check if depleted
133- if ( demandPropOut == 0 ) {
134- depleted = true ;
135- }
136- }
137- }
138- }
139-
140- // Calculate thrust and deltaV if demand output > 0
178+ var UT = Planetarium . GetUniversalTime ( ) ; // Universal time
179+ var m0 = this . vessel . GetTotalMass ( ) ; // Current mass
180+ var thrustUV = this . part . transform . up ; // Thrust direction unit vector
181+ // Calculate deltaV vector & resource demand from propellants with mass
182+ double demandMass ;
183+ var deltaVV = CalculateDeltaVV ( m0 , dT , ThrustPersistent , IspPersistent , thrustUV , out demandMass ) ;
184+ // Calculate resource demands
185+ var demands = CalculateDemands ( demandMass ) ;
186+ // Apply resource demands & test for resource depletion
187+ var depleted = false ;
188+ var demandsOut = ApplyDemands ( demands , ref depleted ) ;
189+ // Apply deltaV vector at UT & dT to orbit if resources not depleted
141190 if ( ! depleted ) {
142- double m1 = m0 - dm ; // Mass at end of burn
143- double deltaV = IspPersistent * 9.81 * Math . Log ( m0 / m1 ) ; // Delta V from burn
144- Vector3d thrustV = this . part . transform . up ; // Thrust direction
145- Vector3d deltaVV = deltaV * thrustV ; // DeltaV vector
146- vessel . orbit . Perturb ( deltaVV , UT , dT ) ; // Update vessel orbit
191+ ApplyDeltaVV ( deltaVV , UT , this . vessel . orbit ) ;
147192 }
148- // Otherwise, if throttle is turned on, and demand out is 0, show warning
193+ // Otherwise log warning and drop out of timewarp if throttle on & depleted
149194 else if ( ThrottlePersistent > 0 ) {
150195 Debug . Log ( "Propellant depleted" ) ;
151- // Return to realtime mode
196+ // Return to realtime
152197 TimeWarp . SetRate ( 0 , true ) ;
153198 }
154199 }
155- // Otherwise suborbital - set throttle to 0 and show error message.
156- // TODO fix persistent thrust orbit perturbation on suborbital trajectory.
157- else if ( vessel . ctrlState . mainThrottle > 0 )
158- {
200+ // Otherwise, if suborbital, set throttle to 0 and show error message
201+ // TODO fix persistent thrust orbit perturbation on suborbital trajectory
202+ else if ( vessel . ctrlState . mainThrottle > 0 ) {
159203 vessel . ctrlState . mainThrottle = 0 ;
160204 ScreenMessages . PostScreenMessage ( "Cannot accelerate and timewarp durring sub orbital spaceflight!" , 5.0f , ScreenMessageStyle . UPPER_CENTER ) ;
161205 }
0 commit comments