How can I limit a hinge2 joint to a single direction?

101 views
Skip to first unread message

Vaillancourt

unread,
Jun 16, 2021, 9:15:39 AM6/16/21
to ode-users
Hello all!

I'm in the process of creating a vehicle. For this, I'm using four Hinge-2 joints. I would like to allow the wheels (axis 2) to drive only in one direction, so allow them to drive forward, but not backward.

This should allow the vehicle to drive up a grade,  and allow it to remain still when the user does not give the wheels power (e.g. when they release the throttle pedal).

How could I achieve this "one-way" rotation around axis 2?

Thanks!
--
Vaillancourt

Oleh Derevenko

unread,
Jun 16, 2021, 9:22:38 AM6/16/21
to ode-...@googlegroups.com

Did you check the demos included with the library? There is a cart in demo_crash, IIRC.

 

Oleh Derevenko

-- Skype with underscore
GPG Key Fingerprint: 2F56 32DC DCD9 B2BB 06E9 39E8 A37E 5E60 376E C691

--
You received this message because you are subscribed to the Google Groups "ode-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ode-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ode-users/73088229-c39f-413b-bff5-5c8566dc7d50n%40googlegroups.com.

openpgp-digital-signature.asc

Vaillancourt

unread,
Jun 16, 2021, 1:02:16 PM6/16/21
to ode-users
Thanks for the reply Oleh,

I have tested this demo and I could reproduce the issue I get in my software; essentially:

* Change `CMASS` from 1 to 100
* Change `WMASS` from 1 to 10
* Change `FMAX` from 25 to 5
* Incline the ground plane (from `dCreatePlane (space,0,0,1,0);` to `dCreatePlane (space,-0.25,0,0.75,0);`

The result we get is (aside from the boxes blowing up at start and an occasional crash), that the car will start rolling down the plane because it has not enough force to keep it still, even if we request non-zero speed to drive up the grade.

I'd like to tell my wheels "if you have a speed request going in a specific direction, don't go in the opposite direction, even if you don't have enough force; just don't move".

Is there a clever way to achieve this with the available settings?

Thanks!

I'm currently testing this in 0.16.2; I have joined the modified file for convenience.

--
Vaillancourt
demo_crash.cpp

Danny Chapman

unread,
Jun 16, 2021, 1:42:51 PM6/16/21
to ode-...@googlegroups.com
On Wed, 16 Jun 2021 at 14:15, Vaillancourt <alexandre.vai...@gmail.com> wrote:

I'm in the process of creating a vehicle. For this, I'm using four Hinge-2 joints. I would like to allow the wheels (axis 2) to drive only in one direction, so allow them to drive forward, but not backward.

You can use multiple constraints to set up a single "thing". For example, if you have a joint with angular limits and a motor, don't create a single motor and ask it to do both (the API lets you through the strange limot thing, but the behaviour is quite bad). Instead, create two constraints, one for the angular limit, the other for the motor drive.

In your case, what you want to do is create two angular motors for each wheel (each with the same orientation etc):
  • One motor is only able to drive the wheel forwards.  It would use your drive velocity. it would have a positive max torque limit for driving forwards, and a zero min limit for driving backwards.
  • The other motor is only able to stop the wheel rolling backwards. It would use a zero drive velocity. It would have a large max limit (so it can drive from negative velocities to zero velocity), and it would have a zero min limit (i.e. it would never drive to slow the wheel down when going forwards).
The problem is, that in vanilla ODE you can't do that! You only have the dParamFMax parameter, so you can't set a different min/max force/torque limit.
However, it's quite easy to modify things, so you could add a dParamFMin parameter. The code that is using the max value for min and max force is in joint.cpp (it might have moved - my code is based on an oldish version):

        if ( powered )
        {
            pairRhsCfm[GI2_CFM] = normal_cfm;
            if ( ! limit )
            {
                pairRhsCfm[GI2_RHS] = vel;
                pairLoHi[GI2_LO] = -fmax;
                pairLoHi[GI2_HI] = fmax;

You can see it is quite easy to explicitly set different min/max values.

I actually made my own constraints to implement angular and linear spring dampers with a nicer API (e.g. exposed as spring stiffness/damping rather than the raw cfm/erp), including things like these asymmetric min/max force limits. 

Hope this helps!

- Danny
 
--

Vaillancourt

unread,
Jun 17, 2021, 1:14:38 PM6/17/21
to ode-users
Thanks Danny, I think we'll give you suggestion a try!

Oleh Derevenko

unread,
Jul 3, 2021, 7:41:46 AM7/3/21
to ode-...@googlegroups.com

Hi Danny,

 

I guess, we can add the minimum limit as a separate parameter if you find it useful. Why not?

 

Oleh Derevenko

-- Skype with underscore
GPG Key Fingerprint: 2F56 32DC DCD9 B2BB 06E9 39E8 A37E 5E60 376E C691

 

openpgp-digital-signature.asc
Reply all
Reply to author
Forward
0 new messages