Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: Multi-stage example #45

Open
nbrophy3 opened this issue Sep 18, 2020 · 21 comments · Fixed by #322
Open

DOC: Multi-stage example #45

nbrophy3 opened this issue Sep 18, 2020 · 21 comments · Fixed by #322
Assignees
Labels
Docs Docs and examples related Flight Flight Class related features Question Further information is requested

Comments

@nbrophy3
Copy link

Beautiful program. Trying to find multistage capability in the Rocket class, couldn't find anything in the documentation. Is this a feature that is a goal for your team? Or was it eliminated?

Also looking at how Complex Recovery dispersion analysis is handled. IE if nose cone and motor have separate chute systems, can this be modeled? Ideally, I'm looking for 6DOF dispersion analysis for a two part sustainer and a booster.

@giovaniceotto
Copy link
Member

Great questions @nbrophy3!

First, multistage rockets can be fully simulated using RocketPy. However, as you have already noticed, this isn't currently hardcoded in any class.

For now, simulating multistage rockets is done as follows:

  1. Create a Motor object for the first stage. Let's call it Motor1.
  2. Create a Rocket object which includes both stages (total mass and inertia moments), but only Motor1. Let's call it Rocket1.
  3. Create a Flight object using Rocket1 and an Environment of your choice, using the argument terminateOnApogee=True. This will calculate the trajectory as if the second stage had never activated, until apogee is reached.
  4. Create a Motor object for the second stage, named Motor2 here.
  5. Create a Rocket object which represents the second stage only, using Motor2. Let's call it Stage2.
  6. Create a Flight object using Stage2 and an Environment of your choice. Initialize de class by specifying the argument initialSolution. This let's you copy the final solution from the first stage simulation as the initial state for this simulation.

Not as easy, but certainly can be done! The good thing is that it's flexible, allowing you to have as many stages as you need. Let me know if you need more information.

About complex recovery, multi-body dynamics (3DOF parachute + N x 3DOF rocket parts) is certainly the weakest part of RocketPy right now and something we need to improve. If you check the code, you will see only a 3DOF recovery simulation. Let me now if you would be interested in joining our team to improve this!

@nbrophy3
Copy link
Author

Ok interesting. Thanks for the info. When you do go about creating automatic multistage, most of the time a vehicle will activate it's second stage well before it would reach apogee. You'd want to reference a separation time and ignition delay. Probably add a "terminate x sec after burnout" (where x is sep. time) is the best way to get that then loop around the code again for the next stage. It'd also be a great feature to have the ignition delay be graphed against altitude (like you do with fin design).

@giovaniceotto
Copy link
Member

You are 100% correct. If burn out time is known for each stage, you can limit the trajectory simulation using the maxTime argument of the Flight class, which essentially simulates the flight until maxTime is reached. This is for efficiency only, you can always simulate the entire flight and get the state of the rocket at any time stamp you wish.

I would really like to create an example Jupyter Notebook implementing this which we discussed. However, unfortunately I have no data of a multi-stage rocket to use as good inputs. Do you have any data or experience with multi-stage rockets to help or review this example?

@nbrophy3
Copy link
Author

Oh that's great! Typically you would know your burn time and set up your second stage to seperate and ignite based on that, so a maxtime output would do the job perfectly. I think I'm going to try and make an add on to make this automated, because it seems like it would actually be fairly simple to do, the real hassle would be in combining the graphing, but I guess you could just have three or four seperate figures for ascent and recovery of each part of the vehicle. I do actually have a few two stage rockets (30K ft+) and some live data I'd like to compare with rocket.py just to see what it looks like. If I can get the add on working would you like me to send you a copy and something that reflects the format of your first example online?

@giovaniceotto
Copy link
Member

That's amazing!! Sure, I would really like to see your progress. If we get good results, we can add the functionality into RocketPy and you become a key contributor.

We have tested RocketPy for single stage rockets (10k ft), and obtained excelente results (~3% error), but having precise inputs is key.

Let me know if you need any help working on your simulations! I will stay tuned to help if any doubts appear.

@nbrophy3
Copy link
Author

Sounds great; hopefully something will come of it--quick question though, to what altitude can your atmosphere plugin model?

@giovaniceotto
Copy link
Member

RocketPy has many weather models as you can see here: Environment Class Usage.

