I feel like I've got my head around steering behaviors, but I've having trouble applying them to a car. The steering behaviors return forces that one could apply to an object that can move in any direction, but a car can essentially only move forward and turn. I'm having trouble determining how hard the car should turn or how much it should accelerate forward based on the steering force. How can I translate a steering force into the car's input?
2 Answers
You will have to calculate the desired input (steering and throttle) based on:
- The relative direction of the desired velocity when compared to the current velocity (for steering input)
- The relative magnitude of the desired velocity when compared to the current velocity (for throttle input)
For calculating steering input, we need to calculate the amount of steering it will take to rotate the current velocity vector in the direction of the desired velocity vector based on the angle of steering at maximum lock in radians (maxSteerAngleInRad
).
Assuming full left and right lock is represented by -1
and 1
respectively, the steering input can be calculated as follows (desired
and current
are the desired and current velocity vectors):
fullSteers = acos(dot(desired.normalized, current.normalized)) / maxSteerAngleInRad
steer = sign(dot(leftperp(desired), current)) * fullSteers
where leftperp
for a 2D vector (x, y)
is given as (y, -x)
. The sign
expression serves to provide the direction (left or right) to steer in. If desired
is to the left of current
, the expression returns -1
and 1
if it is to the right.
If the steering input is reversed (i.e. positive values represent left and negative values represent right), simply use the right perpendicular ((-y, x)
) instead of the left or simply negate the value of steer
.
To get rid of the acos
call, you can use a more inaccurate albeit more performant approach wherein fullSteers
is the quotient of the normalized cross products (where cross(a, b) = a.x * b.y - a.y * b.x
) of the desired and current velocities, and the sine of maxSteerAngleInRad
(which can be precalculated).
steer
should also be clamped between -1
and 1
if your vehicle input system does not do so.
For calculating throttle input, we simply need to accelerate if desired.magnitude
(desired speed) is more than current.magnitude
(current speed), and brake if it is the other way around. You may also want to choose intermediary throttle values based on the speed difference and the vehicle throttle response.
-
\$\begingroup\$ What does "turningCircleInRad" refer to exactly? I'm a little unclear on what a turning circle is. \$\endgroup\$ Oct 25, 2017 at 1:48
-
\$\begingroup\$ I should have made myself more clear. I have edited the variable name for clarity. \$\endgroup\$– EvilTakOct 25, 2017 at 7:08
If you need to figure out which way to turn the car's wheels, then taking the determinant of a target position(that's been subtractad from the car's position) and the car's direction will work.
-
\$\begingroup\$ Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. \$\endgroup\$– Community BotOct 14, 2021 at 8:33