6
6
__copyright__ = "Copyright 20XX, RocketPy Team"
7
7
__license__ = "MIT"
8
8
9
+ from logging import warning
9
10
import math
10
11
import time
11
12
from functools import cached_property
16
17
from scipy import integrate
17
18
18
19
from .Function import Function
20
+ import warnings
19
21
20
22
21
23
class Flight :
@@ -2731,17 +2733,156 @@ def __retrieved_temporary_values_arrays(self):
2731
2733
)
2732
2734
2733
2735
# Rail Button Forces
2734
- def __calculate_rail_button_forces ( self ):
2735
- """Calculate the forces applied to the rail buttons while rocket is still
2736
- on the launch rail.
2736
+ @ cached_property
2737
+ def railButton1NormalForce ( self ):
2738
+ """Upper rail button normal force as a function of time
2737
2739
2738
2740
Returns
2739
2741
-------
2740
- None
2742
+ railButton1NormalForce: Function
2743
+ Upper rail button normal force as a function of time
2744
+ """
2745
+ F11 , F12 = self .__calculate_rail_button_forces ()[0 :1 ]
2746
+ alpha = self .rocket .railButtons .angularPosition * (np .pi / 180 )
2747
+ railButton1NormalForce = F11 * np .cos (alpha ) + F12 * np .sin (alpha )
2748
+ railButton1NormalForce .setOutputs ("Upper Rail Button Normal Force (N)" )
2749
+
2750
+ return railButton1NormalForce
2751
+
2752
+ @cached_property
2753
+ def railButton1ShearForce (self ):
2754
+ """Upper rail button shear force as a function of time
2755
+
2756
+ Returns
2757
+ -------
2758
+ _type_
2759
+ _description_
2741
2760
"""
2761
+ F11 , F12 = self .__calculate_rail_button_forces ()[0 :1 ]
2742
2762
alpha = self .rocket .railButtons .angularPosition * (
2743
2763
np .pi / 180
2744
2764
) # Rail buttons angular position
2765
+ railButton1ShearForce = F11 * - np .sin (alpha ) + F12 * np .cos (alpha )
2766
+ railButton1ShearForce .setOutputs ("Upper Rail Button Shear Force (N)" )
2767
+
2768
+ return railButton1ShearForce
2769
+
2770
+ @cached_property
2771
+ def railButton2NormalForce (self ):
2772
+ """Lower rail button normal force as a function of time
2773
+
2774
+ Returns
2775
+ -------
2776
+ railButton2NormalForce: Function
2777
+ Lower rail button normal force as a function of time
2778
+ """
2779
+ F21 , F22 = self .__calculate_rail_button_forces ()[2 :3 ]
2780
+ alpha = self .rocket .railButtons .angularPosition * (np .pi / 180 )
2781
+ railButton2NormalForce = F21 * np .cos (alpha ) + F22 * np .sin (alpha )
2782
+ railButton2NormalForce .setOutputs ("Lower Rail Button Normal Force (N)" )
2783
+
2784
+ return railButton2NormalForce
2785
+
2786
+ @cached_property
2787
+ def railButton2ShearForce (self ):
2788
+ """Lower rail button shear force as a function of time
2789
+
2790
+ Returns
2791
+ -------
2792
+ railButton2ShearForce: Function
2793
+ Lower rail button shear force as a function of time
2794
+ """
2795
+
2796
+ F21 , F22 = self .__calculate_rail_button_forces ()[2 :3 ]
2797
+ alpha = self .rocket .railButtons .angularPosition * (np .pi / 180 )
2798
+ railButton2ShearForce = F21 * - np .sin (alpha ) + F22 * np .cos (alpha )
2799
+ railButton2ShearForce .setOutputs ("Lower Rail Button Shear Force (N)" )
2800
+
2801
+ return railButton2ShearForce
2802
+
2803
+ @cached_property
2804
+ def maxRailButton1NormalForce (self ):
2805
+ """Maximum upper rail button normal force, in Newtons
2806
+
2807
+ Returns
2808
+ -------
2809
+ maxRailButton1NormalForce: float
2810
+ Maximum upper rail button normal force, in Newtons
2811
+ """
2812
+ outOfRailTimeIndex = np .searchsorted (self .F11 [:, 0 ], self .outOfRailTime )
2813
+ if outOfRailTimeIndex == 0 :
2814
+ return 0
2815
+ else :
2816
+ return np .max (self .railButton1NormalForce [:outOfRailTimeIndex ])
2817
+
2818
+ @cached_property
2819
+ def maxRailButton1ShearForce (self ):
2820
+ """Maximum upper rail button shear force, in Newtons
2821
+
2822
+ Returns
2823
+ -------
2824
+ maxRailButton1ShearForce: float
2825
+ Maximum upper rail button shear force, in Newtons
2826
+ """
2827
+ outOfRailTimeIndex = np .searchsorted (self .F11 [:, 0 ], self .outOfRailTime )
2828
+ if outOfRailTimeIndex == 0 :
2829
+ return 0
2830
+ else :
2831
+ return np .max (self .railButton1ShearForce [:outOfRailTimeIndex ])
2832
+
2833
+ @cached_property
2834
+ def maxRailButton2NormalForce (self ):
2835
+ """Maximum lower rail button normal force, in Newtons
2836
+
2837
+ Returns
2838
+ -------
2839
+ maxRailButton2NormalForce: float
2840
+ Maximum lower rail button normal force, in Newtons
2841
+ """
2842
+ outOfRailTimeIndex = np .searchsorted (self .F11 [:, 0 ], self .outOfRailTime )
2843
+ if outOfRailTimeIndex == 0 :
2844
+ return 0
2845
+ else :
2846
+ return np .max (self .railButton2NormalForce [:outOfRailTimeIndex ])
2847
+
2848
+ @cached_property
2849
+ def maxRailButton2ShearForce (self ):
2850
+ """Maximum lower rail button shear force, in Newtons
2851
+
2852
+ Returns
2853
+ -------
2854
+ maxRailButton2ShearForce: float
2855
+ Maximum lower rail button shear force, in Newtons
2856
+ """
2857
+ outOfRailTimeIndex = np .searchsorted (self .F11 [:, 0 ], self .outOfRailTime )
2858
+ if outOfRailTimeIndex == 0 :
2859
+ return 0
2860
+ else :
2861
+ return np .max (self .railButton2ShearForce [:outOfRailTimeIndex ])
2862
+
2863
+ @cached_property
2864
+ def __calculate_rail_button_forces (self ):
2865
+ """Calculate the forces applied to the rail buttons while rocket is still
2866
+ on the launch rail. It will return 0 if none rail buttons are defined.
2867
+
2868
+ Returns
2869
+ -------
2870
+ F11: Function
2871
+ Rail Button 1 force in the 1 direction
2872
+ F12:
2873
+ Rail Button 1 force in the 2 direction
2874
+ F21:
2875
+ Rail Button 2 force in the 1 direction
2876
+ F22:
2877
+ Rail Button 2 force in the 2 direction
2878
+ """
2879
+
2880
+ if self .rocket .railButtons is None :
2881
+ warnings .warn (
2882
+ "Trying to calculate rail button forces without rail buttons defined."
2883
+ )
2884
+ return 0 , 0 , 0 , 0
2885
+
2745
2886
D1 = self .rocket .railButtons .distanceToCM [
2746
2887
0
2747
2888
] # Distance from Rail Button 1 (upper) to CM
@@ -2760,43 +2901,13 @@ def __calculate_rail_button_forces(self):
2760
2901
F22 = (self .R2 * D1 - self .M1 ) / (
2761
2902
D1 + D2
2762
2903
) # Rail Button 2 force in the 2 direction
2763
- outOfRailTimeIndex = np .searchsorted (
2764
- F11 [:, 0 ], self .outOfRailTime
2765
- ) # Find out of rail time index
2904
+
2766
2905
# F11 = F11[:outOfRailTimeIndex + 1, :] # Limit force calculation to when rocket is in rail
2767
2906
# F12 = F12[:outOfRailTimeIndex + 1, :] # Limit force calculation to when rocket is in rail
2768
2907
# F21 = F21[:outOfRailTimeIndex + 1, :] # Limit force calculation to when rocket is in rail
2769
2908
# F22 = F22[:outOfRailTimeIndex + 1, :] # Limit force calculation to when rocket is in rail
2770
- self .railButton1NormalForce = F11 * np .cos (alpha ) + F12 * np .sin (alpha )
2771
- self .railButton1NormalForce .setOutputs ("Upper Rail Button Normal Force (N)" )
2772
- self .railButton1ShearForce = F11 * - np .sin (alpha ) + F12 * np .cos (alpha )
2773
- self .railButton1ShearForce .setOutputs ("Upper Rail Button Shear Force (N)" )
2774
- self .railButton2NormalForce = F21 * np .cos (alpha ) + F22 * np .sin (alpha )
2775
- self .railButton2NormalForce .setOutputs ("Lower Rail Button Normal Force (N)" )
2776
- self .railButton2ShearForce = F21 * - np .sin (alpha ) + F22 * np .cos (alpha )
2777
- self .railButton2ShearForce .setOutputs ("Lower Rail Button Shear Force (N)" )
2778
- # Rail Button Maximum Forces
2779
- if outOfRailTimeIndex == 0 :
2780
- self .maxRailButton1NormalForce = 0
2781
- self .maxRailButton1ShearForce = 0
2782
- self .maxRailButton2NormalForce = 0
2783
- self .maxRailButton2ShearForce = 0
2784
- else :
2785
- self .maxRailButton1NormalForce = np .amax (
2786
- self .railButton1NormalForce [:outOfRailTimeIndex ]
2787
- )
2788
- self .maxRailButton1ShearForce = np .amax (
2789
- self .railButton1ShearForce [:outOfRailTimeIndex ]
2790
- )
2791
- self .maxRailButton2NormalForce = np .amax (
2792
- self .railButton2NormalForce [:outOfRailTimeIndex ]
2793
- )
2794
- self .maxRailButton2ShearForce = np .amax (
2795
- self .railButton2ShearForce [:outOfRailTimeIndex ]
2796
- )
2797
2909
2798
- self .calculatedRailButtonForces = True
2799
- return None
2910
+ return F11 , F12 , F21 , F22
2800
2911
2801
2912
def __calculate_geodesic_coordinates (self ):
2802
2913
"""Calculate the geodesic coordinates (i.e. latitude and longitude) of
@@ -2943,10 +3054,6 @@ def postProcess(self, interpolation="spline", extrapolation="natural"):
2943
3054
None
2944
3055
"""
2945
3056
2946
- # Deal with the rail buttons forces calculation
2947
- if self .calculatedRailButtonForces is not True :
2948
- self .__calculate_rail_button_forces ()
2949
-
2950
3057
# Post process other quantities # TODO: Implement boolean to check if already done
2951
3058
if self .calculatedGeodesicCoordinates is not True :
2952
3059
self .__calculate_geodesic_coordinates ()
0 commit comments