It is said that:
Vec3 steerToAvoidObstacles (const float minTimeToCollision,const ObstacleGroup& obstacles)
Returns a steering force to avoid given obstacles. ..... If multiple Obstacles were specified, and multiple potential collisions exist, the nearest (most urgent) one is chosen.
So I can only avoid one obstacle [nearest one] at one time. but now I want to avoid many obstacles, how can I achieve that? Is it necessary to change the SteerLibrary.h or Obstacle.cpp?
Here's an example:
_____________________Obstacle II
|
|
|
| O---> steering force I
| |\
| | \
| steering | \
| force II v \ sum of the two force
|
Obstacle I
Thanks!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
sorry for the ugly picture
this one is better, but still ugly:(
_____________________Obstacle II
|+++++++++++++++++++++
|+++++++++++++++++++++
|+++++++++++++++++++++
|++++++++++O---> steering force I
|++++++++++|\+++++++++
|++++++++++|+\++++++++
|+steering+|++\+++++++
|+force II+v++_|+++++
|+++++++++++++++sum of the two force
Obstacle I
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You are correct that while steerToAvoidObstacles handles multiple obstacles, it assumes that they are disjoint, so can be avoided one at a time. For example in the world of the "capture the flag demo" the collection of obstacles can be avoided by picking the nearest one, avoiding it, and temporarily ignoring the others.
The general problem of avoiding unstructured overlapping obstacles is quite difficult. OpenSteer does not provide a solution for that. The map-based avoidance in the MapDrive demo is one approach to this more general problem -- it works by "rasterizing" the collection of obstacles onto a grid map, then processing the map for obstacle avoidance. Some have approached this with a field potential model, assuming the obstacles give off an electric field, and steering down the gradient of this field.
However, if the example you gave is typical of your environment, there may be easier solutions. Indoor and urban environments are composed mainly of "walls" arranged at right angles. For this special case there are simple strategies to avoid collections of walls. For an example take a look at the code for BoxObstacle::findIntersectionWithVehiclePath in Obstacle.cpp ( http://opensteer.svn.sourceforge.net/viewvc/opensteer/trunk/src/Obstacle.cpp?revision=181&view=markup ) its not well commented, but the value for pi.steerHint is a vector that points from the path intersection toward the center of the box (if we are inside the box, or away from the center if we are outside the box).
Perhaps you could define a new obstacle type representing a 90 degree "corner" between two walls, then connect those together with "wall" segments made of BoxObstacle or RectangleObstacle. Then walls would be avoided normally while corners could have the intended radial avoidance. EG, one "CornerObstacle" and two RectangleObstacles:
cccccccccrrrrrr
c
c
c
c
r
r
r
r
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is said that:
Vec3 steerToAvoidObstacles (const float minTimeToCollision,const ObstacleGroup& obstacles)
Returns a steering force to avoid given obstacles. ..... If multiple Obstacles were specified, and multiple potential collisions exist, the nearest (most urgent) one is chosen.
So I can only avoid one obstacle [nearest one] at one time. but now I want to avoid many obstacles, how can I achieve that? Is it necessary to change the SteerLibrary.h or Obstacle.cpp?
Here's an example:
_____________________Obstacle II
|
|
|
| O---> steering force I
| |\
| | \
| steering | \
| force II v \ sum of the two force
|
Obstacle I
Thanks!
sorry for the ugly picture
this one is better, but still ugly:(
_____________________Obstacle II
|+++++++++++++++++++++
|+++++++++++++++++++++
|+++++++++++++++++++++
|++++++++++O---> steering force I
|++++++++++|\+++++++++
|++++++++++|+\++++++++
|+steering+|++\+++++++
|+force II+v++_|+++++
|+++++++++++++++sum of the two force
Obstacle I
You are correct that while steerToAvoidObstacles handles multiple obstacles, it assumes that they are disjoint, so can be avoided one at a time. For example in the world of the "capture the flag demo" the collection of obstacles can be avoided by picking the nearest one, avoiding it, and temporarily ignoring the others.
The general problem of avoiding unstructured overlapping obstacles is quite difficult. OpenSteer does not provide a solution for that. The map-based avoidance in the MapDrive demo is one approach to this more general problem -- it works by "rasterizing" the collection of obstacles onto a grid map, then processing the map for obstacle avoidance. Some have approached this with a field potential model, assuming the obstacles give off an electric field, and steering down the gradient of this field.
However, if the example you gave is typical of your environment, there may be easier solutions. Indoor and urban environments are composed mainly of "walls" arranged at right angles. For this special case there are simple strategies to avoid collections of walls. For an example take a look at the code for BoxObstacle::findIntersectionWithVehiclePath in Obstacle.cpp ( http://opensteer.svn.sourceforge.net/viewvc/opensteer/trunk/src/Obstacle.cpp?revision=181&view=markup ) its not well commented, but the value for pi.steerHint is a vector that points from the path intersection toward the center of the box (if we are inside the box, or away from the center if we are outside the box).
Perhaps you could define a new obstacle type representing a 90 degree "corner" between two walls, then connect those together with "wall" segments made of BoxObstacle or RectangleObstacle. Then walls would be avoided normally while corners could have the intended radial avoidance. EG, one "CornerObstacle" and two RectangleObstacles:
cccccccccrrrrrr
c
c
c
c
r
r
r
r