Joint stops not working? setPosition[Maximum|Minimum]()

I have a program that creates a ball joint with 3 rotational axis, for each axis I"m setting the min and max position (guessing this is for rotation as well, according to the ODE doc), but the joint has a full range of motion, not limited like it should. Also calling getPosition() and getVelocity() on an axis returns NaN. Here's my code:

package test;

import java.util.logging.Level;

import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.util.LoggingSystem;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.Joint;
import com.jmex.physics.JointAxis;
import com.jmex.physics.RotationalJointAxis;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.util.SimplePhysicsGame;

public class BasicTest extends SimplePhysicsGame {
   public static void main( String[] args ) {
      LoggingSystem.getLogger().setLevel( Level.WARNING );
      SimplePhysicsGame game = new BasicTest();
      game.start();
   }

   Joint shoulder_joint;

   protected void simpleInitGame() {

      // Create the floor
      final StaticPhysicsNode floor_node = getPhysicsSpace().createStaticNode();
      final Box floor = new Box( "box", new Vector3f( 0, 0, 0 ), 10, 1f, 10 );
      floor.getLocalTranslation().set( 0, -2, 0 );
      floor.updateModelBound();
      floor_node.attachChild( floor );
      floor_node.generatePhysicsGeometry();
      rootNode.attachChild( floor_node );

      // Create the base
      final DynamicPhysicsNode arm_base_node = getPhysicsSpace()
            .createDynamicNode();
      final Box arm_base = new Box( "visual sphere", new Vector3f( 0, 0, 0 ), 2,
            2, 2 );
      arm_base.updateModelBound();
      arm_base_node.attachChild( arm_base );
      arm_base_node.getLocalTranslation().set( 0, 1, 0 );
      arm_base_node.generatePhysicsGeometry();
      arm_base_node.computeMass();

      rootNode.attachChild( arm_base_node );

      // Create the shoulder
      final DynamicPhysicsNode shoulder_node = getPhysicsSpace()
            .createDynamicNode();
      final Sphere shoulder = new Sphere( "visual sphere 2", 9, 9, 2 );
      shoulder.updateModelBound();
      shoulder_node.attachChild( shoulder );
      shoulder_node.getLocalTranslation().set( 0, 6, 0 );
      shoulder_node.generatePhysicsGeometry();
      shoulder_node.computeMass();

      rootNode.attachChild( shoulder_node );

      showPhysics = true;

      // Create the joint
      shoulder_joint = getPhysicsSpace().createJoint();
      
      final RotationalJointAxis axis1 = shoulder_joint.createRotationalAxis();
      axis1.setDirection( new Vector3f( 0, 1, 0 ) );
      axis1.setPositionMaximum( (float) ( Math.PI * .25 ) );
      axis1.setPositionMinimum( (float) ( -Math.PI * .25 ) );
      
      final RotationalJointAxis axis2 = shoulder_joint.createRotationalAxis();
      axis2.setDirection( new Vector3f( 0, 1, 0 ) );
      axis2.setPositionMaximum( (float) ( Math.PI * .25 ) );
      axis2.setPositionMinimum( (float) ( -Math.PI * .25 ) );
      
      final RotationalJointAxis axis3 = shoulder_joint.createRotationalAxis();
      axis3.setDirection( new Vector3f( 0, 0, 1 ) );
      axis3.setPositionMaximum( (float) ( Math.PI * .25 ) );
      axis3.setPositionMinimum( (float) ( -Math.PI * .25 ) );

      // Attach it
      shoulder_joint.attach( arm_base_node, shoulder_node );

      // Give it some torque to make it move
      shoulder_node.addTorque( new Vector3f( 1000, 1000, 1000 ) );      
   }

   @Override
   public void simpleUpdate() {
      int i = 0;
      for ( JointAxis ja : shoulder_joint.getAxes() ) {
         System.out.println( ( i++ ) + ":p=" + ja.getPosition() + ",v=" + ja.getVelocity() + "[max=" + ja.getPositionMaximum() +",min=" + ja.getPositionMinimum() + "]");
      }
   }
}



If you run the code you can see the ball hinge over till it hits the ground.

Min and max position (or stops) are not supported by ball joints (3 rotational axes) in ODE. In ODE you'd use an angular motor for this. But angular motors are not implemented in jME Physics 2, sorry. So the implementation should currently complain that this is not possible (but it does not, sorry again).

Is there some way to fake this? I was thinking about adding 3 separate joints, each with their own axis, and the using the joints to attach 2 actual elements that I care about with tiny invisible nodes in between…



So you'd have:



|ActualNode1| <-(jointx)->|tinyinvisiblenode1| <-(jointy)->|tinyinvisiblenode2| <-(jointz)->|ActualNode2|



I haven't tried it so I don't know if it would give realistic motion or not…



Someday I hope to understand the engine well enough to actually fix issues like this, but that day is not yet here.

Yes, that could work. It's quite expensive but should work (never tried exactly that, but similar things). You can make the nodes 'invisible' if you do not attach any geometries (neither visual nor physical).



Changing that in ODE would mean to introduce a new joint (in C++).