Jump to content

[1.0.x] [V1.9f] Kerbal Foundries wheels, anti-grav repulsors and tracks


lo-fi

What to work on next?  

1,282 members have voted

  1. 1. What to work on next?

    • More wheels
      123
    • More tracks
      453
    • Rover bodies
      241
    • Landing gear
      137
    • Landing legs
      108
    • Something completely different
      193


Recommended Posts

1 hour ago, damerell said:

Seems reasonable to me.

[snip]

Sorry, don't have time to respond to the full post, but I'll leave this here; this was one of the first problems I examined when working through the spring/damper setup.

This is the reason why suspension forces must be applied along the hit-normal and cannot be applied along the suspension axis. If not there will be a constant force-input, accelerating the vehicle opposite of the suspension angle.  In the image below the vehicle would be accelerated towards the right of the image; more-or-less depending upon the compression of the suspension.

ca8aq8Z.png

Now, I'm not saying that your wrong -- the current implementation has issues when contacting surfaces at oblique angles; merely pointing out why your proposed solution for it is not workable (and was in fact the way I had it originally implemented...).

Link to comment
Share on other sites

1 hour ago, Shadowmage said:

Sorry, don't have time to respond to the full post, but I'll leave this here; this was one of the first problems I examined when working through the spring/damper setup.

This is the reason why suspension forces must be applied along the hit-normal and cannot be applied along the suspension axis. If not there will be a constant force-input, accelerating the vehicle opposite of the suspension angle.  In the image below the vehicle would be accelerated towards the right of the image; more-or-less depending upon the compression of the suspension.

ca8aq8Z.png

Now, I'm not saying that your wrong -- the current implementation has issues when contacting surfaces at oblique angles; merely pointing out why your proposed solution for it is not workable (and was in fact the way I had it originally implemented...).

Just a quick note on not confusing movement with force.

The line of Suspension is a freedom of movement axis, not force.  In fact, the fact that the wheel travel is constrained to that axis guarantees forces are holding it to that.  Travel up and down the suspension is driven by the spring rate and damper, travel outside is governed by modulus of elasticity of big chunks of (usually) steel.  They generally flex a lot less than a spring.  So, usually you just summarize and say there's no movement in those directions.  But the forces are there, and need to be there.

