Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring constraint with ammo driver not working #171

Open
kfarr opened this issue Oct 5, 2020 · 8 comments
Open

Spring constraint with ammo driver not working #171

kfarr opened this issue Oct 5, 2020 · 8 comments
Assignees

Comments

@kfarr
Copy link

kfarr commented Oct 5, 2020

Issue: wish to use a spring constraint with ammo driver

Demo - Working in cannon:
https://aframe-ammo-spring.glitch.me/spring-cannon.html

Demo - Not working in Ammo (after translating syntax):
https://aframe-ammo-spring.glitch.me/spring-ammo.html

Possible causes:

You can see the actual C++ bullet code here:
https://github.com/kripken/ammo.js/blob/00506d296df957d80bd192d27ff8a3ef2aa9f176/bullet/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp#L49

It seems that calling "enableSpring" is required but isn't called in the ammo-constraint component for the spring type.

I tried adding this myself, but constraint.enableSpring() doesn't appear to work (or change the behavior of the scene). I also tried enabling 6 times, one for each axis, per the above C++ source code and this bullet documentation:

  constraint.enableSpring(0, true)
  constraint.enableSpring(1, true)
  constraint.enableSpring(2, true)
  constraint.enableSpring(3, true)
  constraint.enableSpring(4, true)
  constraint.enableSpring(5, true)

Also the other parameters of the spring should be included but I could not verify the following code works:

constraint.setStiffness(data.stiffness) 
constraint.setDamping(data.damping)
constraint.setEquilibriumPoint(data.restLength)

Also those component properties (stiffness, damping and restLength) should be added to the ammo-constraint schema.

Debugging possible issues:

@Galadirith
Copy link
Contributor

@kfarr Thanks so much for compiling all your research on this. Very happy to take a look into this, @Micah1 @MignonBelongie please could I ask one of you to assign this to me 😊 I'll update with any of my findings as soon as I have them, and hopefully a resolution very shortly.

@n5ro
Copy link
Owner

n5ro commented Oct 5, 2020

@kfarr should the green boxes ammo body be type dynamic? I don't see a type specified, like this:

"ammo-body="type: static" ammo-shape>
<a-box id="fourspring"
position="5 1 -3"
color="green"
ammo-body="type: dynamic" ammo-shape"

@kfarr
Copy link
Author

kfarr commented Oct 5, 2020

The intention is for those bodies to be dynamic unless specified.

I believe dynamic is default value for ammo-body component type attribute:
https://github.com/n5ro/aframe-physics-system/blob/master/src/components/body/ammo-body.js#L59

@Galadirith
Copy link
Contributor

Galadirith commented Oct 6, 2020

@kfarr thanks so much for your patience on this issue 😊 So I have a working example for spring physics with the Ammo driver. I remixed your glitch example and simplified the scene https://aframe-ammo-spring-galadirith.glitch.me/

first-ammo-spring trim

It was really useful research that you did, and as you highlighted, the spring physics for the Ammo drive simply wasn't implemented. To get this very specific example working I replaced

//TODO: enableSpring, setStiffness and setDamping

with

        constraint.enableSpring(1, true)
        constraint.setStiffness(1, 25.0)
        constraint.setDamping(1, 0.02)
        const upper = new Ammo.btVector3(0.0, 1000.0, 0.0);
        const lower = new Ammo.btVector3(0.0, -1000.0, 0.0);
        constraint.setLinearUpperLimit(upper);
        constraint.setLinearLowerLimit(lower)
        Ammo.destroy(upper);
        Ammo.destroy(lower);

So this is all very specific to this case, but we can generalise this to use the components properties, and also expose the properties that are not part of the schema right now.

Important things were adding in the limits to make sure the simulation didn't hit any bounds. I couldn't find any info on the defaults of these limits. It's possible there are no defaults and they always need to be set.

The units that Ammo uses seem a little weird to me. There is an issue on this in the Bullet repo bulletphysics/bullet3#345. I say weird, I haven't dealt with spring physics much, so maybe this is normal 😊

There is another peculiarity with the demo, the abrupt stop at the end. Ammo is configured to stop simulating when velocities drop below a certain threshold. I have some snippets somewhere that allow you to reconfigure the simulation, so that you don't get these abrupt stops in the simulation. I can't find these right now, but I'll continue looking tomorrow and post back when I have them 😊

