tags:

views:

1501

answers:

0

My input is Position report of a vehicle:

0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,106,28,0,0,0,26,137745,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1

In order, these are: Type, Time, VID, Spd, XWay, Lane, Dir, Seg, Pos, QID, Sinit, Send, DOW, TOD and Day.

Problem statement:

Alert Accident if two or more vehicles have more than three position report as same.

The rule works well with the DRL attached below.

To make it work I've included 'retract (vehLoc);' in the rule "Identify Collided Vehicles". Which I don't want to do. If I comment this line, rules are getting fired again with first record of VID '107'.

Though I include no-loop true, still the rules are fired when i modify either Vehicle location or Statistics.

May I know what else I can do to achieve desired functionality?

Output: (with retract (vehLoc);)

Setup statistics
Add to stopped cars -- 107---2
Identify Collided Vehicles---2----107
Add to stopped cars -- 107---3
Identify Collided Vehicles---3----107
Add to stopped cars -- 107---4
Identify Collided Vehicles---4----107
Add to stopped cars -- 109---5
Identify Collided Vehicles---5----109
Add to stopped cars -- 109---6
Identify Collided Vehicles---6----109
Add to stopped cars -- 106---7
Identify Collided Vehicles---1----106
Add to stopped cars -- 109---8
Identify Collided Vehicles---7----109
Add to stopped cars -- 109---9
Identify Collided Vehicles---8----109
no of veh : 2
Detect Accident
no of veh : 2

Output: (without retract (vehLoc);)

Setup statistics
Add to stopped cars -- 107---2
Identify Collided Vehicles---2----107
Add to stopped cars -- 107---3
Identify Collided Vehicles---3----107
Add to stopped cars -- 107---4
Identify Collided Vehicles---4----107
Add to stopped cars -- 107---5
Identify Collided Vehicles---5----107
Add to stopped cars -- 107---6
Identify Collided Vehicles---6----107
Add to stopped cars -- 107---7
Identify Collided Vehicles---7----107
Add to stopped cars -- 107---8
Identify Collided Vehicles---8----107
Add to stopped cars -- 107---9
Identify Collided Vehicles---9----107
Add to stopped cars -- 107---10
Identify Collided Vehicles---10----107
Add to stopped cars -- 107---11
Identify Collided Vehicles---11----107

Here is my DRL

package com.hp.hpl.CHAOS.LR;

# importing classes
import java.lang.Integer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.hp.hpl.CHAOS.Rules.VehicleLocation;

global java.lang.String output

declare VehicleLocation
    @role    ( event )
    @expires ( 1m )
end 

declare Statistics
    smashedcars  : ArrayList
    stopped_cars : ArrayList
    accidents    : ArrayList
    collided_at  : HashMap
end

rule "Setup statistics"
    salience 110
    no-loop true
when
   not( Statistics( ) )
   vehLoc : VehicleLocation()
then
   Statistics s = new Statistics();
   s.setSmashedcars (new ArrayList());
   s.setStopped_cars (new ArrayList());
   s.getStopped_cars().add(vehLoc);
   s.setCollided_at(new HashMap());
   insert( s );
   System.out.println("Setup statistics");
end

rule "Add to stopped cars"
    salience 100
    no-loop true
when
    vehLoc : VehicleLocation()
    $stat  : Statistics ()
    ((not( VehicleLocation(vid == vehLoc.vid) from $stat.getSmashedcars())))
then
    modify($stat) {
     getStopped_cars().add(vehLoc);
    }
    System.out.println("Add to stopped cars -- " + vehLoc.getVid() + "---" + $stat.getStopped_cars().size());
end


rule "Identify Collided Vehicles"
    salience 90
    no-loop true
when
    vehLoc : VehicleLocation()
    $stat  : Statistics ()
    $allStoppedcars : ArrayList( size > 0 )
             from collect ( VehicleLocation(xway == vehLoc.xway,
                          pos == vehLoc.pos,
                          dir == vehLoc.dir,
                          lane == vehLoc.lane) from $stat.stopped_cars)
then
    System.out.println("Identify Collided Vehicles" + "---" + $allStoppedcars.size() + "----" + vehLoc.getVid());

    modify($stat) {
     setCollided_at(collided_at($allStoppedcars,
              vehLoc.getXway(),
              vehLoc.getPos(),
              vehLoc.getDir(),
              vehLoc.getLane()));
    }
    retract (vehLoc);
end

rule "Detect Accident"
    salience 80
    no-loop true
when
    $stat  : Statistics (eval(collision_occured($stat.getCollided_at())))
then
    System.out.println("Detect Accident");
end

function HashMap collided_at(ArrayList stopped_cars, int x, int pos, int dir, int lane) {
    HashMap collided_at = new HashMap();
    for (Iterator iterator = stopped_cars.iterator(); iterator.hasNext(); ) {
        VehicleLocation vehLoc = (VehicleLocation) iterator.next();
        if (vehLoc.getXway() == x 
            && vehLoc.getPos() == pos 
            && vehLoc.getDir() == dir 
            && vehLoc.getLane() == lane) {

            int key = vehLoc.getVid();
            if (!collided_at.containsKey(key)) {
                collided_at.put (key, new Integer(1));
                continue;
            }
            collided_at.put (key, ((Integer)collided_at.get(key)).intValue()+1);
        }
    }
    return collided_at;
}

function boolean collision_occured(HashMap collided_vehicles) {
    java.util.Set entries = collided_vehicles.entrySet();
    int noOfCollidedVehicles = 0;
    java.util.Iterator iterator = entries.iterator();

    while ( iterator.hasNext() ) {
        java.util.Map.Entry object = (java.util.Map.Entry) iterator.next();
        if ((Integer)object.getValue() > 3) {
            noOfCollidedVehicles += 1;
        }
    }

    if (noOfCollidedVehicles > 1) {
        System.out.println("no of veh : "  + noOfCollidedVehicles);
        return true;
    }
    return false;
}