Please now return to your regular scheduled programming.
(PS: this is really in response to @damerell, there's zero wrong with Shadowmage's description.  I just thought it needed my brand of clarity, cos we're all egotistical in that way)

Edited by TiktaalikDreaming
Link to comment
Share on other sites

Hm, that makes it clearer; thanks both.

I think what actually needs to be done is to apply a hit-normal force (at the top of the suspension travel) which will produce a force corresponding to the suspension force. The suspension force is known and the hit-normal force is the suspension force divided by cos theta [1] (since cos theta <=1, this makes the hit-normal force greater than the suspension force). This should be capped at some small multiple of the suspension force to avoid comedy ensuing when ramming the wheels into walls head-on (which _does_ produce very large forces - the vehicle will want to bounce rigidly and/or crumple - but the combination of the interval between updates and the lack of modelling of the springiness perpendicular to the suspension axis could produce crazy-huge values in simulation.)

In Shadowmage's diagram above, then, Wheel 1's suspension compresses less (as you'd expect because gravity is acting on it less directly) but the suspension force is then divided by a smaller cos theta to produce the same upward force as on Wheel 2.

[1] As above, theta is the angle between the suspension axis and a line from the top of the suspension travel to the hit, possibly reduced in absolute magnitude to cut down on crazy results and allow for pneumatic tyres and other off-axis compression.

Edited by damerell
Link to comment
Share on other sites

On Tuesday, June 07, 2016 at 8:08 AM, damerell said:

Hm, that makes it clearer; thanks both.

I think what actually needs to be done is to apply a hit-normal force (at the top of the suspension travel) which will produce a force corresponding to the suspension force. The suspension force is known and the hit-normal force is the suspension force divided by cos theta [1] (since cos theta <=1, this makes the hit-normal force greater than the suspension force). This should be capped at some small multiple of the suspension force to avoid comedy ensuing when ramming the wheels into walls head-on (which _does_ produce very large forces - the vehicle will want to bounce rigidly and/or crumple - but the combination of the interval between updates and the lack of modelling of the springiness perpendicular to the suspension axis could produce crazy-huge values in simulation.)

In Shadowmage's diagram above, then, Wheel 1's suspension compresses less (as you'd expect because gravity is acting on it less directly) but the suspension force is then divided by a smaller cos theta to produce the same upward force as on Wheel 2.

[1] As above, theta is the angle between the suspension axis and a line from the top of the suspension travel to the hit, possibly reduced in absolute magnitude to cut down on crazy results and allow for pneumatic tyres and other off-axis compression.

 

Have implemented a spring-force multiplier based on the dot product of the hit.normal and suspension.axis; this only applies to the spring force though for suspension, friction still uses the pre-multiplied spring-force as its 'down-force'.  No clue if this is the 'correct' implementation, but it did seem to clean up some of the problems regarding suspension forces at non surface aligned angles.  Not quite done working with it though, still a few more things to try out, a few more issues to fix.

 

Got one thing implemented today that I've been banging my head against for a few weeks now -- bump stop / anti-punchthrough setup for the wheels.  Actually, @lo-fi is the one who implemented the original code for it (in his joint-based wheel model), I merely adapted the code and added it into the existing force-based framework.  It uses a Unity ConfigurableJoint to handle the constraints; this joint is already setup to be used by the wheel collider for static/sticky/adherent friction (not-yet-implemented), so being able to add a few lines of code to re-purpose it/extend it to fix the bump-stop problem was awesome.  Also nice to have Unity do some work for me/work with me, rather than fighting it as I've had to do for everything else.

Also working on implementing an alternate friction model, the popular Pacejka 'magic-formula'.  Initial results with a partial implementation look promising; though it needs some sort of force-limit to prevent overshoot/oscillations, especially with lateral forces.  But... more options are good (assuming I can get it working) :)

It is slowly coming together.  The bump-stop was one of the larger remaining pieces to get sorted out and working, so that is one big step closer.  Still a few pretty big features to tackle, but I've got a few more ideas to try out for those as well.

 

Link to comment
Share on other sites

15 hours ago, Shadowmage said:

@lo-fiHave implemented a spring-force multiplier based on the dot product of the hit.normal and suspension.axis; this only applies to the spring force though for suspension, friction still uses the pre-multiplied spring-force as its 'down-force'.  No clue if this is the 'correct' implementation, but it did seem to clean up some of the problems regarding suspension forces at non surface aligned angles.  Not quite done working with it though, still a few more things to try out, a few more issues to fix.

I think it's wrong but I also think conceivably I should work out how to build the thing myself and tinker with it. :-/

Link to comment
Share on other sites

51 minutes ago, Steel Dragon said:

is there a working version of this anywhere currently available to download? I really miss my treads

Not yet. Shadowmage is currently working on making a usable wheel collider. Your treads will come...soonTM.

Link to comment
Share on other sites

Indeed, 'Soon' :)

Figured out a couple of the larger remaining issues this week, so things are getting -very- close.  Still a few more problems to tackle; but it shouldn't be too much longer.  Probably a few more weeks at the pace things are progressing; though that is just the time to get the wheel-collider working.  Will require additional time after that to integrate it into various mods and write the PartModules to make it all work in KSP (stock, KF, SSTU, etc).

Got the 'combinatorial' friction sorted out yesterday; no more integration errors causing yaw on thrust input, while still allowing for powered slides and wheels 'breaking loose'.  Playing with it in Unity it is quite predictable and enjoyable to use; you get adequate warning that you are exceeding limits before spin outs, and 'flipping'/'rolling' is mostly dictated by the crafts center-of-mass (so sane designs will be hard to flip or roll).

Have a very basic implementation of Pacejka tire friction working as well; currently using constants for the input values, but will adjust those to use the existing friction curve parameters.  Really not much effective/noticeable difference between the two friction models so far, but options are usually not a bad thing.

Todays/this-weekends' problem to tackle is calculating the force-application axis' relative to the plane defined by the hit-normal.  Currently forces are applied according to the wheels' game-object orientation (plus steering); however, this is not quite correct.  Forces should be applied relative to the surface hit, with the lat/long axis running along the surface of that plane.  So I've got to find a way to 'project' the forward and sideways wheel' axis onto this plane, and use those projected vectors for the force-application axis.  This will also require re-transforming the wheel-local velocity onto this plane so that everything is working in the same coordinate system.  Mostly just a bunch of trig that I've got to remember/learn/implement.

Next up will be validating force limits vs current velocity, mostly as it relates to sitting on an inclined surface; this will see more wheel friction/traction available when on an incline (as determined by the per-tick velocity from gravity/external forces relative to hit-normal) to aid in proper stopping power when on hills and help reduce or eliminate 'creep'.  This functionality will be needed for the 'sticky friction' setup to minimize the velocity that it needs for triggering (so the transition from dynamic-to-static friction is not so jarring).

So... a few steps closer this week, some of them pretty large.  Will try to keep you all informed regarding the status of things; sadly there is still no way to provide an ETA as I do not/can not know how long the remaining problems will take to solve, nor can I anticipate any as-yet-unknown problems being found.

Link to comment
Share on other sites

Look in my code for vector projection onto a plane. I'll post an example when I'm in front of the pc. KFlookat certainly had that equation in, though. 

Link to comment
Share on other sites

1 minute ago, lo-fi said:

Look in my code for vector projection onto a plane. I'll post an example when I'm in front of the pc. KFlookat certainly had that equation in, though. 

Thanks, will do :)