The Standard Atmosphere, for example, works from -2 km to 80 km. Weather reanalysis from NOAA (GFS) or ECMWF (ERA-5) usually go up to 30 km ~ 50 km.

To make sure, you can always use the Environment.info() method to get this data, as can be seen below:

image

@kapusuzoglu
Copy link

Hi, thank you for the information.

I have tried a two-stage rocket following your guideline. However, the second stage results copies the first stage results after the apogee. Basically, using a single stage and two-stage gives the same results (by using the same type of motor and rocket for both stages). Why does for example the apogee is more than using a single stage system? I couldn't find what I am missing.

Also, the Flight object for the second stage cannot be called with info() and allInfo(). 'function' object is not subscriptable is the error I get.

Thank you.

@kapusuzoglu
Copy link

I realized defining an initialsolution results in "'function' object is not subscriptable" error.
Also, I tried single-stage rockets with an initialsolution (somewhere close to the aporgee) and realized that the solution looks exactly the same without an initialsolution.

@giovaniceotto
Copy link
Member

Quite weird results @berkcan1992. Do you mind sharing your code so that I can debug it here?

@kapusuzoglu
Copy link

I realized that the initialsolution should start from tInit = 0.
Have you checked RocketPy for multi-stage rockets? Do you have any input data for it or can you suggest me a place to look for it?

Does this make sense?

Motor1 = SolidMotor(
    thrustSource="../../data/motors/Cesaroni_M1670.eng",
    burnOut=3.9,
    grainNumber=5,
    grainSeparation=5/1000,
    grainDensity=1815,
    grainOuterRadius=33/1000,
    grainInitialInnerRadius=15/1000,
    grainInitialHeight=120/1000,
    nozzleRadius=33/1000,
    throatRadius=11/1000,
    interpolationMethod='linear'
)

Motor2 = SolidMotor(
    thrustSource="../../data/motors/Cesaroni_M1670.eng",
    burnOut=3.9,
    grainNumber=5,
    grainSeparation=5/1000,
    grainDensity=1815,
    grainOuterRadius=33/1000,
    grainInitialInnerRadius=15/1000,
    grainInitialHeight=120/1000,
    nozzleRadius=33/1000,
    throatRadius=11/1000,
    interpolationMethod='linear'
)


Rocket1 = Rocket(
    motor=Motor1,
    radius=127/2000,
    mass=2*19.197-2.956,
    inertiaI=6.60,
    inertiaZ=0.0351,
    distanceRocketNozzle=-1.255,
    distanceRocketPropellant=-0.85704,
    powerOffDrag='../../data/calisto/powerOffDragCurve.csv',
    powerOnDrag='../../data/calisto/powerOnDragCurve.csv'
)

Rocket1.setRailButtons([0.2, -0.5])

Stage2 = Rocket(
    motor=Motor2,
    radius=127/2000,
    mass=19.197-2.956,
    inertiaI=6.60,
    inertiaZ=0.0351,
    distanceRocketNozzle=-1.255,
    distanceRocketPropellant=-0.85704,
    powerOffDrag='../../data/calisto/powerOffDragCurve.csv',
    powerOnDrag='../../data/calisto/powerOnDragCurve.csv'
)
Stage2.setRailButtons([0.2, -0.5])

I don't know how to adjust the inertiaI and inertiaZ.

@kapusuzoglu
Copy link

Also, I assume that we need to change the Euler parameters to the initial values when we are setting up the initialsolution. Otherwise, the rocket will not climb up in the second stage. Am I right?

@giovaniceotto
Copy link
Member

First of all, this example created by Dyllon Preston (@fakeAEmajorRosen) may be helpful.

Now, about your comments...

I realized that the initialsolution should start from tInit = 0.

Yes, indeed. It should look like: [tInit, xInit, yInit, zInit, vxInit, vyInit, vzInit, e0Init, e1Init, e2Init, e3Init, w1Init, w2Init, w3Init].

Also, I assume that we need to change the Euler parameters to the initial values when we are setting up the initialsolution. Otherwise, the rocket will not climb up in the second stage. Am I right?

Yes! Generally speaking, you should use the final solution from the previous flight (which is actually the first stage) as the initial solution of the second flight (second stage).

Keep in mind that you should force the first flight to stop right before separation (perhaps using the maxTime argument of the Flight class) or you can let the first flight run until ground impact/apogee and just get the initialSolution from a specified time of you choice, as @fakeAEmajorRosen did in his code:

