<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.openrocket.info/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justgerrardz</id>
	<title>OpenRocket wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.openrocket.info/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justgerrardz"/>
	<link rel="alternate" type="text/html" href="http://wiki.openrocket.info/Special:Contributions/Justgerrardz"/>
	<updated>2026-04-13T03:45:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>http://wiki.openrocket.info/index.php?title=Scripting_with_Python_and_JPype&amp;diff=33984</id>
		<title>Scripting with Python and JPype</title>
		<link rel="alternate" type="text/html" href="http://wiki.openrocket.info/index.php?title=Scripting_with_Python_and_JPype&amp;diff=33984"/>
		<updated>2016-03-17T07:35:58Z</updated>

		<summary type="html">&lt;p&gt;Justgerrardz: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scripting openrocket with Python and JPype ==&lt;br /&gt;
&lt;br /&gt;
The ability to script openrocket and enhance it with user written code is an often discussed topic among the openrocket community.&lt;br /&gt;
This article demonstrates one approach to the problem. Using python [http://python.org] and the jPype [http://jpype.sourceforge.net/] library it is possible to write external scripts which run outside of openrocket, but make use of openrocket much like any other python library.&lt;br /&gt;
&lt;br /&gt;
This approach provides a very rapid development environment for optimising rocket designs, enhancing and exploring the simulation. It is also probably the best approach if you are interested in making use of openrocket as part of something larger. An important advantage to this approach over something like embedded Jython scripting is that you have full access to all the python ecosystem, crucially numpy [http://numpy.scipy.org/], scipy [http://scipy.org], matplotlib [http://matplotlib.sourceforge.net] and other cpython only libraries. However, because scripts require external software they can not be integrated into a stand-alone openrocket distribution. Nevertheless, they do provide a nice way to prototype new openrocket features.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
To run the following examples you will need python 2.5 or later python 2.x version, jpype, and an Openrocket .jar &amp;gt; 1.19. The numpy, scipy, matplotlib libraries are required (these usually come together). These scripts all make use of a python module &#039;&#039;orhelper.py&#039;&#039; (below).&lt;br /&gt;
&lt;br /&gt;
Note: Until we find a better way to host the files, they can be downloaded from the [https://sourceforge.net/mailarchive/forum.php?thread_name=4F17AA0C.1040002%40rdg.cc&amp;amp;forum_name=openrocket-devel mailing list archive].&lt;br /&gt;
[http://www.rushtonfinancial.com.au Best Investment] | [http://www.rushtonfinancial.com.au/why-invest Managed Funds] | [http://www.rushtonfinancial.com.au/about-us Mutual Funds Australia]&lt;br /&gt;
&lt;br /&gt;
=== Orhelper : &#039;&#039;[[File:orhelper.py]]&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This is a fairly lightweight module which has been written for these examples to take care of some of the more cumbersome aspects of scripting openrocket with jpype.&lt;br /&gt;
At the time of writing the orhelper module contains:&lt;br /&gt;
# a class &#039;&#039;OpenRocketInstance&#039;&#039; which handles starting up a JVM and a working [http://www.papdan.com/ Melbourne Web Developer], [http://www.papdan.com/seo-services-search-engine-optimisation.php Melbourne SEO Services] openrocket instance. It is equip with &#039;&#039;__enter__&#039;&#039; and &#039;&#039;__exit__&#039;&#039; methods and is intended to be called using the &#039;with&#039; construct [http://effbot.org/zone/python-with-statement.htm] of python 2.5. This is to ensure that no matter what happens within that context, the JVM will always properly shutdown and you will get useful (hopefully) exception information.&lt;br /&gt;
# a class &#039;&#039;Helper&#039;&#039; which simply contains a bunch of useful helper functions and wrappers for using openrocket via jpype. These are intended to take care of some of the more cumbersome aspects of calling methods, or provide more &#039;pythonic&#039; data structures for general use. The whole &#039;&#039;net.sf.openrocket&#039;&#039; namespace is available as the &#039;&#039;orp&#039;&#039; property of this class.&lt;br /&gt;
# an &#039;&#039;AbstractSimulationListener&#039;&#039; class. This is essentially a python version of the &#039;&#039;openrocket.simulation.listerners&#039;&#039; class of the same name. You can extend this class to make your own python simulation listeners and receive callbacks from the openrocket simulation.&lt;br /&gt;
# there is also a little wrapper class in there, &#039;&#039;JIterator&#039;&#039; which is for using java iterators as if they are python iterators.&lt;br /&gt;
&lt;br /&gt;
=== Example 1 : &#039;&#039;[[File:simple_plot.py]]&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This is a simple example for plotting the flight of a rocket using matplotlib. A plot of altitude and vertical velocity vs time is generated, with annotations for various events much like the default plot in openrocket.&lt;br /&gt;
&lt;br /&gt;
In this example all the interaction with openrocket is done through various Orhelper methods. The orhelper.Helper class will from now on be referred to as orh.&lt;br /&gt;
&lt;br /&gt;
First, we startup an openrocket instance inside the protected &#039;with&#039; environment. Be sure to change the name of the openrocket .jar file accordingly.&lt;br /&gt;
We then load up an openrocket document, I am using the &#039;simple model rocket example&#039; here. We then grab a simulation object out of this file. This file has multiple simulations set up, we just get the first one. We then run the simulation. We now need to get the data out of the simulation. This is done with the &#039;&#039;orh.get_timeseries&#039;&#039; method. This returns dictionary of timeseries data (as numpy arrays) from a simulation given a sequence of variable names. Variable names are as according to the default locale, check inside the openrocket plot window for the exact names. For adding annotations to the plot, we need to get a dictionary containing all the flight events. This is done with &#039;&#039;orh.get_events&#039;&#039; (keys are the names of the events and values are the times).&lt;br /&gt;
&lt;br /&gt;
The rest of the code is standard matplotlib stuff -- check their documentation if you are not familiar [http://www.phillro.com.au/p/industrial-2/airless-spray-packages-2/ Airless Spray]. A couple of the inline functions though are worthy of further explanation. I wanted to have the axis labels and tick marks the same colour as the lines. Matplotlib doesn&#039;t have a built in way to change all the tickmarks, but that is easily done with the in line function &#039;&#039;change_color&#039;&#039;. Also, because get_events only gives us time information we need to extract the corresponding array index to put the annotations in the correct place. This done with the &#039;&#039;index_at&#039;&#039; function which in turn makes use of the numpy &#039;&#039;argmin&#039;&#039; [http://www.oxone-online.com Oxone] function.&lt;br /&gt;
&lt;br /&gt;
[[File:simple_plot.png]]&lt;br /&gt;
&lt;br /&gt;
=== Example 2 : &#039;&#039;[[File:lazy.py]]&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The purpose of this example is to show how a simulation can be modified and demonstrate the use of scipy&#039;s numerical methods. The toy problem we are attacking is the one of the rocketeer of maximum laziness who does not want to walk from the launch site to collect the rocket and would prefer if it flew exactly back of its own accord. We assume the rocket is flying upwind and optimise the launch rod angle accordingly. We want to plot a family of curves for a few different angles and highlight the optimised angle.&lt;br /&gt;
&lt;br /&gt;
The structure of the program and initial lines for loading the model rocket are the same as in the previous example. In this example, we need to define a function for varying the launch angle before simulating the flight. This requires us to get the simulation options out of the simulation using the &#039;&#039;getOptions()&#039;&#039; method and we can then set the angle inside the &#039;&#039;SimulationOptions&#039;&#039; object. For the uninitiated, in openrocket &#039;&#039;simulation.SimulationOptions&#039;&#039; basically contains all the settings found in the simulation edit window. When the simulation is started these options are used to make a &#039;&#039;simulation.SimulationConditions&#039;&#039; object. After running the simulation we are interested in the &#039;Altitude&#039; and &#039;Position upwind&#039; variables. One option would be to just retrieve the final values with &#039;&#039;orh.get_final_values&#039;&#039;, however for reasons that will shortly become clear we have retrieved the whole time series.&lt;br /&gt;
&lt;br /&gt;
For running an optimisation method, we need some function which is zero at the optimum point. This is not quite as simple as just getting the final upwind distance because the simulation stepper will usually slightly overshoot and calculate a final point with a negative altitude. We also want to exclude the launch. There are more elaborate ways this could be done --- here for simplicity we just slice out the last half of the data, find the index with the smallest absolute altitude and return the corresponding upwind distance. We can then go ahead and pass this to our optimisation method, giving some initial guess (40 deg) to start with. Scipy has a wide range of optimisation methods with a rich heritage, in our case we just choose the basic &#039;&#039;fmin&#039;&#039; which uses the downhill simplex algorithm.&lt;br /&gt;
&lt;br /&gt;
In this example we want to plot a family of curves as well so we generate a range of 10 launch angles with &#039;&#039;np.linspace&#039;&#039; and add our optimal angle. We then run the simulations, making a list of all the timeseries data dictionaries and adding an &#039;Angle&#039; key to each dictionary. We then go ahead and plot this, using a solid line style for the optimal curve and dashed lines for the others.&lt;br /&gt;
&lt;br /&gt;
[[File:lazy.png]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 : &#039;&#039;[[File:monte_carlo.py]]&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
As every student of introductory physics knows, presenting just a number as the result of a calculation is not really sufficient -- we also need to know the uncertainty to make it meaningful. The purpose of this example is to demonstrate a simple monte carlo method [http://en.wikipedia.org/wiki/Monte_Carlo_method] where multiple simulations are run with various parameters perturbed to determine an overall uncertainty for the landing location in terms of range and bearing from the launch site. This example also demonstrates the use of simulation listeners implemented in python. Openrocket simulation listeners are covered in [[Simulation_Listeners|section 9 of the users guide]].&lt;br /&gt;
&lt;br /&gt;
The structure of this script is slightly different from the previous examples. First consider how we get the landing range and bearing information. This information is not available directly as a simulation variable, although latitude and longnitude are. One option would be to get these variables and do the calculation in python. However, openrocket already includes methods to do this as part of &#039;&#039;util.GeodeticComputationStratery&#039;&#039; which is a parameter of each simulation, so it is nice to make use of these which operate natively on &#039;&#039;util.WorldCoordinate&#039;&#039; objects. We do this by defining a new simulation listener &#039;&#039;LandingPoint&#039;&#039; which extends &#039;&#039;orhelper.AbstractSimulationListener&#039;&#039;. We define an &#039;&#039;endSimulation&#039;&#039; method which grabs the simulation &#039;&#039;GeodeticComputationStratergy&#039;&#039; and uses it to find the range and bearing from the lanuch site &#039;&#039;WorldCoordinate&#039;&#039; (from &#039;&#039;SimulationConditions&#039;&#039;) to the rocket position (from &#039;&#039;SimulationStatus&#039;&#039;). These are saved as &#039;&#039;LandingPoint&#039;&#039; instance variables.&lt;br /&gt;
&lt;br /&gt;
Multiple &#039;&#039;LandingPoint&#039;&#039; objects are stored in a &#039;&#039;LandingPointList&#039;&#039;, which is like a regular list except can populate itself with landing points by running multiple openrocket simulations. Various parameters are set by choosing from a gaussian distribution with given mean and standard deviation (pythons &#039;&#039;random.gauss&#039;&#039; method). The code for running the simulations has mostly been discussed earlier, and the same example rocket is used although in my case I turned up the wind and turbulance somewhat and switched to a spherical earth computation method. One aspect that is new is the modification of the rocket model. A &#039;&#039;rocketcomponent.Rocket&#039;&#039; object can be obtained from the simulation options. This is the root of a tree type data structure containing all the rocket components. Our &#039;&#039;orh.Helper&#039;&#039; class has a method for finding components in the tree given their names. We use this to obtain the nose cone and body tube components and override their masses with perturbed values. Running the simulation is again done using &#039;&#039;orh.runsimulation&#039;&#039;, except in this case we pass in a sequence of listener objects to use. To increase the variability still we pass in a &#039;&#039;AirStart&#039;&#039; listener with randomly set start altitude. This listener is a python copy of the example supplied with openrocket.&lt;br /&gt;
&lt;br /&gt;
Finally, when run the main function of the script makes a new &#039;&#039;LandingPointList&#039;&#039;, populates it and then uses the &#039;&#039;print_stats&#039;&#039; method to show the final landing statistics, something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Rocket landing zone 3833.57 m +- 1116.91 m bearing -89.98 deg +- 0.0713 deg from launch site. Based on 20 simulations.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that it might take a minute or two to run all those simulations.&lt;/div&gt;</summary>
		<author><name>Justgerrardz</name></author>
	</entry>
	<entry>
		<id>http://wiki.openrocket.info/index.php?title=Developer%27s_Guide&amp;diff=33983</id>
		<title>Developer&#039;s Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.openrocket.info/index.php?title=Developer%27s_Guide&amp;diff=33983"/>
		<updated>2016-03-17T07:20:42Z</updated>

		<summary type="html">&lt;p&gt;Justgerrardz: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Access}}&lt;br /&gt;
&lt;br /&gt;
This page contains information on the inner workings of OpenRocket and is meant primarily for developers interested in developing OpenRocket.&lt;br /&gt;
&lt;br /&gt;
In addition to this page, information can be found in the [http://openrocket.sourceforge.net/documentation.html Technical documentation] chapter 5.&lt;br /&gt;
&lt;br /&gt;
== Obtaining the source code ==&lt;br /&gt;
&lt;br /&gt;
OpenRocket is primarily developed using [http://www.eclipse.org/ Eclipse], and it&#039;s the recommended IDE for compatibility.  Developers are free to use other IDE&#039;s, but everything may not work out-of-the-box.&lt;br /&gt;
&lt;br /&gt;
The source code is hosted on [https://github.com/openrocket/openrocket/ GitHub].  You need either to install the [http://www.eclipse.org/egit/ EGit] plugin to Eclipse, or use some other Git client (for example the command-line client).&lt;br /&gt;
&lt;br /&gt;
Using the command-line, the OpenRocket code can be retrieved by:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git clone git://github.com/openrocket/openrocket.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The source packages available on the OpenRocket web site (*.zip) are meant for building the application from source code, &#039;&#039;&#039;NOT&#039;&#039;&#039; for development purposes.  They do not contain all the project files etc [http://www.tokobungasabana.com Toko bunga],[http://www.tokobungasabana.com Toko bunga jakarta], [http://trimasjaya.com/products/railing_tangga/index.html Railing Tangga], [http://www.detikauto.com Aksesoris Mobil], [http://www.forklift.co.id Rental Forklift]&lt;br /&gt;
&lt;br /&gt;
== Source == &lt;br /&gt;
* [http://www.pokerworld88.com/ Poker Online]&lt;br /&gt;
* [http://www.musimdomino.com/ Domino Online]&lt;br /&gt;
* [http://www.texaspoker83.com/ Texas Poker]&lt;br /&gt;
* [http://www.specialispoker.com/ Poker Online]&lt;br /&gt;
* [http://www.mejapoker88.com/ Poker Indonesia]&lt;br /&gt;
* [http://www.dinastipoker.com Agen Domino99]&lt;br /&gt;
&lt;br /&gt;
== Running OpenRocket from Eclipse (tested with Eclipse Luna and OpenRocket v15.03, September, 2015) ==&lt;br /&gt;
&lt;br /&gt;
The following steps should get you up and running with OpenRocket source code: &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) After downloading the source code, start Eclipse. &amp;lt;br/&amp;gt;&lt;br /&gt;
2) From the Eclipse main menu, select &amp;lt;b&amp;gt;File&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Import&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt; &lt;br /&gt;
3) In the &amp;lt;i&amp;gt;Import&amp;lt;/i&amp;gt; window that opens, select &amp;lt;b&amp;gt;General&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Existing Projects into Workspace&amp;lt;/b&amp;gt;, then click &amp;lt;b&amp;gt;Next&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
4) In the &amp;lt;i&amp;gt;Select root directory&amp;lt;/i&amp;gt; field, browse to the location of the OpenRocket source code that you downloaded. &amp;lt;br/&amp;gt;&lt;br /&gt;
5) In the file browser that appears, click on the &amp;lt;b&amp;gt;openrocket&amp;lt;/b&amp;gt; root project directory. A list of projects should then appear in the &amp;lt;i&amp;gt;Projects&amp;lt;/i&amp;gt; pane on the import window. &amp;lt;br/&amp;gt;&lt;br /&gt;
6) Select only these three projects from the list: &amp;lt;b&amp;gt;OpenRocket Core&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;OpenRocket Swing&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;OpenRocket Test Libraries&amp;lt;/b&amp;gt;. (Note: As of v15.03 you no longer need to load the other projects to build OpenRocket on the desktop.) &amp;lt;br/&amp;gt;&lt;br /&gt;
7) Once those three projects have been selected, click &amp;lt;b&amp;gt;Finish&amp;lt;/b&amp;gt;. Eclipse should start with those three projects shown in the &amp;lt;i&amp;gt;Package Explorer&amp;lt;/i&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;NOTE: You might see errors in some source files, reporting that various Java classes cannot be found. If that happens, you might try these steps to resolve these issues: &amp;lt;/i&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8) In the &amp;lt;i&amp;gt;Project Explorer&amp;lt;/i&amp;gt; pane in Eclipse, right-click on the project reporting the errors. Select &amp;lt;b&amp;gt;Properties&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
9) In the properties window that opens, select &amp;lt;b&amp;gt;Java Build Path&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Libraries&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
10) Make sure that the &amp;lt;i&amp;gt;JRE System Library&amp;lt;/i&amp;gt; for your version of Java is seen in the list of libraries. &amp;lt;br/&amp;gt;&lt;br /&gt;
11) If it is NOT included in the list, click the &amp;lt;b&amp;gt;Add Library&amp;lt;/b&amp;gt; button in the menu to the right. &amp;lt;br/&amp;gt;&lt;br /&gt;
12) From the &amp;lt;i&amp;gt;Add Library&amp;lt;/i&amp;gt; window that appears, select &amp;lt;b&amp;gt;JRE System Library&amp;lt;/b&amp;gt; from the list. Then click &amp;lt;b&amp;gt;Next&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
13) Make sure that the correct &amp;lt;i&amp;gt;Workspace&amp;lt;/i&amp;gt; is selected in the next window that appears, and then click &amp;lt;b&amp;gt;Finish&amp;lt;/b&amp;gt;. Once the &amp;lt;i&amp;gt;Add Library&amp;lt;/i&amp;gt; window closes, you should then see the JRE System Library added to the list of libraries in the project properties window. &amp;lt;br/&amp;gt;&lt;br /&gt;
14) Click &amp;lt;b&amp;gt;OK&amp;lt;/b&amp;gt;. Once the project properties window closes you will be returned to Eclipse, and hopefully the errors reported by the IDE will then resolve. &amp;lt;br/&amp;gt;&lt;br /&gt;
15) If there are still errors, you&#039;ll need to revert to Google for additional help. Googling the exact error string reported by Eclipse will most likely help you resolve any outstanding dependency issues. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;***&amp;lt;/b&amp;gt; Also note that the main entry point for OpenRocket is in the &amp;lt;i&amp;gt;OpenRocket Swing&amp;lt;/i&amp;gt; project, in the &amp;lt;b&amp;gt;net.sf.openrocket.startup.SwingStartup.java&amp;lt;/b&amp;gt; file. With that file active OpenRocket should build and start. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, remember that help is available either in the OpenRocket forums or in the main developers list. Good Luck! &amp;lt;br/&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Marking TODO&#039;s ==&lt;br /&gt;
&lt;br /&gt;
Often when writing code you know that something could be done better, but at the moment is either impossible or unreasonable.  These are commonly marked with a TODO comment.  The following convension is used to mark the importance of different TODO&#039;s:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;// TODO: CRITICAL: Some comment&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; A bug or something that is not yet implemented, and must be corrected before any release is made.  The Ant build script checks for these and prevents building if such a comment is found.&lt;br /&gt;
* &amp;lt;code&amp;gt;// TODO: HIGH: Some comment&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; An important issue that should be looked into within this or the next major release.&lt;br /&gt;
* &amp;lt;code&amp;gt;// TODO: MEDIUM: Some comment&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Something that would make the software better, but does not represent a problem as such.&lt;br /&gt;
* &amp;lt;code&amp;gt;// TODO: LOW: Some comment&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Something that would be nice to do better in the future&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== LogBack ===&lt;br /&gt;
&lt;br /&gt;
As of version 13.05, OpenRocket uses [http://logback.qos.ch/index.html LogBack] for logging.&lt;br /&gt;
&lt;br /&gt;
If you want to change the default logging that OpenRocket uses, you can create or reuse a LogBack configuration file stored in openrocket/core/config. For example, you can use the logback-stdout-level-error.xml there which tells logback to log everything to stdout with logging level of Error (serious errors only).&lt;br /&gt;
&lt;br /&gt;
To enable use of a LogBack configuration file, pass the JVM the following option during startup:&lt;br /&gt;
&lt;br /&gt;
 -Dlogback.configurationFile=config/logback-stdout-level-error.xml &lt;br /&gt;
&lt;br /&gt;
See the [http://logback.qos.ch/manual/configuration.html LogBack configuration page] for more details. &lt;br /&gt;
&lt;br /&gt;
=== Probably Obsolete Debugging Info ===&lt;br /&gt;
&lt;br /&gt;
Log messages in openrocket are specified by one of six levels. You can specify which level of errors you want reported to standard out with a system property which you can add to your VM argument, e.g:&lt;br /&gt;
 &lt;br /&gt;
 -Dopenrocket.log.stdout=debug&lt;br /&gt;
&lt;br /&gt;
The error levels available are:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;ERROR&#039;&#039;&#039; - Level for indicating a bug or error condition noticed in the software or JRE. No ERROR level events _should_ occur while running the program.&lt;br /&gt;
	&lt;br /&gt;
: &#039;&#039;&#039;WARN&#039;&#039;&#039; - Level for indicating error conditions or atypical events that can occur during normal operation (errors while loading files, weird computation results etc).&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;USER&#039;&#039;&#039; - Level for logging user actions (adding and modifying components, running simulations etc).  A user action should be logged as soon as possible on this level.  The level is separate so that additional INFO messages won&#039;t purge user actions from a bounded log buffer.&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;INFO&#039;&#039;&#039; - Level for indicating general level actions the software is performing and other notable events during execution (dialogs shown, simulations run etc)&lt;br /&gt;
	&lt;br /&gt;
: &#039;&#039;&#039;DEBUG&#039;&#039;&#039; - Level for indicating mid-results, outcomes of methods and other debugging information.  The data logged should be of value when analyzing error conditions and what has caused them.  Places that are called repeatedly during e.g. flight simulation should use the VBOSE level instead.&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;VBOSE&#039;&#039;&#039; - Level of verbose debug logging to be used in areas which are called repeatedly, such as computational methods used in simulations.  This level is separated to allow filtering out the verbose logs generated during simulations, DnD etc. from the normal debug logs.&lt;br /&gt;
&lt;br /&gt;
In the code, the standard way to log errors is with &lt;br /&gt;
 &lt;br /&gt;
 log.verbose(&amp;quot;Error message&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
where log is defined in each class as :&lt;br /&gt;
 &lt;br /&gt;
 private static final LogHelper log = Application.getLogger();&lt;br /&gt;
&lt;br /&gt;
== Units used in OpenRocket ==&lt;br /&gt;
&lt;br /&gt;
OpenRocket always uses internally pure SI units.  For example all rocket dimensions and flight distances are in meters, all masses are in kilograms, density is in kg/m³, temperature is in Kelvin etc.  This convension is also used when storing the design in the OpenRocket format.&lt;br /&gt;
&lt;br /&gt;
The only exception to this rule is angles:&lt;br /&gt;
* Angles are represented as radians internally, but in the file format they are converted to degrees.  This is to make the file format more human-readable and to avoid rounding errors.&lt;br /&gt;
* Latitude and longitude of the launch site are represented in degrees both internally and externally.&lt;br /&gt;
&lt;br /&gt;
When displaying measures to the user, the values are converted into the preferred units of the user.  This is performed using classes in the package &amp;lt;tt&amp;gt;net.sf.openrocket.unit&amp;lt;/tt&amp;gt;.  The &amp;lt;tt&amp;gt;Unit&amp;lt;/tt&amp;gt; class represents a single unit and it includes methods for converting between that unit and SI units in addition to creating a string representation with a suitable amount of decimals.  A &amp;lt;tt&amp;gt;UnitGroup&amp;lt;/tt&amp;gt; describes a measurable quantity such as temperature and contains the units available for that quantity, such as Celcius, Fahrenheit and Kelvin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Rocket design loading and saving ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(This section is based on email correspondence)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All file reading/writing is performed in the package&lt;br /&gt;
&amp;lt;tt&amp;gt;net.sf.openrocket.file&amp;lt;/tt&amp;gt; and subpackages.  To implement a new&lt;br /&gt;
document loader it is necessary to extend the class &amp;lt;tt&amp;gt;RocketLoader&amp;lt;/tt&amp;gt; and&lt;br /&gt;
implement the abstract method &amp;lt;tt&amp;gt;loadFromStream(InputStream)&amp;lt;/tt&amp;gt;.  This&lt;br /&gt;
method simply loads the document and returns an &amp;lt;tt&amp;gt;OpenRocketDocument&amp;lt;/tt&amp;gt;&lt;br /&gt;
object.&lt;br /&gt;
&lt;br /&gt;
An &amp;lt;tt&amp;gt;OpenRocketDocument&amp;lt;/tt&amp;gt; contains all the information about an opened&lt;br /&gt;
document, primarily the rocket structure and the simulations.  The&lt;br /&gt;
rocket structure is a simple tree-like structure of &amp;lt;tt&amp;gt;RocketComponents&amp;lt;/tt&amp;gt;.&lt;br /&gt;
All of the components are in the package &amp;lt;tt&amp;gt;.rocketcomponent&amp;lt;/tt&amp;gt;.  A diagram&lt;br /&gt;
of their hierarchy and a short explanation of each class is available&lt;br /&gt;
in my thesis section 5.1&lt;br /&gt;
(http://openrocket.sourceforge.net/documentation.html)&lt;br /&gt;
&lt;br /&gt;
I&#039;ve implemented a simple XML reading framework (based on SAX), which&lt;br /&gt;
simplifies reading by assuming that XML elements can contain only&lt;br /&gt;
other elements or text content, but not both.  Both the OpenRocket and&lt;br /&gt;
Rocksim format abide with this restriction.&lt;br /&gt;
&lt;br /&gt;
The framework is in the package &amp;lt;tt&amp;gt;.file.simplesax&amp;lt;/tt&amp;gt;.  The primary class&lt;br /&gt;
that will be extended is &amp;lt;tt&amp;gt;ElementHandler&amp;lt;/tt&amp;gt;, which contains three methods.&lt;br /&gt;
&amp;lt;tt&amp;gt;openElement()&amp;lt;/tt&amp;gt; is called when a new subelement is found, and it&lt;br /&gt;
returns a new &amp;lt;tt&amp;gt;ElementHandler&amp;lt;/tt&amp;gt; to handle that element (which can be the&lt;br /&gt;
object itself), or &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; in order to ignore that element and all of its&lt;br /&gt;
contents (for example for unknown elements). &amp;lt;tt&amp;gt;closeElement()&amp;lt;/tt&amp;gt; is called&lt;br /&gt;
when the subelement ends, and &amp;lt;tt&amp;gt;endHandler()&amp;lt;/tt&amp;gt; is called when the element&lt;br /&gt;
of the current handler ends.  The JavaDoc should provide the necessary&lt;br /&gt;
details.&lt;br /&gt;
&lt;br /&gt;
There are a few ready handlers, the most useful of which will probably&lt;br /&gt;
be &amp;lt;tt&amp;gt;PlainTextHandler&amp;lt;/tt&amp;gt;.  This handler accepts only text content and&lt;br /&gt;
ignores all subelements.  If the XML file contains&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&amp;lt;element&amp;gt;value&amp;lt;/element&amp;gt;&amp;lt;/nowiki&amp;gt;, then the handler can return a&lt;br /&gt;
&amp;lt;tt&amp;gt;PlainTextHandler&amp;lt;/tt&amp;gt; and handle the content within the &amp;lt;tt&amp;gt;closeElement()&amp;lt;/tt&amp;gt;&lt;br /&gt;
method, removing the need to write a specialized handler for that&lt;br /&gt;
element.&lt;br /&gt;
&lt;br /&gt;
The XML reading is initiated by calling &amp;lt;tt&amp;gt;SimpleSAX.readXML()&amp;lt;/tt&amp;gt; with the&lt;br /&gt;
input source and the initial &amp;lt;tt&amp;gt;ElementHandler&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The OpenRocket document loading is implemented in&lt;br /&gt;
&amp;lt;tt&amp;gt;.file.openrocket.OpenRocketLoader&amp;lt;/tt&amp;gt;.  Here I&#039;ve used a bit more&lt;br /&gt;
boilerplate code to be able to define most of the rocket structure&lt;br /&gt;
preferences without needing separate handlers for them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The OpenRocket format (*.ork) ===&lt;br /&gt;
&lt;br /&gt;
The OpenRocket native format uses the file extension *.ork.  It is an XML format, which can optionally be compressed using GZIP.  (The extension *.ork.gz is also accepted by the dialogs, though plain .ork is recommended.)&lt;br /&gt;
&lt;br /&gt;
Currently the file format is not documented other than as the reference implementation, and no XML schema exists.  This will hopefully change in the future.  See [[#Units used in OpenRocket]] for details on units.&lt;br /&gt;
&lt;br /&gt;
Every time the XML format changes, the file version number is increased.  This version number is not linked to the version of OpenRocket that created the file, but instead describes the file format.  Later versions of OpenRocket should attempt to store files in the oldest format that supports all the necessary features.  The changes in the format are described in the [http://openrocket.svn.sourceforge.net/viewvc/openrocket/trunk/fileformat.txt fileformat.txt file in SVN].&lt;br /&gt;
&#039;&#039;Italic text&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justgerrardz</name></author>
	</entry>
</feed>