Yeah, I though I had some code I could use from my own axis-locked look-at-constraits, but I was unable to adapt it last night (could have just been too late/tired to be coding though).

Cleaning up a few things in SSTU for an update/release this morning, but I'll likely be back to working on wheel code this afternoon/evening/tomorrow.

Link to comment
Share on other sites

For Future reference: Code to project a vector onto a plane, which is defined by its normal. A bit like casting a shadow of a line in 3D space onto a 2D surface, for those who want an easily visualised explanation.

	Vector3 projectedVector = <VectorToProject> - (<PlaneNormal>) * Vector3.Dot(<VectorToProject>, <PlaneNormal>);
	

Link to comment
Share on other sites

2 hours ago, lo-fi said:

For Future reference: Code to project a vector onto a plane, which is defined by its normal. A bit like casting a shadow of a line in 3D space onto a 2D surface, for those who want an easily visualised explanation.

 


	Vector3 projectedVector = <VectorToProject> - (<PlaneNormal>) * Vector3.Dot(<VectorToProject>, <PlaneNormal>);
	

 

Awesome; will give this a try a bit later today.  Exactly what I was looking for originally.

The method that I came up with over the weekend used the cross-function to determine the contact-patch sideways axis from the hit-normal and wheel-forward axis, and then a second cross function from the hit-normal and newly-calculated contact-patch sideways axis to derive the new 'forwards' axis, which was right in the majority of cases; but at some angles it was calculating the wrong axis slightly (not noticeable in normal use, but not really correct either).

Yeah pretty much I was looking for a way to see the vector as projected onto the plane and viewed from an orthographic view face-on to the plane defined by the normal; pretty much the 'shadow' as it were. 

 


Also going to have to take another look over the bump-stop functionality;  I thought I had something that was working, but upon further examination it.. well.. wasn't.

Apparently there is also a problem regarding using joints when it comes to KSP; anytime I break a joint that I created, KSP sees that as the part-joint breaking, and proceeds to decouple the part from the craft (even though the part joint did -not- break).  So might not be able to use any joint-based solutions as far as KSP is concerned; still investigating a bit.

I think both of these may be able to be solved through a custom constraint manager/solver setup; manually repositioning the rigidbody if/when it needs to be.  I'm not sure how well that is going to play with the rest of the Unity physics and joints setup; nor do I have any experience with implementing constraints or solvers... but it looks like I'll be doing some learning on all that this week :)

 

