avoid_steerI am studying obstacle avoidance steering behaviour. So far I got arrive seek flee, and wander behaviours working, so the math should be right.

Why doesn't this avoid steer behaviour work, though? It outputs force left and right on alternate frames, resulting in the object getting stuck on the obstacle.

export function avoid_steer(position: Matrix, obstacles: Array<Vec2>, distance: number) {

  let orig = matrix_translate(position)
  let forward = matrix_forward(position).scale_in(10)
  let side = matrix_side(position).normalize.scale_in(distance/2)

  let potential = obstacles.map(_ => {
    let o_local = position.inverse.mVec2(_)

    return Math.abs(o_local.y)
  let i = potential.indexOf(Math.min(...potential))
  let d = potential[i]
  let o = obstacles[i]

  if (d < distance) {
    return position.mVec2(position.inverse.mVec2(o).set_in(0).inverse).sub(orig)
  } else {
    return Vec2.zero

position is a 3x3 matrix that defines the object's transformation as translation, forward and side vectors as its basis. The mVec2 method on a matrix multiplies a vector by the matrix, transforming it into its own space. inverse takes the inverse of the matrix, or the vector.

Here's some reference of what I am trying to do (from "Steering Behaviours for Autonomous Characters" by Crag Reynolds)

By localizing the center of each spherical obstacle, the test for non-intersection with the cylinder is very fast. The local obstacle center is projected onto the side-up plane (by setting its forward coordinate to zero) if the 2D distance from that point to the local origin is greater than the sum of the radii of the obstacle and the character, then there is no potential collision. Similarly obstacles which are fully behind the character, or fully ahead of the cylinder, can be quickly rejected. For any remaining obstacles a line-sphere intersection calculation is performed. The obstacle which intersects the forward axis nearest the character is selected as the “most threatening.” Steering to avoid this obstacle is computed by negating the (lateral) side-up projection of the obstacle’s center.

  • \$\begingroup\$ Can you show us an example of a collection of obstacles for which this approach fails? An animated gif could be useful in illustrating the behaviour. \$\endgroup\$
    – DMGregory
    May 15 at 12:00
  • \$\begingroup\$ Continuously steering left and right seems a dead-end road scenario: the steerer could circumnavigate the obstacle ensemble (multiple objects in front of it) or do a U-turn (inner wall corners); however, it doesn't have information about the surroundings, and since the only allowed movement is turning left and right, this leads to indefinitely turning on spot. \$\endgroup\$
    – liggiorgio
    May 15 at 13:36
  • \$\begingroup\$ obstacle is a little bit bigger than it looks, that is the distance parameter is 2000 where whole area is 64000. Also here's a live version eguneys.github.io/spring2d \$\endgroup\$
    – eguneys
    May 15 at 14:27
  • \$\begingroup\$ I don't understand why it doesn't stick to one side, it's hard to debug. \$\endgroup\$
    – eguneys
    May 15 at 14:32


You must log in to answer this question.

Browse other questions tagged .