Applying torque to joined actors. Author Message
georgatos7
Member

 Post: #1 Applying torque to joined actors. I have gone through the tutorials on how to use joints and on how to apply forces, torque etc on actors. I have made a test hinge joint on two parts and i have applied torques to their actors but i haven't found a way to apply torque in relation to the joint and the two joined actors. Trying to apply torque on each actor like it is a standalone entity is going to have a very different simulation outcome than applying it based on the joint and in relation to the two joined actors. Is this possible in the current physX implementation? (This post was last modified: 03-01-2015 10:48 AM by georgatos7.)
02-25-2015 06:54 PM
Member

 Post: #2 RE: Applying torque to joined actors. Not too sure of your particular setup, but here are a few pointers you might like to try, if you have not done so already. 1) If the joint structure is to be in a fixed position then make the fixed actor to be static and the hinged actor to be dynamic 2) If the joint structure is to be moveable (eg a moveable platform) then make the moveable actor to be kinematic and the hinged actor to be dynamic Note that a kinematic actor can only be moved via 'kinematicMoveTo()' and not via applied force like a dynamic actor. 3) If both actors are dynamic then try making the one actor significantly heavier than the other. 4) Fix the one actor to the floor via a fixed joint. (use NULL for the floor actor pointer) When one body is significantly heavier than the other, make the lighter body the second actor in the joint. Similarly, when one of the objects is static or kinematic (or the actor pointer is NULL) make the dynamic body the second actor.
02-25-2015 10:55 PM
Esenthel

 Post: #3 RE: Applying torque to joined actors. So what you want is a method that applies 'torque' at specified position and not the center of mass if I understand it right? In that case I think that would be a combination of angular velocity + linear velocity. For example if you're applying a 'force' at a specified position then PhysX does something like this: Code: PX_INLINE void addForceAtPosInternal(PxRigidBody& body, const PxVec3& force, const PxVec3& pos, PxForceMode::Enum mode, bool wakeup) {     if(mode == PxForceMode::eACCELERATION || mode == PxForceMode::eVELOCITY_CHANGE)     {         //ESENTHEL Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRigidBodyExt::addForce methods do not support eACCELERATION or eVELOCITY_CHANGE modes");         return;     }     const PxTransform globalPose = body.getGlobalPose();     const PxVec3 centerOfMass = globalPose.transform(body.getCMassLocalPose().p);     const PxVec3 torque = (pos - centerOfMass).cross(force);     body.addForce(force, mode, wakeup);     body.addTorque(torque, mode, wakeup); } Applies both linear force and torque. So I think doing with torque at custom position would require applying both torque and linear force. But at the top of my head I don't know the formula for the force/torque vectors/intensities.
02-25-2015 11:06 PM
Esenthel

Default: 0.0     @see PxRevoluteFlags::eDRIVE_FREESPIN     */     virtual void            setDriveVelocity(PxReal velocity)            = 0;     /**     \brief gets the target velocity for the drive model.     \return the drive target velocity     @see setDriveVelocity()     */     virtual PxReal            getDriveVelocity()            const            = 0;     /**     \brief sets the maximum torque the drive can exert.          Setting this to a very large value if velTarget is also very large may cause unexpected results.     The value set here may be used either as an impulse limit or a force limit, depending on the flag PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES     Range: [0, PX_MAX_F32)
Default: PX_MAX_F32     @see setDriveVelocity()     */     virtual void            setDriveForceLimit(PxReal limit)            = 0;     /**     \brief gets the maximum torque the drive can exert.          \return the torque limit     @see setDriveVelocity()     */     virtual PxReal            getDriveForceLimit()        const            = 0;     /**     \brief sets the gear ratio for the drive.          When setting up the drive constraint, the velocity of the first actor is scaled by this value, and its response to drive torque is scaled down.     So if the drive target velocity is zero, the second actor will be driven to the velocity of the first scaled by the gear ratio     Range: [0, PX_MAX_F32)
Default: 1.0     \param[in] ratio the drive gear ratio     @see getDriveGearRatio()     */     virtual void            setDriveGearRatio(PxReal ratio)            = 0;     /**     \brief gets the gear ratio.          \return the drive gear ratio     @see setDriveGearRatio()     */     virtual PxReal            getDriveGearRatio()        const            = 0;     /**     \brief sets the flags specific to the Revolute Joint.     Default PxRevoluteJointFlags(0)     \param[in] flags The joint flags.     @see PxRevoluteJointFlag setFlag() getFlags()     */     virtual void                    setRevoluteJointFlags(PxRevoluteJointFlags flags) = 0;     /**     \brief sets a single flag specific to a Revolute Joint.     \param[in] flag The flag to set or clear.     \param[in] value the value to which to set the flag     @see PxRevoluteJointFlag, getFlags() setFlags()     */     virtual void                    setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool value) = 0;     /**     \brief gets the flags specific to the Revolute Joint.     \return the joint flags     @see PxRevoluteJoint::flags, PxRevoluteJointFlag setFlag() setFlags()     */     virtual PxRevoluteJointFlags    getRevoluteJointFlags(void)                    const    = 0;     /**     \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION     is set for the joint.     If the joint separates by more than this distance along its locked degrees of freedom, the solver     will move the bodies to close the distance.     Setting a very small tolerance may result in simulation jitter or other artifacts.     Sometimes it is not possible to project (for example when the joints form a cycle).     Range: [0, PX_MAX_F32)
Default: 1e10f     \param[in] tolerance the linear tolerance threshold     @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION     */     virtual void                setProjectionLinearTolerance(PxReal tolerance)                    = 0;     /**     \brief Get the linear tolerance threshold for projection.     \return the linear tolerance threshold     @see setProjectionLinearTolerance()     */     virtual PxReal                getProjectionLinearTolerance()            const                    = 0;     /**     \brief Set the angular tolerance threshold for projection. Projection is enabled if     PxConstraintFlag::ePROJECTION is set for the joint.     If the joint deviates by more than this angle around its locked angular degrees of freedom,     the solver will move the bodies to close the angle.          Setting a very small tolerance may result in simulation jitter or other artifacts.     Sometimes it is not possible to project (for example when the joints form a cycle).     Range: [0,Pi]
Default: Pi     \param[in] tolerance the angular tolerance threshold in radians     @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION     */     virtual void                setProjectionAngularTolerance(PxReal tolerance)                    = 0;     /**     \brief gets the angular tolerance threshold for projection.     \return the angular tolerance threshold in radians     @see setProjectionAngularTolerance()     */     virtual PxReal                getProjectionAngularTolerance()            const                    = 0;     /**     \brief Returns string name of PxRevoluteJoint, used for serialization     */     virtual    const char*            getConcreteTypeName() const { return "PxRevoluteJoint"; } protected:     //serialization     /**     \brief Constructor     */     PX_INLINE                    PxRevoluteJoint(PxType concreteType, PxBaseFlags baseFlags) : PxJoint(concreteType, baseFlags) {}     /**     \brief Deserialization constructor     */     PX_INLINE                    PxRevoluteJoint(PxBaseFlags baseFlags) : PxJoint(baseFlags) {}     /**     \brief Returns whether a given type name matches with the type of this instance     */     virtual    bool                isKindOf(const char* name) const { return !strcmp("PxRevoluteJoint", name) || PxJoint::isKindOf(name); }          //~serialization }; #ifndef PX_DOXYGEN } // namespace physx #endif /** @} */ #endif these methods are not currently exposed by the engine. If this is what is needed then I could expose API for that, please be specific which methods would you need.
02-25-2015 11:10 PM
georgatos7
Member

 Post: #5 RE: Applying torque to joined actors. Yeah i will take a close look into those Esenthel and i'll let you know, thanks a lot. Also thanks for the suggestions 3dRaddict but from a first look its the drive/motor functionality that i need but ill be more specific. (This post was last modified: 02-26-2015 02:05 AM by georgatos7.)
