两级火箭模拟求助:odeint使用及“object too deep for desired array”报错
odeint for Two-Stage Rocket Simulation Hey there! I totally get that tackling computational physics coursework with limited English can feel overwhelming—let’s work through this odeint error step by step. That "object too deep" message almost always boils down to dimension mismatches between what odeint expects and what your code is returning, so we’ll focus on that.
Common Causes & Fixes
Let’s break down the most likely issues and how to fix them:
Your state vector is nested/2D instead of 1D
odeintrequires your initial statey0and the derivative returned by your dynamics function to be 1D arrays (or flat lists). If you’ve packed your rocket’s position, velocity, and masses into a nested structure likey0 = [[z0], [v0], [m10], [m20]], that’s a 2D array—andodeintwill throw this error.
Fix: Use a flat 1D array instead:y0 = array([0.0, 0.0, masa1_initial, masa2_initial]) # [position, velocity, m1, m2]Your dynamics function returns a nested/2D array
The function you pass toodeint(let’s call itrocket_dynamics) must return a 1D array of derivatives matching the shape ofy. If you’re returning something like[[dzdt], [dvdt], [dm1dt], [dm2dt]], that’s a 2D structure.
Fix: Return a flat numpy array or list:def rocket_dynamics(y, t, masa1, masa2): z, v, m1, m2 = y # Calculate your derivatives here (dzdt, dvdt, dm1dt, dm2dt) # ... (your physics equations for thrust, gravity, fuel burn rate) # Critical: Return a flat 1D array return array([dzdt, dvdt, dm1dt, dm2dt])You’re passing array parameters instead of scalars to
odeint
If you’re looping through fuel ratios and accidentally passing an entire array ofMasa1values toodeintinstead of a single scalar, this can cause dimension mismatches.
Fix: When callingodeint, make sureargsuses single scalar values for each parameter:# For a single fuel ratio (example values) sol = odeint(rocket_dynamics, y0, time_points, args=(45.0, 25.0))
Quick Debugging Tip
Add print statements to check the shape of your state and derivatives:
def rocket_dynamics(y, t, masa1, masa2): print("State shape:", y.shape) # Should be (4,) for 4 state variables # ... calculate derivatives ... dydt = array([dzdt, dvdt, dm1dt, dm2dt]) print("Derivative shape:", dydt.shape) # Should also be (4,) return dydt
If either shape shows up as (4,1) or (1,4), you’ve got a 2D structure that needs flattening.
Example Working Code Snippet
Here’s a simplified framework to adapt to your rocket physics:
from numpy import array, linspace, odeint import matplotlib.pyplot as plt def rocket_dynamics(y, t, m1_total, m2_total): z, v, m1, m2 = y g = 9.81 thrust = 1200 # Adjust to your rocket's thrust value fuel_burn_rate_1 = -0.2 # Negative because mass decreases fuel_burn_rate_2 = -0.15 # Stop fuel burn when mass hits structural limit (example values) dm1dt = fuel_burn_rate_1 if m1 > 10 else 0 dm2dt = fuel_burn_rate_2 if (m1 <= 10 and m2 > 5) else 0 # Calculate acceleration total_mass = m1 + m2 if total_mass > 15: # Both stages have fuel or structure left dvdt = (thrust - total_mass * g) / total_mass else: dvdt = -g # Only gravity acting dzdt = v return array([dzdt, dvdt, dm1dt, dm2dt]) # Initial conditions: position=0, velocity=0, m1=50, m2=30 y0 = array([0.0, 0.0, 50.0, 30.0]) time = linspace(0, 120, 1000) # Run simulation for a single fuel ratio solution = odeint(rocket_dynamics, y0, time, args=(50.0, 30.0)) # Plot position over time plt.plot(time, solution[:, 0]) plt.xlabel("Time (seconds)") plt.ylabel("Position (meters)") plt.title("Two-Stage Rocket Position") plt.show()
Once you fix the dimension issues, you’ll be able to loop through different Masa1/Masa2 ratios and analyze their impact on flight time. Don’t hesitate to tweak the physics equations to match your coursework’s requirements!
内容的提问来源于stack exchange,提问作者docsk8