initialSolution=[0, Flight_stage1.x(tsecond_stage), 0, Flight_stage1.z(tsecond_stage), Flight_stage1.vx(tsecond_stage), Flight_stage1.vy(tsecond_stage), 0, Flight_stage1.e0(tsecond_stage), Flight_stage1.e1(tsecond_stage), Flight_stage1.e2(tsecond_stage), Flight_stage1.e3(tsecond_stage), Flight_stage1.w1(tsecond_stage), Flight_stage1.w2(tsecond_stage), Flight_stage1.w3(tsecond_stage)]

Let me know if this clears things up for you!

@kapusuzoglu
Copy link

Thank you!

What I did was very close to this. Only thing I didn't understand why Y and Vz are set to 0 for the second stage. When I set Vz to 0, the simulation gives an error (I also do not have the same rocket data as the example).

@giovaniceotto
Copy link
Member

Only thing I didn't understand why Y and Vz are set to 0 for the second stage.

Probably, something specific to his setup.

When I set Vz to 0, the simulation gives an error (I also do not have the same rocket data as the example).

Could you elaborate on what the error is? Perhaps share the traceback given.

@Dyllon-P
Copy link

Dyllon-P commented Jan 26, 2022

Heyo, had this thread brought to my attention and thought I would help out! The example that @giovaniceotto shared was my first stab at doing multistage rocket sims using RocketPy for the Georgia Tech Experimental Rocketry Club (GTXR). Our current multistage flight sim using RocketPy sits at the heart of a mixed-integer optimization problem I've set up to not just simulate rockets, but design them too (even for future spaceshots)!

Unfortunately, our most up to date set up for multistage flight sims is a bit unreadable, but I've attached a more up to date template file that we often refer to for multistage rockets, and you should be able to run it. It also has a nice graphing function!

While this template uses five events to simulate the flight and recovery of a two stage rocket, our most up to date sim actually has six. One additional event for capturing the coast period of the sustainer after it separates from the booster and before the sustainer motor ignites.

I've attached the multistage file, let me know if you have any questions. Multistage Template
MBS Flight Sim

@giovaniceotto
Copy link
Member

@Dyllon-P, congrats on your work at Georgia Tech Experimental Rocketry Club (GTXR)! This is quite amazing!

@Gui-FernandesBR Gui-FernandesBR added Help wanted Extra attention is needed Question Further information is requested and removed Help wanted Extra attention is needed labels Jan 31, 2022
@Gui-FernandesBR
Copy link
Member

Great work @Dyllon-P , awesome!!

Do you mind if we use your example as an inspiration for a new example notebook on rocketpy master branch? his will allow future users to understand multi-stage rockets simulations faster!

@Dyllon-P
Copy link

Dyllon-P commented Feb 1, 2022

Hi @Gui-FernandesBR. As long as you reference my name/username, and provide the Georgia Tech Experimental Rocketry Club (GTXR) some credit, feel free to use it as an example! Multistage capabilities is one of the coolest parts of RocketPy, so I would love for more people to learn about it.

@Gui-FernandesBR
Copy link
Member

The references and credits will definitely be included on the example. Also, be welcome if you want to join and help us on this development.

@giovaniceotto can you please contact Dyllon and start a good example notebook to be published on master branch?

@Dyllon-P
Copy link

Dyllon-P commented Feb 4, 2022

Feel free to reach out to me regarding this development with more specific details. I would love to help however I can! I believe I shared my email with @giovaniceotto

@Gui-FernandesBR Gui-FernandesBR removed this from the RocketPy at EuroC 2022 milestone Oct 9, 2022
@Gui-FernandesBR Gui-FernandesBR linked a pull request Jan 8, 2023 that will close this issue
5 tasks
@Gui-FernandesBR Gui-FernandesBR added this to the Release v1.1.0 milestone May 26, 2023
@Gui-FernandesBR Gui-FernandesBR added the Flight Flight Class related features label Oct 30, 2023
@Gui-FernandesBR Gui-FernandesBR changed the title Multi-stage/ Complex Recovery DOC: Multi-stage example Jan 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs Docs and examples related Flight Flight Class related features Question Further information is requested
Projects
Status: Mid-Term
Development

Successfully merging a pull request may close this issue.

5 participants