4
\$\begingroup\$

I want a system, where a tank moves and rotates based on the speeds I give him for the two tracks, for example, if I give the left track a speed of 1 and the right one a speed of -1, then I want the tank to stay still and rotate right, while if I give the left track 1 and the right track -0.5, I want it to rotate, but at the same time move forwardenter image description here

Of course the speeds will be between -1 and 1

\$\endgroup\$
  • \$\begingroup\$ Average the speeds to get forward speed, take difference and divide by tank radius to get the angular velocity? \$\endgroup\$ – avl_sweden Feb 21 '17 at 17:56
3
\$\begingroup\$

Disclaimer: this is based on intuition only, and there's definitely a missing piece for it to be mathematically exact. However, as far as I can tell, it should be a good enough approximation for small displacement values.

The idea is that the center of each tread describes a perfect motion, without skidding. Let's draw a diagram:

O is your tank's origin, L and R are the treads' centers. Then you'd perform as follows:

  • L and R are found by taking the left and right orthogonal rotations of your direction vector d, and adding them to the origin;
  • L' and R' are found by applying the two lateral speeds to L and R WRT the direction vector.
    i.e. L' = L + speed(L) x d and R' = R + speed(R) x d;
  • O' is the middle of [L'R'], i.e. (L' + R') / 2;
  • The new direction vector is orthogonal to [L'R'].

The approximation comes from the fact that L'R' > LR, that is, the tank actually stretches slightly when turning. Fixing that would require more advanced tools (some sort of curved vector ? I have no clue :p). However, as long as the speeds for each frame remain relatively small, this should be good enough.

\$\endgroup\$
0
\$\begingroup\$

The following example code shows a simple way to move a tank around realistically. It animates a 2D tank from a bird's eye view, but the calculations are the same in any case.

It assumes you have created a sprite named tank, and that you have centred its origin. There are some general notes after the code.

const hone = function(current, target) {

    // This helper takes current and target speeds, and returns
    // the value that the current speed should update to next.

    return current - Math.sign(current - target) / 100;
};

let speed, differential; // the tank speed and track differential

// The user can only set the *target* speed of a track. The actual
// track will usually take some time to reach that speed:

let leftSpeed = 0;  // the actual speed of the left track
let rightSpeed = 0; // the actual speed of the right track
let leftTargetSpeed = 0;  // the target speed of the left track
let rightTargetSpeed = 0; // the target speed of the right track

engine.update = function() {

    // Update the target speeds, then update the actual speeds:

    [leftTargetSpeed, rightTargetSpeed] = ui.levers.getState();
    leftSpeed = hone(leftSpeed, leftTargetSpeed);
    rightSpeed = hone(rightSpeed, rightTargetSpeed);

    // Calculate the `speed` and `differential`:

    speed = (leftSpeed + rightSpeed) / 2;
    differential = leftSpeed - rightSpeed;

    // Then the magic happens...

    tank.rotation += differential;
    tank.position.x += Math.cos(tank.rotation) * speed;
    tank.position.y += Math.sin(tank.rotation) * speed;
};
  • The engine.update function will be invoked on every animation frame.
  • The ui.levers.getState method returns a list of two floats (each between -1 and 1), representing the state of two levers that the user pushes and pulls to control each track.
  • In practice, you'll need to multiply or divide some values, else your tank will drive too fast, or spin too slowly or something.
\$\endgroup\$
-1
\$\begingroup\$

Have a vector for each wheel and then calculate the cross product for the direction the tank should be facing with the result of cross(leftWheel, rightWheel);

\$\endgroup\$
  • 1
    \$\begingroup\$ You can't use cross on 2d vectors... \$\endgroup\$ – Bálint Feb 20 '17 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.