rocketpy-team / rocketpy Goto Github PK
View Code? Open in Web Editor NEWNext generation High-Power Rocketry 6-DOF Trajectory Simulation
Home Page: https://docs.rocketpy.org/
License: MIT License
Next generation High-Power Rocketry 6-DOF Trajectory Simulation
Home Page: https://docs.rocketpy.org/
License: MIT License
Describe the bug
It seems that some the SolidMotor class is failing to read some .eng
files, as reported by a user via Discord.
To Reproduce
Save the following .eng
file as AeroTechK1100T.eng
:
; Motor Data From RocketReviews.com
; https://www.rocketreviews.com/aerotech-k1100t.html
K1100T 54.0000 398.0000 0 0.7616 1.32518 AT
0.034 1234.653
0.105 1233.429
0.176 1192.393
0.247 1163.041
0.318 1147.963
0.389 1146.319
0.460 1140.958
0.532 1132.640
0.603 1123.824
0.674 1108.921
0.745 1090.974
0.816 1073.937
0.887 1049.133
0.959 1021.216
1.030 994.559
1.101 966.571
1.172 940.194
1.243 909.792
1.315 880.264
1.386 844.477
1.457 643.599
1.528 401.861
1.599 145.498
1.670 28.372
1.742 0.000
;
Run the following code:
from rocketpy import SolidMotor
AeroTechK1100T = SolidMotor(
thrustSource="AeroTechK1100T.eng",
burnOut=1.6,
grainNumber=5,
grainSeparation=5/1000,
grainDensity=1815,
grainOuterRadius=33/1000,
grainInitialInnerRadius=15/1000,
grainInitialHeight=120/1000,
nozzleRadius=33/1000,
throatRadius=11/1000,
interpolationMethod='linear'
)
Which results in a ValueError
:
ValueError Traceback (most recent call last)
<ipython-input-2-5b10d3afae20> in <module>()
12 nozzleRadius=33/1000,
13 throatRadius=11/1000,
---> 14 interpolationMethod='linear'
15 )
1 frames
/usr/local/lib/python3.7/dist-packages/rocketpy/SolidMotor.py in __init__(self, thrustSource, burnOut, grainNumber, grainDensity, grainOuterRadius, grainInitialInnerRadius, grainInitialHeight, grainSeparation, nozzleRadius, throatRadius, reshapeThrustCurve, interpolationMethod)
189 if thrustSource[-3:] == "eng":
190 # Import content
--> 191 comments, desc, points = self.importEng(thrustSource)
192 # Process description and points
193 # diameter = float(desc[1])/1000
/usr/local/lib/python3.7/dist-packages/rocketpy/SolidMotor.py in importEng(self, fileName)
650 else:
651 # Extract thrust curve data points
--> 652 time, thrust = re.findall(r"[-+]?\d*\.\d+|[-+]?\d+", line)
653 dataPoints.append([float(time), float(thrust)])
654
ValueError: not enough values to unpack (expected 2, got 0)
Expected behavior
It is expected that the SolidMotor
class can load any .eng
file which correctly follows the specification, as this one does.
Additional context
Thanks to myspaceisthenewblack for bringing to bug to our attention.
@Gui-FernandesBR hypothesized that the ;
in the last line of the file, which is preceeded by spaces, is causing the problem. RocketPy should remove trailing white space from all lines before parsing them. If it did that, then the line would be flagged as a comment. Rather, it is currently trying to parse it as a data entry since the line does not immediately start with ;
.
Describe the bug
Recently ,I found that there are bugs when using RocketPy to simulate a two-stage rocket .
OS: Windows
RocketPy Version: 0.97
Problem
The following code only shows that the initial speed of the second stage rocket in X direction and Y direction must be set to 0,
otherwise the simulation results of the second stage rocket will not be obtained due to too long simulation time
Simulation condition assumptions
We assume that the shape and motor of the first stage rocket and the second stage rocket are the same,
but the initial state of launch is different. The first stage rocket is launched from the ground at a standstill,
and the second stage rocket is fired at the highest point of the first stage rocket
Here is the complete demo code.
`
import datetime
from rocketpy import Environment
from rocketpy import Flight
from rocketpy import Rocket
from rocketpy import SolidMotor
Env = Environment(
railLength=5.2,
latitude=32.990254,
longitude=-106.974998,
elevation=1400,
date=(2020, 3, 4, 12) # Tomorrow's date in year, month, day, hour UTC format
)
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
Env.setDate((tomorrow.year, tomorrow.month, tomorrow.day, 6))
Env.setAtmosphericModel(type='StandardAtmosphere')
Pro75M1670 = SolidMotor(
thrustSource="E:\rocketpy\mydeepin\Desktop\rockstpy096\rocketpyDocument\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'
)
Calisto = Rocket(
motor=Pro75M1670,
radius=127/2000,
mass=19.197-2.956,
inertiaI=6.60,
inertiaZ=0.0351,
distanceRocketNozzle=-1.255,
distanceRocketPropellant=-0.85704,
powerOffDrag='E:\rocketpy\mydeepin\Desktop\rockstpy096\rocketpyDocument\data\calisto\powerOffDragCurve.csv',
powerOnDrag='E:\rocketpy\mydeepin\Desktop\rockstpy096\rocketpyDocument\data\calisto\powerOnDragCurve.csv'
)
Calisto.setRailButtons([0.2, -0.5])
NoseCone = Calisto.addNose(length=0.55829, kind="vonKarman", distanceToCM=0.71971)
FinSet = Calisto.addFins(4, span=0.100, rootChord=0.120, tipChord=0.040, distanceToCM=-1.04956)
Tail = Calisto.addTail(topRadius=0.0635, bottomRadius=0.0435, length=0.060, distanceToCM=-1.194656)
TestFlight1 = Flight(rocket=Calisto, environment=Env, inclination=85, heading=0,terminateOnApogee=True)
TestFlight1.info()
print("###################### run 2ndStage simulation ############################")
initSolution2Stage = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0]
initSolution2Stage[1] = TestFlight1.solution[-1][1] # Init_x of 2ndStage
initSolution2Stage[2] = TestFlight1.solution[-1][2] # Init_y of 2ndStage
initSolution2Stage[3] = TestFlight1.solution[-1][3] # Init_z of 2ndStage
initSolution2Stage[4] = TestFlight1.solution[-1][4] # Init_vx of 2ndStage
initSolution2Stage[5] = TestFlight1.solution[-1][5] # Init_vy of 2ndStage
initSolution2Stage[6] = TestFlight1.solution[-1][6] # Init_vz of 2ndStage
TestFlight2 = Flight(rocket=Calisto, environment=Env, inclination=85, heading=0,initialSolution=initSolution2Stage)
TestFlight2.info()
`
Describe the bug
When running the getting started notebook (which can be done via Colab), it fails and throws and error in the Dynamic Stability Analysis section.
The error happens because a typo was fixed in every file of the master branch, including in the notebook (#106). The typo in question was the incorrect spelling "Costum" instead of "Custom", which affects the "CustomAtmosphere" argument that can be used in the Environment.setAtmosphericModel
method. However, the current version of rocketpy released on PYPI (0.9.8) does not yet incorporate this typo fix.
To Reproduce
ValueError: Unknown model type
after running the Dynamic Stability Analysis cellExpected behavior
The entire notebook should run without errors.
Screenshots
Solution Sugestion
Release a new version!
The current Flight simulation does not take into account the fact the for a very short amount of time, a high powered rocket is guided through the launch rail with a single rail button, after the first has already cleared the rail. Under this condition, the rocket displays a planar motion, with 3 degrees of freedom.
This should be implemented as a new flight phase due to its importance to dynamic stability when the rocket is clearing the rail.
I noticed that your Cd is purely from (I assume Rasaero) Power on and Power off cd data. With Missile Datcom readers and other simulations, either Alpha or both Alpha and Beta values are plotted along with Mach in order to yield a Cd at a certain moment in time. Do you make any adjustments to your Cd in order to account for this difference (like some kind of offset)? Or does your code make the assumption of small angle of attack and symmetric about an axis to avoid using this information? It's a good assumption tbh, if that's what you're doing, but how do your results compare to something like Rasaero or Open Rocket?
In general, there are two types of files: text files and binary files.
Text files, like most code files, are easily tracked with Git 📖 and are very lightweight.
However, binary files like spreadsheets, presentations with slides, and videos don't work well with Git. If your repository already has some of these files, it's best to have a plan in place before you enable Git version control.
You could choose to remove the binary files, or use another tool like git-lfs (Git Large File Storage). We won't get into detail on how to set up git-lfs in this course, but we will talk about .gitignore
files next, which are key to protecting your code from becoming bloated with binaries.
.gitignore
As we convert your project to a Git repository, it should only include the source code necessary to build or compile your project. In addition to avoiding binaries as we discussed above, you will also want to keep build artifacts out of your version controlled code.
To do this, you will create a file in your current project named .gitignore
. Git will use the .gitignore
to determine which files and directories should not be tracked under version control. The .gitignore
file is stored in your repository in order to share the ignore rules with any other users that interact with the repository.
Since the files to be ignored are dependent on the language you are using, the open source community has contributed some great templates for .gitignore
files in the github/gitignore
repository.
.gitignore
file. You can use a template or create your own.When you are finished, close this issue. I will open a new issue with the next steps. 🎉
🤖 I'm waiting for you to close this issue before moving on.
Can you tell me how to use the program to modify the trajectory of the rocket, for example, the second half can automatically turn like an airplane
The Function.getValueOpt method is not implemented for the following interpolation methods:
Furthermore, it can be made faster by making used of Numba's just in time compiling functions.
Describe the bug
Rockets with slightly negative stability margins seem stable in RocketPy
To Reproduce
Run the following code:
# Helper class
from rocketpy import Environment, SolidMotor, Rocket, Flight, Function
# Prepare Motor
Pro75M1670 = 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'
)
# Prepare Rocket
Calisto = Rocket(
motor=Pro75M1670,
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'
)
Calisto.setRailButtons([0.2, -0.5])
Nose = Calisto.addNose(length=0.55829, kind="vonKarman", distanceToCM=0.71971)
FinSet = Calisto.addFins(4, span=0.1, rootChord=0.120, tipChord=0.040, distanceToCM=-1.04956)
Tail = Calisto.addTail(topRadius=0.0635, bottomRadius=0.0435, length=0.060, distanceToCM=-1.194656)
# Prepare Environment
Env = Environment(5.2, 9.8)
Env.setAtmosphericModel(type='CostumAtmosphere', wind_v=-10)
# Simulate Different Static Margins by Varying Fin Position
simulation_results = []
for factor in [0.1, 0.3, 0.5, 0.8, 1.0]:
# Modify rocket fin set by removing previous one and adding new one
Calisto.aerodynamicSurfaces.remove(FinSet)
FinSet = Calisto.addFins(4, span=0.1, rootChord=0.120, tipChord=0.040, distanceToCM=-1.04956*factor)
# Simulate
TestFlight = Flight(rocket=Calisto, environment=Env, inclination=90, heading=0, maxTimeStep=0.01, maxTime=2.5, terminateOnApogee=True)
# Post process flight data
TestFlight.postProcess()
# Store Results
staticMarginAtIginition = Calisto.staticMargin(0)
staticMarginAtOutOfRail = Calisto.staticMargin(TestFlight.outOfRailTime)
staticMarginAtSteadyState = Calisto.staticMargin(TestFlight.tFinal)
simulation_results += [(TestFlight.attitudeAngle, 'Static Margin of {:1.2f} c'.format(staticMarginAtOutOfRail))]
Function.comparePlots(simulation_results, lower=0, upper=2.5, xlabel='Time (s)', ylabel='Attitude Angle (deg)')
Expected behavior
Negative stability margins should be unstable.... right?
Screenshots
Here is a plot of the angle that the Rocket makes with the horizontal plane after leaving the rail. Notice how the green and orange trajectories are stable even thought their stability margin is negative,
The current implementation of the Environment class in rocketpyAlpha.py claims to support netCDF files. However, only specific ones are supported due to different naming conventions.
To be more specific, ERA 5 netCDF files from ECMWF use short names such as latitude and longitude, while GFS uses lat and lon.
Since the current implementation has the names latitude and longitude hard coded, GFS files cannot be opened.
Hey, love this project! I'm the founder of open research rocketry and i'd love to chat to you about various aspects of this and some of our burgeoning projects over in that community. Was wondering if you had/would consider adding different recovery system design options (we have some parachute design calculators and scripts over on our webpage and gitlab repo). We are using either a designed diameter or a reference surface area and a drag coefficient and I wondered if it could be built into your project? (Full disclosure... I am much more mechanical so I might be way off the mark!) If you are on riot/matrix we would love to have you drop in the chat! https://riot.im/app/#/room/#OpenResearchRocketry:matrix.org
@giovaniceotto. Thank you so much.I have run the Monte Carlo analysis successfully.And the new reference documents are so comprehensive and detailed. Besides,I made some changes to the sample code ,so that I can get simulation data of every timestep and do more in-depth analysis. All data will be saved in an excel file in the location you specify.
The specific methods are as follows:
First, make sure the name of instance of your flight calss is TestFlight. For example, TestFlight=Flight(maxTime=7000,rocket=Rocket01,environment=Env,inclination=80,heading=0)
Second ,add the following code after all your code or after TestFlight=Flight(maxTime=7000,rocket=Rocket01,environment=Env,inclination=80,heading=0)
And change the value of filepath_default to where you want to store the data.
Add the following code,and you can save the detailed simulation data in an excel file in the location you specify.
# filepath_default='/home/myLinux/Documents/RocketPyOutPut.xlsx' #This is the only code you need to change.
# wb = openpyxl.Workbook()
# ws = wb.active
# wb.save(filepath_default)
#
# def append_to_excel(header, datalist, filepath = filepath_default) -> None:
# datalist_list= datalist.tolist()
# datalist_list.insert(0, header)
# dataframe = pandas.DataFrame(datalist_list)
# writer = pandas.ExcelWriter(filepath, mode='w')
# data = pandas.read_excel(writer, index_col=None, header=None)
# data.to_excel(writer, startcol=0, index=None, header=None, sheet_name='sheet1')
# dataframe.to_excel(writer, startcol=data.shape[1], startrow=1,index=None, header=header, sheet_name='sheet1')
# writer.save()
#
# paramDict = { 'Time':TestFlight.acceleration.source[:,0],
# 'x': TestFlight.x.source[:, 1],
# 'y': TestFlight.y.source[:, 1],
# 'z or attitude': TestFlight.z.source[:, 1],
# 'staticMargin': TestFlight.staticMargin.source[:, 1],
# 'Accleration(m/s^2)':TestFlight.acceleration.source[:,1],
# 'Velocit vx':TestFlight.vx.source[:,1],
# 'Velocit vy':TestFlight.vy.source[:,1],
# 'Velocit vz':TestFlight.vz.source[:,1],
# 'Velocit Total':TestFlight.speed.source[:,1],
#
# 'Acceleration x':TestFlight.ax.source[:,1],
# 'Acceleration y':TestFlight.ay.source[:,1],
# 'Acceleration z':TestFlight.az.source[:,1],
#
# 'Euler e0':TestFlight.e0.source[:,1],
# 'Euler e1':TestFlight.e1.source[:,1],
# 'Euler e2':TestFlight.e2.source[:,1],
# 'Euler e3':TestFlight.e3.source[:,1],
#
# 'Euler Precession Angle ψ (°)':TestFlight.psi.source[:,1],
# 'Euler Nutation Angle θ (°)':TestFlight.theta.source[:,1],
# 'Euler Spin Angle φ (°)':TestFlight.phi.source[:,1],
#
# 'Flight Path Angle (°)':TestFlight.pathAngle.source[:,1],
# 'Rocket Attitude Angle (°)':TestFlight.attitudeAngle.source[:,1],
# 'Lateral Attitude Angle (°)':TestFlight.lateralAttitudeAngle.source[:,1],
#
# 'Angular Velocity -w1(rad/s)':TestFlight.w1.source[:,1],
# 'Angular Velocity -w2(rad/s)':TestFlight.w2.source[:,1],
# 'Angular Velocity -w3(rad/s)':TestFlight.w3.source[:,1],
# 'Angular Acceleration -alpha1(rad/s²)':TestFlight.alpha1.source[:,1],
# 'Angular Acceleration -alpha2(rad/s²)':TestFlight.alpha2.source[:,1],
# 'Angular Acceleration -alpha3(rad/s²)':TestFlight.alpha3.source[:,1],
#
# 'Rail Buttons Normal Force Upper Rail Button(N)':TestFlight.railButton1NormalForce.source[:,1],
# 'Rail Buttons Normal Force Lower Rail Button(N)':TestFlight.railButton2NormalForce.source[:,1],
# 'Rail Buttons Shear Force Upper Rail Button(N)':TestFlight.railButton1ShearForce.source[:,1],
# 'Rail Buttons Shear Force Lower Rail Button(N)':TestFlight.railButton2ShearForce.source[:,1],
# 'Aerodynamic Lift Resultant Force Resultant':TestFlight.aerodynamicLift.source[:,1],
# 'Aerodynamic Lift Resultant Force R1':TestFlight.R1.source[:,1],
# 'Aerodynamic Lift Resultant Force R2':TestFlight.R2.source[:,1],
# 'R3':TestFlight.R3.source[:,1],
#
# 'Aerodynamic Drag Force (N) ':TestFlight.aerodynamicDrag.source[:,1],
# 'Aerodynamic Bending Resultant Moment Resultant ':TestFlight.aerodynamicBendingMoment.source[:,1],
# 'Aerodynamic Bending Resultant Moment M1':TestFlight.M1.source[:,1],
# 'M2':TestFlight.M2.source[:,1],
# 'M3':TestFlight.M3.source[:,1],
# 'Aerodynamic Spin Moment (N m)':TestFlight.aerodynamicSpinMoment.source[:,1],
#
# 'Kinetic Energy Kinetic Energy Components(J)':TestFlight.kineticEnergy.source[:,1],
# 'rotationalEnergy':TestFlight.rotationalEnergy.source[:,1],
# 'Translational Energy':TestFlight.translationalEnergy.source[:,1],
# 'total Energy':TestFlight.totalEnergy.source[:,1],
# 'potential Energy':TestFlight.potentialEnergy.source[:,1],
# 'Thrust Absolute Power':TestFlight.thrustPower.source[:,1],
# 'Drag Absolute Power(value <0)':-TestFlight.dragPower.source[:,1],
#
# 'Mach Number':TestFlight.MachNumber.source[:,1],
# 'Reynolds Number':TestFlight.ReynoldsNumber.source[:,1],
# 'dynamic Pressure':TestFlight.dynamicPressure.source[:,1],
# 'total Pressure':TestFlight.totalPressure.source[:,1],
# 'Static Pressure':TestFlight.pressure.source[:,1],
# 'Angle of Attack':TestFlight.angleOfAttack.source[:,1],
# 'Pressure at Rocket\'s Altitude Altitude(m)':TestFlight.z.source[:,1],
# 'Pressure at Rocket\'s Altitude Pressure(Pa':TestFlight.pressure.source[:,1],
#
# 'static Margin':TestFlight.staticMargin.source[:,1]}
#
# for key in paramDict.keys():
# print(key)
# append_to_excel(key, paramDict[key])
# # print('The data has been successfully written into an excel file.')
Having a project already stored locally enables you to move it to GitHub rather quickly. The following activity provides instructions to move your local project to GitHub using various tools. Select the tool you are most comfortable with and get importing 😄.
git init
to initialize the directory as a Git repository.git remote add origin https://github.com/giovaniceotto/github-upload.git
git add .
git commit -m "initializing repository"
git push -u origin master
to push the files you have locally to the remote on GitHub. (You may be asked to log in.)File > Add a Local Repository
, and then navigating to your local repository.Repository > Repository Settings...
and pasting the URL from your repository on GitHub into the "Primary remote repository (origin)" field. Click Save.git remote add origin
git remote add origin
🤖 Once you push your project to GitHub, I'll provide the next steps in your journey.
Right now, your repository is set to public.
You can change the visibility of a repository to Private or Public at any time in your repository's Settings tab, but there are some things you should know.
If your repository is private, the only people who can see your code are you and the collaborators 📖 you've invited.
There is a small charge associated with Private repositories, but if your project has sensitive information, it's worth it.
In public repositories, anybody can see your code. Millions of open source repositories on GitHub are public, too!
Licenses, code of conduct, and other files are important when you create a public repository. There are many benefits to this, but it's also a large responsibility. Keep in mind that once a repository is public and open source, there are certain implications about keeping it public, depending on the license chosen.
It's important to note that public does not equal open source! The license associated with code determines whether or not it is open source.
🤖 I'm waiting for you to close this issue.
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.
The current implementation of the Environment class performs interpolation of rectangular grids given by weather data files by using the nearest neighbor method instead of using bi-linear interpolation.
Considering the latitude and longitude grids used by weather files are generally rectangular, bi-linear interpolation is a simple method to be used reliably.
Perhaps even more sophisticated methods could be used, such as bi-cubic splines or bi-cubic akimas.
Describe the bug
__init__
constructors not appearing in the documentation.
To Reproduce
Steps to reproduce the behavior:
__init__
constructor is not documented.Expected behavior
The docstring contained in the __init__
constructor should appear in the documentation somehow, either inside the class documentation or the __init__
method itself.
Thanks to @Lucas-KB for noticing this bug.
NOAA is starting to push a couple of updates to its Open-source Project for a Network Data Access Protocol (OPeNDAP)
server, which will affect how RocketPy downloads weather forecasts from NOAA, including GFS and GEFS.
The main change is the port used. The standard SSL 443 port will be replace the 9090 port currently in use. Therefore, everywhere in the Environment class code where the string https://nomads.ncep.noaa.gov:9090 appears, it will need to be replaced.
More detail is available at: https://www.weather.gov/media/notification/scn20-13nomads_website.pdf
Furthermore, since FV3 has been merged into GFS, its servers have stopped updating. So no new forecasts are available. This means the FV3 name should be removed from RocketPy.Environment.
The current method used to determine the index corresponding to latitude and longitude is not efficient. It goes through all possible indices and checks if the latitude and longitude desired is in between the values of latitude and longitude corresponding to such index and its previous value. To emphasize, it does not stop after it has already found a value.
Increasing the efficiency of this search could improve the speed of the execution of the code.
When the Environment class performs atmospheric field interpolation, it requests data from netCDF and OPeNDAP files a pressure level at a time, both in the processNetCDFFile and reprocessNetCDFFile methods. This is extremely inefficient, especially for OPeNDAP files which can take longer than 10 seconds to load with this implementation.
To fix this, I propose the use of netCDF subset capabilities to retrieve all pressure levels at once. Vector operations could then be used to further improve interpolation speed.
Is your feature request related to a problem? Please describe.
RocketPy's documentation looks a little outdated using the default ReadTheDocs theme.
Describe the solution you'd like
Let's update the theme to a modern one!
Describe alternatives you've considered
Perhaps there are better ones, but PyData Sphinx Theme looks nice! Numpy, Pandas and many others are using it.
There is currently no method two compare two or more Function plots. It is an useful feature every now and then.
We need to improve the Function.differentiate method. As we know, its implementation is not ready for production and should be enhanced
See #122 as an example of where it is mentioned
Congratulations @giovaniceotto, you've completed this course! 🎉
Before I say good-bye, I want to recap all the tasks you've accomplished. You:
Now that you've moved your Git repository to GitHub, managing your repository is the next step you'll probably want to take. Join the Community Starter Kit course to learn how to invite collaborators, setup integrations, add documentation, and define several important settings and features.
There's so much more you can do with GitHub, and you have a solid start. Now...what will you learn next?
@Gui-FernandesBR mentioned some candidates to be included in the utilities.py module being introduced in #108:
Environment.py:
decimalDegressToArcSeconds(self, angle)
Flight.py:
calculateFinFlutterAnalysis(self, finThickness, shearModulus)
exportPressures(self, fileName, timeStep)
These could help give more "body" to this new module.
Also, @Gui-FernandesBR recommends creating a simple example usage for these functions. At least for me, it is not easy to visualize how I could use the new capabilities.
Some methods in rocketpyAlpha return None, while others return self. This behavior should be consistent so that its predictable.
I see no problems in all methods which edit an object either returning the object itself or valuable information relating to the edit.
Use case
Try to add fins to a rocket object using the airfoil option:
FinSet = TestRocket.addFins(
n=3,
rootChord=0.077,
tipChord=47/1000,
span=0.104,
distanceToCM=-0.99586,
airfoil='NACA0012_Cl.csv'
)
Contents of 'NACA0012_Cl.csv' are:
0, 6.86E-09
0.200712864, 1.05E+00
1.560796326, 0.0
Expected result
Fins are added properly with no errors or warnings.
What happens instead
RuntimeWarning: divide by zero encountered in double_scalars FD = 2 * np.pi * AR / (cn *np.cos(gamac))
RuntimeWarning: invalid value encountered in double_scalars Cnalfa1 = cn * FD * (Af/self.area) * np.cos(gamac) / (2 + FD * ( 1 + (4/FD**2) )**0.5)
Furthermore, the resulting cldata
created has a nan (not a number) everywhere a zero is expected.
[[0.00000000e+00 5.18408620e-09]
[2.00712864e-01 7.19089724e-01]
[1.56079633e+00 nan]]
I believe the error from originates from calling cnalfa1
with cn=0.0
in line 610 of the Rocket.py file.
Applies to versions:
Master branch only, no releases yet.
Currently, the RocketPy code assumes all rocket launches are made from sea level. At least, this is a necessary assumption to agree with the weather models that can be supplied in terms of altitude matching.
However, weather models generally state their considered elevation for a certain latitude and longitude. Furthermore, this has a great impact on the flight trajectory considering that true wind values are misaligned in terms of altitude.
Therefore, I would suggest differentiating between altitude above sea leve (ASL) and altitude above ground level (AGL) to fix this issue.
Possibly, a topographic dataset may be needed to get elevation data on non gridded latitudes and longitudes.
Uploading your project to GitHub gives you the feature-rich tools and collaboration needed to elevate your project to the next level. Not to mention, it's also pretty exciting. If you're doing this for the first time, you have a few options when uploading your project to GitHub. This course will guide you through the necessary steps to upload a local project to be hosted on GitHub.
I know some people like to get straight to the point while others like more information. For those who like more information, be sure to check out the drop-downs like this one ⬇️
You may be wondering what this GitHub thing is all about and why you should use it. If this sounds like you, here are a few reasons to make GitHub your project's new home:
Most users find it is easiest to upload a project that is already located on their local machine, so the goal of this first step is to make a local copy of the repository. First, let's make sure this course is going to give you the right steps:
If you are moving your project from another version control system, the steps are a bit different that uploading your project from your local machine. Because of this, we have a dedicated course for migrating your project to GitHub.
If you are moving your project from Mercurial, Subversion, or another Git platform, join the Migrating your project to GitHub course to migrate your project to GitHub.
If you aren't sure whether or not your code is under version control, it probably isn't. However, here are a few tests you can apply to know for certain:
If none of these are true, your project isn't using version control.
Choose the drop-down below that best fits your current situation or for a printable version of the steps in this course, check out the Quick Reference Guide.
✨ Terrific! @giovaniceotto since you already have the project locally, you are almost ready to move it to GitHub.
To confirm: You have a project directory on your computer and you want to save it on GitHub.
If this is correct, close this issue to signal you are finished with this step. I will open a new issue to show you how to optimize your repository for Git operations.
If this is incorrect, please use the next drop-down to learn how to export your project to your local machine or join the Migrating your project to GitHub course to migrate your project to GitHub.
There are many platforms that allow users to create and store projects. We can't cover them all, but we will do our best to cover the more common examples. First, let's cover general instructions:
Now let's talk about specific platforms:
From the main page of your CodePen project:
From your Glitch project page:
app
folder as desiredClose this issue to signal you are finished with this step. I will open a new issue to show you how to optimize your repository for Git operations. 🎉
🤖 I'm waiting for you to close the issue before moving on.
Sometimes I respond too fast for the page to update! If you perform an expected action and don't see a response from me, wait a few seconds and refresh the page for your next steps.
The code in nbks/rocketpyAlpha.py is not fully documented. Methods in classes Motor, Rocket and Flight are missing docstring documentation.
Beautiful program. But I have some difficulties when running the code example in Monte Carlo Dispersion Analysis section of the reference docs. I can't understand the meaning of some parameters in the code so that I can't simulate my rocket flight correctly.
Could you tell me the meaning of "m_prop", "m_aero", "m_rec", "lag_rec" , "m_se", "lag_se" in rockst‘s parameters that will be analyzed by Monte Carlo method ? And how do I determine the second arguments of the Gaussian distribution of the variable? Take this parameter , "m_prop": (1.664, 0.05) , for example, how do I get an appropriate number, such as 0.05?
Besides, from the code, I konw that mass , a parameter of Rocket class , is the total mass of the rocket without propellant, but why ‘’m_aero‘’ was added twice to get rocket’s mass?
Beautiful program. But I have some difficulties when running the code example in Monte Carlo Dispersion Analysis section of the reference docs. I can't understand the meaning of some parameters in the code so that I can't simulate my rocket flight correctly.
Could you tell me the meaning of "m_prop", "m_aero", "m_rec", "lag_rec" , "m_se", "lag_se" in rockst‘s parameters that will be analyzed by Monte Carlo method ? And how do I determine the second arguments of the Gaussian distribution of the variable? Take this parameter , "m_prop": (1.664, 0.05) , for example, how do I get an appropriate number, such as 0.05?
Besides, from the code, I konw that mass , a parameter of Rocket class , is the total mass of the rocket without propellant, but why ‘’m_aero‘’ was added twice to get rocket’s mass?
When defining an instance of the Environment class, latitude, longitude and time must be specified when a weather data file such netCDF or OPeNDAP is used.
When the latitude, longitude or time coordinate specified are actually outside the range given by the weather file, no warning is given and simple nearest neighbor interpolation is performed, which could be misleading. Such an event can occur when the user uses wrong weather files or specifies wrong space-time coordinates.
Therefore, I would suggest a warning is given to the user in such cases.
Documentation for all of the classes is currently broken. See, for example, the Flight Class docs .
ReadTheDocs generates the following logs which may be useful:
No module named 'rocketpyalpha'
WARNING: autodoc: failed to import module 'Flight' from module 'rocketpy'; the following exception was raised:
No module named 'numpy'
WARNING: autodoc: failed to import module 'Function' from module 'rocketpyalpha'; the following exception was raised:
No module named 'rocketpyalpha'
WARNING: autodoc: failed to import module 'Rocket' from module 'rocketpyalpha'; the following exception was raised:
No module named 'rocketpyalpha'
WARNING: autodoc: failed to import module 'SolidMotor' from module 'rocketpyalpha'; the following exception was raised:
No module named 'rocketpyalpha'```
Currently the parameter initialSolution can be passed on Flight class in order to save ouur lives when dealing with cases where we don't wnat to start a simulation from the origin (0,0,0) or using a pre-defined initial attitude for the rocket.
However, currently there's no way to use initialSolution to set the simulation to start when the rocket is still flying over the rail.
How could we solve that?
See file Flight.py :
The current implementation of the Environment class raises an error whenever weather files which make use of negative values for longitude are imported. This error happens in the processNetCDFFile method.
Both longitude ranges, from 0 to 360 and from -180 to 180 should be supported.
One alternative is to try using the 0-360 range and except the -180 to 180 range if an error is raised. This order is motivated by the fact that global models generally use 0-360 ranges, where regional models from the left hemisphere generally use -180 to 180.
There is an error when naturally extrapolating linear interpolated Function objects.
Here is the code to reproduce the error:
xData = np.linspace(0, 2, 40)
yData = sum([((-1)**(i))*(xData**(2*i+1))/(2*i+1) for i in range(3)])
F = Function(np.array([xData, yData]).T, interpolation='linear', extrapolation='natural')
Function(F.getValue).plot(-1,3, forceData=True)
Function(F.getValueOpt).plot(-1,3, forceData=True)
Function(F.getValueOpt2).plot(-1,3, forceData=True)
The getValueOpt method throws an error, while the getValue method gives a wrong results. The getValueOpt2 is the only one wit a correct implementation.
RocketPy supports parachute trigger functions, which can be quite nice to test ejection activation algorithms. However, when running simple simulations with parachutes, having to code a trigger function can be an unnecessary overhead.
I would like the trigger
argument of the Flight.addParachute
method to support, besides a callable, two other types of input:
'apogee'
, in which case, the parachute would be ejected at apogee (intuitive I believe)1400
, in which case the parachute would be ejected at an altitude (above sea level, ASL) corresponding to the numeric value in meters.Here is a code snippet showcasing both:
Main = Calisto.addParachute(
"Main",
CdS=10.0,
trigger=800,
samplingRate=105,
lag=1.5,
noise=(0, 8.3, 0.5),
)
Drogue = Calisto.addParachute(
"Drogue",
CdS=1.0,
trigger='apogee',
samplingRate=105,
lag=1.5,
noise=(0, 8.3, 0.5),
)
Internally, the Rocket.addParachute
method may convert both types of new inputs into trigger functions (callables) which will continue to work with the Flight Class without the need of modifying it.
Such a feature would facilitate the creation of parachutes, making RocketPy easier to use. This is particularly important for inexperienced users. Furthermore, the advanced feature of using a trigger function would keep working exactly as it does today.
It is also important to note that this idea originated when using RocketPy in MATLAB. Currently, a function needs to be defined in Python inside MATLAB to create the triggers, which is awfully bad for user experience, since it can only be done with lambdas. Therefore, such a feature would also greatly enhance the experience for MATLAB users.
Currently we have calculation of Lif Coefficient in function of Mach Number for our fins, but in the future will be important having the same approach for the nosecone and tail
The current folder structure is disorganized and the main code is not available as a Python package.
This enhancement proposes separating the current code in separate files for each class, as well as a packaging it as a Python module that can be uploaded to PyPI.
Furthermore, other files such as tutorial notebooks should be inserted as documentation located in an examples folder.
Finally, remaining files should be deleted.
Use case
Try to add fins to a rocket object using a list as the airfoil argument:
cl_data = [
[0.00, 0.0],
[0.20, 1.05],
[1.00, 1.05],
[1.57, 0.0],
]
FinSet = TestRocket.addFins(
n=3,
rootChord=0.077,
tipChord=47/1000,
span=0.104,
distanceToCM=-0.99586,
airfoil=cl_data
)
Expected result
Fins are added properly with no errors or warnings.
Airfoil argument should support entries in list format, just like other similar RocketPy entries (powerOnDrag, powerOffDrag, thrust, etc.):
What happens instead
Exception has occurred: AttributeError 'list' object has no attribute 'split'
File "rocketpy\Rocket.py", line 607, in addFins
read = genfromtxt(airfoil, delimiter = ',')
File "test.py", line 41, in <module>
FinSet = TestRocket.addFins(
Applies to versions:
Master branch only, no releases yet.
From what I've known for so long using RocketPy (you can correct me if necessary), the rail departure time is assumed to be the time when the Rocket CM crosses the top of the Launch Rail. However, the main international rocket competition (SACup) defines rail departure time as "the first instant in which the launch vehicle becomes free to move about the pitch, yaw, or roll axis."[DTEG - SACUP]
I believe that we must make some changes to the Flight class so that the railDepartureTime variable be considered as the time that the upper button crosses the top of the rail.
Not so long ago, we had #140 solving bugs regarding airfoil implementation.
It's true that now rocketpy is dealing very well with these non-flat fins, however I feel we could implement some plots in rocket.py file to show to the user.
Some of them could be:
But of course feel free to add any other information you consider important!
Current TODO.md list is outdated, we might transfer main topics to github project in order to facilitate our management and then we discuss if we keep TODO.md on our repository or not
Hey, I noticed that the Environment Classe uses, by default, the first Ensemble member available in the Ensemble files.
But I think that could be interesting if we would use mean values based on the ensemble members. For example:
Env.selectEnsembleMember(Env.ensembleMean)
This way we could calculate mean and standard deviation from Ensemble members, and I believe the standard deviation of wind speed is actually named wind turbulence (an important input parameter for other rocket simulators).
What do you think about that? Is there a reason for using only one specific ensemble member?
There is no current way to determine the forces and moments on the pair of rail buttons which guide High Powered Rockets in the launch rail.
This could probably be implemented in the post processing phase of the flight simulation, in the Flight.postProcess
method.
Currently, the Rocket class has no support for rail button characteristic input.
With the Rail Buttons Simulation Milestone in mind, a method such as Rocket.addRailButtons
should be implemented allowing the user to define the axial and tangential position of two rail buttons used in the rocket.
The arithmetic operations defined in the Function class of rocketpyAlpha are not very well optimized for Function objects defined in the same grid points.
Functions defined in terms of data points that have the same domain should have a different implementation of the arithmetic operations. Since they are defined in the same grid points, it should be possible add and multiply them and return a new interpolated Function instead of a Function based on lambda functions, which results in much slower evaluations.
netCDF4 is not automatically installed.
If user blindly follows the getting started tutorial, they will stumble upon an error when running
Env = Environment(
railLength=5.2,
latitude=32.990254,
longitude=-106.974998,
elevation=1400,
date=(2020, 3, 4, 12) # Tomorrow's date in year, month, day, hour UTC format
)
Env.setAtmosphericModel(type='Forecast', file='GFS')
which results in the following error:
[NameError: name 'netCDF4' is not defined]()
There should be a reminder in the tutorial telling the user to install the optional package
The Flight class in rocketpyAlpha.py currently employs Scipy's LSODA wrapper to solve to dynamic equations of flight. However, it creates a new solver instance for every micro time step, which is highly inefficient.
The LSODA algorithm uses a variable time step Adams Bashforth implementation for non-stiff problems. Since Adams Bashforth is a multistep method, every time a new solver instance is created, the previous steps are lost and new data needs to be created using other algorithms to start the Adams Bashforth. Therefore, a lot of time is spent using other solvers instead of the Adams Bashforth itself. For very small time steps, it may be the case that none of the advantages of a multi step method are being exploited.
This inefficient implementation should be fixed either by using Scipy's LSODA class and its step method or by moving to a new ODE solver.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.