Moving a vehicle with force based controls

I’m trying to implement force-based controls for a tank/vehicle style entity. The entity has a box collider (so it’s essentially a box) and I apply a force (along the local z-axis) to push it forward as well as a moment (around the local y-axis) to turn it. The entity also has a third-person camera attached to it, which is following it around.

During movement, the object is bumping a lot, which causes unwanted camera shake. I think this is caused by inaccuracies in the physics engine, which make me temporarily steer the corners and edges of the cube into the ground. The physics engine will then resolve this collision by displacing (teleporting) the entity, leading to undesirable bumps. It could be caused by something else though; this is my best guess so far.

Does anybody have any ideas what the cause is and how to remedy it?

Here is the control script and I will also add the project, once I figured out how to get a sharable link.

CozmoController.js
var CozmoController = pc.createScript('CozmoController');

CozmoController.attributes.add('translation_power', {
    type: 'number',
    default: 1,
    description: 'Translational Acceleration'
});

CozmoController.attributes.add('rotation_power', {
    type: 'number',
    default: 0.01,
    description: 'Rotational Acceleration'
});

// initialize code called once per entity
CozmoController.prototype.initialize = function() {
    this.force = new pc.Vec3();
    this.angular = new pc.Vec3();
    this.eulers = new pc.Vec3();
    this.colliderEntity = this.entity;

    var app = this.app;
};

// update code called every frame
CozmoController.prototype.update = function(dt) {
    
    var forward = this.colliderEntity.forward;
    var up = this.colliderEntity.up;

    var app = this.app;

    // movement
    var translationDirection = 0;
    var rotationDirection = 0;

    // Use W-A-S-D keys to move player
    // Check for key presses
    if (app.keyboard.isPressed(pc.KEY_A)) {
        rotationDirection++;
    }

    if (app.keyboard.isPressed(pc.KEY_D)) {
        rotationDirection--;
    }

    if (app.keyboard.isPressed(pc.KEY_W)) {
        translationDirection++;
    }

    if (app.keyboard.isPressed(pc.KEY_S)) {
        translationDirection--;
    }

    if (translationDirection !== 0) {
        this.entity.rigidbody.applyForce(
            forward.clone().normalize().scale(translationDirection * this.translation_power)
        );
        console.log(forward);
    }
    
    if (rotationDirection !== 0) {
        this.entity.rigidbody.applyTorque(
            up.clone().normalize().scale(rotationDirection * this.rotation_power)
        );
    }
    

};

Edit:
So based on my reading I should simply be able to share the editor link (the project is public), and that should give read-only access to people that are not me.

Here is the project link: https://playcanvas.com/editor/scene/1046551

Edit 2:

If I set the Y-component of the rigidbody’s linear fact to 0, the movement is smooth. However, this is not a solution, because (a) I loose friction between the ground and the entity, (b) the object “floats” above the ground, (c ) I don’t think I can steer up ramps (untested).

Does anybody have a better idea?

I don’t see jitters here:

@yaustar Yes, presumably because the LinearFactor is set to 0 for the Y-component. This way there is no gravity and the robot/entity actually floats over the ground.

If you set the value to 1 then you should see the jitter.

Tangent: I’ve noticed these videos across the forum. Is there documentation on how to create them? If so, I will create a short clip of the problem and add it to the top post.

Edit: I created a branch and checkpoint for the faulty version when I created the post and then continued editing it to see if I can fix it. Is there a way to share a specific branches of a project?

(sorry for the many questions; I’m still new to playcanvas and getting up to speed)

Recor[quote=“FirefoxMetzger, post:4, topic:16214”]
Tangent: I’ve noticed these videos across the forum. Is there documentation on how to create them? If so, I will create a short clip of the problem and add it to the top post.
[/quote]

Record using a screen video using something like OBS, Kap, ShareX and upload the MP4 video file as part of your post :slight_smile:

1 Like

I managed to reduce the amount of jitter by attaching the box collider to a child entity and setting the top level collider to type “compound”. Still not completely jitter free, - and it feels a little esoteric - so I’m still hoping for some wise person to enlighten me as to how to do this properly.

Not really sure what the jitter is from :thinking: It almost looks like it wants to roll. How does it look when you detach the camera? I’m wondering if this is an order update issue?

If you look at the tracks you can see them dipping into the ground, in particular while turning on the spot.

With a cylindrical collider it actually clips half way into the ground and jitters uncontrollably

The cylindrical collider “falls” into the box collider in the beginning. Collision should avoid them getting stuck in each other, no?

Only thing I can think of is that the size of all the colliders/world is very small. The bot is 3cm cube.

Physics libraries tend to not handle very small objects very well so I would try scaling everything up so that the bot is about 1m.

(Side note: Collision extents are not linked to the entity scale.)

I’ve forked the project and scaled everything up, the physics looks more stable now:

Yes! I will have to do some more work tomorrow to get rid of skidding (drifting with tank tracks seems a little unrealistic), but sizing things up does indeed fix the jitter. Thank you so much for that!

1 Like