@@ -470,6 +470,18 @@ class Flight:
470470 array.
471471 Flight.simulation_mode : str
472472 Simulation mode for the flight. Can be "6 DOF" or "3 DOF".
473+ Flight.rail_button1_bending_moment : Function
474+ Internal bending moment at upper rail button attachment point in N·m
475+ as a function of time. Calculated using beam theory during rail phase.
476+ Flight.max_rail_button1_bending_moment : float
477+ Maximum internal bending moment experienced at upper rail button
478+ attachment point during rail flight phase in N·m.
479+ Flight.rail_button2_bending_moment : Function
480+ Internal bending moment at lower rail button attachment point in N·m
481+ as a function of time. Calculated using beam theory during rail phase.
482+ Flight.max_rail_button2_bending_moment : float
483+ Maximum internal bending moment experienced at lower rail button
484+ attachment point during rail flight phase in N·m.
473485 """
474486
475487 def __init__ ( # pylint: disable=too-many-arguments,too-many-statements
@@ -3958,3 +3970,62 @@ def __lt__(self, other):
39583970 otherwise.
39593971 """
39603972 return self .t < other .t
3973+ def _calculate_rail_button_bending_moments (self ):
3974+ """
3975+ Calculate internal bending moments at rail button attachment points.
3976+
3977+ Uses beam theory with simple support assumptions (ΣF≠0, M_contact=0)
3978+ to determine internal structural moments for stress analysis.
3979+
3980+ The bending moment at each button consists of two components:
3981+ 1. Main bending from the opposing button's normal force (M = N × L)
3982+ 2. Additional moment from shear force at button tip (M = S × h)
3983+
3984+ Returns
3985+ -------
3986+ None
3987+ """
3988+ # Check if rail buttons exist
3989+ if len (self .rocket .rail_buttons ) == 0 :
3990+ warnings .warn (
3991+ "Trying to calculate rail button bending moments without "
3992+ "rail buttons defined. Setting moments to zero." ,
3993+ UserWarning ,
3994+ )
3995+ null_moment = Function (0 )
3996+ self .rail_button1_bending_moment = null_moment
3997+ self .rail_button2_bending_moment = null_moment
3998+ self .max_rail_button1_bending_moment = 0.0
3999+ self .max_rail_button2_bending_moment = 0.0
4000+ return
4001+ #distance between points
4002+ button1_pos = self .rocket .rail_buttons .component_coordinate_system_orientation * (self .rocket .rail_buttons .position )
4003+ button2_pos = button1_pos + self .rocket .rail_buttons .buttons_distance
4004+ d1 = abs (button1_pos - self .rocket .center_of_mass_without_motor )
4005+ d2 = abs (button2_pos - self .rocket .center_of_mass_without_motor )
4006+ L = d1 + d2 # Distance between buttons
4007+ h_button = self .rocket .rail_buttons .button_height #rail button height
4008+ #forces
4009+ N1 = self .rail_button1_normal_force
4010+ N2 = self .rail_button2_normal_force
4011+ S1 = self .rail_button1_shear_force
4012+ S2 = self .rail_button2_shear_force
4013+ t = N1 .source [:, 0 ]
4014+ # Main bending from opposing button + additional moment from shear at tip
4015+ M1_values = N2 .source [:, 1 ] * L + S1 .source [:, 1 ] * h_button
4016+ M2_values = N1 .source [:, 1 ] * L + S2 .source [:, 1 ] * h_button
4017+ self .rail_button1_bending_moment = Function (
4018+ np .column_stack ([t , M1_values ]),
4019+ inputs = "Time (s)" ,
4020+ outputs = "Bending Moment (N·m)" ,
4021+ interpolation = "linear" ,
4022+ )
4023+ self .rail_button2_bending_moment = Function (
4024+ np .column_stack ([t , M2_values ]),
4025+ inputs = "Time (s)" ,
4026+ outputs = "Bending Moment (N·m)" ,
4027+ interpolation = "linear" ,
4028+ )
4029+ # Maximum bending moments in terms of absolute value for stress calculations
4030+ self .max_rail_button1_bending_moment = float (np .max (np .abs (M1_values )))
4031+ self .max_rail_button2_bending_moment = float (np .max (np .abs (M2_values )))
0 commit comments