Jump to content

One Attitude Controller to Rule Them All


Majiir

Recommended Posts

(I couldn\'t help the puns.)

Some of the most popular plugins seem to be autopilots. Whatever these plugins do, they all share at least one common component: an attitude controller. Why? Because if you\'re an autopilot, you need to be able to steer!

While working on an autopilot plugin of my own (precision descent controller) I found that the attitude control problem is much more complicated than I had originally expected. It\'s easy to come up with primitive solutions, but these have problems that seriously limit their potential uses. The following is a (probably incomplete) list of features than an ideal attitude controller has:


  • [li]Orientation control - This is the core function of an attitude controller. The user (which is usually some other code) tells the attitude controller to put the ship at a specified orientation.[/li]
    [li]Stability - There are various mathematical definitions of controller stability, and they\'re important. We don\'t want our ships to oscillate or spin out of control.[/li]
    [li]Disturbance rejection - KSP is a simple simulator, but there are still some disturbances to account for. Angular drag can be accounted for ahead of time, but things like collisions or floating-point errors can\'t be predicted.[/li]
    [li]Disturbance compensation - I put this in a different category because it\'s a slightly different problem. Imagine you grapple another ship with some lander legs, and then you make an orbital burn. The second ship is slightly off-center. A plugin can\'t compensate for the offset center of mass, so your attitude will always be slightly off. A proper attitude controller will detect (usually through error integration) that it must apply additional torque in order to stay on course.[/li]
    [li]Optimal pathing - This is where simple (usually Euler angle-based) attitude controllers really fall short. When we\'re adjusting the orientation of the ship, we want to take the shortest path to get there. It\'s quicker, which is always good, but it\'s also more stable. If you\'re launching and you want to roll your ship 180 degrees, a simple attitude controller might pitch you 90 degrees forward, yaw around 180 degrees, and then pitch 90 degrees up. That\'ll crash your ship.[/li]
    [li]Speed - Some maneuvers require a quick attitude change, so our controller should make reasonable use of available torque.[/li]
    [li]Rate control - Suppose you want to spin in a controlled way. The user code might set a moving orientation target, but many controllers will lag a set distance behind, depending on how fast the target is moving. An ideal controller allows the user to specify a target rate.[/li]
    [li]Roll ambivalence - Sometimes, we only care about where we are on the navball, and we\'re happy to let our roll do whatever we (or the pilot) want. I believe this is a minimization problem, and that we can\'t simply ignore the roll commands. (More details in
this post. Thanks The_Duck for reminding me of this issue.)[/li]

Now, let me be clear: this is only a wish list. Even to get just a few of these, we need to dig into some pretty heady academic papers. I\'ve read through a few myself, but unfortunately I don\'t have any formal training in control systems, so some of it goes over my head.

Let\'s take a look at an existing (KSP) attitude controller and see how it stacks up. (If none of this paragraph makes sense, just skip to the last sentence.) Since MechJeb is pretty popular, I\'m going to pick on it. The MechJeb 'Smart A.S.S.' accepts a target orientation (as a quaternion) and computes the orientation change required to move from the ship\'s current orientation to the desired orientation. After this, it breaks down a little; Euler angles, angular velocity and angular acceleration are combined in an attitude-control PID, with some special cases where the error quaternion is slerp\'d. The result is that MechJeb can make large-angle changes, but it can be unstable and makes a convoluted path.