02-25-2015 11:38 PM
Member

 Post: #6 RE: Applying torque to joined actors. I agree... the joint drive/motor functionality would certainly be an added benefit. Its something I've been used to in other PhysX based 3D engines, and its missing from Esenthel. (hence the workaround of adding torque to revolute jointed actors)
02-26-2015 06:08 AM
georgatos7
Member

 Post: #7 RE: Applying torque to joined actors. Hey Esenthel well the functionality that i was refering to is the drive/motor of the revolute joint which seems to be controlled by the methods below. -setDriveVelocity(PxReal velocity) -setDriveForceLimit(PxReal limit) -setLimit(const PxJointAngularLimitPair& limits) And probably to customize on the behavior you would need to change the "Limit", "Drive" and "Freespin" flags. -setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool value) For useful joint input. -getAngle() -getVelocity() Now i don't know if this is too hard to implement at this stage. (This post was last modified: 02-28-2015 01:51 PM by georgatos7.)
02-26-2015 03:35 PM
Esenthel

 Post: #8 RE: Applying torque to joined actors. This doesn't sound that complex, so I'll try to implement this soon!
03-05-2015 10:19 PM
georgatos7
Member

 Post: #9 RE: Applying torque to joined actors. Awesome, thanks a lot. I bet it's gonna be a nice addition to the existing joint functionality.
03-05-2015 10:30 PM
Esenthel

 Post: #10 RE: Applying torque to joined actors. Just added following methods to the Joint class in the GitHub source: Code: // hinge joint specific (following methods are supported only in PhysX 3)     Flt  hingeAngle          ()C; // get joint angle in range (-PI, PI]     Flt  hingeVel            ()C; // get joint velocity    Bool hingeDriveEnabled   ()C;   Joint& hingeDriveEnabled   (Bool on   ); // get/set if drive is enabled    Bool hingeDriveFreeSpin  ()C;   Joint& hingeDriveFreeSpin  (Bool on   ); // get/set if the existing velocity is beyond the drive velocity, do not add force    Flt  hingeDriveVel       ()C;   Joint& hingeDriveVel       (Flt  vel  ); // get/set drive target velocity, 0..Inf, default=0    Flt  hingeDriveForceLimit()C;   Joint& hingeDriveForceLimit(Flt  limit); // get/set the maximum torque the drive can exert, setting this to a very large value if 'hingeDriveVel' is also very large may cause unexpected results, 0..Inf, default=Inf    Flt  hingeDriveGearRatio ()C;   Joint& hingeDriveGearRatio (Flt  ratio); // get/set the gear ratio for the drive, when setting up the drive constraint, the velocity of the first actor is scaled by this value, and its response to drive torque is scaled down. So if the drive target velocity is zero, the second actor will be driven to the velocity of the first scaled by the gear ratio. 0..Inf, default=1
03-09-2015 12:28 AM
georgatos7
Member

 Post: #11 RE: Applying torque to joined actors. Awesome.
03-09-2015 01:44 AM