Adding an Inertial External Force #960
Replies: 6 comments 1 reply
-
Out of interest what sorts of forces are you planning to model? |
Beta Was this translation helpful? Give feedback.
-
Would like to model orbital phasing maneuvers – increasing orbital velocity or decreasing to change apogee/perigee, etc. The inertial velocity value effectively gives the axis of thrust to do this. A unit vector can be calculated in XML for pointing. For the ball_orbit example this is effectively like modeling a 3-Dof orbital problem. The force would be like a deorbit rocket engine. But a very simple one – not doing anything other than applying a force. Could increase complexity of such a model later, but I’m really only interested in orbital phasing at the moment.
|
Beta Was this translation helpful? Give feedback.
-
I think I have it working, but not sure how to pass along the proposed changes. Plus, there is apparently maybe something going on with the FGForce class or FGExternalForce class. Anyhow, here's my story. I wanted to be able to extend the ball_orbit example to do a simple change of orbital altitude. That is, to make a simulated burn IN THE PLANE OF THE ORBIT to raise or lower the orbit. This turned out to be easier to implement than I thought it would be. First, in FGForce.h|cpp I needed to add support for specifying a direction vector in the inertial frame. I did this by changing the header/code in FGForce to include this in the Transform() function (note the new tInertialBody case): const FGMatrix33& FGForce::Transform(void) const
{
switch(ttype) {
case tWindBody:
return fdmex->GetAuxiliary()->GetTw2b();
case tLocalBody:
return fdmex->GetPropagate()->GetTl2b();
case tInertialBody:
return fdmex->GetPropagate()->GetTi2b();
case tCustom:
case tNone:
return mT;
default:
{
const string s("Unrecognized tranform requested from FGForce::Transform()");
cout << s << endl;
throw BaseException(s);
}
}
} In FGExternalForce there needed to be a way to read in the new type, so I modified the bind() function there (note the new handler for sFrame == INERTIAL): FGParameter* FGExternalForce::bind(Element *el, const string& magName,
FGPropertyVector3& v)
{
// Set frame (from FGForce).
string sFrame = el->GetAttributeValue("frame");
if (sFrame.empty()) {
cerr << el->ReadFrom()
<< "No frame specified for external " << el->GetName() << ", \""
<< Name << "\"." << endl
<< "Frame set to Body" << endl;
ttype = tNone;
} else if (sFrame == "BODY") {
ttype = tNone;
} else if (sFrame == "LOCAL") {
ttype = tLocalBody;
} else if (sFrame == "WIND") {
ttype = tWindBody;
} else if (sFrame == "INERTIAL") {
ttype = tInertialBody;
} else {
cerr << el->ReadFrom()
<< "Invalid frame specified for external " << el->GetName() << ", \""
<< Name << "\"." << endl
<< "Frame set to Body" << endl;
ttype = tNone;
} So, then, how would I set up an external force that could be used to change the orbital altitude? In ball.xml I defined an external force: <external_reactions>
<property>propulsion/rocket_thrust</property>
<force name="rocket" frame="INERTIAL">
<function>
<property> propulsion/rocket_thrust </property>
</function>
<location unit="FT">
<x>0</x>
<y>0</y>
<z>0</z>
</location>
<direction>
<x> 0 </x>
<y> 0 </y>
<z> 0 </z>
</direction>
</force>
</external_reactions> The thrust direction was set (in the Inertial frame) to the negative of the normalized velocity vector in a flight control channel, since I needed to set the direction of the external force vector: <flight_control name="FGFCS">
<channel name="Pointing">
<fcs_function name="propulsion/tvc_inertial_x">
<function>
<quotient>
<property> -velocities/eci-x-fps </property>
<property> velocities/eci-velocity-mag-fps </property>
</quotient>
</function>
<output> external_reactions/rocket/x </output>
</fcs_function>
<fcs_function name="propulsion/tvc_inertial_y">
<function>
<quotient>
<property> -velocities/eci-y-fps </property>
<property> velocities/eci-velocity-mag-fps </property>
</quotient>
</function>
<output> external_reactions/rocket/y </output>
</fcs_function>
<fcs_function name="propulsion/tvc_inertial_z">
<function>
<quotient>
<property> -velocities/eci-z-fps </property>
<property> velocities/eci-velocity-mag-fps </property>
</quotient>
</function>
<output> external_reactions/rocket/z </output>
</fcs_function>
</channel>
</flight_control> The force vector, representing a rocket engine, was fired in a script: <event name="start deorbit burn">
<description> Change orbit </description>
<condition>
simulation/sim-time-sec gt 10
</condition>
<set name="propulsion/rocket_thrust" value="10000" action="FG_RAMP" tc="1.0"/>
<notify>
<property>simulation/sim-time-sec</property>
</notify>
</event>
<event name="end deorbit burn">
<description> Change orbit </description>
<condition>
simulation/sim-time-sec gt 35
</condition>
<set name="propulsion/rocket_thrust" value="0" action="FG_RAMP" tc="1.0"/>
<notify>
<property>simulation/sim-time-sec</property>
</notify>
</event> Very little was needed in the way of code changes. And I have a couple of new or modified XML files (vehicle, IC, script). I'd like to get it into other hands for testing and comments. |
Beta Was this translation helpful? Give feedback.
-
One weird issue happens when reading in the ball.xml vehicle file. In the external output readback there is this:
I don't think there should be two OUTPUT lines echoed out ... |
Beta Was this translation helpful? Give feedback.
-
@jonsberndt the way to do this is to generate a Github pull request. Ideally create your own fork of the JSBSim repo, and then in your forked repo create a new branch, e.g. See the following links for some tutorial info on generating pull requests:
Once the pull request is made others will see it, be able to browse the diffs, make general comments, comments about specific lines etc. and pull a copy to try it out themselves. If there are suggested changes based on others or yourself noticing some issues then simply push additional commits to your branch. Once the reviewers are happy etc. then they'll merge your pull request into the main JSBSim repo. |
Beta Was this translation helpful? Give feedback.
-
So the inertial force is a convenience then as opposed to adding a rocket thruster to the object and making sure it's attitude is correctly aligned when firing the rocket? |
Beta Was this translation helpful? Give feedback.
-
I have a need to add an inertial frame external force capability in addition to an external force referenced to the Body, Local, or Wind frames. This seems to be pretty simple, and the most complicated part of the code seems to be simply adding another type to be handled in
FGForce.cpp
(see casetInertialBody
):I am also preparing along with this an orbital mechanics use case example.
Just wanted to throw this out there for comment. :-)
Beta Was this translation helpful? Give feedback.
All reactions