AI: Obstacle Avoidance

See all my AI projects HERE

For Obstacle Avoidance, I created a few circles of different sizes as obstacles, and a circular actor moving around while tring to avoid all the obstacles without using any colliders.oa1

The actor is constantly casting two rays with certain length from each side of its body, always pointing at the direction it is moving towards.

oa3

RaycastHit2D hit1 = Physics2D.Raycast(_collision_detector1.transform.position, _actor.Velocity, COLLISION_LINE_SCALE);
RaycastHit2D hit2 = Physics2D.Raycast(_collision_detector2.transform.position, _actor.Velocity, COLLISION_LINE_SCALE);

Whenever the rays hit something, no matter if it is just one of them or both, I know where exactly the ray is intercepting with the obstacle. I calculate the “proportion” of the distance to the intercept point of the length of the ray, then subtract it by 1, name it T.

oa4oa5

oa6

If the ray didn’t hit anything, T = 0. Now I can decide which way to steer to base on which ray has a higher T. Also, T is actually the “level of emergency” to steer away, so I can use it to decide how much we steer and how much we brake.

if (hit1 || hit2) {
    float dis1 = hit1 ? (hit1.point - new Vector2 (_collision_detector1.transform.position.x, _collision_detector1.transform.position.y)).magnitude : COLLISION_LINE_SCALE;
    float prop1 = (1.0f - dis1 / COLLISION_LINE_SCALE);
    float dis2 = hit2 ? (hit2.point - new Vector2 (_collision_detector2.transform.position.x, _collision_detector2.transform.position.y)).magnitude : COLLISION_LINE_SCALE;
    float prop2 = (1.0f - dis2 / COLLISION_LINE_SCALE);
    float prop = prop1 >= prop2 ? prop1 : prop2;
    bool right = prop1 >= prop2 ? true : false;

    steer = Steer (prop, right);
    brake = Brake (prop);
    }
else {
    steer = Vector2.zero;
    brake= Vector2.zero;
}

For steering the amount could be linear to the proportion, but for braking its better to make it exponential.

private Vector2 Steer(float proportion, bool right){
    int r = right ? 1 : -1;
        return new Vector2 (-_actor.Velocity.y, _actor.Velocity.x).normalized * MAX_STEER  * proportion  * r;
}

private Vector2 Brake(float proportion){
    return _actor.Velocity.normalized  * proportion * proportion  * MAX_BRAKE * -1.0f;
}

For easier debugging, I drew a box to visualize the rays, also when an obstacle is detected, it turns yellow, and when it’s collided into, it turns red. As a result, it looks like this:oa2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s