Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved How to implement a Motor of HingeJoint in dots physics?

Discussion in 'Physics for ECS' started by BobFlame, Feb 22, 2021.

  1. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    I'm making a physics based game, and I need a feature for configurable motor of hinge joint. (just like physx)

    However in dots physics, I see no API related to applying force on a joint. So I need to implement myself, directly modify connected rigidbody's linear and angular velocity, as physics samples showed.

    My question is: Given a fixed output torque of rotor (motor of hinge joint), it will generate both a linear velocity change and an angular velocity change on connected body. How should torque distribute among different part of effects? If they are treated separatedly, the hinge joint constrain rotate motion with [v = w x r] may be confilicted. If apply to linear velocity only, and deduct angular velocity by [v = w x r], it will be unreasonalbe when hinge axis on the pricinple axis of connected body, because r is 0.

    Could anyone help? Thanks.
     
  2. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    I think the right answer should be: create a new inertia matrix according to hinge joint's connected point, take connected body's inertia as child. The motor apply torque on the new converted inertia matrix, get new angular velocity hence the linear velocity.
     
  3. MaxAbernethy

    MaxAbernethy

    Joined:
    Mar 16, 2019
    Posts:
    53
    Hi, I think you have the right idea. You can calculate the new inertia matrix easily using the parallel axis theorem, https://en.wikipedia.org/wiki/Parallel_axis_theorem

    I'll note that DOTS and Havok physics use a simpler approach, which is to create separate constraints for the angular and linear velocities and then solve both. That way the solver can use the same inertia matrix for all constraints. With an iterative solver it is less accurate than the method you're describing, but it is often accurate enough.
     
  4. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    Thanks for reply. I'm not quite understand, is there any constraints API I can use to create motor? I would like to trade some accuration for performance. Could you explain more?
     
  5. MaxAbernethy

    MaxAbernethy

    Joined:
    Mar 16, 2019
    Posts:
    53
    There is no motor API in DOTS physics. There is a hinge joint, but it is broken into two pieces: 1) an angular constraint that constrains the bodies' relative orientation by applying torques at the center of mass, and 2) a positional constraint that keeps the hinge's pivot point on each body lined up.

    DOTS physics solves with Gauss Seidel, which means that it solves constraint (1), then solves constraint (2), then goes back and solves (1) again, then (2) again, etc. for some number of iterations. If the hinge axis does not pass through the center of mass, then when constraint (1) is solved, constraint (2) will be violated, because changing the bodies' orientations moves the pivots. Then when constraint (2) is solved, constraint (1) will be violated again, because moving the bodies' pivots changes the bodies' orientations. But if we repeat this process enough, it can converge to a solution for both constraints that is good enough.

    If you wanted to add an angular motor to the DOTS physics hinge constraint, you could do it in AngularLimit2DJacobian.cs. It is only 100 lines of code, not too much to sort through. It calculates futureAngle, which is what the relative angle of the bodies about the hinge axis will be at the end of the step without intervention. If your motor is driving towards a particular angle, you could calculate the torque required to reach that angle from futureAngle, then limit the torque to your motor's maximum.

    You could also just apply your motor's torque before the physics step. This will be less accurate for simulating situations where something is resisting the motor, but it's an easy place to start.
     
    Iron-Warrior and BobFlame like this.
  6. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    Thank you so much. I will look into it.
     
  7. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    After three days attempting, I finally end up with a method that simulating rotor's scalar velocity and angle, and setting connected body's position and rotation directly. It still have a inertia scalar. There are some reasons for this.
    1, It's simple to implement.
    2, It save performance.
    3, When connected body's mass is comparable to base body. It can avoid dragging base body (although it is more realistic, but maybe undesirable)
    4, Connected body remains dynamic, not kinematic. So collision could deliver force to base body through connected body.
    Here comes another question, in physx, setting position and rotation could break broadphase AABB detection, so could be a performance hit. Is this a problem to DOTS physics, how much impact will it cause?
     
    Last edited: Feb 26, 2021
  8. MaxAbernethy

    MaxAbernethy

    Joined:
    Mar 16, 2019
    Posts:
    53
    Hi, in DOTS physics I don't think it will cost much to set position and rotation, although someone might need to correct me there. In Havok physics it's more expensive, because Havok uses collisions caches that have to be thrown out when the body transform is changed.

    But either way, I would recommend setting velocity instead of position. By setting position you could tunnel through a wall or otherwise put the rest of the engine in a state that is more difficult to recover from.
     
    petarmHavok likes this.
  9. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    The main usage of this rotor is for turret, It have limited position range. So the posibility of tunnelling through wall may could be accepted.
     
  10. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    After doing further work in project, I found the method manipulating position cause so obvious a problem: If you are setting position and rotation each frame, you are not using physics engine at all. So at last I still implement a velocity based rotor (motor on hinge joint).

    Here is my method:
    1, Calculate angle from current relative position, compute velocity with angle in previous frame.
    2, Using a PID to get correction from current angle and target.
    3, Compute torque needed to achieve that correction, and clamp with max torque available.
    4, Here comes the crucial, how to apply torque to two connected body. My Approach is decomposing torque into dual impulse with reversed directions and oppsitie positions. Add dual impulses on body A, then reverse them (reacting force) and add to body B. (actually, the linear velocity is not involved at all.)

    The implementation is tested pretty well, so far so good.
     
    Last edited: Mar 5, 2021
  11. Extrys

    Extrys

    Joined:
    Oct 25, 2017
    Posts:
    343
    Please, could you explain what do you mean by PID?
     
  12. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    I mean a PID controller. https://en.wikipedia.org/wiki/PID_controller
    If you are setting angular velocity directly, you could use angle error as input, and use correction as velocity.
    But hence I am setting torque, I need a second order PID, input angle error, and ouput angular acceleration.
    This is different from normal PID controller.
     
    Extrys likes this.
  13. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    Last edited: Mar 24, 2021