So I think this get's us most of the way, actually getting a spring to work with the Ammo driver 🎉 Now it's a matter of coding this up so it can be generally used in aframe-physics-system. I'll work on that next, and hopefully have a PR shortly.

@kfarr
Copy link
Author

kfarr commented Oct 6, 2020

Great progress! Looking very good! Yes this looks like it would be possible to generalize to expose in the component as attributes.

Perhaps the sleeping issue can be solved by modifying activation state setting on the dynamic body?
https://github.com/n5ro/aframe-physics-system/blob/master/AmmoDriver.md#activation-states

Also I noticed in this comment that we might want to use spring2 since the "the older variant will be deprecated"

@Galadirith
Copy link
Contributor

Galadirith commented Oct 6, 2020

@kfarr great find, I should have checked the Ammo driver docs, it's the linearSleepingThreshold that is the important bit, thanks 😊 set that to something low and you prevent the abrupt stop of the simulation.

Thanks so much for pointing out that depreciation comment, seems like that would be a good thing to try to migrate towards. For the MozillaReality build it looks like btGeneric6DofSpring2Constraint is not exposed, maybe that is something that we can recompile for. I'll look into that.

There is still some weird behaviour in the spring. Setting the linearSleepingThreshold to be low enough that it doesn't halt the simulation, the dynamic body never settles. It's possible this is related to one of the systems settings and so its just a matter of calibrating to the right ones.

@Galadirith
Copy link
Contributor

Galadirith commented Oct 9, 2020

@kfarr I've updated the build for ammo.js to now expose the btGeneric6DofSpring2Constraint interface, and expose the setEquilibriumPoint methods. From the source it looked like that setEquilibriumPoint was already exposed, but maybe the build was not up to date as I couldn't see it in the MozillaReality build. This build also is updated to use the Bullet 2.89 release. I think this is likely to be the last 2.X release of Bullet so it's a reasonable update. I think updating to the 3.X series will be quite a bit more involved as many of the interfaces have changed, and I don't think it's really necessary for us, but it's something that we might like to think about down the road 😊

The spring physics now look much better. I'm not sure if btGeneric6DofSpringConstraint was bugged or it was being used incorrectly, I really don't know, but btGeneric6DofSpring2Constraint looks great, here's a render from the current state of the Glitch https://aframe-ammo-spring-galadirith.glitch.me/

second-ammo-spring

If it's useful I'm currently using the following modification to the CONSTRAINT.SPRING case

        window.constraint = constraint = new Ammo.btGeneric6DofSpring2Constraint(body, targetBody, bodyTransform, targetTransform, 0);
        for (var i in [0,1,2,3,4,5]) {
          constraint.enableSpring(i, true);
          constraint.setStiffness(i, 10.0);
          constraint.setDamping(i, 0.75);
        }
        const upper = new Ammo.btVector3(-1, -1, -1);
        const lower = new Ammo.btVector3(1, 1, 1);
        constraint.setLinearUpperLimit(upper);
        constraint.setLinearLowerLimit(lower);
        constraint.setEquilibriumPoint(1, 0.0);
        Ammo.destroy(upper);
        Ammo.destroy(lower);

I'm much happier now with these results, and now I feel comfortable implementing a general interface as it appears that btGeneric6DofSpring2Constraint behaves properly. I probably will not be able to get to this until mid next week, really sorry about that. Of course if you don't want to wait please do feel free to have a go at implementing it yourself 😊

I'll also attach the ammo.js build. I'll have to figure out the best way to distribute the source and build for this. Perhaps just opening a PR to kripken/ammo.js or MozillaReality/ammo.js but there are enough changes that may it's useful for us to just maintain our own fork. Especially if there is a list of interfaces that we would like exposed that were not exposed in either the kripken or MozillaReality builds, we can now do that ourselves. But I'll figure that out next week 😊

Attachments

@kfarr
Copy link
Author

kfarr commented Oct 9, 2020

This is great! Makes sense that another version of bullet was required from my research earlier and to stick with the most recent 2.x release, thank you for taking on that effort.

I think it would probably be most appropriate for this repo to host the ammo.js build. Could be in /dist/ (similar to the idea of having the js build in there too) or /lib/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants