Hi gang. I got a question posted in Q&A about calculating the angle on a CannonJS hinge joint, which remains open to more ideas. I thank ya. (I’m not totally against a little real-mesh disk-like protractor, sitting adjacent to the hinge joint, demarcated in 30 degree increments… with an indicator needle.)
Anyway, I didn’t want to contaminate that other Q&A thread… with my incessant yapping, so I came here and started a thread. Anyway, I have learned some things about motorizing CannonJS hinge joints, and I wanted to share those, and invite discussion.
As some of you already know, I am working on a project to retract/deploy 4 landing-gear legs… to/from an orbiter/lunar-lander. It is important in this sim… that the landing gear is physics-active for contact with ground, whether fully-deployed/retracted, or not. (NO removing physics during animations). “Coming-in too fast” is an important factor in this sim… and partially-deployed landing gear… is part of that fun (better crashes).
Now let’s get juicy. BJS physics impostors have a setMotor function… making it easy to activate a motor on a hinge joint. BUT… that motor… suffers from some problems.
It back-slides/back-spins after being turned-off, no matter its speed or maxforce settings. It takes very little leg mass and scene gravity… to make the landing-gear leg… start “sinking” from its folded-up (retracted) position.
It drastically changes speeds… because of leg mass and gravity. When the leg is deploying (unfolding), the motor runs faster. When retracting, the motor runs slower. I’d rather have my lander… have consistent 22 seconds to deploy/retract landing gear, no matter the gravity, no matter the leg mass, no matter the orbiter orientation (tilt).
So, I went looking for a different “motor”… and I found it… with leg1.physicsImpostor.setAngularVelocity(). But… IT TOO… had backslide problems. I discovered that you couldn’t set it JUST ONCE, and expect the gear to nicely fold/unfold at a constant speed. Instead… it needed to be done… constantly, by putting it within an onBeforeRenderObervable eventHandler (ie. in the render loop).
Early tests looked fine, but without being able to monitor hinge angle (yet) (see my other forum thread)… I needed another way to REMOVE the continuous leg1.setAngularVelocity… from the render loop… at the PERFECT isFolded stopping angle/point.
SO… I made some “sensors”… tiny, yellow non-physics objects… that could “watch-for” intersectsMesh(leg1). Micro-switches! The intersectsMesh system worked PERFECT for this. These little yellow sensors are parented to the lander greenbox, and can be set invisible.
Wingnut runs the “Continuous Angular Velocity Engine” (CAVE)… and when the leg touches the yellow non-physics sensor, it REMOVES the CAVE from the render loop (removes the CAVE from beforeRenderObserver).
When I did that… the leg went limp… instantly dropped from folded position, and swung back and forth like a pendulum. “Oh no! Gravity and mass are still nearby.” How was I going to “latch” the landing leg in folded position… after I turned-off the CAV engine?
(think think think. latch = umm… uhh… lock) LOCK! LOCKJOINT!!! YAY!
And that’s what I did. https://playground.babylonjs.com/#7YV8E0#78
Two yellow non-physics sensors for intersectsMesh with leg1, one for retracted, one for deployed. The moment a trigger “throws”, a previously-placed lockJoint between greenbox and leg1 NEAR the sensor… is enabled. The yellow sensors themselves are NOT physics objects, so they cannot be attached to a lockJoint (a latch). Maybe later. To “unlatch”… the lockJoint/latch is disabled.
As you can see, the leg still deploys substantially faster than it retracts… due to gravity and legMass, but it is still far more consistent-speed than CannonJS native hinge motors. The maxForce for Cannon hinges is not really very powerful, no matter how large. (esp true with slow motor speeds, like I need)
Also, you can see some “jiggle” at the point of “deployed”… at sensor2, near latch2. (rem… no yellow sensor is a latch-to point for the lockJoints.) I’m always latching leg1 to greenbox, no matter which sensor triggers.
Speaking of which… line 146… erf. I spent HOURS hand-tweaking those Y and Z values. Those are the LOCALspace coordinates… on blue leg1… where the “latch” (isDeployed lock) attaches. I was trying to remove the jiggle that happens when leg finishes deploying (when latch2 lockJoint enables). HARD!!! SO many 45 degree angles involved!
Anyway, watch the CAVE retract/deploy the landing gear leg… have a good time. Yes, when the orbiter has a severe tilt, things start a little rough, but eventually recover.
I’m working-on a re-visit of the setMotor version, still using the “locking latches”… here, but it’s still a little broken.
Ok, that’s the story, so far, as best I understand it. C’mon along for the ride… steal ALL this code… call it yours… have a good time. Try not to injure your children or pets with it. Cya.
Extra Show’n’Tell stuff: The “lander” might eventually look like this: For thruster/auto-pilot testing, with particles… this. Advanced daddy-long-legs landing gear work… here (using spring restLength deploy/retract system)(elastic puppet strings). Someday, it will all come-together (I hope).