However, I must say, that the stuff that I do have working 'feels' very good while in use.  The traction and friction model seem quite appropriate, both for accuracy and for ease-of-use/understanding; there aren't really any 'surprises' when using it.  Give it too much power and you'll spin out, too much sideways friction and too high of a CG/COM and you'll roll/flip.  Even my test vehicle setup to simulate tracks works very pleasantly and without surprises (even without any special code for wheel-rpm-averaging).

For general 'wheeled vehicle' use it all functions quite well; at this point the two most notable missing features are sticky/adherent friction (nope, still haven't been able to solve that one), and the bump-stop mechanics, neither of which prevent general use.  The lack of sticky/adherent friction mostly means that there is some sliding/creeping while parked on hills, and the lack of bump stop means that wheels can (and will) over-compress when overloaded (possibly resulting in compressing so far that the suspension sweep no longer detects the contact surface and punch-through occurring).

I'll likely post up a 'testing' release of the stock-wheel conversions hopefully this-weekend; this will give a good test-case for the wheel-collider component and hopefully let the work on bug-finding commence while other mods' part-modules are being worked on and the wheel-collider finished up.

Link to comment
Share on other sites

4 hours ago, Shadowmage said:

Apparently there is also a problem regarding using joints when it comes to KSP; anytime I break a joint that I created, KSP sees that as the part-joint breaking, and proceeds to decouple the part from the craft (even though the part joint did -not- break).  So might not be able to use any joint-based solutions as far as KSP is concerned; still investigating a bit.

The solution is maybe not to break the joints. Simply set the connected body to null and set the linear and rotational joints to free. I've been though this with my trailer hitch module, so look that up in the dev branch of KF. It's a mess, but you'll get the idea. I reckon the sticky friction is solvable with the joint too - they were rock solid in my testing.

Glad the vector projection is what you're after. @ZodiusInfuser was kind enough to help me out with that.

https://github.com/KerbalFoundries/KF_plugin/blob/Dev/KF_plugin/KFCouplingHitch.cs

Edited by lo-fi
Link to comment
Share on other sites

Thanks for the link @lo-fi.

Sadly I have not been able to get joints to do what I want/need them to do (likely due to my inexperience with them and lack of actual documentation on them). 

I've been able to make them constrain to a certain distance for bump-stop purposes, but unable to make them constraint to a certain min distance; e.g. to only enforce the constraint if distance < limit (currently they force the suspension to max compression and keep it there, without allowing it to uncompress).  It seems like they are intended for more the opposite; to keep something from going beyond a certain max-distance.  But again, this is likely mostly due to my inexperience with them and lack of properly detailed documentation.


So, today, I've gone with a bit of an alternate route of investigation; bare un-solved constraints (un-solved in that they operate independently with no attempt made to find the 'most acceptable solution' for all of them).  This basically just operates on a if(position!=desiredPosition){ rigidbody.addForce(positionDelta, wheelPos, ForceMode.VelocityChange); }, which so far seems to work very well.  There is some slight jittering when the 'constraints' are activated in an unsolvable configuration, but the oscillations are minimal and should be able to be cleaned up by doing a solving pass over all of the constraints (which will require some sort of entire-vessel-aware setup, to solve for all of them on a vessel at a given time).  Have the bare constraints setup working so far for both bump-stop and sticky friction. 

For sticky friction it basically just checks the last-frame-movement of the rigidbody, and if below a certain threshold, set the 'sticky target pos' and activate the constraint, else recheck next tick.  When active it will 'force' the wheel back into the sticky-constraint desired position (which is not updated after being initially set); if the movement exceeds the movement threshold after the 'sticky' has been activated (through external forces, motor input, whatever), the constraint will be deactivated and re-checked next update tick.

Bump stop does pretty much the same thing, but checking position along the suspension sweep and intended to prevent over-compression of the suspension.  The main quirkiness that it currently exhibits is that I don't know how much 'downforce' to add to simulate the force used by the bump-stop (as the constraint is velocity based and not force based); so that when the bump-stop is engaged the maximum friction that can be applied is that specified by the spring at max compression as opposed to the actual sprung mass.  Not quite ideal... but none of the other 'bump-stop' methods has allowed me to derive a force either, so... not less ideal than the other methods either.

Is this the proper way to do it?  I don't know, but I'm going to investigate it a bit more as I was about at the end of my patience dealing with Unity joints.  With the results that I'm currently seeing... this seems to be a much easier to implement and likely a more controllable solution in the end.  After all... PhysX itself uses suspension and sticky-friction constraints, so it can't be that far off from a 'proper' solution :)