I tried my hand at something smoother. (I can\'t find the paper I derived the control law from, but I\'ll grab it from my laptop sometime.) This control law was quaternion-based and avoided Euler angles completely. It also made absolutely no sense to me. I don\'t know how or why it works, but it does. The pathing isn\'t completely optimal (I don\'t think) but it\'s pretty damn near close. It\'s fast. It\'s stable, both subjectively and in at least one mathematical sense. I didn\'t understand enough of the paper to properly calibrate the controller for the ship\'s moment of inertia, but the results were pretty good even so.

I think MechJeb and some other plugins would immediately benefit by implementing the controller as-is, but I think we can do better. As a first milestone, I propose creating an attitude controller with the following of the above features:


  • [li]Quaternion-based orientation control[/li]
    [li]Disturbance rejection (in other words, don\'t pilot blindly)[/li]
    [li]Optimal pathing[/li]
    [li]Optimal settling speed, within a threshold (this means our controller should measure available torque and the ship\'s moment of inertia and fly accordingly).[/li]

The first two are easy; a simple PID can do it. The second two are much more challenging, and will require some math-fu. I think it\'ll pay off, though. Who\'s up for helping? 8)

Link to comment
Share on other sites

Alright, I found the paper. I took equation (10) from this paper: http://www.ajc.org.tw/pages/paper/5.3PD/9FR-02-18.pdf

%5CLARGE%5C!%5Cunderline%7Bu%7D%20%3D%20-%5Cfrac%7B2%7D%7B%5Crho%5E2%7D%20%28a%5Cunderline%7B%5Comega%7D%20%2B%20b_1%5Cunderline%7B%5Cvarepsilon%7D%20%2B%20b_2%5Ceta%5Cunderline%7B%5Cvarepsilon%7D%29.gif

Now, I\'m definitely missing a lot of the insights from that paper, but it\'s still progress! There are four constants (?, a, b1, b2). ? is angular velocity, ? is the vector part of the error quaternion, and ? is the scalar part. For some reason, this works really well.

I\'m working on compiling a list of some more resources that might help us here.

Link to comment
Share on other sites

You know, I\'d like to expand my little ASAS hack that I published before Easter with some of the same things you mention in your list ;) Seems like we have a common interest... though I\'m more interested in 'pilot assistance' devices, while you seem to be more interested in autopilots.

A better algorithm for RCS was one of the things I wanted to try and make; but right now we have a big limitation... we can\'t split RCS control from SAS and fin control; and the correct algos for each of these systems are different. Do you have any idea for a workaround?

I don\'t know how much free time I will have to put into this, but I\'m game.

Link to comment
Share on other sites

This paper seems to imply that an asymptotically stable controller will necessarily follow an optimal path. I don\'t really see how that\'s true, but it\'s worth noting anyway. Most literature seems to stress various kinds of stability, and doesn\'t make much reference to pathing.

It occurred to me that there\'s at least one easy way to implement rate control as I described it. If we already have a linear controller where ? (angular velocity) is one of the components, we can substitute ??, the difference between the current and desired angular velocity. If the controller has the right angular velocity but lags behind, the error quaternion component(s) should correct it as normal. If the target orientation isn\'t actually moving, the controller will pull in the direction of the target angular velocity, but this is a user (and by that I mean user code) error. Such a construction would, however, probably invalidate any assumptions of stability that we can derive from literature.

Link to comment
Share on other sites

You know, I\'d like to expand my little ASAS hack that I published before Easter with some of the same things you mention in your list ;) Seems like we have a common interest... though I\'m more interested in 'pilot assistance' devices, while you seem to be more interested in autopilots.

I\'m interested in both, but you can\'t have either without a solid foundation. I spent a couple weeks working on a landing computer, but I got very frustrated that some things (attitude control, drag modeling, etc.) were so complex. The community at large seems only to have scratched the surface of these core components.

A better algorithm for RCS was one of the things I wanted to try and make; but right now we have a big limitation... we can\'t split RCS control from SAS and fin control; and the correct algos for each of these systems are different. Do you have any idea for a workaround?

That depends. If there\'s a way to manually fire RCS without using the fly-by-wire controls, then yes, I think it can be done. (By the way, I strongly suspect it\'s possible to do exactly what, since the RCS thruster class exposes thrust levels for each of its axes. At the very least, a replacement RCS class could do it.) Plugins can both monitor user input and override it, so you could split off the RCS logic and only use the fly-by-wire controls for capsule SAS, which is a much simpler model. You might run into trouble if your part\'s fly-by-wire delegate runs after some other autopilot\'s, but since there are only a handful of autopilot plugins anyway, it should be pretty easy to have them integrate with your plugin when it\'s present.

Out of curiosity, in what ways do SAS, RCS and fins need to be treated differently? (I mean, not flapping fins around while in orbit would be great, but that\'s sort of harmless.)

Link to comment
Share on other sites

%5CLARGE%5C!%5Cunderline%7Bu%7D%20%3D%20-%5Cfrac%7B2%7D%7B%5Crho%5E2%7D%20%28a%5Cunderline%7B%5Comega%7D%20%2B%20b_1%5Cunderline%7B%5Cvarepsilon%7D%20%2B%20b_2%5Ceta%5Cunderline%7B%5Cvarepsilon%7D%29.gif

Now, I\'m definitely missing a lot of the insights from that paper, but it\'s still progress! There are four constants (?, a, b1, b2). ? is angular velocity, ? is the vector part of the error quaternion, and ? is the scalar part. For some reason, this works really well.

I\'ve only spent about 5 minutes looking at that paper, and I\'m not very familiar with quaternions, but it seems to me that this is more or less a PD controller? If I understand things correctly then

-The omega term says to apply a torque opposite the current angular velocity (like a PID\'s D term).

-the two epsilon terms say to apply a torque opposite the current angular error (like a PID\'s P term). For small errors the torque is indeed proportional to the error, if I understand quaternions correctly.

One thing to consider in an attitude controller for KSP is that often we only care about the pointing direction and not the roll around the pointing direction. I\'m not sure how easy it is to be disentangle the two when using quaternions?

Link to comment
Share on other sites

I\'ve only spent about 5 minutes looking at that paper, and I\'m not very familiar with quaternions, but it seems to me that this is more or less a PD controller? If I understand things correctly then

-The u term says to apply a torque opposite the current angular velocity (like a PID\'s D term).

-the two epsilon terms say to apply a torque opposite the current angular error (like a PID\'s P term). For small errors the torque is indeed proportional to the error, if I understand quaternions correctly.

Yes, it\'s much like a PD. I think the eta term (the second epsilon term) is important, though. Somehow. Don\'t ask me how. ;)

[EDIT] I should mention that only the part I\'ve pulled out resembles a PD. There\'s a lot more in there that I completely ignored (for lack of understanding it) which I believe makes the controller aware of the spacecraft\'s torque and inertia characteristics.

One thing to consider in an attitude controller for KSP is that often we only care about the pointing direction and not the roll around the pointing direction. I\'m not sure how easy it is to be disentangle the two when using quaternions?

Thanks for reminding me of this; I need to include this in my original post.

I think we need to approach this from the math side. We don\'t want to approach a given quaternion and simply ignore the roll commands; that could lead to instability (as I\'ve found out the hard way). What we\'re really doing is specifying an entire set of quaternions, any of which we\'d be happy with. This set is essentially any of the quaternions that result when the desired quaternion is rolled any which way. Now we need a way to determine which quaternion(s) in that set are 'easiest' to reach. This may be a simple minimization problem, but without a good understanding of optimal pathing, I\'m not sure we can tackle this quite yet.

[EDIT] I\'ve got a working list of sources I\'ve been looking at here. I\'ll throw up good PDF links later, but Google should be able to find those.

Link to comment
Share on other sites

Okay, I\'m digging into this rolling thing a bit.

The Wikipedia article on conversion between quaternions and Euler angles, the following equations are given:

2%29%5Ccos%28%5Cbeta_z%29%5Cend%7Beqnarray%2A%7D.gif

I think our axis for a roll would be [0, 1, 0] giving us the following:

2%29%5C%5C%5Cmathbf%7Bq%7D_3%20%26%3D%26%200%5C%5C%5Calpha%20%26%3D%26%20%5B0%2C%204%5Cpi%29%5Cend%7Beqnarray%2A%7D.gif

The angle range is double what you might expect because there are two quaternion representations for any given rotation. Now, since we don\'t care about roll, we can feel free to apply any rotation from this set to our quaternion setpoint.

%5CLARGE%5C%21%5Clarge%5Cmathbf%7Bq%7D%20%3D%20q_rq_s.gif

Our goal is to find a q_r such that the angular distance between q (above) and q_v (the current orientation of our vessel) is minimized. Stated a different way, we want to minimize the following quaternion product:

%5CLARGE%5C%21%5Clarge%7Bq_v%7D%5E%7B-1%7D%5Cmathbf%7Bq%7D%20%3D%20%7Bq_v%7D%5E%7B-1%7Dq_rq_s.gif

I\'m just not sure how to determine the 'distance' between two quaternions, or a meaningful 'angular magnitude' of a quaternion. Various sources indicate that the dot product is or isn\'t acceptable. Any ideas?

Link to comment
Share on other sites

Thank you for looking into this.

Here\'s something that kinda irritates me with MechJeb but not to a huge extent because we\'re still waiting on the full rebuild of the atmospheric flight model(s).

Roll should not be ignored or left to pilot input. The moment you put lifting surfaces on a rocket you must control roll as part of maintaining its proper path. Imagine if NASA tried to launch the shuttle and instead of pitching head\'s down they rolled only 90 degrees and had the ship essentially flying on it\'s side. Now try to maintain the pitch attitude and yaw it along the path. You\'re fighting a lot more resistance to movement doing it that way because you have a lot less control authority. By pitching \'heads down\', you not only increase the comfort of the crew, you also put all the control authority on your side. The upward-canted SSME\'s have the most movement available when on the bottom of the stack, you have the body flap, the elevons, and the SRB gimbals all working for you. Additionally, the lifting surface of the wing and the combined SRB/ET stack helps to stabilize the entire stack by pushing it forward.

People seem to think that a rocket can really launch in any direction. There\'s a reason that the designers always have the rockets roll 'heads down'. There\'s a function to it. It not only minimizes the felt acceleration for the payload (whether human or mechanical) but it also makes sure that on those vehicles that have lifting surfaces they\'re used to the maximum effect.

Link to comment
Share on other sites

Thank you for looking into this.

Here\'s something that kinda irritates me with MechJeb but not to a huge extent because we\'re still waiting on the full rebuild of the atmospheric flight model(s).

Roll should not be ignored or left to pilot input. The moment you put lifting surfaces on a rocket you must control roll as part of maintaining its proper path. Imagine if NASA tried to launch the shuttle and instead of pitching head\'s down they rolled only 90 degrees and had the ship essentially flying on it\'s side. Now try to maintain the pitch attitude and yaw it along the path. You\'re fighting a lot more resistance to movement doing it that way because you have a lot less control authority. By pitching \'heads down\', you not only increase the comfort of the crew, you also put all the control authority on your side. The upward-canted SSME\'s have the most movement available when on the bottom of the stack, you have the body flap, the elevons, and the SRB gimbals all working for you. Additionally, the lifting surface of the wing and the combined SRB/ET stack helps to stabilize the entire stack by pushing it forward.

People seem to think that a rocket can really launch in any direction. There\'s a reason that the designers always have the rockets roll 'heads down'. There\'s a function to it. It not only minimizes the felt acceleration for the payload (whether human or mechanical) but it also makes sure that on those vehicles that have lifting surfaces they\'re used to the maximum effect.

I think I\'m gonna make a suggestion of a roll setting in the ascent autopilot and in the SASS.

Link to comment
Share on other sites

So I don\'t think the dot product can help us with the roll-minimization problem.

You can use a quaternion dot product to find the angle between two quaternions, but roll doesn\'t change the angle, it changes the direction of the vector component. I\'ll have to think about this in a different way.

Link to comment
Share on other sites

I think I don\'t really understand what you mean by 'shortest path'. You\'re thinking at rolling the ship to bring one axis in the plane of the required maneuver, and then do a pitch or yaw to the new attitude, instead of maneuvering the two axes simutaneously?

Yes, with a long and thin ship, the difference in moments of inertia should make that economical in terms of fuel expenditure or speed over a considerable range; personally, I wouldn\'t want the craft to roll if I have not commanded it, unless the scenario is punching some numbers in the computer for a large attitude change. But I suppose you meant just that... (it should roll back to the original angle at the end of the maneuver, though)

Re. the algorithms for RCS and fins: well, maneuvers with reaction controls should be done as acceleration-coast-deceleration, while the aerodynamic surfaces generally need a constant input to mantain rate (since you\'re counteracting the natural stability of the craft). SAS is a middle ground, in that it behaves sorta like RCS, but you don\'t have to worry about not wasting fuel.

As for what we have now, the ASAS oscillations are due to integral windup.

The ASAS PID tries to bring angular momentum to zero, plain and simple... since when the value actually crosses zero, the integral term still 'remembers' the precedent offset, the ASAS keeps thrusting/torquing until the error in the opposite direction cancels the integral, then it starts bouncing back (at reduced amplitude).

My first fix would be shortening the 'memory span' of the ASAS: I\'d try to add an exponential decay to the integral value, with a time constant of... uhm... 500 msec? Does that make any sense for you? If I don\'t hear objections, I\'ll try it in my modded ASAS and see how it goes ;)

As for the Shuttle attitude at launch: I think that the heads down attitude wasn\'t particularly more stable, but since the SSMEs need to be angled upwards to have their thrust going through the center of gravity, in this way the sideways thrust component is directed up, where it\'s useful... flying in normal attitude would mean pushing downwards.

Anybody knows which way the Energija/Buran pitched? Or even better, the cargo version of Energija (the Polyus launch, for example)?

Link to comment
Share on other sites

I think I don\'t really understand what you mean by 'shortest path'. You\'re thinking at rolling the ship to bring one axis in the plane of the required maneuver, and then do a pitch or yaw to the new attitude, instead of maneuvering the two axes simutaneously?

Imagine that you trace a marker along the navball whenever you rotate. The most efficient rotation will appear to be a straight line on the ball. Some control laws, especially those that use Euler angles, will make a meandering path.

Yes, with a long and thin ship, the difference in moments of inertia should make that economical in terms of fuel expenditure or speed over a considerable range; personally, I wouldn\'t want the craft to roll if I have not commanded it, unless the scenario is punching some numbers in the computer for a large attitude change. But I suppose you meant just that... (it should roll back to the original angle at the end of the maneuver, though)

The roll problem is something else entirely. Imagine you have a symmetrical ship and you want an autopilot to hold it at 5 degrees pitching north. That\'s a pretty small change, and you don\'t want the autopilot to also roll your ship all the way around to align with some arbitrary horizon that it picked. You just care about the pitch and heading. I\'m trying to figure out a way to analytically find a setpoint that won\'t issue a roll command.

Re. the algorithms for RCS and fins: well, maneuvers with reaction controls should be done as acceleration-coast-deceleration, while the aerodynamic surfaces generally need a constant input to mantain rate (since you\'re counteracting the natural stability of the craft). SAS is a middle ground, in that it behaves sorta like RCS, but you don\'t have to worry about not wasting fuel.

One thing you can do is only activate RCS thrusters if the attitude controller wants more torque than the SAS or fins can provide. You could also supply the attitude controller with some parameters for how it should behave, since the fastest control action isn\'t usually as fuel-efficient.

Regarding fins, I think you need a constant input because you\'re in atmosphere, not because you\'re controlling fins. Imagine using fixed fins and SAS to keep the ship pitched over slightly; you\'ll still need a constant torque because your heading and velocity are different, and the fins are torquing you back. All that said, it wouldn\'t hurt to give fins the same treatment as RCS, and only move them when SAS isn\'t enough. (You could even attempt to move fins as few times as possible, or as smoothly as possible, using SAS torque to cover the difference. It would make a big visual impact, since fins currently jerk all over the place.)

As for what we have now, the ASAS oscillations are due to integral windup.

The ASAS PID tries to bring angular momentum to zero, plain and simple... since when the value actually crosses zero, the integral term still 'remembers' the precedent offset, the ASAS keeps thrusting/torquing until the error in the opposite direction cancels the integral, then it starts bouncing back (at reduced amplitude).

My first fix would be shortening the 'memory span' of the ASAS: I\'d try to add an exponential decay to the integral value, with a time constant of... uhm... 500 msec? Does that make any sense for you? If I don\'t hear objections, I\'ll try it in my modded ASAS and see how it goes ;)

Actually, I\'m not sure integral windup is the problem. Remember, when the ship is approaching the ASAS target point, the error in angular momentum is the opposite sign of the integral. In other words, as you get closer, you\'re already ticking down the integral. The moment you hit where you want to be, the integral term is already zero. Most of the oscillation problems are actually caused by the proportional term, since the PID\'s constants aren\'t tuned to account for the torque or inertia of the vessel. They\'re just some arbitrary constants that Harvester determined were 'good enough' for most ships. There are also problems caused by the derivative term; most notably, if you\'re only spinning slightly and you activate ASAS, you\'ll 'jerk' in a random direction for a moment.

Integral windup is a problem when you\'re spinning very quickly in a heavy ship with little torque. When you activate the ASAS, you might actually spin around a few times before it slows you all the way down, and now the integral term has accumulated several revolutions worth of angular momentum change. In order to wind that down, it needs to make a few revolutions back, and since the ship is heavy and the PID isn\'t tuned for the ship\'s characteristics, you get integral windup in the other direction for a while. Eventually, the proportional term and angular drag work it all out, but it can make already difficult-to-control ships a real challenge to fly.

As for the Shuttle attitude at launch: I think that the heads down attitude wasn\'t particularly more stable, but since the SSMEs need to be angled upwards to have their thrust going through the center of gravity, in this way the sideways thrust component is directed up, where it\'s useful... flying in normal attitude would mean pushing downwards.

Anybody knows which way the Energija/Buran pitched? Or even better, the cargo version of Energija (the Polyus launch, for example)?

I think you\'re right about this; the SSME gimbals couldn\'t angle 'down' in the same way. I don\'t know about the Energia, but it was sufficiently different. (It had two engines, and its carrier rocket had eight, some/all of which were liquid.)

Link to comment
Share on other sites

As for the Shuttle attitude at launch: I think that the heads down attitude wasn\'t particularly more stable, but since the SSMEs need to be angled upwards to have their thrust going through the center of gravity, in this way the sideways thrust component is directed up, where it\'s useful... flying in normal attitude would mean pushing downwards.

Anybody knows which way the Energija/Buran pitched? Or even better, the cargo version of Energija (the Polyus launch, for example)?

The engines of the shuttle were angled the way they were to ensure that sufficient thrust offset was created to balance the asymmetric drag and lift of the combined vehicle stack. No matter which way you pointed the ship, the shuttle would tend to 'pull' the stack. The head down position was to maximize leverage of that asymmetric drag to help with the gravity turn so that you were spending the least amount of fuel in maintaining the ship\'s attitude possible and thus wasted energy. The proof of this is that later in the program, they began rolling the shuttle 'heads up' about 5 minutes into the flight to allow them to utilize satellites to communicate and track the shuttle\'s ascent as it passed out of range of the tracking station in Bermuda. As the shuttle was no longer having to offset the thrust of the SRB\'s, there was also a net 'push' to the stack as the ET drag in the atmosphere would tend to require an 'up' thrust component to offset, even if minor, again, to the advantage of a heads-down shuttle until high enough that atmospheric drag was no longer a major component.

As for Energia/Buran, it also rolled heads down, just as the Soyuz stack does. It\'s a fairly 'universal' maneuver.

Link to comment
Share on other sites

I made a custom RCS block which ignores control input and accepts commands from plugin code. You\'ve got to extend RCSModule, override onCtrlUpd() and be sure to not call the base method. Also override onPartFixedUpdate(), and in this method construct a fresh FlightCtrlState object with your desired controls. (These can be stored in properties or something.) Call base.onCtrlUpd() with that state, and then call base.onPartFixedUpdate(). I think the same will work for the stabilizer fins.

[EDIT] Success! Take a look:

screenshot10.png

If you look closely (it\'s a bad shot, I know) you can see that the pitch/yaw/roll controls are all zero, the RCS thrusters are pitching the ship, and the fins are rolling it. This, of course, left the ship nearly impossible to control even with my flight computer, but I think it\'s a sound proof of concept. Currently, this is my code for issuing the commands:

(Ignore the vessel.transform.rotation bit for now.)


foreach (var part in vessel.parts)
{
if (part is SmartRCSModule)
{
((SmartRCSModule)part).InputRotation = vessel.transform.rotation * new Vector3(0.5f, 0, 0);
}
if (part is SmartControlSurface)
{
((SmartControlSurface)part).InputRotation = vessel.transform.rotation * new Vector3(0, -0.5f, 0);
}
}

Link to comment
Share on other sites

I made a custom RCS block which ignores control input and accepts commands from plugin code. You\'ve got to extend RCSModule, override onCtrlUpd() and be sure to not call the base method. Also override onPartFixedUpdate(), and in this method construct a fresh FlightCtrlState object with your desired controls. (These can be stored in properties or something.) Call base.onCtrlUpd() with that state, and then call base.onPartFixedUpdate(). I think the same will work for the stabilizer fins.

[EDIT] Success! Take a look:

screenshot10.png

If you look closely (it\'s a bad shot, I know) you can see that the pitch/yaw/roll controls are all zero, the RCS thrusters are pitching the ship, and the fins are rolling it. This, of course, left the ship nearly impossible to control even with my flight computer, but I think it\'s a sound proof of concept. Currently, this is my code for issuing the commands:

(Ignore the vessel.transform.rotation bit for now.)


foreach (var part in vessel.parts)
{
if (part is SmartRCSModule)
{
((SmartRCSModule)part).InputRotation = vessel.transform.rotation * new Vector3(0.5f, 0, 0);
}
if (part is SmartControlSurface)
{
((SmartControlSurface)part).InputRotation = vessel.transform.rotation * new Vector3(0, -0.5f, 0);
}
}

Looks to me like the RCS thrusters are only applying roll...

Never mind, there\'s some yaw, too. It looks like it\'s mostly roll, though.

Link to comment
Share on other sites

Looks to me like the RCS thrusters are only applying roll...

Never mind, there\'s some yaw, too. It looks like it\'s mostly roll, though.

It\'s a bad picture, but it\'s working properly. The top and bottom thrusters (relative to the picture) are both thrusting left. The left one is thrusting down, and the right one is thrusting up. There\'s a little erroneous thrust showing up in other places because the parts jostle around a little bit and their positions don\'t stay perfectly static.

[EDIT] I had a thought about the winglets. They could easily be modified to react to the translation inputs. Stick a set of winglets at the top and bottom of the ship, and you\'ve got lateral force. The plugin would need to check that enough winglets exist in the right places, because you don\'t want a translation command to flip the vessel over, but I think I can cook something up. This might be turning into a distinct plugin...

Link to comment
Share on other sites

I\'m a little frustrated that I can\'t figure this whole no-roll-control thing, but I had some ideas. First things first: you definitely can\'t just disable roll torque and expect it to do the same thing. You get instabilities and maybe even singularities. Now, the optimal path from one rotation to another is about the eigenaxis of rotation. So, if you want to minimize the amount of rotating, you need to minimize the angle (?) of rotation about the axis.

Reviewing the problem for a moment: we\'re given a target orientation (the setpoint) and our current orientation. Normally, we\'d match the setpoint exactly, but we don\'t care about our roll (in this particular case). So, we want to apply a 'roll compensation' to our setpoint such that the error between the setpoint and our current orientation is minimized.

[EDIT] Removed derivation.

Link to comment
Share on other sites

  • 2 weeks later...

Alright, I figured it out. I even found a way to allow freedom of rotation around any arbitrary axis, so you can pitch, yaw, or roll freely, or even rotate freely around some offset axis.

The derivation is a bit long, though, and I\'d like to figure out a way to allow freedom of rotation around multiple axes. (I\'m not even sure if that makes sense in terms of rotation, but I\'ll give it a try anyway. An example would be 'keep me at 25 degrees pitch, but do whatever you want with roll and heading.') Currently, the axis of freedom is given as a unit vector; I suspect multiple axes would be specified in a matrix.

On the controller front, I\'m still looking for a control law that accounts for the ship moment of inertia and the available torque. A time-optimal controller may end up being too computationally expensive, so eigenaxis slew maneuvers are fine. It\'s difficult to find applicable literature since everyone assumes you have real-world problems like imperfect instruments and magnetic fields. ::) (We do have to cope with angular drag, which we\'ll want to account for to make the controller faster. I think a more basic, working controller is important first.)

[EDIT] Here are the setpoint-adjustment equations:

%5CLARGE%5C%21%5Clarge%5Cbegin%7Beqnarray%7D%5Cmathbf%7Bs%7D%20%26%3A%26%20%5Ctext%7Bsetpoint%7D%5C%5C%5Cmathbf%7Bq%7D%20%26%3A%26%20%5Ctext%7Bship%20rotation%7D%5C%5C%5Cvec%7Bu%7D%20%20%20%20%26%3A%26%20%5Ctext%7Baxis%20of%20freedom%20%28unit%20vector%29%7D%5C%5C%5Cmathbf%7Bn%7D%20%26%3A%26%20%5Ctext%7Bnew%20setpoint%7D%5C%5C%5Cend%7Beqnarray%7D.gif

%5CLARGE%5C%21%5Cbegin%7Barray%7D%7Brcl%7D%5Cmathbf%7Bu%7D%20%26%3D%26%20%5Cleft%280%2C%5C%2C%5Cvec%7Bu%7D%5Cright%29%5C%5C%20%20%20%20%5Calpha%20%26%3D%26%20%5Cmathbf%7Bq%7D%5Ccdot%28%5Cmathbf%7Bs%7D%5Cmathbf%7Bu%7D%29%5C%5C%20%20%20%20%20%5Cbeta%20%26%3D%26%20%5Cleft%5C%7B%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cbegin%7Barray%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cfrac%7B%5Cmathbf%7Bq%7D%5Ccdot%5Cmathbf%7Bs%7D%7D%7B%5Calpha%7D%20%5Cqquad%20%26%5Calpha%26%20%26%5Cnot%3D%26%20%260%26%20%5C%5C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cfrac%7B%5Cmathbf%7Bq%7D%5Ccdot%5Cmathbf%7Bs%7D%7D%7B%7C%5Cmathbf%7Bq%7D%5Ccdot%5Cmathbf%7Bs%7D%7C%7D%20%5Cqquad%20%26%5Calpha%26%20%26%3D%26%20%260%26%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cend%7Barray%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%5Cright.%5C%5C%20%20%20%20%5Cgamma%20%26%3D%26%20%5Cfrac%7B%5Cbeta%7D%7B%5Csqrt%7B%5Cbeta%5E2%20%2B%201%7D%7D%5C%5C%5Cmathbf%7Bn%7D%20%26%3D%26%20%5Cmathbf%7Bs%7D%5Cleft%28%5Csqrt%7B1-%5Cgamma%5E2%7D%2C%5C%2C%5Cgamma%5Cvec%7Bu%7D%5Cright%29%5C%5C%5Cend%7Barray%7D.gif

[EDIT 2] Here\'s a working snippet of code:

var u = new Vector3(0, 1, 0);

var q = FlightGlobals.ship_rotation;
var q_s = attitudeController.Setpoint;

var q_u = new Quaternion(u.x, u.y, u.z, 0);
var a = Quaternion.Dot(q, q_s * q_u);
var q_qs = Quaternion.Dot(q, q_s);
var b = (a == 0) ? Math.Sign(q_qs) : (q_qs / a);
var g = b / Mathf.Sqrt((b * + 1);
var gu = Mathf.Sqrt(1 - (g * g)) * u;
var q_d = new Quaternion()
{
w = g,
x = gu.x,
y = gu.y,
z = gu.z
};
var n = q_s * q_d;

attitudeController.Setpoint = n;

The axis of freedom is set on the first line. In this case, it allows free rolling. Non-basis vectors do work, but they behave a bit counterintuitively since our controls work on the basis vectors. There\'s definitely some kind of geometric significance in this solution, but I couldn\'t tell you what it is. I just got a huge mess of component terms and pulled out dot products until it looked all cleaned up. For the parametrized version (where you supply the vector, instead of it being built-in to the equation) I just sort of... guessed. Funny how that works out.

I guess ? is the 'distance' between your current rotation and a 'rolled-over' setpoint, and ? is the distance between the current rotation and the real setpoint divided by ?. So the further you get from the real setpoint in some way that gets you toward the flipped setpoint, the more the controller adjusts your setpoint so you don\'t perform a roll. Yeah? Yeah.

That was a fun detour. Back to eigenaxis slewing...

Link to comment
Share on other sites

I think a more basic, working controller is important first.)

I\'ve been working on a basic closed-loop controller, using the quaternions as states and applying a full state feedback. I\'ve also read some papers (which I cannot link to here, you\'ll need a subscription to various journals) about the subject. The basics are easy to understand: you measure the position (quaternions obviously), calculate the error, derive the required angular velocity, use that in a feedback controller to actually try to achieve that angular velocity (using the angular velocities around the principle axis as states and use those in feedback). In short: you need two feedback controllers.

Above is theoretical. I have no idea yet if one is able to measure the moments of inertia around the center of mass in KSP. If you want a high performance controller, you\'ll probably need a good model of the flight dynamics. I\'m currently working on the identification of flight dynamics, and the (hopefully) low complexity of the physics engine used should yield a pretty accurate model.

Anyway, I\'ve actually implemented a very basic controller, which currently is lacking the angular velocity feedback loop (that\'s where flight dynamics come in). The controller currently assumes the vessel is able to achieve the required angular velocity instantaneously. I did calculate the error a bit differently, and I don\'t have an axis of freedom, just the shortest path. But that\'s how I defined performance in this case. I did analyse the controller in Matlab and turns out it performs pretty well (just need to get a better settling time, but that is just tuning).

Link to comment
Share on other sites

  • 1 year later...

The RCS system as it stands has also been, umm, sugaring me to tears...

My biggest annoyance is that it doesn't seem to have any concept of zero-torque translations - attach a tiny tug to one end of a big, dumb long thing (e.g. a stack o' big fuel tanks), and thrust "up", and it just sets you tumbling. Various tutorials suggest placing your thrusters symmetrically about the centre of mass, but no, just NO. - this is SPACE, and that's just silly in this context. Leverage - it's not rocket science (well...), it's primary school science...

This scenario:

V 10N

|------------------------------|

|--------------0---------------|

|------------------------------|

------/\ 20 N

yields 10N in the upwards direction, and no torque. You'd think this would be what happens when you're in docking mode and press shift for 'up', but apparently 'up' actually just means 'fire all thrusters that point down', which is, as previously noted, just silly.

Looking at the MechJeb 2 source, they have code for an 'RCS balancer', which sets RCS throttles individually - so, it's not too hard to do. The algorithm implemented, however, is currently pretty poor though - better can be done. On the question of quaternions - yes, they can be used to model either a change in direction only or a change in direction and roll.

I'm going to try putting together a better 'balancer', which allows angular control with or without net linear effects, and linear control without angular effects (as per the lever above).

Other things I'd like to do / have in an RCS system:

- Angular velocity limiter - all that wasted monoprop trying to swing a ship around as fast as mechanically possible makes my inner dolphin cry.

- better handling of rate and direction when performing a large maneuver, e.g. a PID for movement along the shortest path, and a damper (just the 'D' of a PID) for movement perpendicular, so the perpendicular error can damp out early, leaving the ship headed towards the right direction. Currently it appears to be treated as a single-axis system, just thrusting 'towards' or 'away from' the target, resulting in some nasty seeking behaviour (e.g. spiralling around the target).

One thing which I'm not sure about either is getting the moment of inertia (not that it matters for my immediate purposes) - the Vessel class (in Assembly-CSharp.dll) has a "Vector3 MOI", but I don't see the principal axes anywhere - they could just be using moments about the x, y, and z axes, but that's not just wrong, it's wronggitty wronggity wrong - I choose to think better of the devs, but I'm not sure where to look.

Edited by Madact
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...