Now, as to implementing a solver... that is going to be a bit of fun learning and implementing.  My experience with constraints/solvers is, as of now, non-existent.  But several implementations exist that I can examine for solutions, so hopefully I'll be able to come up with something usable/workable.

 

Link to comment
Share on other sites

I'll have a look and see if I can plug my joint knowledge into your solution. I ought to write some documentation on joints, as I struggled myself. The Unity documents are rather poor, and most community references are either out of date, just as poor, or plain wrong. 

Link to comment
Share on other sites

21 hours ago, lo-fi said:

I'll have a look and see if I can plug my joint knowledge into your solution. I ought to write some documentation on joints, as I struggled myself. The Unity documents are rather poor, and most community references are either out of date, just as poor, or plain wrong. 

Indeed, if/when you have time to take a look, that would be great :)

Elsewise I'll keep working at it as I have been; there is still a bit more cleanup that can be done with the friction model code, a few more friction models/options to implement.  At this point most of the things needed for 'basic' functionality are in place and working very well, so I'll likely work on finishing up the stock replacement module and patches so that some in-KSP testing can be done on them.


Yeah, the Unity documentation is sorely lacking;  for example:


Linear Limit 	 Limit on the joint’s linear movement (ie, movement over distance rather than rotation), specified as a distance from the joint’s origin.
        Limit	The distance in world units from the origin to the limit.
   
   

Limit to what? Limit to minimum distance, limit to maximum distance? Limit to movement from the origin (and what is the joints origin... the anchor?)?  What does it do when set to '2'?  Why does it not allow negative values?  What is the valid range/domain for input?  What units does it use? What axis/axes does it work on?    (not really looking for answers to those, merely posting examples of why the documentation is so poor)

Should be like 2-3 paragraphs for each setting/option/function.  Instead they post a single sentence, mostly just expanding on the name of the option.  Gee, thanks Unity... I could tell it was some sort of a limit based on the name alone; you really didn't need to re-explain that in your 'description'; how about an actual description of its functionality with some example use-cases?

 

 

Link to comment
Share on other sites

I feel your pain. Agreed that each ought to have at least a paragraph or two - I've asked myself the very same questions. "Glib" doesn't even come close. I'd go so far as terse!

Link to comment
Share on other sites

Man, I'm champing at the bit for this to release for 1.1.x!  I had to reinstall 1.0.5 along with the latest version coz I really don't get into building much without this mod.  It's a great mod and the effort you guys put into it is appreciated here!

Link to comment
Share on other sites

On June 15, 2016 at 6:44 PM, lo-fi said:

I feel your pain. Agreed that each ought to have at least a paragraph or two - I've asked myself the very same questions. "Glib" doesn't even come close. I'd go so far as terse!

What percentage of the parts have you finished by now?

Link to comment
Share on other sites

Parts?! Surely you mean PartModules.
The actual wheel technology is not yet done.
Evidently we should be looking between "soon" and "soonTM" for the release of the plugin, and I expect the adaptation of the old parts to go as smoothly as something of this sort can go.

Link to comment
Share on other sites

I am actually about to make a backup external copy of KSP at 1.0.5 just so I can do more rover fun from mising this, even though I hate the fact I won't be able to go super crazy with mods on that version because of no proper 64 bit tricks >.< But I miss these wheels so much, but thats becasuse I love rovers, and messing with these, And it really is "Boring" to try to do rover contracts from contract configurator, without ways to make awesome rovers XD

Link to comment
Share on other sites

Yeah, sorry it's taking a while. ShadowMage is writing a brand new wheel simulation model to fix the "odd" behavior of stock parts, and to allow the more advanced KF parts to function as they should. Sadly, it's not easy. Once it's done, it will be AWESOME, though. Better than even the previous versions. Thanks to all for hanging in there and patiently encouraging. We're just as excited as you!

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...